Skip to main content
大规模构建智能体会引入非平凡的、基于使用量的成本,这些成本可能难以跟踪。LangSmith 会自动记录主要提供商的 LLM 令牌使用量和成本,同时也允许您为任何其他组件提交自定义成本数据。 这为您提供了整个应用程序成本的单一、统一视图,使您可以轻松监控、理解和调试您的支出。

在 LangSmith UI 中查看成本

LangSmith UI 中,您可以通过三种方式探索使用量和支出:在单个跟踪内查看细分、在项目统计中查看聚合指标,以及在仪表板中查看。

令牌和成本细分

UI 将令牌使用量和成本分为三类:
  • 输入:发送给模型的提示中的令牌。子类型包括:缓存读取、文本令牌、图像令牌等。
  • 输出:模型响应中生成的令牌。子类型包括:推理令牌、文本令牌、图像令牌等。
  • 其他:来自工具调用、检索步骤或任何自定义运行的成本。
您可以通过将鼠标悬停在 UI 中的成本部分上来查看详细细分。如果可用,每个部分会进一步按子类型分类。 成本工具提示 您可以在整个 LangSmith UI 中检查这些细分:

在跟踪树中

跟踪树显示了令牌使用量和成本的最详细视图(针对单个跟踪)。它显示了整个跟踪的总使用量、每个父运行的聚合值,以及每个子运行的令牌和成本细分。 打开跟踪项目中的任何运行以查看其跟踪树。
在跟踪线程中的成本时,请确保所有子运行都包含线程元数据(session_idthread_idconversation_id)。如果子运行没有线程元数据,则这些运行的令牌计数和成本将不会包含在线程级聚合中。有关设置线程元数据的详细信息,请参阅配置线程

在项目统计中

项目统计面板显示项目中所有跟踪的总令牌使用量和成本。

在仪表板中

仪表板可帮助您探索随时间变化的成本和令牌使用趋势。跟踪项目的预构建仪表板显示总成本以及按输入和输出令牌细分的成本。 您还可以在自定义仪表板中配置自定义成本跟踪图表。

成本跟踪

您可以通过两种方式跟踪成本:
  1. 自动:根据令牌计数和模型价格为 LLM 调用推导。
  2. 手动:直接在任何运行上指定,包括非 LLM 类型。
方法运行类型:LLM运行类型:其他
自动不适用。
手动如果 LLM 调用成本是非线性的(例如,遵循自定义成本函数)发送任何运行类型的成本,例如工具调用、检索步骤

LLM 调用:根据令牌计数自动跟踪成本

要根据令牌使用量自动计算成本,您需要提供令牌计数模型和提供商以及模型价格
如果您使用 LangChain 调用 LLM,使用 @traceable 跟踪 OpenAI 或 Anthropic(或 OpenAI 兼容模型),或使用 LangSmith 包装器跟踪 OpenAIAnthropic,请跳过本节。
  1. 发送令牌计数。许多模型将令牌计数作为响应的一部分包含在内。您必须提取此信息并使用以下方法之一将其包含在您的运行中:
    • 在运行的元数据上设置 usage_metadata 字段。此方法的优点是您无需更改被跟踪函数的运行时输出:
      from langsmith import traceable, get_current_run_tree
      
      inputs = [
          {"role": "system", "content": "You are a helpful assistant."},
          {"role": "user", "content": "I'd like to book a table for two."},
      ]
      
      @traceable(
          run_type="llm",
          metadata={"ls_provider": "my_provider", "ls_model_name": "my_model"}
      )
      def chat_model(messages: list):
          # Imagine this is the real model output format your application expects
          assistant_message = {
              "role": "assistant",
              "content": "Sure, what time would you like to book the table for?"
          }
      
          # Token usage you compute or receive from the provider
          token_usage = {
              "input_tokens": 27,
              "output_tokens": 13,
              "total_tokens": 40,
              "input_token_details": {"cache_read": 10}
          }
      
          # Attach token usage to the LangSmith run
          run = get_current_run_tree()
          run.set(usage_metadata=token_usage)
      
          return assistant_message
      
      chat_model(inputs)
      
    • 在被跟踪函数的输出中返回 usage_metadata 字段。将 usage_metadata 键直接包含在被跟踪函数返回的对象中。LangSmith 将从输出中提取它:
      from langsmith import traceable
      
      inputs = [
          {"role": "system", "content": "You are a helpful assistant."},
          {"role": "user", "content": "I'd like to book a table for two."},
      ]
      output = {
          "choices": [
              {
                  "message": {
                      "role": "assistant",
                      "content": "Sure, what time would you like to book the table for?"
                  }
              }
          ],
          "usage_metadata": {
              "input_tokens": 27,
              "output_tokens": 13,
              "total_tokens": 40,
              "input_token_details": {"cache_read": 10}
          },
      }
      
      @traceable(
          run_type="llm",
          metadata={"ls_provider": "my_provider", "ls_model_name": "my_model"}
      )
      def chat_model(messages: list):
          return output
      
      chat_model(inputs)
      
    在任何一种情况下,使用元数据都应包含以下 LangSmith 识别字段的子集:
    usage_metadata 字典中的以下字段被 LangSmith 识别。您可以直接查看完整的 Python 类型TypeScript 接口
    input_tokens
    number
    模型输入中使用的令牌数量。所有输入令牌类型的总和。
    output_tokens
    number
    模型响应中使用的令牌数量。所有输出令牌类型的总和。
    total_tokens
    number
    输入和输出中使用的令牌数量。可选,可以推断。input_tokens + output_tokens 的总和。
    input_token_details
    object
    输入令牌类型的细分。键是令牌类型字符串,值是计数。例如 {"cache_read": 5}已知字段包括:audiotextimagecache_readcache_creationcache_read_over_200k(Gemini)、ephemeral_5m_input_tokensephemeral_1h_input_tokens(Anthropic 临时缓存层)。根据模型或提供商,可能存在其他字段。
    output_token_details
    object
    输出令牌类型的细分。键是令牌类型字符串,值是计数。例如 {"reasoning": 5}已知字段包括:audiotextimagereasoning。根据模型或提供商,可能存在其他字段。
    input_cost
    number
    输入令牌的成本。
    output_cost
    number
    输出令牌的成本。
    total_cost
    number
    令牌的成本。可选,可以推断。input_cost + output_cost 的总和。
    input_cost_details
    object
    输入成本的详细信息。键是令牌类型字符串,值是成本金额。
    output_cost_details
    object
    输出成本的详细信息。键是令牌类型字符串,值是成本金额。
    成本计算运行的成本是从最具体到最不具体的令牌类型贪婪计算的。假设您设置了每 1M 输入令牌 2 美元的价格,其中 cache_read 输入令牌的详细价格为每 1M 1 美元,输出令牌为每 1M 3 美元。如果您上传了以下使用元数据:
    {
    "input_tokens": 20,
    "input_token_details": {"cache_read": 5},
    "output_tokens": 10,
    "total_tokens": 30,
    }
    
    那么,令牌成本将计算如下:
    # Notice that LangSmith computes the cache_read cost and then for any
    # remaining input_tokens, the default input price is applied.
    input_cost = 5 * 1e-6 + (20 - 5) * 2e-6  # 3.5e-5
    output_cost = 10 * 3e-6  # 3e-5
    total_cost = input_cost + output_cost  # 6.5e-5
    
  2. 指定模型名称。使用自定义模型时,需要在运行的元数据中指定以下字段,以便将令牌计数与成本关联起来。在查看跟踪和进行筛选时,提供这些元数据字段也有助于识别模型。
    • ls_provider:模型的提供商,例如 “openai”、“anthropic”
    • ls_model_name:模型的名称,例如 “gpt-5.4-mini”、“claude-3-opus-20240229”
  3. 设置模型价格。LangSmith 使用其模型定价表将模型名称映射到每令牌价格,以根据令牌计数计算成本。
    该表包含大多数 OpenAI、Anthropic 和 Gemini 模型的定价信息。如果您有自定义定价,可以创建新的模型价格条目或覆盖默认模型的定价。
    对于不同令牌类型有不同定价的模型(例如,多模态或缓存令牌),您可以指定每种令牌类型的价格细分。将鼠标悬停在 Input priceOutput price 条目旁边的 上,可以查看按令牌类型细分的价格。
    LangSmith 不会反映模型定价映射的更新对记录跟踪的成本的影响。不支持回填模型定价更改。

创建新的或修改现有的模型价格条目

要修改默认模型价格,请创建一个与默认条目具有相同模型、提供商和匹配模式的新条目。 要在模型定价映射中创建新条目,请单击右上角的 + Model 按钮。 在这里,您可以指定以下字段:
  • Model Name:模型的人类可读名称。
  • Input Price:模型每 1M 输入令牌的成本。此数字乘以提示中的令牌数以计算提示成本。
  • Input Price Breakdown(可选):每种不同类型输入令牌的价格细分,例如 cache_readvideoaudio
  • Output Price:模型每 1M 输出令牌的成本。此数字乘以完成中的令牌数以计算完成成本。
  • Output Price Breakdown(可选):每种不同类型输出令牌的价格细分,例如 reasoningimage 等。
  • Model Activation Date(可选):定价适用的日期。只有此日期之后的运行才会应用此模型价格。
  • Match Pattern:用于匹配模型名称的正则表达式模式。用于匹配运行元数据中 ls_model_name 的值。
  • Provider(可选):模型的提供商。如果指定,则与运行元数据中的 ls_provider 进行匹配。
设置好模型定价映射后,LangSmith 将根据 LLM 调用中提供的令牌计数自动计算和聚合基于令牌的成本。

LLM 调用:直接发送成本

Gemini 2.5 Pro Preview 和 Gemini 2.5 Pro 使用分步成本函数,LangSmith 默认支持。对于任何其他具有非线性定价的模型,请在客户端计算成本,并将其作为 usage_metadata 发送,如以下代码所示:
from langsmith import traceable, get_current_run_tree

inputs = [
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "I'd like to book a table for two."},
]

@traceable(
    run_type="llm",
    metadata={"ls_provider": "my_provider", "ls_model_name": "my_model"}
)
def chat_model(messages: list):
    llm_output = {
        "choices": [
            {
                "message": {
                    "role": "assistant",
                    "content": "Sure, what time would you like to book the table for?"
                }
            }
        ],
        "usage_metadata": {
            # Specify cost (in dollars) for the inputs and outputs
            "input_cost": 1.1e-6,
            "input_cost_details": {"cache_read": 2.3e-7},
            "output_cost": 5.0e-6,
        },
    }
    run = get_current_run_tree()
    run.set(usage_metadata=llm_output["usage_metadata"])
    return llm_output["choices"][0]["message"]

chat_model(inputs)

其他运行:发送成本

您也可以为任何非 LLM 运行(例如工具调用)发送成本信息。在运行的 usage_metadatatotal_cost 字段中指定成本:
from langsmith import traceable, get_current_run_tree

# Example tool: get_weather
@traceable(run_type="tool", name="get_weather")
def get_weather(city: str):
    # Your tool logic goes here
    result = {
        "temperature_f": 68,
        "condition": "sunny",
        "city": city,
    }

    # Cost for this tool call (computed however you like)
    tool_cost = 0.0015

    # Attach usage metadata to the LangSmith run
    run = get_current_run_tree()
    run.set(usage_metadata={"total_cost": tool_cost})

    # Return only the actual tool result (no usage info)
    return result

tool_response = get_weather("San Francisco")
或者,直接在被跟踪函数的返回值中包含 usage_metadata
from langsmith import traceable

# Example tool: get_weather
@traceable(run_type="tool", name="get_weather")
def get_weather(city: str):
    # Your tool logic goes here
    result = {
        "temperature_f": 68,
        "condition": "sunny",
        "city": city,
    }

    # Attach tool call costs here
    return {
        **result,
        "usage_metadata": {
            "total_cost": 0.0015,   # <-- cost for this tool call
        },
    }

tool_response = get_weather("San Francisco")