1. AI金融投研到底在解决什么问题
金融投研这个行当,外人看着光鲜,真正干过的人都知道,大量时间花在了“找数据、读报告、算指标、写纪要”这四件事上。一个覆盖消费行业的分析师,每天要盯的公告少则几十份,多则上百份,再加上行业数据、产业链调研、电话会议纪要,信息量早就超过了个人处理能力的上限。AI进入这个领域,本质上不是为了替代分析师做决策,而是把信息处理的效率提升一个数量级,让人把精力集中在判断和逻辑上。
我接触AI金融投研这条线大概有几年时间,从最早用规则引擎做财报结构化,到后来用预训练模型做情感分析,再到现在大模型和多智能体协同做全流程投研辅助,变化非常快。AI金融投研的核心价值可以拆成三层:第一层是信息获取与清洗,把非结构化的公告、研报、新闻、纪要转成结构化数据;第二层是分析与推理,基于结构化数据做财务建模、事件影响评估、估值区间测算;第三层是表达与交互,把分析结果用自然语言输出成可读的报告或对话式问答。
适合看这篇内容的人,我大致分三类。一类是金融从业者,想搞清楚AI到底能在投研流程里插到哪个环节,怎么用起来;一类是技术开发者,想了解金融场景对AI系统的特殊要求,比如准确性、可解释性、合规性;还有一类是产品经理或创业者,在找AI金融投研的产品切入点。不管哪一类,我都会尽量把技术细节和业务逻辑讲透,不堆术语,用实际能落地的视角来说。
提示:金融投研对AI输出的容错率极低,一个数字算错可能导致完全相反的结论。所以本文讨论的所有方案,都建立在“AI辅助、人做最终判断”的前提下,不涉及任何全自动交易决策。
2. 从单模型到多智能体:架构选型的底层逻辑
2.1 为什么单一大模型搞不定金融投研
很多人第一反应是:现在大模型这么强,直接丢一篇研报进去让它分析不就行了?我实测下来,单模型在金融投研场景有几个硬伤。第一是上下文长度限制,一份深度研报动辄几万字,加上财报附注、行业数据,很容易超出窗口,截断之后关键信息就丢了。第二是幻觉问题,金融领域数字密集,模型一旦编造一个财务数据,外行根本看不出来。第三是任务耦合,投研流程里“提取数据”和“撰写结论”对模型能力的要求完全不同,用一个模型兼顾,往往两头都不讨好。
更关键的是,金融投研是一个多步骤、多来源、多角色的工作流。一个完整的个股研究,至少涉及数据采集、财务分析、行业对比、风险评估、报告撰写五个环节,每个环节的输入输出格式、精度要求、知识依赖都不一样。单模型硬扛,就像让一个博士生同时干数据录入、建模、写稿、校对,不是不能做,是效率和准确率都上不去。
2.2 多智能体架构的拆分思路
多智能体(Multi-Agent)的思路,是把投研流程拆成若干个专职“智能体”,每个智能体负责一个明确子任务,通过消息传递协同完成整体目标。我目前看到比较成熟的拆分方式是这样的:
- 数据采集智能体:负责从公告、财报、新闻、数据库拉取原始数据,做初步清洗和格式化。
- 财务分析智能体:接收结构化财务数据,计算核心指标,做同比环比、杜邦分析、现金流质量评估。
- 行业对比智能体:拉取同行业公司数据,做横向估值对比、市占率变化、竞争格局分析。
- 风险评估智能体:识别公告中的风险提示、诉讼、质押、减持等负面信号,做事件影响评级。
- 报告撰写智能体:汇总前序智能体的输出,按投研报告模板生成初稿。
- 审核校验智能体:对报告中的数字、逻辑、引用做交叉验证,标记可疑点。
这套架构的好处是每个智能体的提示词、工具集、输出格式都可以独立优化。比如财务分析智能体可以挂一个计算器工具,确保所有算术结果精确;风险评估智能体可以挂一个关键词库和事件规则引擎,降低漏报率。智能体之间通过结构化消息(通常是JSON)传递数据,而不是自然语言,这样下游智能体解析起来更稳定。
2.3 智能体框架选型:Dify、LangGraph还是自研
目前市面上智能体框架不少,我实际用过的有Dify、LangGraph、AutoGen,也见过团队完全自研。选型主要看三个维度:流程复杂度、团队技术栈、部署要求。
Dify的优势是可视化编排,拖拽式搭建工作流,适合快速验证和中小团队。它的智能体节点、工具节点、条件分支都能在界面上配,调试也方便。但缺点是深度定制受限,比如你想在智能体之间做复杂的消息路由或状态管理,Dify的表达能力就不太够。
LangGraph更适合复杂流程,它把智能体协作建模成图结构,节点和边都可以自定义,状态管理很灵活。金融投研里常见的“条件触发”场景,比如“如果风险评估智能体发现重大诉讼,则触发深度调查子流程”,用LangGraph实现起来很自然。代价是学习曲线陡一些,需要写代码。
AutoGen偏向对话式多智能体,适合研究型场景,但在生产环境的稳定性和可观测性上,我个人觉得还需要再打磨。自研的话,控制力最强,但工作量也最大,除非团队有明确的长期规划,否则不建议一上来就自研。
注意:金融场景对数据安全要求高,如果涉及未公开的研报或内部数据,智能体框架的部署方式要优先考虑私有化。Dify和LangGraph都支持本地部署,这一点在选型时权重很高。
3. 核心细节拆解:数据、提示词与工具链
3.1 金融数据的特殊性与预处理要点
金融数据跟通用文本最大的区别,是它的时效性、精确性和关联性。一条公告发出来,几分钟内就可能影响股价,所以数据采集智能体的延迟要尽可能低。财务数字必须精确到小数点后两位,不能有半点含糊。关联性指的是,一个数据点往往要跟历史数据、同行数据、市场预期数据放在一起才有意义。
预处理环节我踩过不少坑。第一个坑是表格解析。财报里的表格格式五花八门,有的用合并单元格,有的用脚注,有的单位藏在表头。直接用通用OCR或PDF解析工具,经常把“营业收入”和“营业成本”的行列搞混。我的做法是,对已知格式的财报用模板匹配,对未知格式的用多模态大模型做表格理解,再人工抽检一批校准。
第二个坑是时间对齐。不同数据源的时间口径不一样,有的按自然季度,有的按财年,有的按公告日。做同比分析时,如果时间没对齐,算出来的增长率就是错的。我通常会在数据层建一个统一的时间索引,所有数据入库时都映射到这个索引上。
第三个坑是缺失值处理。金融数据缺失很常见,直接填零或者均值都会引入偏差。我的经验是,对关键财务指标,缺失就标记为“待补充”,让下游智能体知道这里数据不完整,而不是用一个假数字糊弄过去。
3.2 提示词工程在投研场景的落地方法
大模型提示词工程(Prompt Engineering)在金融投研里,核心目标是约束输出格式、降低幻觉、注入领域知识。我总结了一套比较实用的提示词结构,分四段:
第一段是角色设定,明确告诉模型“你是一名有十年经验的消费行业分析师,擅长财务分析和估值建模”。角色越具体,输出的专业度越高。
第二段是任务描述,把要做的分析拆成步骤,比如“第一步,提取近三年营收、净利润、毛利率;第二步,计算同比增速;第三步,与行业均值对比;第四步,给出结论”。
第三段是输出格式,用JSON Schema或者Markdown模板约束。金融场景我强烈建议用结构化输出,方便下游程序解析。比如要求模型输出一个包含“指标名称、数值、同比、行业均值、评价”五个字段的表格。
第四段是约束条件,明确告诉模型“所有数字必须来自提供的原文,不得自行推算或编造;如果原文没有,输出‘数据缺失’”。这一条能大幅降低幻觉率。
上下文工程(Context Engineering)则是解决“给模型看什么”的问题。金融投研的上下文往往很长,全塞进去既贵又慢。我的做法是分层检索:先用关键词或向量检索粗筛相关段落,再用重排序模型精排,最后只把最相关的Top-K段落放进上下文。这样既控制了token消耗,又保证了关键信息不丢。
3.3 工具链配置:计算器、数据库与代码执行
智能体光靠语言模型不够,必须挂工具。金融投研里最常用的工具有三类:
计算器工具:所有算术运算都走工具,不让模型心算。我见过模型把“1.2亿除以3.5亿”算成34.3%的,实际是34.29%,虽然差得不多,但在金融场景就是事故。挂一个Python计算器工具,输入表达式返回精确结果,这个问题就解决了。
数据库查询工具:把财务数据、行情数据、行业数据存在结构化数据库里,智能体通过SQL或API查询。这样数据源统一,避免每次从原文重新提取。
代码执行工具:有些分析需要跑回归、做蒙特卡洛模拟、画图表,这些用代码执行工具完成。比如估值建模里的DCF,让模型生成Python代码,在沙箱里执行,返回结果。
工具链的配置原则是:能确定性计算的,绝不交给模型生成。模型负责理解意图、编排流程、生成表达,具体计算和查询交给工具。
4. 实操过程:搭建一个个股投研多智能体系统
4.1 环境准备与基础依赖
假设我们要搭建一个最小可用的个股投研多智能体系统,技术栈选Python + LangGraph + 本地部署的开源大模型(比如Qwen或DeepSeek系列),数据库用PostgreSQL,向量库用Milvus或Chroma。为什么选本地部署?金融数据敏感,而且投研场景调用频繁,本地部署长期成本更低,延迟也更可控。
基础依赖安装:
pip install langgraph langchain openai psycopg2-binary pymilvus pandas numpy模型方面,如果本地GPU资源有限,可以用量化版本。我实测下来,7B到14B级别的模型,在财务数据提取和格式化输出任务上,配合好的提示词,已经能达到可用水平。更大的模型在复杂推理和报告撰写上更有优势,但推理成本也更高,需要根据实际场景权衡。
4.2 智能体定义与消息协议
先定义智能体之间的消息格式。我通常用一个统一的JSON结构:
{ "task_id": "uuid", "agent": "financial_analysis", "status": "success", "data": { "metrics": [ {"name": "营业收入", "value": 123.45, "unit": "亿元", "yoy": 0.15} ] }, "errors": [], "next_agent": "industry_comparison" }每个智能体接收上游消息,处理后输出同样格式的消息,next_agent字段决定路由。这样整个流程就是一个状态机,容易调试和追踪。
财务分析智能体的核心逻辑:
def financial_analysis_agent(state): raw_data = state["data"]["financials"] prompt = build_financial_prompt(raw_data) response = llm.invoke(prompt) parsed = parse_json_response(response) # 用计算器工具校验所有计算 for metric in parsed["metrics"]: if metric.get("yoy") is not None: expected = calculate_yoy(metric["value"], metric["prev_value"]) if abs(expected - metric["yoy"]) > 0.001: metric["yoy"] = expected metric["corrected"] = True return {"data": parsed, "next_agent": "industry_comparison"}这段代码的关键点是校验环节。模型算出来的同比,必须用工具重新算一遍,不一致就以工具为准。这个习惯能避免绝大多数数字错误。
4.3 报告生成与交叉校验
报告撰写智能体接收前序所有智能体的输出,按模板生成初稿。模板我建议用Markdown,结构固定:公司概况、财务表现、行业对比、风险提示、估值讨论。每个部分的内容来自对应智能体的输出,模型只负责组织语言和过渡。
交叉校验智能体是最后一道防线。它的任务是:第一,检查报告里所有数字是否能在上游数据中找到出处;第二,检查逻辑是否自洽,比如“营收增长”和“毛利率下降”同时出现时,是否有合理解释;第三,检查是否有未标记的风险点。校验不通过的地方,标记出来让人工复核。
实操心得:交叉校验智能体的提示词里,一定要加一句“如果发现数字无法溯源,直接标记为‘待核实’,不要尝试修正”。我早期让模型自动修正,结果它把正确的数字改错了,教训很深。
5. 常见问题与排查技巧实录
5.1 数字幻觉与溯源失败
数字幻觉是金融投研AI最致命的问题。表现是模型输出了一个看起来合理但原文没有的数字。排查思路:第一,检查提示词是否明确要求“只使用提供的数据”;第二,检查上下文是否被截断,导致模型看不到原始数据;第三,检查是否有工具调用失败,模型退而求其次自己编了。
我的解决方案是强制溯源。每个数字后面要求模型附上来源片段,比如“营业收入123.45亿元(来源:2024年报第15页)”。如果模型给不出来源,这个数字就不采纳。另外,所有关键数字在入库前,用规则引擎做一次范围校验,比如营收增长率超过500%就触发人工复核。
5.2 智能体死循环与超时
多智能体系统常见的问题是智能体之间互相等待或循环调用。比如风险评估智能体认为需要更多数据,触发数据采集智能体重新拉取,数据采集智能体返回后,风险评估智能体又觉得不够,再次触发。排查方法是给每个任务设最大步数限制,超过就强制终止并报警。
LangGraph里可以用recursion_limit参数控制。我一般设20步,正常投研流程10步以内就能完成,超过20步基本可以判定是异常。另外,智能体之间的消息要带时间戳和版本号,避免处理过期消息。
5.3 表格解析错位与单位混乱
财报表格解析错位是高频问题。典型表现是“营业收入”和“营业成本”的数据对调,或者“本期”和“上期”搞反。排查时先看解析后的表格结构,跟原文对照。如果错位率高,考虑换解析工具,或者对关键表格做人工模板。
单位混乱也很常见,有的财报用“万元”,有的用“亿元”,有的在表头标注,有的在脚注。我的做法是在数据入库时统一转成“元”,并在元数据里记录原始单位。这样下游计算不会因为单位不一致出错。
5.4 常见问题速查表
| 问题现象 | 可能原因 | 排查方法 | 解决措施 |
|---|---|---|---|
| 数字与原文不符 | 模型幻觉或上下文截断 | 检查溯源标记,核对原文 | 强制溯源,关键数字工具校验 |
| 智能体循环调用 | 任务未设终止条件 | 查看调用日志和步数 | 设置最大步数,消息带版本号 |
| 表格数据错位 | 解析工具不适配 | 对照原文检查解析结果 | 换工具或做模板匹配 |
| 单位不一致 | 数据源单位不统一 | 检查元数据单位字段 | 入库统一转“元”,记录原始单位 |
| 报告逻辑矛盾 | 智能体输出未对齐 | 检查各智能体输出时间戳 | 交叉校验,标记矛盾点人工复核 |
| 响应超时 | 模型推理慢或上下文过长 | 查看token数和推理耗时 | 分层检索,控制上下文长度 |
5.5 几个容易被忽略的细节
第一个细节是日期格式。不同数据源的日期格式不一样,有的“2024-01-01”,有的“2024/1/1”,有的“2024年1月1日”。统一成ISO格式再入库,能避免很多排序和筛选错误。
第二个细节是股票代码。A股、港股、美股的代码格式不同,有的带后缀,有的不带。建一个代码映射表,所有数据源都映射到统一代码,避免关联失败。
第三个细节是停牌和复牌。停牌期间的数据处理要特别小心,行情数据可能缺失,但财务数据照常更新。智能体在做时间序列分析时,要能识别停牌区间,不能简单用前值填充。
6. 多智能体协同的进阶玩法
6.1 辩论式多智能体提升判断质量
单一智能体做判断,容易陷入一种思维定式。辩论式多智能体的思路是,让两个智能体分别持“看多”和“看空”立场,基于同一组数据各自论证,然后由第三个智能体做裁判,综合双方论据给出结论。我实测下来,这种方式在风险评估和估值讨论环节,能显著减少遗漏。
具体实现上,看多智能体的提示词强调“找出所有支持当前估值的证据”,看空智能体强调“找出所有可能被低估的风险”。裁判智能体的提示词要求“逐条评估双方论据的数据支撑强度,给出加权结论”。这样输出的报告,比单智能体直接写,论据更全面,逻辑也更扎实。
6.2 记忆机制与跨会话一致性
投研不是一次性的,同一家公司可能跟踪几个月甚至几年。如果每次分析都从零开始,智能体就记不住之前的结论和假设。记忆机制分短期和长期:短期记忆存当前会话的上下文,长期记忆存历史分析结论、关键假设、人工修正记录。
我的做法是用向量库存长期记忆,每次分析前先检索相关历史记录,作为上下文的一部分注入。这样智能体在写新报告时,能引用之前的判断,保持一致性。比如上次分析假设“行业增速15%”,这次如果要用新假设,智能体会提示“与历史假设不一致,请确认”。
6.3 人机协同的介入点设计
全自动投研目前还不现实,人机协同才是落地路径。介入点我建议设三个:第一,数据采集后,人工抽检关键数据;第二,风险评估后,人工确认重大风险判断;第三,报告生成后,人工做最终审核和修改。这三个点覆盖了数据、判断、表达三个关键环节,既保证了效率,又控制了风险。
智能体系统要支持“人工修正回写”。人工改了报告里的某个数字或结论,系统要记录修改内容,并反馈给对应智能体,用于后续优化。这个反馈闭环,是系统越用越准的关键。
7. 我在这条路上踩过的坑和真实体会
最早做AI金融投研的时候,我迷信“大模型万能”,觉得只要模型够大,提示词够好,什么都能干。结果第一个项目就翻车了。模型把一家公司的“扣非净利润”和“归母净利润”搞混,报告结论完全反了。后来才明白,金融领域的专业概念,必须通过工具和规则来约束,不能指望模型自己理解。
第二个坑是过度追求自动化。有段时间我想把整个投研流程全自动跑通,从数据采集到报告输出零人工。结果发现,异常情况太多,模型处理不了,反而需要花更多时间去排查。后来改成“关键节点人工确认”,整体效率反而更高。自动化的边界,是那些确定性高、容错率高的环节,判断类的工作还是得人来做。
第三个坑是忽视数据质量。智能体再强,喂进去的数据是脏的,输出一定是错的。我现在花在数据清洗和校验上的时间,比调提示词的时间还多。但这是值得的,数据干净了,后面所有环节都顺。
实操心得:如果你刚开始做AI金融投研,建议从一个细分场景切入,比如“财报关键指标提取”或“公告事件影响分类”,把单点做透,再扩展到全流程。一上来就搞大而全的系统,大概率会陷入无穷无尽的调试。
最后分享一个我觉得很实用的技巧:给每个智能体的输出加一个“置信度”字段,让模型自己评估这次输出的可靠程度。置信度低的输出,自动触发人工复核。这个机制能帮你把有限的人力,集中在最需要的地方。置信度的提示词可以这样写:“请评估你本次输出的置信度,范围0到1,0表示完全不确定,1表示完全确定。如果数据缺失或存在歧义,置信度应低于0.5。”实测下来,这个字段跟实际错误率的相关性还挺高的,能过滤掉不少潜在问题。