Skip to content

Commit 4a1ea78

Browse files
committed
Manual GPT (remote) instrumentation example
1 parent caa4cb1 commit 4a1ea78

1 file changed

Lines changed: 113 additions & 0 deletions

File tree

examples/chatgpt_example.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# /// script
2+
# requires-python = ">=3.10"
3+
# dependencies = ["wildedge-sdk", "openai"]
4+
#
5+
# [tool.uv.sources]
6+
# wildedge-sdk = { path = "..", editable = true }
7+
# ///
8+
"""ChatGPT (OpenAI API) — fully manual integration.
9+
10+
Shows how to instrument a remote LLM with no local model file.
11+
Tracks input/output token counts, generation config, latency, errors,
12+
and user feedback without any auto-instrumentation hooks.
13+
14+
Run with: uv run chatgpt_example.py
15+
Requires: WILDEDGE_DSN and OPENAI_API_KEY environment variables.
16+
"""
17+
18+
from openai import OpenAI
19+
20+
import wildedge
21+
from wildedge import FeedbackType, GenerationConfig, GenerationOutputMeta, TextInputMeta
22+
from wildedge.timing import Timer
23+
24+
MODEL = "gpt-4o"
25+
MODEL_VERSION = "2024-08-06"
26+
27+
client = wildedge.WildEdge(
28+
app_version="1.0.0", # set WILDEDGE_DSN env var
29+
)
30+
31+
# Remote models have no local object to inspect, so register with a
32+
# placeholder and supply all metadata explicitly.
33+
handle = client.register_model(
34+
object(),
35+
model_id=f"openai/{MODEL}",
36+
source="https://api.openai.com",
37+
family="gpt-4o",
38+
version=MODEL_VERSION,
39+
)
40+
41+
openai_client = OpenAI() # set OPENAI_API_KEY env var or pass api_key= explicitly
42+
43+
prompts = [
44+
"Explain transformer attention in one sentence.",
45+
"What is the capital of Japan?",
46+
"Write a haiku about edge AI.",
47+
]
48+
49+
temperature = 0.7
50+
max_tokens = 256
51+
52+
for turn_index, prompt in enumerate(prompts):
53+
messages = [{"role": "user", "content": prompt}]
54+
55+
try:
56+
with Timer() as t:
57+
response = openai_client.chat.completions.create(
58+
model=MODEL,
59+
messages=messages,
60+
temperature=temperature,
61+
max_tokens=max_tokens,
62+
)
63+
64+
usage = response.usage
65+
choice = response.choices[0]
66+
completion = choice.message.content or ""
67+
tokens_per_second = (
68+
round(usage.completion_tokens / t.elapsed_ms * 1000, 1)
69+
if usage.completion_tokens and t.elapsed_ms > 0
70+
else None
71+
)
72+
73+
inference_id = handle.track_inference(
74+
duration_ms=t.elapsed_ms,
75+
input_modality="text",
76+
output_modality="text",
77+
success=True,
78+
input_meta=TextInputMeta(
79+
char_count=len(prompt),
80+
word_count=len(prompt.split()),
81+
token_count=usage.prompt_tokens,
82+
prompt_type="chat",
83+
turn_index=turn_index,
84+
contains_code="```" in prompt,
85+
),
86+
output_meta=GenerationOutputMeta(
87+
tokens_in=usage.prompt_tokens,
88+
tokens_out=usage.completion_tokens,
89+
tokens_per_second=tokens_per_second,
90+
stop_reason=choice.finish_reason,
91+
context_used=usage.total_tokens,
92+
),
93+
generation_config=GenerationConfig(
94+
temperature=temperature,
95+
max_tokens=max_tokens,
96+
),
97+
)
98+
99+
print(f"Q: {prompt}\nA: {completion}\n")
100+
101+
# Simulate feedback: short completions get a thumbs down.
102+
feedback_type = (
103+
FeedbackType.THUMBS_UP
104+
if len(completion) > 40
105+
else FeedbackType.THUMBS_DOWN
106+
)
107+
handle.track_feedback(inference_id, feedback_type)
108+
109+
except Exception as exc:
110+
handle.track_error(error_code="UNKNOWN", error_message=str(exc)[:200])
111+
raise
112+
113+
client.close(timeout=5.0)

0 commit comments

Comments
 (0)