如何在LangChain JS Agent中传递并获取source_documents?
问题:LangChain JS中RetrievalQAChain的source_documents无法传递给Agent,自定义工具类型不匹配
我在使用LangChain JS时遇到两个问题:
- 已经给RetrievalQAChain配置了
returnSourceDocuments: true,但执行Agent后,结果里拿不到source_documents内容; - 尝试创建自定义工具适配时,遭遇类型不匹配问题。
核心原因
默认的ChainTool只会返回链的outputKey指定字段(RetrievalQAChain默认outputKey是result),所以即使链生成了source_documents,也不会被工具传递给Agent。另外直接用ChainTool包装RetrievalQAChain存在类型约束限制,需要自定义工具来适配需求。
解决步骤
1. 创建自定义工具替代ChainTool
手动实现工具,调用RetrievalQAChain后返回包含result和source_documents的完整结构,同时处理类型问题:
import { Tool } from "langchain/tools"; // 自定义QA工具,支持返回source_documents class CustomQATool extends Tool { static lc_name() { return "CustomQATool"; } constructor(fields) { super(fields); this.retrievalChain = fields.retrievalChain; this.name = fields.name; this.description = fields.description; } async _run(input) { // 调用RetrievalQAChain获取完整结果 const chainResult = await this.retrievalChain.call({ query: input }); // 返回包含结果和来源文档的结构 return { result: chainResult.result, source_documents: chainResult.source_documents }; } async _call(input) { return this._run(input); } }
2. 替换原ChainTool为自定义工具
把原来的qaTool替换成自定义工具实例:
const qaTool = new CustomQATool({ name: `state-of-${company}-qa`, description: `State of the ${company} QA - useful for when you need to ask questions about ${company}.`, retrievalChain: retrievalChain, });
3. 从Agent结果中提取source_documents
开启returnIntermediateSteps: true后,可以从Agent的执行结果里提取工具返回的完整数据:
const result = await executor.call( { input: input }, { callbacks: [ { handleLLMNewToken(token) { res.write(token); } } ] } ); // 从中间步骤过滤并提取来源文档 const sourceDocs = result.intermediateSteps .filter(step => step.tool === `state-of-${company}-qa`) .map(step => step.toolReturn.source_documents); console.log('来源文档:', sourceDocs);
4. TypeScript环境下的类型适配
如果用TS开发,给自定义工具添加明确的类型定义即可解决类型不匹配:
import { Tool } from "langchain/tools"; import { RetrievalQAChain } from "langchain/chains"; import { Document } from "langchain/document"; class CustomQATool extends Tool { retrievalChain: RetrievalQAChain; constructor(fields: { name: string; description: string; retrievalChain: RetrievalQAChain; }) { super(fields); this.retrievalChain = fields.retrievalChain; this.name = fields.name; this.description = fields.description; } async _run(input: string): Promise<{ result: string; source_documents: Document[] }> { const chainResult = await this.retrievalChain.call({ query: input }); return { result: chainResult.result, source_documents: chainResult.source_documents as Document[], }; } async _call(input: string): Promise<{ result: string; source_documents: Document[] }> { return this._run(input); } }
关键说明
- 自定义工具的核心是完整返回RetrievalQAChain的输出,打破默认
ChainTool只返回result的限制; - 通过
returnIntermediateSteps: true能获取Agent调用工具的详细返回值,从而提取source_documents; - 类型问题本质是默认工具的返回值约束,自定义工具可以灵活控制返回结构。
内容的提问来源于stack exchange,提问作者andreasmoreno
相关产品推荐
相关产品推荐

