Commit b738fd9
authored
feat(examples): migrate AI examples to OpenTelemetry instrumentation (#482)
## Problem
Our AI examples use PostHog's direct SDK wrappers (`posthog.ai.openai`, `posthog.ai.anthropic`, etc.) for tracking LLM calls. We want to silently deprecate these in favor of standard OpenTelemetry auto-instrumentation, which is more portable and follows industry conventions.
## Changes
Migrates Python AI examples from PostHog wrappers to OpenTelemetry auto-instrumentation:
- **OpenAI-compatible providers** (Groq, DeepSeek, Mistral, xAI, Together AI, Ollama, Cohere, Hugging Face, Perplexity, Cerebras, Fireworks AI, OpenRouter, Helicone, Vercel AI Gateway, Portkey) → `opentelemetry-instrumentation-openai-v2`
- **OpenAI** (all files), **Azure OpenAI**, **Instructor**, **Autogen**, **Mirascope**, **Semantic Kernel**, **smolagents** → `opentelemetry-instrumentation-openai-v2`
- **Anthropic** (chat, streaming, extended thinking) → `opentelemetry-instrumentation-anthropic`
- **LangChain**, **LangGraph** → `opentelemetry-instrumentation-langchain`
- **LlamaIndex** → `opentelemetry-instrumentation-llamaindex`
- **Gemini** → `opentelemetry-instrumentation-google-generativeai`
All OTel-based examples set resource attributes to demonstrate the full feature set:
```python
resource = Resource(
attributes={
SERVICE_NAME: "example-groq-app",
"posthog.distinct_id": "example-user",
"foo": "bar",
"conversation_id": "abc-123",
}
)
```
These map to `distinct_id` and custom event properties via PostHog's OTLP ingestion endpoint.
**Kept as-is:** CrewAI (uses LiteLLM callbacks, internally manages its own TracerProvider), LiteLLM/DSPy (use LiteLLM's built-in PostHog callback), OpenAI Agents (uses dedicated `posthog.ai.openai_agents.instrument()`), Pydantic AI (already OTel via `Agent.instrument_all()`), AWS Bedrock (already OTel via `opentelemetry-instrumentation-botocore`).
Key implementation details:
- Uses `SimpleSpanProcessor` instead of `BatchSpanProcessor` so spans export immediately without needing `provider.shutdown()`
- `# noqa: E402` on intentional late imports after `Instrumentor().instrument()` calls
- Azure OpenAI example uses the generic `gpt-4o` model name instead of a deployment-specific one
## How did you test this code?
Manually ran each example against real provider API keys via `llm-analytics-apps/run-examples.sh` to verify:
1. Each script runs successfully end-to-end
2. Traces arrive at PostHog as `$ai_generation` events
3. Resource attributes (`posthog.distinct_id`, `foo`, `conversation_id`) flow through as event properties
4. `distinct_id` is correctly set on each event
All examples passing `ruff format` and `ruff check`.
This is an agent-authored PR — I haven't manually tested each provider end-to-end beyond spot checks, though all examples follow the same pattern and the migration was verified on several providers.
## Publish to changelog?
No
## Docs update
The onboarding docs will be updated separately in PostHog/posthog#53668 and PostHog/posthog.com#16236.
## 🤖 LLM context
Co-authored with Claude Code. Related PRs:
- PostHog/posthog-js#3349 (Node.js examples)
- PostHog/posthog#53668 (in-app onboarding docs)
- PostHog/posthog.com#16236 (docs.posthog.com TOC updates)1 parent 794cf07 commit b738fd9
101 files changed
Lines changed: 11434 additions & 2807 deletions
File tree
- examples
- example-ai-anthropic
- example-ai-autogen
- example-ai-aws-bedrock
- example-ai-azure-openai
- example-ai-cerebras
- example-ai-cohere
- example-ai-crewai
- example-ai-deepseek
- example-ai-fireworks-ai
- example-ai-gemini
- example-ai-groq
- example-ai-helicone
- example-ai-hugging-face
- example-ai-instructor
- example-ai-langchain
- example-ai-langgraph
- example-ai-litellm
- example-ai-llamaindex
- example-ai-mirascope
- example-ai-mistral
- example-ai-ollama
- example-ai-openai-agents
- example-ai-openai
- example-ai-openrouter
- example-ai-perplexity
- example-ai-portkey
- example-ai-pydantic-ai
- example-ai-semantic-kernel
- example-ai-smolagents
- example-ai-together-ai
- example-ai-vercel-ai-gateway
- example-ai-xai
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
7 | | - | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
8 | 11 | | |
9 | | - | |
10 | | - | |
11 | | - | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
12 | 26 | | |
13 | | - | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
14 | 34 | | |
15 | 35 | | |
16 | 36 | | |
| |||
40 | 60 | | |
41 | 61 | | |
42 | 62 | | |
43 | | - | |
44 | 63 | | |
45 | 64 | | |
46 | 65 | | |
| |||
53 | 72 | | |
54 | 73 | | |
55 | 74 | | |
56 | | - | |
57 | | - | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
8 | | - | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
9 | 12 | | |
10 | | - | |
11 | | - | |
12 | | - | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
13 | 20 | | |
14 | | - | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
15 | 35 | | |
16 | 36 | | |
17 | 37 | | |
18 | 38 | | |
19 | | - | |
20 | 39 | | |
21 | 40 | | |
22 | 41 | | |
| |||
31 | 50 | | |
32 | 51 | | |
33 | 52 | | |
34 | | - | |
35 | | - | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
7 | | - | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
8 | 10 | | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
5 | | - | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
6 | 9 | | |
7 | | - | |
8 | | - | |
9 | | - | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
10 | 17 | | |
11 | | - | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
12 | 32 | | |
13 | 33 | | |
14 | 34 | | |
15 | 35 | | |
16 | | - | |
17 | 36 | | |
18 | 37 | | |
19 | 38 | | |
| |||
24 | 43 | | |
25 | 44 | | |
26 | 45 | | |
27 | | - | |
| |||
0 commit comments