基于LangChain+OpenAI+Pinecone的Chat API函数调用无响应问题排查
解决LangChain + OpenAI函数调用时接口无响应的问题
问题背景
基于OpenAI、LangChain和Pinecone实现的/api/chat接口,在OpenAI返回普通文本响应时运行正常;但当OpenAI触发函数调用(如getWeather)时,接口无任何响应。从LLM日志可见,返回的AIMessageChunk中content为空,函数调用信息存储在additional_kwargs.function_call字段中。
原因分析
当前链中使用的StringOutputParser和BytesOutputParser仅提取消息的content字段内容,完全忽略additional_kwargs中的函数调用信息。当LLM返回函数调用时,content为空,导致解析器输出空内容,最终StreamingTextResponse没有可返回的数据。
解决方案
自定义消息解析器,同时处理普通文本响应和函数调用响应,将函数调用序列化为JSON字符串输出,确保接口返回一致格式的响应。
步骤1:实现自定义消息解析器
创建支持处理AIMessage和AIMessageChunk的解析器,兼容文本和函数调用场景:
import { BaseMessageOutputParser } from "langchain/schema/output_parser"; import { AIMessage, AIMessageChunk } from "langchain/schema"; class CustomMessageParser extends BaseMessageOutputParser { async parse(message: AIMessage | AIMessageChunk): Promise<string> { // 优先处理函数调用 if (message.additional_kwargs.function_call) { return JSON.stringify({ type: "function_call", name: message.additional_kwargs.function_call.name, arguments: JSON.parse(message.additional_kwargs.function_call.arguments) }); } // 处理普通文本内容 return message.content || ""; } getFormatInstructions(): string { return ""; } }
步骤2:替换链中的解析器
将原链中的StringOutputParser和BytesOutputParser替换为自定义解析器:
// 修改standaloneQuestionChain const standaloneQuestionChain = RunnableSequence.from([ { question: (input: ConversationalRetrievalQAChainInput) => input.question, chat_history: (input: ConversationalRetrievalQAChainInput) => formatVercelMessages(input.chat_history), }, condenseQuestionPrompt, llm, new CustomMessageParser(), // 替换原StringOutputParser ]) // 修改answerChain const answerChain = RunnableSequence.from([ { context: retriever.pipe(combineDocumentsFn), question: new RunnablePassthrough(), }, answerPrompt, llm, new CustomMessageParser(), // 替换原BytesOutputParser ])
步骤3:调整流式响应格式(可选)
如果需要更规范的流式输出,可以设置响应的Content-Type为application/jsonl(JSON Lines格式),方便前端逐行解析:
return new StreamingTextResponse(stream, { headers: { "Content-Type": "application/jsonl" } })
测试验证
重新运行服务后,执行函数调用测试请求:
curl --location 'http://localhost:3000/api/v2/chat' \ --header 'Content-Type: application/json' \ --data '{ "messages": [ { "role": "user", "content": "current weather at Ho Chi Minh city" } ] }'
接口会返回序列化后的函数调用JSON:
{"type":"function_call","name":"getWeather","arguments":{"location":"Ho Chi Minh city"}}
内容的提问来源于stack exchange,提问作者Van Huynh
相关产品推荐
相关产品推荐

