以编程方式使用文档

规模化构建 Agent 会引入大量基于使用量的成本,这些成本难以追踪。LangSmith 会自动记录主要提供商的 LLM Token 使用量和成本,也允许您为任何其他组件提交自定义成本数据。

这为您提供了整个应用程序成本的单一统一视图,使您可以轻松监控、理解和调试支出。

在 LangSmith UI 中查看成本

LangSmith UI,您可以通过三种方式探索使用量和支出:作为单个追踪中的明细,作为项目统计中的聚合指标,以及在仪表板中。

Token 和成本明细

UI 将 Token 使用量和成本分为三个类别:

  • 输入:发送给模型的提示词中的 Token。子类型包括:缓存读取、文本 Token、图像 Token 等。
  • 输出:模型在响应中生成的 Token。子类型包括:推理 Token、文本 Token、图像 Token 等。
  • 其他:工具调用、检索步骤或任何自定义运行的费用。

您可以通过将鼠标悬停在 UI 中的费用部分来查看详细明细。如果可用,每个部分还会按子类型进一步分类。

成本提示 Cost tooltip

您可以在 LangSmith UI 中查看这些细分:

在追踪树中

追踪树显示令牌使用和成本的最详细视图(对于单个追踪)。它显示整个追踪的总使用量、每个父级运行的聚合值,以及每个子级运行的令牌和成本细分。

打开追踪项目中的任何运行以查看其追踪树。

在项目统计中

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

在仪表板中

仪表板帮助您探索成本和令牌使用趋势。 预构建仪表板 显示追踪项目的总成本以及按输入和输出令牌的的成本细分。

您还可以在中配置自定义成本追踪图表 自定义仪表板.

成本追踪

您可以通过两种方式追踪成本:

  1. **自动**:根据 LLM 调用的令牌数量和模型价格计算。
  2. **手动**:直接在任意运行上指定,包括非LLM类型。
方法运行类型:LLM运行类型:其他
**自动**<ul><li>使用 LangChain</li><li>使用 LangChain 将 LLM 调用追踪到 OpenAI、Anthropic 或遵循 OpenAI 兼容格式的模型 @traceable</li><li> 使用 LangSmith 包装器调用 OpenAI or Anthropic</li><li>对于其他模型提供商,请阅读 令牌和成本信息指南</li></ul>不适用。
**手动**如果LLM调用成本是非线性的(例如遵循自定义成本函数)发送任何运行类型的成本,例如工具调用、检索步骤

LLM调用:基于令牌数量自动跟踪成本

要根据令牌使用量自动计算成本,您需要提供 **令牌数量**、 **模型和提供商**以及 **模型价格**.

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)
        
        const inputs = [
        { role: "system", content: "You are a helpful assistant." },
        { role: "user", content: "I'd like to book a table for two." },
        ];

        const chatModel = traceable(
        async ({ messages }) => {
            // The output your application expects
            const assistantMessage = {
            role: "assistant",
            content: "Sure, what time would you like to book the table for?",
            };

            // Token usage you compute or receive from the provider
            const tokenUsage = {
            input_tokens: 27,
            output_tokens: 13,
            total_tokens: 40,
            input_token_details: { cache_read: 10 },
            };

            // Attach usage to the LangSmith run
            const runTree = getCurrentRunTree();
            runTree.metadata.usage_metadata = tokenUsage;

            return assistantMessage;
        },
        {
            run_type: "llm",
            name: "chat_model",
            metadata: {
            ls_provider: "my_provider",
            ls_model_name: "my_model",
            },
        }
        );

        await chatModel({ messages: inputs });
        

Java 和 Kotlin 示例使用专用执行器。关闭执行器并等待终止可确保在进程退出前完成后台追踪提交。

  • - 在追踪函数的输出中返回一个 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)
        
        const messages = [
            { role: "system", content: "You are a helpful assistant." },
            { role: "user", content: "I'd like to book a table for two." }
        ];
        const 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,
            },
        };

        const chatModel = traceable(
            async ({
                messages,
            }: {
                messages: { role: string; content: string }[];
                model: string;
            }) => {
                return output;
            },
            {
                run_type: "llm",
                name: "chat_model",
                metadata: {
                    ls_provider: "my_provider",
                    ls_model_name: "my_model"
                }
            }
        );

        await chatModel({ messages });
        

在任何一种情况下,使用元数据应包含以下 LangSmith 识别的字段子集:

Usage Metadata Schema and Cost Calculation

以下字段在 usage_metadata 字典中由 LangSmith 识别。您可以查看完整的 Python 类型 or TypeScript 接口 directly.

模型输入中使用的令牌数量。所有输入令牌类型的总和。

模型响应中使用的令牌数量。所有输出令牌类型的总和。

输入和输出中使用的令牌数量。可选,可以推断。是输入_令牌 + 输出_tokens.

输入令牌类型的细分。键是令牌类型字符串,值是计数。例如 {"cache_read": 5}.

已知字段包括: audio, text, image, cache_read, cache_creation, cache_read_over_200k (Gemini)、 ephemeral_5m_input_tokens, ephemeral_1h_input_tokens (Anthropic 临时缓存层级)。根据模型或提供商的不同,可能还有其他字段。

输出token类型的细分。键是token类型字符串,值是计数。示例 {"reasoning": 5}.

已知字段包括: audio, text, image, reasoning。根据模型或提供商的不同,可能存在其他字段。

输入token的成本。

输出token的成本。

Token的成本。可选,可以推断。输入之和_成本 + 输出_cost.

输入成本的详细信息。键是token类型字符串,值是成本金额。

输出成本的详细信息。键是token类型字符串,值是成本金额。

成本计算

The cost for a run is computed greedily from most-to-least specific token type. Suppose you set a price of \$2 per 1M input tokens with a detailed price of \$1 per 1M cache_read input tokens, and \$3 per 1M output tokens. If you uploaded the following usage metadata:

    {
    "input_tokens": 20,
    "input_token_details": {"cache_read": 5},
    "output_tokens": 10,
    "total_tokens": 30,
    }
    

然后,token成本将按如下方式计算:

    # 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
    
  1. 指定模型名称。使用自定义模型时,需要在 运行的元数据 中指定以下字段,以便将token计数与成本关联。在查看traces和过滤时,提供这些元数据字段也有助于识别模型。
  • - ls_provider:模型的提供商,例如"openai"、"anthropic"
  • - ls_model_name:模型的名称,例如"gpt-5.4-mini"、"claude-3-opus-20240229"
  1. 设置模型价格。LangSmith使用其 模型定价表 将模型名称映射到每token价格以从token计数计算成本。

对于具有不同token类型不同定价的模型(例如多模态或缓存token),您可以为每种token类型指定价格细分。将鼠标悬停在 **...** 旁边的 **输入价格** 和 **输出价格** 条目上会显示按token类型的价格细分。

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

要修改默认模型价格,请使用与默认条目相同的模型、提供商和匹配模式创建一个新条目。

要在模型定价映射中创建新条目,请点击 **+ 模型** 右上角的按钮。

在这里,您可以指定以下字段:

  • 模型名称:模型的人类可读名称。
  • 输入价格:模型的每1M输入token的成本。这个数字乘以prompt中的token数量来计算prompt成本。
  • 输入价格细分 (可选):每种不同类型输入token的价格细分,例如, cache_read, video, audio.
  • 输出价格:模型的每1M输出token的成本。这个数字乘以completion中的token数量来计算completion成本。
  • 输出价格细分 (可选):每种不同类型输出令牌的价格明细,例如: reasoning, image等。
  • 模型激活日期 (可选):价格生效的日期。只有在此日期之后运行的才会应用此模型价格。
  • 匹配模式:用于匹配模型名称的正则表达式模式。用于匹配 ls_model_name 中的值。
  • 提供商 (可选):模型的提供商。如果指定,将与 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)
const messages = [
  { role: "system", content: "You are a helpful assistant." },
  { role: "user", content: "I'd like to book a table for two." }
];

const chatModel = traceable(
  async (messages: { role: string; content: string }[]) => {
    const llmOutput = {
      choices: [
        {
          message: {
            role: "assistant",
            content: "Sure, what time would you like to book the table for?",
          },
        },
      ],
      // Specify cost (in dollars) for the inputs and outputs
      usage_metadata: {
        input_cost: 1.1e-6,
        input_cost_details: { cache_read: 2.3e-7 },
        output_cost: 5.0e-6,
      },
    };

    // Attach usage metadata to the run
    const runTree = getCurrentRunTree();
    runTree.metadata.usage_metadata = llmOutput.usage_metadata;

    // Return only the assistant message
    return llmOutput.choices[0].message;
  },
  {
    run_type: "llm",
    name: "chat_model",
    metadata: {
      ls_provider: "my_provider",
      ls_model_name: "my_model",
    },
  }
);

await chatModel(messages);

其他运行:发送成本

您还可以为任何非 LLM 运行(如工具调用)发送成本信息。请在 total_cost 字段中指定成本 usage_metadata:

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")
// Example tool: get_weather
const getWeather = traceable(
  async ({ city }) => {
    // Your tool logic goes here
    const result = {
      temperature_f: 68,
      condition: "sunny",
      city,
    };

    // Cost for this tool call (computed however you like)
    const toolCost = 0.0015;

    // Attach usage metadata to the LangSmith run
    const runTree = getCurrentRunTree();
    runTree.metadata.usage_metadata = {
      total_cost: toolCost,
    };

    // Return only the actual tool result (no usage info)
    return result;
  },
  {
    run_type: "tool",
    name: "get_weather",
  }
);

const toolResponse = await getWeather({ city: "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")
// Example tool: get_weather
const getWeather = traceable(
  async ({ city }) => {
    // Your tool logic goes here
    const result = {
      temperature_f: 68,
      condition: "sunny",
      city,
    };

    // Attach tool call costs here
    return {
      ...result,
      usage_metadata: {
        total_cost: 0.0015,  // <-- cost for this tool call
      },
    };
  },
  {
    run_type: "tool",
    name: "get_weather",
  }
);

const toolResponse = await getWeather({ city: "San Francisco" });