SrcLurker commited on
Commit
766d2d7
·
1 Parent(s): 17885ea

change the models, add tracing.

Browse files
Files changed (4) hide show
  1. app.py +30 -0
  2. basic_agent.py +26 -35
  3. basic_agent_test.py +25 -0
  4. requirements.txt +9 -0
app.py CHANGED
@@ -10,6 +10,36 @@ import basic_agent
10
  # --- Constants ---
11
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
  def run_and_submit_all(profile: gr.OAuthProfile | None):
15
  """
 
10
  # --- Constants ---
11
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
12
 
13
+ # Tracing to Lanfuse
14
+ from opentelemetry.sdk.trace import TracerProvider
15
+ from openinference.instrumentation.smolagents import SmolagentsInstrumentor
16
+ from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
17
+ from opentelemetry.sdk.trace.export import SimpleSpanProcessor
18
+
19
+ LANGFUSE_PUBLIC_KEY = os.environ.get("LANGFUSE_PUBLIC_KEY")
20
+ LANGFUSE_SECRET_KEY = os.environ.get("LANGFUSE_SECRET_KEY")
21
+
22
+ LANGFUSE_AUTH = base64.b64encode(
23
+ f"{LANGFUSE_PUBLIC_KEY}:{LANGFUSE_SECRET_KEY}".encode()
24
+ ).decode()
25
+
26
+ os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"] = os.environ.get("LANGFUSE_HOST") + "/api/public/otel"
27
+ os.environ["OTEL_EXPORTER_OTLP_HEADERS"] = f"Authorization=Basic {LANGFUSE_AUTH}"
28
+
29
+ # Create a TracerProvider for OpenTelemetry
30
+ trace_provider = TracerProvider()
31
+
32
+ # Add a SimpleSpanProcessor with the OTLPSpanExporter to send traces
33
+ trace_provider.add_span_processor(SimpleSpanProcessor(OTLPSpanExporter()))
34
+
35
+ # Set the global default tracer provider
36
+ from opentelemetry import trace
37
+ trace.set_tracer_provider(trace_provider)
38
+ tracer = trace.get_tracer(__name__)
39
+
40
+ # Instrument smolagents with the configured provider
41
+ SmolagentsInstrumentor().instrument(tracer_provider=trace_provider)
42
+
43
 
44
  def run_and_submit_all(profile: gr.OAuthProfile | None):
45
  """
basic_agent.py CHANGED
@@ -5,6 +5,7 @@ import time
5
 
6
  import smolagents
7
 
 
8
  LOG = logging.getLogger(__name__)
9
 
10
  SYSTEM_PROMPT = """
@@ -13,44 +14,37 @@ You are a general AI assistant. I will ask you a question. Report your thoughts,
13
  The current date is April 30, 2025.
14
 
15
  Take the time to plan the steps to reach the solution. Show the steps and then execute the steps.
 
 
 
 
 
 
16
  """
17
 
18
 
19
  class BasicAgent:
 
 
 
 
 
 
20
 
21
  def __init__(self):
22
  print("BasicAgent initializing.")
23
- # Logs appear to be swallowed.
24
- LOG.warning("logging BasicAgent initialized.")
25
 
26
- self.manager_model_id = "Qwen/Qwen3-32B"
 
 
 
 
 
27
  self.manager_model = None
28
 
29
  self.code_model_id = "Qwen/Qwen2.5-Coder-32B-Instruct"
30
  self.code_model = None
31
 
32
- """
33
- # Handle the special cases
34
- if self.model_id.lower() == "google":
35
- self.model_id = "google"
36
-
37
- # Use Google gemini free tier
38
- GEM_KEY=os.environ["GOOGLE_API_KEY"]
39
- self.model = smolagents.OpenAIServerModel(
40
- model_id="gemini-2.0-flash",
41
- api_base="https://generativelanguage.googleapis.com/v1beta/openai/",
42
- api_key=GEM_KEY,
43
- temperature=0.3)
44
- elif self.model_id.lower() == "local":
45
- self.model_id = "Qwen/Qwen3-4B-FP8"
46
- # Run locally.
47
- self.model = smolagents.TransformersModel(
48
- model_id=self.model_id,
49
- max_new_tokens=32000,
50
- temperature=0.3
51
- )
52
- """
53
-
54
  if not self.manager_model:
55
  self.manager_model = smolagents.HfApiModel(
56
  max_tokens=32000,
@@ -67,7 +61,7 @@ class BasicAgent:
67
  custom_role_conversions=None,
68
  )
69
 
70
- print(f"NEW3: BasicAgent {self.manager_model_id=} {self.code_model_id=}")
71
 
72
  self.math_agent = smolagents.CodeAgent(
73
  name="date_time_math_agent",
@@ -86,7 +80,6 @@ class BasicAgent:
86
  smolagents.FinalAnswerTool()
87
  ]
88
 
89
- print("BasicAgent making search tool.")
90
  self.web_search_agent = smolagents.CodeAgent(
91
  name="web_search_agent",
92
  description="Search the web",
@@ -115,10 +108,6 @@ class BasicAgent:
115
  additional_authorized_imports=["wikipedia-api"],
116
  )
117
 
118
- print("BasicAgent making wikipedia search tool.")
119
-
120
-
121
- print("BasicAgent making manager.")
122
  self.manager_agent = smolagents.CodeAgent(
123
  name="manager_agent",
124
  description="Manger of other agents",
@@ -129,11 +118,13 @@ class BasicAgent:
129
  verbosity_level=2,
130
  planning_interval=None,
131
  additional_authorized_imports=["duckduckgo_search", "wikipedia-api"],
132
- managed_agents=[self.web_search_agent, self.wikipedia_search_agent, self.math_agent])
 
 
133
 
134
  def __call__(self, question: str) -> str:
135
- print(f"NEW Agent received question (first 50 chars): {question[:50]}...")
136
- prompt = f"{SYSTEM_PROMPT}\n\n{question}"
137
  answer = self.manager_agent.run(prompt)
138
- print(f"NEW {answer=}")
139
  return answer
 
5
 
6
  import smolagents
7
 
8
+ # Logs appear to be swallowed.
9
  LOG = logging.getLogger(__name__)
10
 
11
  SYSTEM_PROMPT = """
 
14
  The current date is April 30, 2025.
15
 
16
  Take the time to plan the steps to reach the solution. Show the steps and then execute the steps.
17
+
18
+ The question is below:
19
+ """
20
+
21
+ SUFFIX_PROMPT = """
22
+ Remember - The FINAL ANSWER must be a string, a number or a comma separated list that is only strings and numbers. No other output is allowed for a FINAL ANSWER! If any other output is provided other than a string, number or comma separated list that contains only strings and numbers, you fail. Don't fail.
23
  """
24
 
25
 
26
  class BasicAgent:
27
+ def check_results(self, final_answer, agent_memory):
28
+ if isinstance(final_answer, str) or isinstance(final_answer, int) or isinstance(final_answer, float):
29
+ return True
30
+ failure = "FAILED! The final answer must be a string, a number or a comma separated list of strings and numbers."
31
+ print(f"Feedback: {failure}")
32
+ raise Exception(failure)
33
 
34
  def __init__(self):
35
  print("BasicAgent initializing.")
 
 
36
 
37
+ # too big
38
+ # self.manager_model_id = "google/gemma-3-27B-it"
39
+ # self.manager_model_id = "OpenGVLab/InternVL3-14B"
40
+ # self.manager_model_id = "AIDC-AI/Ovis2-34B"
41
+
42
+ self.manager_model_id = "meta-llama/Llama-3.3-70B-Instruct"
43
  self.manager_model = None
44
 
45
  self.code_model_id = "Qwen/Qwen2.5-Coder-32B-Instruct"
46
  self.code_model = None
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  if not self.manager_model:
49
  self.manager_model = smolagents.HfApiModel(
50
  max_tokens=32000,
 
61
  custom_role_conversions=None,
62
  )
63
 
64
+ print(f"NEW4: BasicAgent {self.manager_model_id=} {self.code_model_id=}")
65
 
66
  self.math_agent = smolagents.CodeAgent(
67
  name="date_time_math_agent",
 
80
  smolagents.FinalAnswerTool()
81
  ]
82
 
 
83
  self.web_search_agent = smolagents.CodeAgent(
84
  name="web_search_agent",
85
  description="Search the web",
 
108
  additional_authorized_imports=["wikipedia-api"],
109
  )
110
 
 
 
 
 
111
  self.manager_agent = smolagents.CodeAgent(
112
  name="manager_agent",
113
  description="Manger of other agents",
 
118
  verbosity_level=2,
119
  planning_interval=None,
120
  additional_authorized_imports=["duckduckgo_search", "wikipedia-api"],
121
+ managed_agents=[self.web_search_agent, self.wikipedia_search_agent, self.math_agent],
122
+ final_answer_checks=[self.check_results],
123
+ )
124
 
125
  def __call__(self, question: str) -> str:
126
+ print(f"Agent received question (first 50 chars): {question[:50]}...")
127
+ prompt = f'{SYSTEM_PROMPT}\n\n{question}\n\n {SUFFIX_PROMPT}'
128
  answer = self.manager_agent.run(prompt)
129
+ print(f"{answer=}")
130
  return answer
basic_agent_test.py CHANGED
@@ -6,6 +6,31 @@ import basic_agent
6
 
7
  LOG = logging.getLogger(__name__)
8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  ba = basic_agent.BasicAgent()
10
 
11
  """
 
6
 
7
  LOG = logging.getLogger(__name__)
8
 
9
+
10
+ # Local:
11
+ # https://huggingface.co/docs/smolagents/tutorials/inspect_runs
12
+ # https://cobusgreyling.medium.com/introduce-inspectability-to-huggingface-smolagents-571bd3f8da4c
13
+ #
14
+ # pip install arize-phoenix opentelemetry-sdk opentelemetry-exporter-otlp openinference-instrumentation-smolagents
15
+ #
16
+ # pip install 'smolagents[telemetry]'
17
+ #
18
+ # python -m phoenix.server.main serve
19
+
20
+ from opentelemetry import trace
21
+ from opentelemetry.sdk.trace import TracerProvider
22
+ from opentelemetry.sdk.trace.export import BatchSpanProcessor
23
+
24
+ from openinference.instrumentation.smolagents import SmolagentsInstrumentor
25
+ from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
26
+ from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor
27
+
28
+ endpoint = "http://0.0.0.0:6006/v1/traces"
29
+ trace_provider = TracerProvider()
30
+ trace_provider.add_span_processor(SimpleSpanProcessor(OTLPSpanExporter(endpoint)))
31
+
32
+ SmolagentsInstrumentor().instrument(tracer_provider=trace_provider)
33
+
34
  ba = basic_agent.BasicAgent()
35
 
36
  """
requirements.txt CHANGED
@@ -5,6 +5,15 @@ smolagents
5
  smolagents[openai]
6
  wikipedia-api
7
 
 
 
 
 
 
 
 
 
 
8
  # Only needed for running locally
9
  #compressed-tensors
10
  #smolagents[transformers]
 
5
  smolagents[openai]
6
  wikipedia-api
7
 
8
+ # For tracing/monitoring
9
+ smolagents[telemetry]
10
+ opentelemetry-sdk
11
+ opentelemetry-exporter-otlp
12
+ openinference-instrumentation-smolagents
13
+ langfuse
14
+ datasets
15
+ smolagents[gradio]
16
+
17
  # Only needed for running locally
18
  #compressed-tensors
19
  #smolagents[transformers]