尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

金融财报问答系统实战:从RAG到Agent的完整技术方案

金融财报问答系统实战:从RAG到Agent的完整技术方案 简介在金融投资领域财报分析是高频且复杂的场景。大模型技术为自动化解读财报提供了可能但直接使用通用问答模型无法满足金融场景对准确性和可验证性的严苛要求。构建一个可靠的金融财报问答系统关键在于如何将PDF解析、表格结构识别、检索增强生成RAG与智能体Agent技术有机结合。RAG负责从海量、长篇幅的财报文本中精准召回相关数据解决长文档与上下文窗口的冲突而Agent则通过Function Calling调动外部计算工具弥补大模型在数值运算上的天然短板。这种架构不仅能够回答“某公司营收是多少”这类事实性问题还能处理“毛利率同比变化”等需要计算和推理的复杂问题。对于正在落地金融RAG应用或探索Agent实战的工程师本文提供了一套兼顾技术深度与工程可行性的参考路径涵盖数据预处理、向量召回、重排序、评测体系及幻觉抑制等关键环节。1. 项目概述与痛点分析1.1 为什么金融财报问答这么难做金融财报问答大模型这个项目说白了就是把“看财报”这件苦差事交给大模型。我做这个项目的原因很简单我自己在看财报这件事上已经耗了太多时间。A股四千多家公司每季度一次定期报告每份报告少则几十页多则几百页里面塞满了管理层讨论、会计附注、非经常性损益说明真正关键的指标往往埋在几万字里人工翻要找半天。更要命的是想对比两家公司的财报得同时打开好几个PDF来回切看完这个季度再看上个季度脑子稍微乱一下就把数字搞混了。我做这个项目的初衷很朴素能不能做一个工具把财报扔进去用户用自然语言提问比如“这家公司今年一季度营收同比增长多少”“毛利率为什么下降了”“应收账款占营收比例是否异常”它能在几秒内给出准确答案并且能说明数据来源和计算逻辑而不是凭空给你编一个数字。金融财报问答和通用问答最大的区别在于三个字要负责。通用聊天机器人答错了顶多被当成笑话财报问答要是把净利润说错了、把同比增速算错了那是会让人做错投资决策的。所以这个项目从第一天起我就把可验证性放在一切设计之上——每个数字都要能追溯到原材料每个结论都要有推理过程宁可答“不知道”也不能胡编。1.2 这个项目适合谁参考如果你正在做以下事情这篇文档应该能提供一些实打实的参考需要在内部搭建财报分析、投研辅助、年报解读类工具的技术团队正在做RAG检索增强生成落地但发现通用RAG处理不了长文档和表格的工程师想用Agent方式解决“大模型数学能力差”问题的算法同学需要处理证券公告、招股书、募集说明书等长文档OCR和结构化解析的产品经理我自己的技术栈偏Python模型层用了开源和商用API混合方案向量库用了轻量级方案整个项目从零搭起来大约花了两周。这个过程中踩了不少坑后面我会把每个坑的细节都展开讲。2. 财报数据的预处理与解析链路2.1 财报格式的复杂度远超你的想象财报问答的第一步不是训练模型而是把PDF变成模型能读的文本。这一步看起来简单实际上整个项目里最耗时间、最容易出错的部分。A股财报的PDF通常是文字版和扫描版混合的文字版还好说扫描版必须走OCR。但就算文字版PDF提取出来的文本也是乱序的单栏变成多栏混乱、文本框错位、表格断裂各种问题层出不穷。我第一个版本直接用开源PDF库硬提取文本结果惨不忍睹资产负债表里“货币资金”这一行被分成了两半后半截“10,234,567.89”跑到了下一页跟模型的输入上下文完全接不上。后来我重建了提取链路处理顺序是这样的先用解析工具检测PDF是文字版还是扫描版扫描版自动对接OCR服务这里可以使用本地OCR模型或云端服务考虑到部署成本我倾向于本地跑OCR。对文字版PDF进行版面分析识别出页码、段落、表格区域这一步非常关键因为财报里数字几乎都在表格里而通用文本提取器对表格的处理极弱。表格数据以“行号单元格”的方式结构化输出而不是纯文本流。这样后续指标提取时能根据表头名称定位指标所在行。文本内容按阅读顺序重组去掉页眉页脚、页码、重复的封面信息避免无用内容污染向量检索。这里我用了表格结构识别方案把每个表格提取成一个二维数组效果比纯文本提取好了很多。你要信我一句话处理财报第一步把表格结构保住了整个项目就成功了一半。如果表格散成文本你后面不管用多好的模型都很难准确关联“利润总额”和它后面的数值。2.2 指标提取与口径统一财报解析链路跑通之后下一步是把“文本”变成“指标”。一家公司的利润表里“营业收入”这个名词在不同年份的报表里可能表述为“营业总收入”“营业收入(万元)”“Operating Income”如果直接按字面匹配会漏掉很多数据。我维护了一套指标映射表把财务三大表里常用的几十个指标做了别名归并。凡是遇到“总营收”“主营收入”“营业总收入”统一映射到规范名。这一步没有技术难度但需要耐心和财务常识相当于给模型准备一套“同义词词典”。但光有同义词还不够还有统计口径的问题。比如“营业收入同比增长率”有的公司直接披露了有的公司没有披露但给了上期数和本期数需要模型自己算。这种场景在纯RAG架构里很难处理因为RAG只能“检索已存在的信息”不能“计算不存在的信息”。所以我在架构里加了Agent层让模型调用一个“计算器工具”来完成指标运算。后面第4章会详细讲这个设计。还要注意一个容易被忽略的点单位不同。有的财报金额单位是“元”有的是“万元”还有的是“亿元”。如果不做单位归一化随便翻错一个单位答案就差好几个数量级。我在解析阶段统一读单位字段然后全部转成“万元”提示词里也单独写了单位规范要求实测下来能显著降低低级错误。2.3 财报数据量级与上下文规划一份典型的年报PDF在30万到50万字之间而主流大模型上下文窗口虽然已经挺大了但直接塞进去代价很高——长上下文API费用会大幅上涨且相关性和注意力质量会下降。如果用户连续问几个问题每次都把整份年报喂给模型体验和成本都会爆炸。所以不能直接“全文喂给模型”而是走检索路线把财报切块、向量化、存索引用户提问时先检索出最相关的几段再拼成上下文送给模型。这就是RAG的基本思路。但财报里的表格切块有特殊性简单按字符长度切块会把表格的完整行切断导致检索到的片段缺失关键数值。我的切块策略是文本部分按500~800字一片同时与相邻片段保留10%的重叠表格部分不按字符切按行切每个表格片段至少包含一整个横行的完整数据并携带表头信息。这样检索时只要命中某一行的数据表头也跟着进去了模型才能知道这一行数据的列名对应关系。3. 检索增强生成RAG链路构建3.1 向量化与索引构建向量化环节我对比过不少方案最终选了性能够用、部署成本低的方案。如果你公司有现成的向量化服务直接用就行效果差异没那么大。关键不在于选哪个模型而在于怎么处理好文本。财报的文本块大多有明确的财务语境直接丢给通用向量模型效果尚可但有个小技巧可以显著提升效果切块时保留“财务指标路径”。什么意思呢如果一个片段是“第二节 公司简介 经营情况 营业收入”那向量化前的文本不要只放表格数值要把这个路径拼在正文开头比如“本节涉及指标营业收入、营业成本、毛利率。正文如下……”。这样检索时用户问“毛利率”向量模型能靠前置的指标词匹配到该片段命中率提升很大。向量库我用了轻量级的本地方案如果数据量不大几千个片段都能秒级检索没必要上重型分布式数据库。真正的瓶颈从来不在检索性能而在召回质量。我实测下来单纯的向量检索命中率在70%左右剩下30%需要用关键词BM25做加权混合召回把两者得分合并排序整体命中率能提到90%以上。3.2 重排序为什么必不可少RAG链路里很多人都忽略了重排序这一步但财报问答场景里这步特别关键。因为向量检索返回的Top-K段里可能有两三段看起来很相似但真正能回答用户问题的只有一段。把不相关内容喂给模型模型不仅答不好还可能被干扰开始胡编。比如用户问“销售费用率”检出来的可能是“管理费用率”或者“财务费用率”的段落数字长得很像模型很容易张冠李戴。我加了一个重排序模型专门对检索结果做精排。重排之后真正包含目标指标的段落会被提到最前面不相关段落被压到后面再结合上下文截断策略只把重排后的前3段送入大模型。这一步的逻辑很简单检索可以宽松生成必须精准宁缺毋滥。3.3 上下文拼装与引文标记上下文拼装的方式也影响回答质量。我采用的模板大致是这样的你是一名专业的财务分析师请仅根据以下财报片段回答用户问题。 回答时请注明每个数值出现的片段编号如[片段1]如果片段中没有相关信息请明确回答“财报中未提及该指标”。 需求指标{用户问题} 片段 [片段1] {正文} [片段2] {正文} [片段3] {正文}注意这里要求模型“注明片段编号”这个设计非常有用。一方面让模型不会跳过片段凭空发挥另一方面在最终回答里自动带上了引用标记用户能直接回到原财报里校验。做金融问答没有引用佐证的回答是没人敢信的你也不希望自己的工具给出的数字没法追溯。4. Agent模块设计让模型学会“算账”4.1 为什么必须引入Agent而不是纯RAG我在项目早期用纯RAG做财报问答发现一个非常尴尬的问题问“今年一季度净利润同比增速是多少”这种“需要计算”的问题时RAG只能把去年和今年的净利润数值都检索出来但算不出增长率。就算你强行把数值都放在上下文中让大模型直接算除法它也会偶发出错尤其是带小数点和负数的科目。这里不是模型笨而是大语言模型本质是一个“下一个词预测器”它做数学运算天生不靠谱。你是硬让一个文科生心算复杂除法时灵时不灵。解决方案很明确把计算任务从“内容生成”中剥离出来交给外部工具。这就是Agent的思路——模型不直接算它调用一个计算器工具把检索到的数值填进去工具负责算算完再把结果交给模型组织语言。4.2 Function Calling与工具设计细节实现上我用的是Function Calling机制。给模型声明一个函数def cal_indicator(metric_name: str, **kwargs): 计算财务指标 metric_name: 指标中文名如营收同比增速 kwargs: 所需参数如 {营收本期:1000, 营收上期:800} # 内部根据指标名称选择公式计算 if metric_name 营收同比增速: return (float(kwargs[营收本期]) - float(kwargs[营收上期])) / float(kwargs[营收上期]) ...模型在对话过程中先通过RAG检索到“本期营收”和“上期营收”的数值然后它判断需要执行计算就会输出一个结构化调用请求把参数填进去。系统拉起计算器函数得到数字再回传给模型让模型把结果组织成自然语言答案。有一个细节必须强调模型在提取参数时也会出错。比如它可能把“2024年一季度营收”和“2023年全年营收”混在一起做同比算出的数字当然就错了。为了抑制这种错误我在调用前加了一层“参数校验”用规则检查两个对比周期是否一致如果一个是季度口径、一个是年度口径直接拒绝计算要求模型重新检索。这个校验规则的准确率虽然不完美但已经能拦截掉大部分低级错误。4.3 Agent编排多轮问答的上下文累积Agent场景还有一个麻烦事用户会在连续对话里追问。比如用户先问“今年毛利率多少”系统回答了然后用户接着问“那净利率呢”这里的“那”指代的是同一个时间范围。如果不做多轮上下文管理第二次提问会丢失“今年”这个限定条件模型可能默认拿全年数据导致答案口径偏差。我的处理方式是在每次Agent调用前把历史对话的关键限定条件做一次“条件累积”。具体实现是用一个临时字段记录当前对话的额外限定词比如“时间2024Q1”“主体某某公司”每次新问题解析时先把这个条件拼接上去再送进检索和计算。这样用户省略主语、时间时系统也能正确理解。5. 评测体系与常见问题排查5.1 评测集构建财经问答的分数怎么打我建了一个约200道题的财经评测集覆盖了四大类问题问题类型示例评测标准数值检索型2024年一季度营业收入是多少数值完全正确单位正确计算推导型今年毛利率同比变化了多少数值结果与财报中披露值一致逻辑判断型为什么现金流下降但净利润增长引用财报中相关解释片段信息缺失型该财报是否披露了商誉减值风险能明确回答披露/未披露评测时我用了“LLM-as-a-Judge”的方案自己写了一个评分提示词让另一个大模型根据参考答案和系统回答逐项打分并输出扣分原因。但这套方案有坑主要在于评测大模型本身可能对数字不敏感所以我额外加了一个“数值硬校验”环节——凡是数值类问题用正则从回答中提取所有数字与标准答案比对只要一个数字不一致就直接判错。这比单纯让大模型评分严格得多。5.2 大模型幻觉问题怎么压幻觉是大模型问答的头号公敌在金融场景里更是无法容忍。我压幻觉主要做了三件事第一前面提到的引文标记强制每条回答都带片段出处。第二在提示词里明确写了一句“如果片段中没有回答该问题所需的信息请直接回答‘未找到相关信息’不要推测或编造。”很多情况下模型会服从这个指令。第三做了一层后置校验系统对最终回答做一次“关键数值回查”如果回答里出现了超过10万以上的大额数字系统回查这个数字是否在检索片段中出现过如果没出现过自动标记“疑似幻觉”提示用户谨慎参考。这三层下来幻觉发生率从最开始的不可容忍降到了大概2%以内错漏基本都是小数值、非关键指标作为辅助工具已经可以交付了。5.3 长文档截断与上下文过载另一个常见坑是财报太长检索出来的片段拼接后依然超过模型上下文限制。压缩的手段有三步优先丢弃“管理层讨论与分析”这类主观表述片段因为核心数值都在三张表里对表格片段做降维只保留表头和数值列丢弃无意义的注释列如果还不够就限制每次送入的片段数量从3段降为2段信息密度优先于信息广度。如果你实际部署的时候也遇到上下文爆掉我建议先看检索出来的片段质量而不是盲目加大上下文窗口。很多时候断句、切块方式调优后你会发现根本不需要那么多片段。5.4 部署运维从实验到小范围试用部署时我用的是容器化方案模型层API化检索层和Agent服务独立跑。整个系统可以在普通开发机上运行内存占用不高响应延迟大概在4到6秒这速度已经能满足交互式问答。如果做成异步批量问答比如用户用Excel表格上传几百个公司代码系统后台一个个解析、问答那就更适合拉数据管道。我后期加了一个批量处理入口让用户传一个股票列表系统自动拉取报告的文本片段并批量生成问答结果导成CSV。这个玩法在实际使用中比单轮问答更受欢迎因为很多使用者是在做批量筛选。6. 几点经验总结与后续规划如果你要复现这个项目我给你几个实打实的建议。千万别一上来就训练微调模型。财报问答的核心障碍不在模型能力而在数据加工和链路设计。通用大模型本身已经掌握了基本的财务报表知识你只要把正确的上下文送进去它就能答对。微调的必要性远没有你想得大成本倒是实打实的高。先跑通最小闭环再考虑优化。第一个版本哪怕准确率只有60%你也可以用因为核心路径已经验证了。从60%到90%主要是靠数据清洗和质量优化而不是模型魔法。对数字的敬畏心要贯穿始终。金融场景的容错率极低一个单位错误、一个口径混用都会导致灾难性结论。你一定要在系统里设置多道校验闸门宁可多花一点算力也要保证每个输出数字可溯源、可复核。后续我打算把能力扩展到港股和美股财报那边PDF格式更乱英文缩写更多需要额外处理。同时考虑增加“财务异常检测”模块自动标记财报里异常波动的科目比如应收账款增速远高于营收增速、存货异常升高等等帮用户快速定位潜在风险。这条路还很长但方向已经摸出来了。最后分享一个小技巧你在做财报问答系统时建议先把“不知道”说清楚的能力练好。一个模型如果敢于坦率承认自己不知道比它硬着头皮编一个看起来合理的数字要可靠得多。这个原则不只是写提示词也是整个金融AI系统设计的第一准则。本文还有配套的精品资源点击获取
返回列表