Skip to content

Commit 168f390

Browse files
authored
Feature/OpenAI agents content capture (#3824)
1 parent 40932c2 commit 168f390

File tree

16 files changed

+3027
-684
lines changed

16 files changed

+3027
-684
lines changed

instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
([#3805](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3805))
1313
- Implement OpenAI Agents span processing aligned with GenAI semantic conventions.
1414
([#3817](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3817))
15+
- Input and output according to GenAI spec.
16+
([#3824](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3824))
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copy to .env and add values before running the sample.
2+
# Required for OpenAI client (only used if you swap in a real OpenAI call)
3+
OPENAI_API_KEY=
4+
5+
# Optional overrides for span attributes / exporters
6+
OTEL_SERVICE_NAME=openai-agents-content-capture-demo
7+
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
8+
OTEL_EXPORTER_OTLP_PROTOCOL=grpc
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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. Copy `.env.example` to `.env` and provide any overrides you need (for example,
19+
setting `OTEL_EXPORTER_OTLP_ENDPOINT`).
20+
3. Ensure `openai-agents` is installed in the environment (it is included in
21+
the shared development venv for this repository).
22+
23+
## Run the demo
24+
25+
```bash
26+
python main.py
27+
```
28+
29+
The script will:
30+
31+
- Configure the OpenTelemetry SDK with an OTLP exporter so spans reach your collector.
32+
- Instrument the OpenAI Agents tracing hooks with content capture enabled.
33+
- Simulate an agent invocation that performs a generation and a tool call.
34+
- Print the resulting spans, attributes, and events (including JSON-encoded
35+
prompts and responses) to stdout.
36+
37+
## Customisation tips
38+
39+
- Set `OTEL_SERVICE_NAME` before running to override the default service name.
40+
- Adjust the OTLP exporter configuration (endpoint, protocol) through `.env`.
41+
- Modify the prompts, tool payloads, or add additional spans in `run_workflow`
42+
to explore different content capture scenarios.
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
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+
from dotenv import load_dotenv
19+
20+
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import (
21+
OTLPSpanExporter,
22+
)
23+
from opentelemetry.instrumentation.openai_agents import (
24+
OpenAIAgentsInstrumentor,
25+
)
26+
from opentelemetry.sdk.resources import Resource
27+
from opentelemetry.sdk.trace import TracerProvider
28+
from opentelemetry.sdk.trace.export import BatchSpanProcessor
29+
30+
load_dotenv() # take environment variables from .env.
31+
32+
33+
def configure_tracing() -> None:
34+
"""Configure a tracer provider that exports spans via OTLP."""
35+
resource = Resource.create(
36+
{
37+
"service.name": os.environ.get(
38+
"OTEL_SERVICE_NAME", "openai-agents-content-capture-demo"
39+
)
40+
}
41+
)
42+
provider = TracerProvider(resource=resource)
43+
provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
44+
45+
# Instrument with explicit content capture mode to ensure prompts/responses are recorded.
46+
OpenAIAgentsInstrumentor().instrument(
47+
tracer_provider=provider,
48+
capture_message_content="span_and_event",
49+
system="openai",
50+
agent_name="Travel Concierge",
51+
base_url="https://api.openai.com/v1",
52+
)
53+
54+
55+
def dump(title: str, payload: Any) -> None:
56+
"""Pretty-print helper used to show intermediate context."""
57+
print(f"\n=== {title} ===")
58+
print(json.dumps(payload, indent=2))
59+
60+
61+
def run_workflow() -> None:
62+
"""Simulate an agent workflow with a generation and a tool invocation."""
63+
itinerary_prompt = [
64+
{"role": "system", "content": "Plan high level travel itineraries."},
65+
{
66+
"role": "user",
67+
"content": "I'm visiting Paris for 3 days in November.",
68+
},
69+
]
70+
71+
tool_args = {"city": "Paris", "date": "2025-11-12"}
72+
tool_result = {
73+
"forecast": "Mostly sunny, highs 15°C",
74+
"packing_tips": ["light jacket", "comfortable shoes"],
75+
}
76+
77+
with trace("travel-booking-workflow"):
78+
with agent_span(name="travel_planner") as agent:
79+
dump(
80+
"Agent span started",
81+
{"span_id": agent.span_id, "trace_id": agent.trace_id},
82+
)
83+
84+
with generation_span(
85+
input=itinerary_prompt,
86+
output=[
87+
{
88+
"role": "assistant",
89+
"content": (
90+
"Day 1 visit the Louvre, Day 2 tour Versailles, "
91+
"Day 3 explore Montmartre."
92+
),
93+
}
94+
],
95+
model="gpt-4o-mini",
96+
usage={
97+
"input_tokens": 128,
98+
"output_tokens": 96,
99+
"total_tokens": 224,
100+
},
101+
):
102+
pass
103+
104+
with function_span(
105+
name="fetch_weather",
106+
input=json.dumps(tool_args),
107+
output=tool_result,
108+
):
109+
pass
110+
111+
print(
112+
"\nWorkflow complete – spans exported to the configured OTLP endpoint."
113+
)
114+
115+
116+
def main() -> None:
117+
configure_tracing()
118+
run_workflow()
119+
120+
121+
if __name__ == "__main__":
122+
main()
Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
1-
# Update this with your real OpenAI API key
2-
OPENAI_API_KEY=sk-YOUR_API_KEY
3-
4-
# Uncomment and adjust if you use a non-default OTLP collector endpoint
5-
# OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
6-
# OTEL_EXPORTER_OTLP_PROTOCOL=grpc
7-
8-
OTEL_SERVICE_NAME=opentelemetry-python-openai-agents-manual
9-
10-
# Optionally override the agent name reported on spans
11-
# OTEL_GENAI_AGENT_NAME=Travel Concierge
1+
# Copy to .env and add real values before running main.py
2+
OPENAI_API_KEY=
3+
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
4+
OTEL_EXPORTER_OTLP_PROTOCOL=grpc
5+
OTEL_SERVICE_NAME=openai-agents-manual-demo

instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/examples/manual/README.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Setup
2222
python3 -m venv .venv
2323
source .venv/bin/activate
2424
pip install "python-dotenv[cli]"
25-
pip install -r requirements.txt
25+
uv pip install -r requirements.txt --prerelease=allow
2626

2727
Run
2828
---
@@ -34,6 +34,8 @@ are applied:
3434

3535
dotenv run -- python main.py
3636

37+
Ensure ``OPENAI_API_KEY`` is present in your environment (or ``.env`` file); the OpenAI client raises ``OpenAIError`` if the key is missing.
38+
3739
The script automatically loads environment variables from ``.env`` so running
3840
``python main.py`` directly also works if the shell already has the required
3941
values exported.

instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/examples/zero-code/README.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Setup
2222
python3 -m venv .venv
2323
source .venv/bin/activate
2424
pip install "python-dotenv[cli]"
25-
pip install -r requirements.txt
25+
uv pip install -r requirements.txt --prerelease=allow
2626

2727
Run
2828
---
@@ -34,6 +34,8 @@ instrumentation is activated automatically:
3434

3535
dotenv run -- opentelemetry-instrument python main.py
3636

37+
Ensure ``OPENAI_API_KEY`` is set in your shell or `.env`; the OpenAI client raises ``OpenAIError`` if the key is missing.
38+
3739
Because ``main.py`` invokes ``load_dotenv``, running ``python main.py`` directly
3840
also works when the required environment variables are already exported.
3941

instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ classifiers = [
2626
dependencies = [
2727
"opentelemetry-api >= 1.37",
2828
"opentelemetry-instrumentation >= 0.58b0",
29-
"opentelemetry-semantic-conventions >= 0.58b0"
29+
"opentelemetry-semantic-conventions >= 0.58b0",
30+
"opentelemetry-util-genai"
3031
]
3132

3233
[project.optional-dependencies]

0 commit comments

Comments
 (0)