如何通过LangChain/OpenAI回调处理器准确捕获Token使用及成本数据?
问题原因及修复方案
你的代码中Token统计全部显示为0,核心问题是OpenAICallbackHandler未被正确绑定到LLM的实际调用流程中,以下是具体修复步骤:
1. 确保回调绑定到LLM层级
ConversationChain初始化时传入的callbacks属于链级回调,而Token统计需要LLM层级的回调才能捕获调用数据。你需要在调用invoke时明确传递回调参数:
修改generate_response方法:
def generate_response(self, user_message): callback_handler = OpenAICallbackHandler() # 在invoke时传入callbacks,确保LLM调用触发回调统计 response_data = self.conversation.invoke(user_message, config={"callbacks": [callback_handler]}) response = response_data.get('response') if response_data and 'response' in response_data else "No response generated." print("Total cost:", callback_handler.total_cost) print("Prompt tokens:", callback_handler.prompt_tokens) print("Completion tokens:", callback_handler.completion_tokens) return response
同时将ConversationChain的初始化移到__init__方法中,避免每次生成响应都重复创建链:
def __init__(self, api_key): # 明确指定模型,确保token计费规则匹配 self.chat_model = ChatOpenAI(api_key=api_key, model="gpt-3.5-turbo") self.memory = ConversationBufferMemory() # 提前初始化对话链 self.conversation = ConversationChain(llm=self.chat_model, memory=self.memory)
2. 避免重复创建LangChainService实例
handle_send_message中每次请求都新建服务实例,会导致对话记忆丢失,也可能干扰回调的正常工作。改为全局复用实例:
# 全局初始化一次服务实例 langchain_service = LangChainService(api_key="你的OpenAI密钥") def handle_send_message(): data = request.json message = data.get('message') print("Generating bot response for message:", message) response = langchain_service.generate_response(message) print("Generated response:", response)
注意:你之前代码中api_key=['OPENAI_API_KEY']是错误写法,需传入字符串类型的密钥,而非列表。
3. 验证模型参数
确保ChatOpenAI指定了正确的模型(如gpt-3.5-turbo、gpt-4),不同模型的token计费标准不同,OpenAICallbackHandler需要依赖模型信息计算成本,未指定模型可能导致统计异常。
额外提示:启用自定义Prompt
你定义了prompt_template但未在对话链中使用,若要应用自定义系统提示,需替换链的默认prompt:
def __init__(self, api_key): # ... 其他初始化代码 self.prompt_template = ChatPromptTemplate(messages=[ SystemMessagePromptTemplate.from_template("你的系统提示内容"), HumanMessagePromptTemplate.from_template("{user_message}") ]) # 替换对话链的默认prompt self.conversation = ConversationChain(llm=self.chat_model, memory=self.memory, prompt=self.prompt_template)
经过以上修改,OpenAICallbackHandler即可正确捕获每次交互的prompt tokens、completion tokens及对应成本。
内容的提问来源于stack exchange,提问作者wellsinsideout
相关产品推荐
相关产品推荐

