金融文档智能问答:从传统RAG到Agentic RAG的架构演进与实践
1. 从“被动检索”到“主动思考”为什么金融文档问答需要Agentic RAG如果你处理过金融领域的文档比如年报、招股书、审计报告或者复杂的合同条款你肯定遇到过这样的困境用传统的RAG检索增强生成系统提问得到的答案要么是照搬原文的“复读机”要么是面对复杂问题时“顾左右而言他”的片汤话。比如你问“对比公司A和公司B在2023年的研发投入强度及其对毛利率的影响”传统RAG很可能给你两段独立的、关于各自公司研发费用和毛利率的文字然后让大模型“硬着头皮”去拼凑结果往往逻辑混乱甚至出现事实性矛盾。问题的根源在于传统RAG本质上是一个“被动”的管道用户提问 - 检索相关片段 - 扔给大模型生成答案。这个流程里检索和生成是两个割裂的步骤。检索器比如基于向量相似度只负责找“像”的文本它不理解问题的深层意图也不负责验证召回片段之间的逻辑一致性。生成器大模型则像一个“盲人摸象”的厨师你给它什么原料它就做什么菜哪怕原料之间互相打架它也无力调和。金融文档的复杂性恰恰放大了这种“被动管道”的缺陷。金融信息具有高度的关联性如收入、成本、费用之间的勾稽关系、时序性同比、环比、趋势分析和逻辑性因果关系、假设条件。一个简单的问题背后往往需要串联多个文档、多个章节、甚至跨表格的数据。这时一个只会“关键词匹配”的检索器和一个“来料加工”的生成器就显得力不从心了。这就是Agentic RAG登场的背景。它不是一个新工具而是一种新的系统设计范式。其核心思想是引入一个具备“思考”和“决策”能力的智能体Agent来主动协调和控制整个问答流程。这个Agent不再是管道中的一个固定环节而是整个系统的“大脑”和“指挥官”。它会把一个复杂的用户问题拆解成一系列可执行的子任务比如先查定义、再找数据、然后对比分析动态地决定何时检索、检索什么、如何验证检索结果、以及如何组织最终答案的逻辑。简单说Agentic RAG让系统从“你问啥我搜啥答啥”的机械反应变成了“我理解你想问什么并主动规划步骤去找到最靠谱答案”的智能协作。在金融这个容错率极低、对准确性和逻辑性要求极高的领域Agentic RAG的价值尤为突出。它不仅能提升答案的准确率更能处理那些需要多步推理、信息整合和逻辑判断的复杂分析性问题让AI从“文档搜索引擎”升级为“初级金融分析师”。2. Agentic RAG的核心架构智能体如何驱动金融问答流程理解Agentic RAG关键在于拆解那个“智能体”是如何工作的。它不是一个黑盒子而是一套清晰、可设计的逻辑框架。下面我们以一个典型的金融问答场景为例拆解Agentic RAG的核心工作流。2.1 任务规划与分解把大问题拆成小步骤当用户提出一个问题比如“请分析公司X在本次并购案中可能面临的财务风险及法律风险并评估其对公司未来两年现金流的影响”时传统的RAG会直接把整个长句扔给检索器结果很可能召回一堆泛泛而谈“并购风险”的文章与公司X和具体案例无关。Agentic RAG中的智能体第一步是进行任务规划。它利用大语言模型LLM对问题的理解能力将宏大的、模糊的用户请求分解为一系列具体的、可操作的子任务。这个过程可能如下信息澄清与界定首先确认问题核心。例如识别出“公司X”、“本次并购案”需要具体名称或时间、“财务风险”、“法律风险”、“现金流影响”、“未来两年”等关键实体和时间范围。制定执行计划子任务1检索并提取公司X近三年的资产负债表、现金流量表关键数据特别是负债结构、现金储备。子任务2检索本次并购案的交易公告、独立财务顾问报告提取交易对价、支付方式现金/股权、融资安排。子任务3检索行业研究报告或类似案例总结并购中常见的财务风险点如商誉减值、整合成本、协同效应不及预期和法律风险点如反垄断审查、合规条款、或有负债。子任务4基于子任务1和2的数据构建一个简单的现金流预测模型哪怕是定性或半定量分析估算并购后整合期未来两年的额外现金支出和潜在收入影响。子任务5综合所有信息按照“财务风险-法律风险-现金流影响”的结构组织答案并确保每一项分析都有检索到的信息作为依据。这个规划过程不是一次性的。智能体会根据每一步执行的结果动态调整后续计划比如发现某个子任务检索结果为空或质量太差它可能会尝试换一个查询方式或者将这个任务标记为“信息不足需在答案中说明”。2.2 定向检索与多轮交互像侦探一样追问规划好子任务后智能体就开始执行定向检索。与传统RAG的“一次性检索”不同这里是多轮、交互式的。生成精准查询对于“检索公司X近三年负债结构”智能体不会直接用这个句子去搜。它会生成更精准的查询语句例如“公司X 2022年报 长期负债 短期借款 债券”“公司X 2023年中期报告 资产负债率”。它甚至知道去不同的文档章节找不同信息管理层讨论与分析找定性描述财务报表附注找明细。结果验证与过滤检索器返回文本片段后智能体不会照单全收。它会进行初步验证来源可信度该片段来自年报正文还是新闻稿来自官方公告还是分析师评论在金融领域来源权威性至关重要信息时效性该数据是否在要求的“近三年”时间范围内片段相关性该片段是否直接回答了子任务的问题还是仅仅提到了关键词内部一致性新检索到的数据是否与之前已确认的数据冲突例如两个片段对公司X现金储备的描述相差巨大迭代追问如果检索结果不理想比如只找到负债总额没找到明细智能体会自主生成新的、更具体的查询进行追问。例如“检索公司X 2022年报财务报表附注中关于‘借款’的明细包括银行借款和债券条款”。这个过程模拟了分析师在阅读文档时不断根据已有信息提出新问题的思考过程。2.3 综合推理与答案生成从信息拼图到逻辑叙述当所有子任务所需的“信息拼图”都收集、验证完毕后智能体进入综合推理与答案生成阶段。这一步智能体扮演的是“报告撰写人”的角色。信息整合与去重将来自不同子任务、不同文档的片段进行整合去除重复信息合并同类项。例如将关于“财务风险”的多个片段归类整理。逻辑链条构建这是与传统RAG生成器最大的不同。智能体不是简单地把所有相关片段拼接起来。它会主动构建逻辑链条。比如它会推理“检索到的信息A交易对价高 信息B公司现金储备低 - 推论C可能需要大量融资 - 结合信息D当前市场利率上行 - 最终风险点E融资成本上升侵蚀利润”。这个推理过程会明确地在思维链Chain-of-Thought中体现并作为生成答案的骨架。基于证据的生成最终生成的每一句陈述都尽可能引用或关联到具体的检索片段证据。在答案中可能会以“根据公司X2023年报第X页……”或“如交易公告所述……”等形式体现极大地增强了答案的可解释性和可信度。不确定性管理对于检索不到或存在矛盾的信息智能体会在答案中明确标注“该信息未在提供文档中找到”或“不同来源对XX数据的表述存在差异一种说法是……另一种说法是……”而不是强行给出一个可能错误的答案。这种“知之为知之不知为不知”的态度在金融场景下是必备的专业素养。通过这一整套流程Agentic RAG实现了对复杂金融问题的深度、可靠解答。它不再是一个简单的Q-A匹配器而是一个具备规划、检索、验证、推理、执行能力的智能分析助手。3. 构建金融领域Agentic RAG的关键组件与技术选型理解了架构下一步就是动手搭建。一个面向金融文档的Agentic RAG系统需要精心挑选和组合一系列组件。这里我结合自己的实践分享一套经过验证的技术栈和选型思路。3.1 智能体Agent框架系统的“大脑”智能体框架负责实现任务规划、工具调用、状态管理等功能。目前主流的选择有LangChain / LangGraph这是生态最丰富、社区最活跃的选择。LangChain提供了大量的Agent、Tool、Chain组件开箱即用。LangGraph是其用于构建复杂、有状态的多智能体工作流的利器特别适合实现我们前面描述的“规划-执行-循环”流程。它的可视化编排能力对调试非常有帮助。为什么选它文档齐全例子多遇到问题容易找到解决方案。对于快速原型验证和大多数生产场景LangChain系是稳妥的选择。LlamaIndex它最初以“数据连接”和高效索引闻名现在其AgentRunner和ReActAgent也越来越成熟。如果你的场景极度依赖复杂的数据查询比如需要联合查询结构化财报数据和 unstructured的文本分析LlamaIndex在数据层有天然优势。为什么选它数据与Agent的集成更紧密对于金融场景中常见的“表格数据文本”混合查询处理得可能更优雅。自主编排框架对于有极强定制化需求或对性能有苛刻要求的团队可以用OpenAI Function Calling、Anthropic Messages API提供的工具调用能力结合Python如asyncio或TypeScript自行编排智能体逻辑。这提供了最大的灵活性但开发成本也最高。我的建议对于大多数团队从LangGraph开始。它平衡了灵活性和开发效率。你可以用StateGraph清晰地定义智能体的状态如已收集的证据列表、待完成的任务列表、当前问题焦点用节点Node表示每个处理步骤规划、检索、生成查询等用边Edge控制流程流转。这能让你的系统逻辑一目了然。3.2 检索核心向量数据库与检索器的选择检索是RAG的基石在金融场景下对准确性要求极高。向量数据库Milvus/Zilliz Cloud性能强劲尤其擅长海量向量千万级以上的快速检索支持标量过滤这对金融场景很重要比如按年份、文档类型过滤。社区版足够用于大多数场景。Pinecone/Weaviate全托管的云服务省去运维烦恼。Weaviate除了向量检索还内置了面向对象的数据库特性可以很自然地将“公司”、“年报”、“财务指标”建模为对象并关联起来这在处理实体关系复杂的金融数据时是一个亮点。PGVector如果你的数据量不是特别巨大百万级且团队已经有PostgreSQL技术栈PGVector是最简单、最无缝的选择。它让你能用熟悉的SQL同时处理结构化和向量数据例如可以轻松执行“查找与‘现金流风险’语义相似且年份在2022年之后的段落”这类混合查询。检索器与重排序器基础检索器通常使用向量数据库的相似性搜索如余弦相似度。关键点在于嵌入模型。对于中文金融文本建议使用针对中文优化的模型如BAAI/bge-large-zh-v1.5或moka-ai/m3e-base。它们对金融术语的理解比通用模型好得多。混合检索这是必选项。单纯依靠向量检索语义搜索在金融场景下容易漏掉关键数字、代号如股票代码600519.SH。必须结合关键词检索如BM25。LangChain和LlamaIndex都提供了EnsembleRetriever之类的组件可以加权融合两种检索方式的结果。重排序器这是提升精度的“神器”。初步检索可能返回20个片段重排序器如BAAI/bge-reranker-large会根据原始问题对这20个片段进行更精细的相关性打分和重新排序将最相关的3-5个提到最前面。这能显著改善输入给大模型的上下文质量。实操心得不要迷信单一的检索方式。我们线上系统采用“关键词检索召回 向量检索召回 重排序精排”的三级流水线。对于数字、代码多的查询关键词检索权重调高对于概念性、分析性的查询向量检索权重调高。重排序器虽然增加了一点延迟但对答案质量的提升是立竿见影的。3.3 大语言模型LLM生成与推理的引擎LLM是智能体“思考”能力的来源。选型主要考虑三点推理能力、上下文长度、成本。闭源模型APIGPT-4/GPT-4o在复杂推理、任务规划和遵循指令方面仍然是标杆。对于金融分析这类需要强逻辑的任务如果预算允许GPT-4系列是首选。其超长的上下文128K也能吞下更多检索结果进行综合判断。Claude 3Opus/Sonnet在长文档理解、逻辑性和“无害性”上表现优异。对于需要从冗长年报中提取关键信息的任务Claude 3常常有惊喜。它的“思维链”输出也更清晰。深度求索/智谱GLM国内优秀的选择对中文金融语境理解好API稳定符合数据合规要求。开源模型本地部署Qwen系列Qwen2.5-72B-Instruct综合能力极强的中文开源模型在数学、代码、推理任务上表现出色非常适合需要多步计算的财务分析。Llama 3.1系列405B/70B英文能力顶尖开源社区的宠儿有丰富的微调版本和工具生态。如果业务以英文文档为主这是很好的选择。小型化模型7B-14B级别如Qwen2.5-7B-Instruct、Llama-3.2-3B-Instruct它们可以作为“工具使用模型”或“路由模型”专门负责理解用户意图、拆解任务、调用工具检索、计算而把最终的复杂答案生成交给更大的模型。这种“大小模型协同”的架构能有效平衡成本和效果。重要提示在金融领域不要完全依赖LLM的数学能力。对于涉及百分比、增长率、复合计算等任务最佳实践是让智能体调用计算工具如Pythonnumexpr或公式解释器。即让LLM识别出“需要计算毛利率增长率”然后生成并执行代码(current_gross_margin - last_gross_margin) / last_gross_margin最后将计算结果填入答案。这能保证数字的绝对准确。4. 金融文档处理与知识库构建的专项挑战Agentic RAG的上层建筑再智能如果底层的知识库向量库质量不行那就是“垃圾进垃圾出”。金融文档的处理有诸多特殊之处。4.1 文档解析与清洗告别混乱的文本流金融PDF尤其是扫描版是出了名的难处理。你的解析器必须能处理复杂版式多栏排版、页眉页脚、文本框、表格。非文本元素图表、印章、手写签名。特殊内容财务报表资产负债表、利润表、现金流量表是结构化数据的海洋但通常以非结构化的形式嵌在PDF里。工具链建议优先使用云服务或专业库对于高精度要求Azure Document Intelligence、Amazon Textract或Google Document AI的付费服务效果最好能较好地保留表格结构和阅读顺序。开源方案中Unstructured.io库是一个强大的全能选手支持多种文件格式和分区策略。表格提取是重中之重必须使用专门的表格提取模型或工具如Camelot、Tabula针对简单表格或基于深度学习的Table Transformer。提取后要将表格数据转换为Markdown格式或结构化字典/JSON并作为一段带有明确标记如table.../table的文本与其他正文一起处理。这能极大提升后续检索和模型理解的效果。清洗与归一化去除无意义字符大量换行符、页码、无关水印。实体归一化将“本公司”、“集团”、“XX股份有限公司”统一为规范的实体名称“公司X”。数字与单位归一化将“1,234.56万元”、“12.3456亿”统一转换为“12345600”基础单位或保留原始文本但添加标记。这对于后续的数值检索和计算至关重要。4.2 文本切片策略平衡信息完整性与检索精度如何把一篇上百页的年报切成适合检索的“片段”chunks是RAG效果的关键。切忌盲目按固定长度切分用256或512个token的滑动窗口切分会把一个完整的表格、一个关键的论点拆得七零八落。基于语义的智能切分优先尊重文档结构利用解析器识别出的标题层级H1, H2, H3、段落、列表。以一个完整的“节”或“子节”作为一个块。例如“第三节 公司业务概要”下的所有内容作为一个块。表格单独成块一张完整的利润表作为一个块。如果表格太大可以考虑按年度列切分但必须保证表头完整。使用递归切分对于长段落再按句子或语义边界如langchain的RecursiveCharacterTextSplitter进行二次切分但设置overlap重叠以减少上下文断裂。添加丰富的元数据每个切片必须携带元数据这是金融RAG的生命线。至少包括source: 文档名称如“公司A_2023年年报.pdf”page: 页码或页码范围section: 所属章节标题如“财务报告 - 合并利润表”year: 报告年份doc_type: 文档类型年报、季报、招股书、公告company: 公司实体contains_table: 布尔值是否包含表格这些元数据将在检索时用于高效的过滤。当智能体需要“公司A 2023年利润表数据”时它可以构建查询向量相似度搜索“营业收入 营业成本”同时过滤company公司AANDyear2023ANDcontains_tableTrue。这能精准定位避免从管理层讨论章节中召回无关的数字描述。4.3 嵌入模型的选择与微调切片后的文本需要转化为向量嵌入。通用嵌入模型在金融领域可能“水土不服”。领域适配优先选择在金融语料上训练或微调过的模型。例如BAAI/bge-large-zh-v1.5-financial或m3e-financial等变体。它们对“市盈率”、“计提减值”、“现金流量套期”等术语有更好的向量表示。微调嵌入模型如果效果仍不理想可以考虑用自己的金融文档问答对对开源嵌入模型进行轻量微调。这能让你系统的向量空间更贴合你的特定数据分布。可以使用Sentence Transformers库和对比学习损失函数进行。长上下文处理对于特别长的切片如一个完整章节可以考虑使用能生成长上下文嵌入的模型如OpenAI的text-embedding-3-large支持更长的输入或者采用将长文本摘要后再嵌入的策略但摘要会损失细节需权衡。构建一个高质量的知识库工作量可能占整个项目的70%。这部分投入是值得的它直接决定了系统效果的上限。5. 实战设计一个处理并购风险分析的FinAgent-RAG智能体让我们把前面所有理论落地设计一个名为FinAgent-RAG的智能体专门处理开头的那个复杂问题“分析公司X在并购案中的财务与法律风险及现金流影响”。我们将使用LangGraph来构建这个智能体的工作流。以下是核心的节点Node设计5.1 状态定义与初始化节点首先定义智能体运行过程中需要维护的状态State。这是一个TypedDict包含了所有中间信息。from typing import TypedDict, List, Annotated import operator class AgentState(TypedDict): # 用户输入 original_question: str # 规划与执行 plan: List[str] # 存储分解后的子任务列表 current_task: str # 当前正在执行的子任务 completed_tasks: List[str] # 已完成的任务列表 # 检索与信息 queries_generated: List[str] # 为每个任务生成的查询列表 retrieved_docs: List[dict] # 检索到的文档片段列表每个片段包含内容和元数据 validated_evidence: List[dict] # 经过验证和过滤后的证据列表 # 分析与生成 analysis_notes: str # 推理过程中的分析笔记思维链 final_answer: str # 最终答案初始化节点负责接收用户问题并触发规划。def init_node(state: AgentState) - AgentState: 初始化记录原始问题 print(f[初始化] 收到用户问题: {state[original_question]}) # 初始化其他状态字段 state[plan] [] state[completed_tasks] [] state[retrieved_docs] [] state[validated_evidence] [] state[analysis_notes] return state5.2 规划节点任务分解与策略制定这是智能体的“总参谋部”。它调用LLM将复杂问题分解。from langchain_core.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI llm ChatOpenAI(modelgpt-4, temperature0) PLANNER_PROMPT ChatPromptTemplate.from_messages([ (system, 你是一个资深的金融分析师助理。你的任务是将一个复杂的金融分析问题分解为一系列具体的、可执行的检索或分析子任务。 请遵循以下原则 1. 子任务应足够具体能直接转化为对知识库的查询。 2. 考虑信息的类型定量数据财报数字、定性描述风险分析、法律条款、市场评论。 3. 考虑信息的来源和时效性。 4. 子任务之间可能有依赖关系请按逻辑顺序列出。 用户问题{question} 请输出一个JSON列表每个元素是一个子任务描述。), ]) def planning_node(state: AgentState) - AgentState: 任务规划节点 print(f[规划] 开始分解问题...) prompt_value PLANNER_PROMPT.format_prompt(questionstate[original_question]) # 这里简化处理实际应解析LLM返回的JSON # 假设LLM返回了以下计划解析后 state[plan] [ 检索公司X近三年2021-2023的资产负债表和现金流量表摘要重点关注负债结构、现金及等价物。, 检索关于[具体并购案名称]的交易公告或报告提取交易对价、支付方式、融资安排等关键条款。, 检索金融教科书、行业指南或权威报告中关于‘并购财务风险’和‘并购法律风险’的常见类型与案例分析。, 基于前两步获取的具体数据进行简单的现金流压力测试分析估算并购后未来两年的额外现金流出和潜在收入协同效应。, 综合所有信息按照‘财务风险-法律风险-现金流影响’的结构撰写分析报告确保每一项论断都有依据。 ] print(f[规划] 生成子任务: {state[plan]}) state[current_task] state[plan][0] if state[plan] else None return state5.3 执行节点定向检索、验证与工具调用这是智能体的“手脚”。它根据当前任务生成查询调用检索工具并验证结果。# 假设我们已经有一个强大的检索工具函数 def hybrid_retrieval_with_filter(query: str, filters: dict) - List[dict]: 混合检索函数支持元数据过滤 # 这里集成关键词检索、向量检索和重排序 # 返回格式[{content: ..., metadata: {...}, score: 0.95}, ...] pass def validation_and_filtering(docs: List[dict], task: str) - List[dict]: 对检索结果进行验证和过滤 validated [] for doc in docs: # 1. 检查来源可信度例如优先选择年报、公告而非新闻稿 if doc[metadata][doc_type] in [annual_report, official_announcement]: credibility high else: credibility medium # 2. 检查时效性假设任务中隐含了时间要求 # 这里可以根据任务描述提取时间关键词与元数据中的year比较 # 简化处理暂时全部接受 # 3. 利用一个小型LLM或规则判断片段与任务的相关性 # 简化处理假设score 0.8为高度相关 if doc[score] 0.8: doc[credibility] credibility validated.append(doc) return validated def execution_node(state: AgentState) - AgentState: 执行当前任务节点 if not state[current_task]: return state print(f[执行] 正在处理任务: {state[current_task]}) # 1. 生成精准查询可再次调用LLM # 简化直接从任务描述中提取关键词 query state[current_task] # 实际中需要更精细的查询生成 # 2. 构建元数据过滤器这是金融RAG的精髓 filters {} if 公司X in state[current_task]: filters[company] 公司X if 近三年 in state[current_task]: filters[year] {$gte: 2021, $lte: 2023} if 资产负债表 in state[current_task] or 现金流量表 in state[current_task]: filters[section] {$regex: 财务报告|财务报表} filters[contains_table] True # 3. 调用检索工具 retrieved_chunks hybrid_retrieval_with_filter(query, filters) print(f[执行] 检索到 {len(retrieved_chunks)} 个片段) # 4. 验证与过滤 validated_chunks validation_and_filtering(retrieved_chunks, state[current_task]) print(f[执行] 验证后保留 {len(validated_chunks)} 个片段) # 5. 更新状态 state[retrieved_docs].extend(retrieved_chunks) state[validated_evidence].extend(validated_chunks) state[queries_generated].append(query) # 6. 如果是计算类任务调用计算工具 if 压力测试 in state[current_task] or 计算 in state[current_task]: # 从 validated_evidence 中提取相关数字 numbers extract_numbers_from_evidence(state[validated_evidence]) # 调用一个预设的财务模型或Python计算函数 cash_flow_impact run_cash_flow_model(numbers) # 将计算结果也作为一条“证据”加入 state[validated_evidence].append({ content: f现金流压力测试结果: {cash_flow_impact}, metadata: {source: internal_calculation}, credibility: high }) return state5.4 路由与循环控制决定下一步做什么执行完一个任务后智能体需要决定继续下一个任务还是对当前任务进行补充检索或者直接进入生成阶段def should_continue(state: AgentState) - str: 判断逻辑下一步去哪 # 条件1: 如果当前任务检索结果为空或质量极差可能需要“重试”或“细化查询” current_task_evidence [e for e in state[validated_evidence] if e.get(query) state[queries_generated][-1]] if len(current_task_evidence) 0: print([路由] 当前任务未找到有效证据尝试细化查询或标记信息缺失。) # 可以在这里添加一个“查询优化”节点或者直接标记并继续 return mark_missing_and_continue # 条件2: 如果还有未完成的计划任务继续执行下一个 completed_count len(state[completed_tasks]) if completed_count len(state[plan]): print(f[路由] 任务 {state[current_task]} 完成继续下一个。) return continue_to_next_task # 条件3: 所有计划任务都执行完毕进入最终生成阶段 print([路由] 所有计划任务完成进入答案生成。) return generate_final_answer在LangGraph中我们会根据should_continue函数的返回值将状态路由到不同的下一个节点。5.5 生成与报告节点整合信息输出答案最后将所有收集到的、经过验证的证据和分析笔记整合成一份结构化的答案。def generation_node(state: AgentState) - AgentState: 最终答案生成节点 print([生成] 开始整合证据生成最终答案...) # 准备上下文将所有有效证据的内容拼接起来 context \n\n.join([f[来源: {e[metadata].get(source, N/A)}, 可信度: {e.get(credibility, N/A)}]\n{e[content]} for e in state[validated_evidence]]) GENERATION_PROMPT ChatPromptTemplate.from_messages([ (system, 你是一位严谨的金融分析师。请基于以下经过验证的证据回答用户的原始问题。 要求 1. 答案必须严格基于提供的证据。如果证据不足请明确指出。 2. 答案结构清晰逻辑严谨。请按照“财务风险”、“法律风险”、“现金流影响”三个部分组织。 3. 在每一部分的分析中引用具体的证据来源用括号标注。 4. 对于涉及数字计算的部分展示简要的计算逻辑或依据。 5. 最后给出一个综合性的结论。 原始问题{question} 证据列表 {context} 你的分析笔记可选 {analysis_notes} ), (user, 请生成最终的分析报告。) ]) prompt GENERATION_PROMPT.format_prompt( questionstate[original_question], contextcontext, analysis_notesstate[analysis_notes] ) # 调用LLM生成最终答案 response llm.invoke(prompt.to_messages()) state[final_answer] response.content print([生成] 最终答案已生成。) return state通过LangGraph将上述节点连接起来形成一个闭环的工作流初始化 - 规划 - 执行 - 路由 - (继续执行/生成) - 结束。这个智能体就能自动完成从问题理解到报告生成的全过程。6. 评估、迭代与避坑指南构建完Agentic RAG系统只是开始如何评估其效果并持续迭代优化才是更漫长的过程。6.1 如何评估一个金融Agentic RAG系统不能只看答案“看起来”对不对需要一套多维度的评估体系。事实准确性这是底线。答案中的每一个事实陈述如数字、日期、事件是否与源文档严格一致可以构建一个测试集用LLM如GPT-4或人工去判断“答案中的事实是否被源文档支持”。推理逻辑性答案的论证过程是否合理因果链条是否清晰这可以通过让评审员或高级LLM评估答案的连贯性和说服力来判断。信息完整性对于复杂问题系统是否覆盖了所有必要的子问题可以对照“规划节点”生成的子任务列表检查最终答案是否都涉及了。可解释性系统是否能提供答案的依据引用来源这是建立信任的关键。评估时检查答案中是否包含了清晰的引用标记。拒绝能力对于文档中没有答案或信息不足的问题系统是否敢于说“不知道”而不是胡编乱造幻觉效率平均响应时间、Token消耗成本。这对于高频使用的生产系统很重要。建议的评估流程构建黄金测试集收集50-100个真实的、不同复杂度的金融问答对并标注标准答案和对应的证据来源。自动化评分利用LLM-as-a-Judge如用GPT-4做裁判针对每个维度设计评分提示词对系统输出进行批量评分。人工深度复查定期如每周抽样审查一些复杂案例尤其是自动化评分不高或有争议的案例分析根因。A/B测试如果对系统做了重大改进如换了嵌入模型、改了切片策略可以在小流量上进行A/B测试对比关键指标。6.2 常见陷阱与避坑指南根据我的踩坑经验以下几个问题需要特别注意幻觉问题这是RAG的头号敌人。Agentic RAG通过“基于证据的生成”和“验证”环节能大幅缓解但未根除。坑LLM在整合信息时可能会“脑补”一些不存在的联系或结论。避坑在生成提示词中反复强调“严格基于证据”。使用引用强制技术要求LLM在输出的每一句话后面标注支持它的证据片段的ID。甚至可以设计后处理程序检查每个引用是否真实存在。检索器“偏科”向量检索器可能过于关注语义相似而忽略精确匹配。坑问“毛利率从15%提升到18%”检索到的全是关于“毛利率”的讨论但偏偏没有包含“15%”和“18%”这两个关键数字的片段。避坑必须使用混合检索。并且对于包含明确实体公司名、股票代码、数字、日期的查询要调高关键词检索的权重。可以训练一个简单的分类器根据查询特征动态调整混合检索的权重。任务规划“跑偏”LLM在分解任务时可能产生不切实际或冗余的子任务。坑规划出“检索全球宏观经济形势”这种与公司特定并购案无关的宽泛任务。避坑在给规划LLM的指令中明确限制任务的范围和依据“仅基于已知的公司文档和通用金融知识库”。同时可以为智能体预设一些工具白名单让它知道只能通过检索、计算等有限工具来完成任务避免规划出无法执行的步骤。流程陷入死循环智能体可能因为某个子任务始终无法找到满意答案而不断重试。坑在“检索某份不存在的内部备忘录”上无限循环。避坑在状态中设置最大重试次数或超时机制。在路由逻辑中如果同一个任务失败多次就强制将其标记为“信息不足”并记录到分析笔记中然后继续流程。计算与逻辑错误LLM不擅长精确计算。坑让LLM直接计算复合增长率结果出错。避坑凡是涉及计算必用工具。在规划阶段就识别出需要计算的任务并在执行阶段调用Python解释器或专用计算函数。让LLM只负责识别计算意图和解释计算结果。6.3 持续迭代的飞轮一个好的Agentic RAG系统是一个活系统需要持续喂养数据、观察效果、进行优化。收集反馈数据在系统中内置“反馈”按钮让用户对答案进行“有帮助/无帮助”评分甚至标注具体问题如“事实错误”、“逻辑不清”、“信息不全”。错误分析定期分析反馈不好的案例。是检索没找到还是规划不合理或者是生成时出了问题将案例归类形成优化待办列表。针对性优化检索问题考虑优化切片策略、微调嵌入模型、增加检索的元数据字段。规划问题用错误的案例去微调规划LLM的提示词或者提供少量示例few-shot。生成问题优化最终生成的提示词模板加入更多约束和示例。知识库更新建立文档知识库的定期更新机制确保信息的时效性。金融领域的Agentic RAG是一个令人兴奋且充满挑战的方向。它不再是一个简单的问答玩具而是一个真正能嵌入业务流程、辅助专业分析的智能系统。从被动检索到主动思考的这一步跨越背后是架构设计、组件选型、数据处理和评估优化的全方位考量。希望这篇从原理到实战的长文能为你启动自己的FinAgent-RAG项目提供一张有价值的路线图。记住关键不是追求最酷的技术而是构建一个可靠、可信、可解释的系统这在金融领域比什么都重要。