跳转至

使用量

Agents SDK 会自动追踪每次运行的 token 使用量。你可以从运行上下文中访问这些数据,用于监控成本、强制执行限制或记录分析数据。

追踪内容

  • 请求数:发起的 LLM API 调用次数
  • 输入 token 数:发送的输入 token 总数
  • 输出 token 数:接收的输出 token 总数
  • token 总数:输入 + 输出
  • 每个请求的使用量条目:每个请求的使用量明细列表
  • 详细信息
  • input_tokens_details.cached_tokens
  • input_tokens_details.cache_write_tokens
  • output_tokens_details.reasoning_tokens

运行使用量的访问

执行 Runner.run(...) 后,可通过 result.context_wrapper.usage 访问使用量。

result = await Runner.run(agent, "What's the weather in Tokyo?")
usage = result.context_wrapper.usage

print("Requests:", usage.requests)
print("Input tokens:", usage.input_tokens)
print("Output tokens:", usage.output_tokens)
print("Total tokens:", usage.total_tokens)

使用量会汇总运行期间的所有模型调用,包括生成工具调用或任务转移的模型调用。

OpenAIResponsesCompactionSession 在运行结束前自动压缩历史记录时,该 responses.compact 请求报告的使用量也会计入同一次运行的总量。在运行之外手动调用 run_compaction() 时,由于没有包含它的运行上下文,因此不会更新先前运行所返回的使用量对象。请参阅 OpenAI Responses 压缩会话

第三方适配器的使用量启用

不同第三方适配器和提供商后端报告使用量的方式各不相同。如果你通过第三方适配器访问模型,并且需要准确的 result.context_wrapper.usage 值:

  • 使用 AnyLLMModel 时,如果上游提供商返回使用量,系统会自动传递该数据。从 Chat Completions 后端以流式方式获取响应时,可能需要设置 ModelSettings(include_usage=True),才能发出使用量数据块。
  • 使用 LitellmModel 时,某些提供商后端默认不报告使用量,因此通常需要设置 ModelSettings(include_usage=True)

请查看模型指南中第三方适配器部分针对各适配器的说明,并在你计划部署的具体提供商后端上验证使用量报告。

每个请求的使用量追踪

SDK 会在 request_usage_entries 中自动追踪每个 API 请求的使用量,这有助于详细计算成本和监控上下文窗口消耗。

result = await Runner.run(agent, "What's the weather in Tokyo?")

for i, request in enumerate(result.context_wrapper.usage.request_usage_entries):
    print(f"Request {i + 1}: {request.input_tokens} in, {request.output_tokens} out")

当 SDK 将一个 Usage 对象汇总到另一个对象中时,会复制每个请求的条目及其嵌套的输入和输出 token 详细信息。之后修改源使用量对象不会改变汇总对象的 request_usage_entries,修改汇总对象也不会改变源条目。

提供商使用量载荷的保留

Agents SDK 会将提供商的使用量规范化为 Usage 字段,从而在不同模型提供商之间提供一致的总量。如果应用必须保留提供商特定的使用量字段,或区分缺失字段与提供商报告的零值,请将 ModelSettings.preserve_raw_usage 设置为 True

from agents import Agent, ModelSettings, Runner

agent = Agent(
    name="Assistant",
    model_settings=ModelSettings(preserve_raw_usage=True),
)
result = await Runner.run(agent, "What's the weather in Tokyo?")

for response in result.raw_responses:
    print(response.raw_usage)

Agents SDK 会将每个 ModelResponse.raw_usage 值存储为该模型调用的提供商载荷的独立 JSON 兼容快照。Agents SDK 不会在整个运行期间汇总 raw_usage。如果禁用了保留功能、提供商未返回使用量载荷,或上游适配器已丢弃原始字段存在性信息,该值将保持为 None

preserve_raw_usage 只能保留传递至模型适配器的使用量载荷;此设置不会向提供商请求使用量。当流式 Chat Completions 提供商要求显式请求使用量时,还需设置 ModelSettings(include_usage=True)

目前,无论是流式运行还是非流式运行,LitellmModel 都不会填充 ModelResponse.raw_usage,因此 preserve_raw_usage=True 对该适配器无效。使用 LitellmModel 时,请继续使用规范化的 Usage 字段;如果需要提供商特定的字段存在性信息,请选择支持保留原始使用量的适配器。

会话中的使用量访问

使用 Session(例如 SQLiteSession)时,每次调用 Runner.run(...) 都会返回该次特定运行的使用量。会话会维护对话历史记录以提供上下文,但每次运行的使用量彼此独立。

session = SQLiteSession("my_conversation")

first = await Runner.run(agent, "Hi!", session=session)
print(first.context_wrapper.usage.total_tokens)  # Usage for first run

second = await Runner.run(agent, "Can you elaborate?", session=session)
print(second.context_wrapper.usage.total_tokens)  # Usage for second run

请注意,虽然会话会在多次运行之间保留对话上下文,但每次调用 Runner.run() 返回的使用量指标仅代表该次执行。在会话中,先前的消息可能会作为输入重新提供给每次运行,从而影响后续轮次的输入 token 数。

RunState 检查点中的使用量

RunResult.to_state() 会捕获截至当前已累计使用量的独立快照。从该检查点恢复的运行会以捕获的总量为起点,并累加自身模型调用的使用量。恢复后的运行不会将这些新增总量添加到原始 RunResult,也不会添加到从该结果创建的其他检查点。

first = await Runner.run(agent, "First request")
checkpoint_a = first.to_state()
checkpoint_b = first.to_state()

resumed_a = await Runner.run(agent, checkpoint_a)
resumed_b = await Runner.run(agent, checkpoint_b)

assert resumed_a.context_wrapper.usage is not first.context_wrapper.usage
assert resumed_b.context_wrapper.usage is not resumed_a.context_wrapper.usage

这种隔离也适用于 Usage 中的 request_usage_entries 列表。恢复后的嵌套 Agent.as_tool() 运行是独立顶层计量的例外:它在恢复后的模型使用量会有意汇总到当前外层运行的使用量中,就像该嵌套运行之前的模型调用一样。

钩子中的使用量

如果你使用 RunHooks,传递给每个钩子的 context 对象都包含 usage。借助此功能,你可以在生命周期的关键时刻记录使用量。

class MyHooks(RunHooks):
    async def on_agent_end(self, context: RunContextWrapper, agent: Agent, output: Any) -> None:
        u = context.usage
        print(f"{agent.name}{u.requests} requests, {u.total_tokens} total tokens")

API 参考

有关详细的 API 文档,请参阅: