如何通过代码统计使用LangChain的create_pandas_dataframe_agent时的单次请求token消耗?
如何通过代码统计使用LangChain的create_pandas_dataframe_agent时的单次请求token消耗?
我之前也碰到过这种需求——想精准统计单次调用create_pandas_dataframe_agent时的token消耗,不想去Azure控制台翻找(确实很难单独隔离单次请求的数据),用代码就能轻松搞定,给你几个实用的方案:
方法一:自定义回调捕获Azure OpenAI的官方token统计
因为create_pandas_dataframe_agent是工具调用型agent,它可能会多次和LLM交互(比如先生成Python代码执行,再根据结果生成最终回答),所以我们可以通过自定义回调函数,每次LLM调用结束后从Azure的API响应里提取官方的token使用数据,这样统计的结果和实际计费完全一致。
from langchain.callbacks.base import BaseCallbackHandler from langchain.schema import LLMResult from langchain_experimental.agents import create_pandas_dataframe_agent import pandas as pd from langchain_openai import AzureOpenAI # 自定义token计数回调 class TokenCounterHandler(BaseCallbackHandler): def __init__(self): self.total_prompt_tokens = 0 self.total_completion_tokens = 0 self.total_tokens = 0 def on_llm_end(self, response: LLMResult, **kwargs) -> None: # 遍历每一次LLM调用的结果,提取token使用信息 for generation_group in response.generations: for generation in generation_group: if generation.generation_info and "usage" in generation.generation_info: usage = generation.generation_info["usage"] self.total_prompt_tokens += usage["prompt_tokens"] self.total_completion_tokens += usage["completion_tokens"] self.total_tokens += usage["total_tokens"] print(f"单次LLM调用消耗:prompt tokens={usage['prompt_tokens']}, completion tokens={usage['completion_tokens']}, 总计={usage['total_tokens']}") # 初始化计数器 token_counter = TokenCounterHandler() # 读取数据 df = pd.read_csv("file_path") # 初始化LLM并绑定回调 llm = AzureOpenAI( deployment_name=name, # 你的deployment_name变量 temperature=0.0, callbacks=[token_counter] ) # 创建agent agent_executor = create_pandas_dataframe_agent( llm, df, # 你的其他参数 ) # 执行请求 prompt = """ Some Text """ agent_executor.invoke(prompt) # 打印本次请求的总token消耗 print(f"\n本次agent请求总token消耗:prompt={token_counter.total_prompt_tokens}, completion={token_counter.total_completion_tokens}, 总计={token_counter.total_tokens}")
方法二:使用LangChain内置的Token计数回调
LangChain已经内置了专门的token统计回调,用法更简洁,适合快速实现:
from langchain.callbacks import TokenUsageCallbackHandler from langchain_experimental.agents import create_pandas_dataframe_agent import pandas as pd from langchain_openai import AzureOpenAI # 初始化内置token计数器 token_handler = TokenUsageCallbackHandler() # 读取数据 df = pd.read_csv("file_path") # 初始化LLM并绑定内置回调 llm = AzureOpenAI( deployment_name=name, temperature=0.0, callbacks=[token_handler] ) # 创建并执行agent agent_executor = create_pandas_dataframe_agent(llm, df) prompt = """ Some Text """ agent_executor.invoke(prompt) # 获取统计结果 print(f"总prompt token消耗:{token_handler.prompt_tokens}") print(f"总completion token消耗:{token_handler.completion_tokens}") print(f"总token消耗:{token_handler.total_tokens}")
额外说明
- 因为agent会多次调用LLM(比如工具调用的思考过程、最终回答生成),所以上述方法统计的是整个agent执行流程的总token消耗,这才是单次请求的真实计费数据。
- 如果你想手动验证prompt的token数,可以用
tiktoken库(OpenAI官方的token计数工具),不过不如从API响应中提取的数据准确:import tiktoken def count_tokens(text: str, model: str = "gpt-3.5-turbo-instruct") -> int: encoding = tiktoken.encoding_for_model(model) return len(encoding.encode(text)) # 假设你拿到了传给LLM的完整prompt文本 # prompt_text = "..." # print(f"Prompt token数:{count_tokens(prompt_text)}")
备注:内容来源于stack exchange,提问作者Ankush Pandit




