Skip to main content
Try in Colab · GitHub source The Weave SDK lets you trace agents built with popular SDKs or custom harnesses. This quickstart shows you how to manually integrate Weave into a custom-built multi-turn agent to emit and capture OpenTelemetry spans. For conceptual understanding about Weave for agents, see Trace your agents. If you’re looking to integrate Weave with SDKs or harnesses such as the Claude Agent SDK or Codex, see Choose an agent integration. Weave autopatches into several agent-building SDKs and agent harnesses for quick integration.

What you’ll learn

By the end of this quickstart, you’ll have a working multi-turn agent that emits Weave-compatible OTel spans. You’ll also understand how Weave maps conversations, turns, LLM calls, and tool calls onto your agent code so you can apply the same pattern to your own custom agents. The code in this guide sets up a small research agent that can look things up on Wikipedia. It asks three questions (three turns) and uses the LLM to choose when to search Wikipedia for an answer. Weave records every step (the conversation, each question, each AI response, and each Wikipedia lookup) so you can see what happened in the Weave Agents view. This guide shows you how to:
  • Initialize Weave for agent tracing with weave.init().
  • Open a conversation and a turn with start_conversation / startConversation and start_turn / startTurn.
  • Wrap LLM calls with start_llm / startLLM and record usage.
  • Wrap tool executions with start_tool / startTool and record results.
  • Record complete token usage and a priceable model so token counts and cost render.
  • View the resulting conversation, turns, and tool calls in the Agents view.

How the Weave SDK works with agents

The Weave SDK includes a generic OTel ingest system for agents, meaning that Weave can capture information from any OTel span in your agent’s code. However, Weave requires special handling of the following spans to render your agent’s traces in the Agents view of the Weave UI. In Python, all four functions work as context managers (with weave.start_*(...) as obj:). On exit, they end the span and flush attributes, including on exceptions. In TypeScript, call .end() on each returned object. Use try { ... } finally { obj.end(); } to guarantee cleanup on exceptions. Other GenAI semantic-convention attributes, such as gen_ai.usage.* and gen_ai.agent.name, enable additional rendering, but they’re optional.

Prerequisites

  • A W&B account and API key.
  • An OpenAI API key.
  • Python 3.10+ (for the Python examples).
  • Node.js 18+ (the TypeScript examples require built-in fetch).

Install packages

Install the following packages into your developer environment:

Initialize Weave

weave.init() authenticates with W&B and configures the OTel exporter that sends agent spans to the Agents view. If the project doesn’t exist on your team, Weave creates it the first time you write to it.

Define a tool

The following code defines the agent’s Wikipedia search tool along with an OpenAI tool schema that specifies when and how to use the tool.

Run a traced multi-turn agent

With the tool and Weave initialization in place, the next step combines them into a complete agent loop. This loop shows how conversations, turns, LLM calls, and tool calls nest together. The following example runs three turns in a single conversation. Each turn:
  1. Opens a chat span and lets the LLM choose whether to call the tool.
  2. If the LLM requests a tool, opens an execute_tool span around the call and feeds the result back to the LLM.
  3. Opens a second chat span to produce the final answer.

Record token usage and cost

Each chat span carries token usage and a model id. Weave renders token counts from usage and derives cost from usage plus the model id, so an incomplete or unpriceable value shows 0 in / 0 out tokens or Cost - even when the rest of the trace looks correct. record(...) sets these fields (along with output_messages, response_id, reasoning, and more) in one call. Only the fields you pass are applied. Two things must be right for cost to appear:
  • Complete usage. input_tokens is the total input, including any cached tokens. Weave prices cache reads and cache writes at their own rates and subtracts them from the input total, so cache_read_input_tokens and cache_creation_input_tokens must be reported in addition to a total input_tokens that includes them. For providers with prompt caching (for example, Anthropic), cached tokens routinely dominate the input, so omitting them makes usage and cost render as roughly zero.
  • A priceable model id. Cost is a lookup on the model. Weave prefers response_model (the exact model the provider served) and falls back to the model you passed to start_llm. An alias such as opus or sonnet is not priceable and renders Cost -, so pass the concrete id the response returns (resp.model) as response_model.
OpenAI counts cached tokens inside prompt_tokens, so the example above maps directly. Anthropic reports cached tokens separately from input_tokens, so add them back into the total Weave prices against:

See your agent traces in the Agents view

When weave.init() runs, it prints a link to your project where you can see:
  • A row in the Agents tab for research-bot.
  • One conversation containing three turns.
  • Each turn (invoke_agent) with two chat spans and an execute_tool span nested inside.
  • Token counts, latency, model, and the full message exchange on each chat.
Click any turn to inspect the inputs, outputs, tool arguments, and tool results. To deep-link from your own UI to a conversation in the Weave Agents view, build the URL from your entity, project, and the conversation id. weave.init() returns a client that carries entity and project, and start_conversation exposes conversation_id.

Next steps