Kai Jennissen commited on
Commit
d971efd
·
unverified ·
1 Parent(s): c4821fe

tracing with phoenix

Browse files
Files changed (4) hide show
  1. README.md +44 -1
  2. agent.py +40 -1
  3. app.py +3 -36
  4. tracing.py +94 -0
README.md CHANGED
@@ -13,4 +13,47 @@ hf_oauth: true
13
  hf_oauth_expiration_minutes: 480
14
  ---
15
 
16
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  hf_oauth_expiration_minutes: 480
14
  ---
15
 
16
+ # SmolaAgents Course Final Assignment
17
+
18
+ This application is a demonstration of creating a robust agent system with monitoring and tracing capabilities.
19
+
20
+ ## Features
21
+
22
+ - **Multi-Agent System**: Uses a manager agent to orchestrate a specialized web agent.
23
+ - **Advanced Models**: Leverages Qwen and DeepSeek models through HuggingFace's Inference API.
24
+ - **Gradio Interface**: Simple UI for agent interaction and evaluation.
25
+ - **Comprehensive Tracing**: Integrated observability through Langfuse and Phoenix.
26
+
27
+ ## Tracing and Monitoring
28
+
29
+ The application includes a modular tracing system that supports both:
30
+
31
+ ### Langfuse
32
+ - Cloud-based LLM observability platform
33
+ - Configure with environment variables:
34
+ - `LANGFUSE_PUBLIC_KEY`
35
+ - `LANGFUSE_SECRET_KEY`
36
+ - `LANGFUSE_HOST` (defaults to EU region)
37
+
38
+ ### Arize Phoenix
39
+ - Local, open-source LLM observability tool
40
+ - Start the Phoenix UI with:
41
+ ```
42
+ python -m phoenix.server.main serve
43
+ ```
44
+ - View traces at http://localhost:6006
45
+
46
+ You can enable either or both systems by configuring the tracing setup:
47
+
48
+ ```python
49
+ # Use just Langfuse
50
+ initialize_tracing(provider="langfuse")
51
+
52
+ # Use just Phoenix
53
+ initialize_tracing(provider="phoenix")
54
+
55
+ # Use both (default)
56
+ initialize_tracing(provider="both")
57
+ ```
58
+
59
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
agent.py CHANGED
@@ -6,11 +6,36 @@ from smolagents import (
6
  InferenceClientModel,
7
  )
8
  from dotenv import load_dotenv
 
9
 
10
  load_dotenv()
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
  def get_agent():
 
 
 
 
 
14
  llm_qwen = InferenceClientModel(
15
  model_id="Qwen/Qwen2.5-Coder-32B-Instruct", provider="together"
16
  )
@@ -18,6 +43,7 @@ def get_agent():
18
  "deepseek-ai/DeepSeek-R1", provider="together", max_tokens=8096
19
  )
20
 
 
21
  web_agent = ToolCallingAgent(
22
  tools=[DuckDuckGoSearchTool(), VisitWebpageTool()],
23
  model=llm_qwen,
@@ -26,6 +52,7 @@ def get_agent():
26
  description="A web agent that can search the web and visit webpages.",
27
  )
28
 
 
29
  manager_agent = CodeAgent(
30
  tools=[],
31
  managed_agents=[web_agent],
@@ -36,7 +63,19 @@ def get_agent():
36
 
37
 
38
  if __name__ == "__main__":
 
 
 
 
39
  agent = get_agent()
40
- agent.run(
 
 
 
41
  "What is the latest news about AI? Please search the web and summarize the results."
42
  )
 
 
 
 
 
 
6
  InferenceClientModel,
7
  )
8
  from dotenv import load_dotenv
9
+ from tracing import setup_tracing
10
 
11
  load_dotenv()
12
 
13
+ # Initialize tracing when module is imported
14
+ trace_provider = None
15
+
16
+
17
+ def initialize_tracing(enabled=True, provider="both"):
18
+ """
19
+ Initialize tracing for the agent module
20
+
21
+ Args:
22
+ enabled: Whether tracing should be active
23
+ provider: Which provider(s) to use - "langfuse", "phoenix", or "both"
24
+ """
25
+ global trace_provider
26
+ if trace_provider is None:
27
+ trace_provider = setup_tracing(
28
+ service_name="smolagent", enabled=enabled, provider=provider
29
+ )
30
+ return trace_provider
31
+
32
 
33
  def get_agent():
34
+ # Ensure tracing is initialized
35
+ initialize_tracing()
36
+
37
+ # SmolagentsInstrumentor will automatically trace agent operations
38
+
39
  llm_qwen = InferenceClientModel(
40
  model_id="Qwen/Qwen2.5-Coder-32B-Instruct", provider="together"
41
  )
 
43
  "deepseek-ai/DeepSeek-R1", provider="together", max_tokens=8096
44
  )
45
 
46
+ # Create web agent
47
  web_agent = ToolCallingAgent(
48
  tools=[DuckDuckGoSearchTool(), VisitWebpageTool()],
49
  model=llm_qwen,
 
52
  description="A web agent that can search the web and visit webpages.",
53
  )
54
 
55
+ # Create manager agent
56
  manager_agent = CodeAgent(
57
  tools=[],
58
  managed_agents=[web_agent],
 
63
 
64
 
65
  if __name__ == "__main__":
66
+ # Initialize tracing when run directly - enable both Langfuse and Phoenix
67
+ initialize_tracing(enabled=True, provider="both")
68
+
69
+ # Get agent with tracing already configured
70
  agent = get_agent()
71
+
72
+ # Run agent - SmolagentsInstrumentor will automatically trace the execution
73
+ print("Running agent with tracing enabled...")
74
+ result = agent.run(
75
  "What is the latest news about AI? Please search the web and summarize the results."
76
  )
77
+ print(f"Result: {result}")
78
+ print(
79
+ "View traces in Phoenix UI (run 'python -m phoenix.server.main serve' in another terminal)"
80
+ )
81
+ print("View traces in Langfuse dashboard (if configured)")
app.py CHANGED
@@ -3,13 +3,7 @@ import gradio as gr
3
  import requests
4
  import pandas as pd
5
  from dotenv import load_dotenv
6
- import base64
7
- from opentelemetry.sdk.trace import TracerProvider
8
- from openinference.instrumentation.smolagents import SmolagentsInstrumentor
9
- from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
10
- from opentelemetry.sdk.trace.export import SimpleSpanProcessor
11
- from opentelemetry import trace
12
- from .agent import get_agent
13
 
14
  load_dotenv()
15
 
@@ -17,35 +11,8 @@ load_dotenv()
17
  # --- Constants ---
18
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
19
 
20
-
21
- # Get your own keys from https://cloud.langfuse.com
22
-
23
-
24
- os.environ["LANGFUSE_HOST"] = "https://cloud.langfuse.com" # 🇪🇺 EU region example
25
- # os.environ["LANGFUSE_HOST"] = "https://us.cloud.langfuse.com" # 🇺🇸 US region example
26
-
27
- LANGFUSE_AUTH = base64.b64encode(
28
- f"{os.environ.get('LANGFUSE_PUBLIC_KEY')}:{os.environ.get('LANGFUSE_SECRET_KEY')}".encode()
29
- ).decode()
30
-
31
- os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"] = (
32
- os.environ.get("LANGFUSE_HOST") + "/api/public/otel"
33
- )
34
- os.environ["OTEL_EXPORTER_OTLP_HEADERS"] = f"Authorization=Basic {LANGFUSE_AUTH}"
35
-
36
- # Create a TracerProvider for OpenTelemetry
37
- trace_provider = TracerProvider()
38
-
39
- # Add a SimpleSpanProcessor with the OTLPSpanExporter to send traces
40
- trace_provider.add_span_processor(SimpleSpanProcessor(OTLPSpanExporter()))
41
-
42
- # Set the global default tracer provider
43
-
44
- trace.set_tracer_provider(trace_provider)
45
- tracer = trace.get_tracer(__name__)
46
-
47
- # Instrument smolagents with the configured provider
48
- SmolagentsInstrumentor().instrument(tracer_provider=trace_provider)
49
 
50
 
51
  # --- Basic Agent Definition ---
 
3
  import requests
4
  import pandas as pd
5
  from dotenv import load_dotenv
6
+ from agent import get_agent, initialize_tracing
 
 
 
 
 
 
7
 
8
  load_dotenv()
9
 
 
11
  # --- Constants ---
12
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
13
 
14
+ # Initialize tracing - smolagents instrumentation will handle the rest
15
+ trace_provider = initialize_tracing(service_name="smolagent-app")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
 
18
  # --- Basic Agent Definition ---
tracing.py ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import base64
3
+ from typing import Optional, Literal
4
+ from opentelemetry.sdk.trace import TracerProvider
5
+ from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
6
+ from opentelemetry.sdk.trace.export import SimpleSpanProcessor
7
+ from opentelemetry import trace
8
+ from openinference.instrumentation.smolagents import SmolagentsInstrumentor
9
+
10
+
11
+ def setup_tracing(
12
+ service_name: str = "agent-service",
13
+ enabled: bool = True,
14
+ provider: Literal["langfuse", "phoenix", "both"] = "langfuse",
15
+ ) -> Optional[TracerProvider]:
16
+ """
17
+ Configure and set up OpenTelemetry tracing with Langfuse and/or Phoenix integration.
18
+
19
+ Args:
20
+ service_name: Name of the service for trace identification
21
+ enabled: Whether tracing should be active
22
+ provider: Which tracing provider(s) to use - "langfuse", "phoenix", or "both"
23
+
24
+ Returns:
25
+ Configured TracerProvider instance or None if disabled
26
+ """
27
+ if not enabled:
28
+ return None
29
+
30
+ trace_provider = None
31
+
32
+ # Setup Phoenix if requested
33
+ if provider in ["phoenix", "both"]:
34
+ try:
35
+ from phoenix.otel import register
36
+
37
+ # Create Phoenix tracer provider
38
+
39
+ trace_provider = register(
40
+ project_name=service_name,
41
+ endpoint="http://127.0.0.1:6006/v1/traces",
42
+ auto_instrument=True,
43
+ )
44
+ print(f"✅ Phoenix tracing enabled for {service_name}")
45
+
46
+ except ImportError:
47
+ print("⚠️ Phoenix not installed. Run: pip install 'smolagents[telemetry]'")
48
+
49
+ # Setup Langfuse if requested
50
+ if provider in ["langfuse", "both"]:
51
+ # Configure Langfuse host
52
+ langfuse_host = os.environ.get("LANGFUSE_HOST", "https://cloud.langfuse.com")
53
+
54
+ # Create auth token for Langfuse
55
+ langfuse_public_key = os.environ.get("LANGFUSE_PUBLIC_KEY")
56
+ langfuse_secret_key = os.environ.get("LANGFUSE_SECRET_KEY")
57
+
58
+ if not langfuse_public_key or not langfuse_secret_key:
59
+ print("⚠️ Langfuse keys not found in environment")
60
+
61
+ # If Phoenix is not set up either, return None
62
+ if trace_provider is None:
63
+ return None
64
+ else:
65
+ langfuse_auth = base64.b64encode(
66
+ f"{langfuse_public_key}:{langfuse_secret_key}".encode()
67
+ ).decode()
68
+
69
+ # Set environment variables for OTLP exporter
70
+ os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"] = (
71
+ f"{langfuse_host}/api/public/otel"
72
+ )
73
+ os.environ["OTEL_EXPORTER_OTLP_HEADERS"] = (
74
+ f"Authorization=Basic {langfuse_auth}"
75
+ )
76
+
77
+ if trace_provider is None:
78
+ # Create new TracerProvider if Phoenix wasn't enabled
79
+ trace_provider = TracerProvider()
80
+ # Set as the global default tracer provider
81
+ trace.set_tracer_provider(trace_provider)
82
+
83
+ # Add Langfuse exporter to the tracer provider
84
+ trace_provider.add_span_processor(SimpleSpanProcessor(OTLPSpanExporter()))
85
+ print(f"✅ Langfuse tracing enabled for {service_name}")
86
+
87
+ if trace_provider:
88
+ # Instrument smolagents with the configured provider
89
+ SmolagentsInstrumentor().instrument(tracer_provider=trace_provider)
90
+
91
+ # Create a single tracer for the entire application
92
+ trace.get_tracer(service_name)
93
+
94
+ return trace_provider