Docs/Guides/First Agent

Monitor Your First Agent

In this tutorial you build a small currency agent in Python and trace it end to end. The finished trace shows a root agent observation with a nested tool call and an LLM generation that carries the model, token usage and cost.

Prerequisites

  • An ANTS Platform project and permission to create API keys in it
  • Python 3.9 or later
  • An OpenAI API key (the agent makes one chat completion call)

Create API keys

In your project, open Settings > API Keys and create a key pair. Copy the secret key when it is shown. The dialog also shows the host URL of your ANTS Platform app. See API Keys.

Install the SDK

bash
pip install "ants-platform[openai]"

Set environment variables

bash
export ANTS_PLATFORM_PUBLIC_KEY="pk-ap-..." export ANTS_PLATFORM_SECRET_KEY="sk-ap-..." export ANTS_PLATFORM_HOST="https://<your-host>" export OPENAI_API_KEY="sk-..."

Check the connection

python
from ants_platform import AntsPlatform ants = AntsPlatform() print(ants.auth_check())

AntsPlatform() reads the three ANTS_PLATFORM_* variables. auth_check() returns True when the keys and host are valid and raises an error when they are not. It is a blocking network call, so use it while setting up, not on every request.

Write the agent

Save this as agent.py:

python
from ants_platform import AntsPlatform from ants_platform.openai import OpenAI ants = AntsPlatform( public_key=os.environ["ANTS_PLATFORM_PUBLIC_KEY"], secret_key=os.environ["ANTS_PLATFORM_SECRET_KEY"], host=os.environ["ANTS_PLATFORM_HOST"], ) llm = OpenAI() RATES = {("USD", "EUR"): 0.92, ("USD", "GBP"): 0.79} def convert(amount: float, base: str, quote: str) -> float: with ants.start_as_current_observation( name="convert-currency", as_type="tool", input={"amount": amount, "base": base, "quote": quote}, ) as tool: result = round(amount * RATES[(base, quote)], 2) tool.update(output={"result": result}) return result def currency_agent(question: str, user_id: str, session_id: str) -> str: with ants.start_as_current_observation( name="currency-agent", as_type="agent", agent_name="currency-agent", input=question, ) as agent: agent.update_trace( user_id=user_id, session_id=session_id, tags=["tutorial"], input=question, ) converted = convert(100, "USD", "EUR") completion = llm.chat.completions.create( name="write-answer", model="gpt-4o-mini", messages=[ {"role": "system", "content": "Answer in one sentence."}, {"role": "user", "content": f"{question} The converted amount is {converted} EUR."}, ], ) answer = completion.choices[0].message.content agent.update(output=answer) agent.update_trace(output=answer) return answer if __name__ == "__main__": print(currency_agent("How much is 100 USD in EUR?", "demo-user", "demo-session")) ants.flush()

What each part does:

  • start_as_current_observation(as_type="agent", agent_name=...) opens the root of the trace. The SDK requires an agent_name on the outermost observation; everything opened inside it inherits that name. The SDK stores agent names in lowercase.
  • convert opens a nested tool observation with its own input and output.
  • from ants_platform.openai import OpenAI is a drop-in replacement for the OpenAI client. Each call is recorded as a generation with the model, messages, completion and token usage. The extra name= argument names the generation.
  • update_trace sets the user, session and tags on the trace, so it appears under Users and Sessions.
  • flush() sends buffered data before a short script exits. Long-running services flush automatically.

Run it

bash
python agent.py

Find the trace

  1. Open Discover AI > Tracing and select the currency-agent trace. The observation tree shows currency-agent, then convert-currency and write-answer beneath it.
  2. Select write-answer to see the prompt, completion, model, token counts and cost.
  3. Open Discover AI > Sessions and select demo-session to see every trace from that conversation.
  4. After a few runs, open Gauge AI > Cost Dashboard to see spend by model.

See Traces and Sessions for what each screen offers.

ℹ

Cost is calculated from the generation's model name and token usage, using the model prices under Settings > Models. If a model has no price, add one. See Models & Pricing.

Trace an LLM call without the OpenAI client

If you call a different provider, record the generation yourself and report usage:

python
def call_model(prompt: str) -> str: with ants.start_as_current_observation( name="call-model", as_type="generation", model="gpt-4o-mini", input=prompt, model_parameters={"temperature": 0.2}, ) as generation: text, input_tokens, output_tokens = my_provider_call(prompt) generation.update( output=text, usage_details={"input": input_tokens, "output": output_tokens}, ) return text

Call it inside the agent observation, the same way convert is called.

Use the decorator for helper functions

@observe() turns a function into a nested observation and captures its arguments and return value. Decorated functions must run inside an observation that has an agent_name.

python
from ants_platform import observe @observe(name="lookup-rate", as_type="tool") def lookup_rate(base: str, quote: str) -> float: return RATES[(base, quote)]

Record errors

An exception raised inside an observation is recorded on it. To record a handled failure, set the level and a status message:

python
def safe_convert(amount: float, base: str, quote: str): with ants.start_as_current_observation( name="safe-convert", as_type="tool", input={"base": base, "quote": quote} ) as tool: if (base, quote) not in RATES: tool.update(level="ERROR", status_message=f"no rate for {base}/{quote}") return None return convert(amount, base, quote)

Levels are DEBUG, DEFAULT, WARNING and ERROR. In Tracing, filter by level to find failing traces.

Add a score

Scores attach a quality signal, such as user feedback, to a trace:

python
with ants.start_as_current_observation( name="currency-agent", as_type="agent", agent_name="currency-agent" ) as agent: answer = "100 USD is 92.0 EUR." agent.update(output=answer) agent.score_trace(name="user-feedback", value=1, data_type="BOOLEAN")

See Scores.

Common issues

SymptomFix
ValueError: agent_name is requiredWrap the work in start_as_current_observation(..., as_type="agent", agent_name="..."). This also applies to @observe() functions and OpenAI drop-in calls made outside any observation.
auth_check() failsCheck that both keys belong to the same project and that ANTS_PLATFORM_HOST is your app URL.
No trace appears after the script endsCall ants.flush() before the process exits.
Generation has tokens but no costAdd a price for the model under Settings > Models.

More help: Debugging AI Agents.

Next steps

© 2026 ANTS Platform, Inc.Docs v1.0 · Last updated June 2026