Skip to content

Commit 48a7747

Browse files
committed
Add content capture demonstration
1 parent f63cbbf commit 48a7747

File tree

2 files changed

+158
-0
lines changed
  • instrumentation-genai/opentelemetry-instrumentation-openai-agents/examples/content-capture

2 files changed

+158
-0
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# OpenAI Agents Content Capture Demo
2+
3+
This example exercises the `OpenAIAgentsInstrumentor` with message content
4+
capture enabled, illustrating how prompts, responses, and tool payloads are
5+
recorded on spans and span events.
6+
7+
> The demo uses the local tracing utilities from the `openai-agents`
8+
> package—no outbound API calls are made.
9+
10+
## Prerequisites
11+
12+
1. Activate the repository virtual environment:
13+
14+
```bash
15+
source ../../../../.venv/bin/activate
16+
```
17+
18+
2. Ensure `openai-agents` is installed in the environment (it is included in
19+
the shared development venv for this repository).
20+
21+
## Run the demo
22+
23+
```bash
24+
python main.py
25+
```
26+
27+
The script will:
28+
29+
- Configure the OpenTelemetry SDK with a console span exporter.
30+
- Instrument the OpenAI Agents tracing hooks with content capture enabled.
31+
- Simulate an agent invocation that performs a generation and a tool call.
32+
- Print the resulting spans, attributes, and events (including JSON-encoded
33+
prompts and responses) to stdout.
34+
35+
## Customisation tips
36+
37+
- Set `OTEL_SERVICE_NAME` before running to override the default service name.
38+
- Swap the `ConsoleSpanExporter` in `demo.py` for an OTLP exporter if you want
39+
to ship spans to a collector.
40+
- Modify the prompts, tool payloads, or add additional spans in `run_workflow`
41+
to explore different content capture scenarios.
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
"""
2+
Content capture demo for the OpenAI Agents instrumentation.
3+
4+
This script spins up the instrumentation with message capture enabled and
5+
simulates an agent invocation plus a tool call using the tracing helpers from
6+
the ``openai-agents`` package. Spans are exported to the console so you can
7+
inspect captured prompts, responses, and tool payloads without making any
8+
OpenAI API calls.
9+
"""
10+
11+
from __future__ import annotations
12+
13+
import json
14+
import os
15+
from typing import Any
16+
17+
from agents.tracing import agent_span, function_span, generation_span, trace
18+
19+
from opentelemetry.instrumentation.openai_agents import (
20+
OpenAIAgentsInstrumentor,
21+
)
22+
from opentelemetry.sdk.resources import Resource
23+
from opentelemetry.sdk.trace import TracerProvider
24+
from opentelemetry.sdk.trace.export import (
25+
ConsoleSpanExporter,
26+
SimpleSpanProcessor,
27+
)
28+
29+
30+
def configure_tracing() -> None:
31+
"""Configure a tracer provider that writes spans to stdout."""
32+
resource = Resource.create(
33+
{
34+
"service.name": os.environ.get(
35+
"OTEL_SERVICE_NAME", "openai-agents-content-capture-demo"
36+
)
37+
}
38+
)
39+
provider = TracerProvider(resource=resource)
40+
provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))
41+
42+
# Instrument with explicit content capture mode to ensure prompts/responses are recorded.
43+
OpenAIAgentsInstrumentor().instrument(
44+
tracer_provider=provider,
45+
capture_message_content="span_and_event",
46+
system="openai",
47+
agent_name="Travel Concierge",
48+
base_url="https://api.openai.com/v1",
49+
)
50+
51+
52+
def dump(title: str, payload: Any) -> None:
53+
"""Pretty-print helper used to show intermediate context."""
54+
print(f"\n=== {title} ===")
55+
print(json.dumps(payload, indent=2))
56+
57+
58+
def run_workflow() -> None:
59+
"""Simulate an agent workflow with a generation and a tool invocation."""
60+
itinerary_prompt = [
61+
{"role": "system", "content": "Plan high level travel itineraries."},
62+
{
63+
"role": "user",
64+
"content": "I'm visiting Paris for 3 days in November.",
65+
},
66+
]
67+
68+
tool_args = {"city": "Paris", "date": "2025-11-12"}
69+
tool_result = {
70+
"forecast": "Mostly sunny, highs 15°C",
71+
"packing_tips": ["light jacket", "comfortable shoes"],
72+
}
73+
74+
with trace("travel-booking-workflow"):
75+
with agent_span(operation="invoke", name="travel_planner") as agent:
76+
dump(
77+
"Agent span started",
78+
{"span_id": agent.span_id, "trace_id": agent.trace_id},
79+
)
80+
81+
with generation_span(
82+
input=itinerary_prompt,
83+
output=[
84+
{
85+
"role": "assistant",
86+
"content": (
87+
"Day 1 visit the Louvre, Day 2 tour Versailles, "
88+
"Day 3 explore Montmartre."
89+
),
90+
}
91+
],
92+
model="gpt-4o-mini",
93+
usage={
94+
"input_tokens": 128,
95+
"output_tokens": 96,
96+
"total_tokens": 224,
97+
},
98+
):
99+
pass
100+
101+
with function_span(
102+
name="fetch_weather",
103+
input=json.dumps(tool_args),
104+
output=tool_result,
105+
):
106+
pass
107+
108+
print("\nWorkflow complete – spans exported to console above.")
109+
110+
111+
def main() -> None:
112+
configure_tracing()
113+
run_workflow()
114+
115+
116+
if __name__ == "__main__":
117+
main()

0 commit comments

Comments
 (0)