完整投资研究
把取数、建模、成稿串成一条可重复的链路。适合研究频率高、每次都要重复同样准备动作的场景;估值假设仍需你确认。
FinRobot 智能体与编排 / AI4Finance-Foundation
「FinRobot 有几个智能体」取决于你问的是哪一代:论文期的 V0 有 10 个角色与 5 种会话拓扑;当前生产版 V2 是 9 个 Agent —— 1 个 Lead 负责编排,5 个流水线角色(data / analysis / modeling / synthesis / report),3 个辩论角色(bull / bear / judge)。其中 8 个 Agent 的行为写在 markdown 指令文件里,改行为不用改 Python。
官方 README 给的是一句「Lead Agent 编排五类角色 + 三个辩论角色」,落到代码里就是下面这 9 个。最后一列写的是每个角色失效时的表现——这一列官方文档没有,但排查时会用到。
| Agent | 分组 | 职责 | 定义在哪 | 它失效时会怎样 |
|---|---|---|---|---|
| Lead(编排) | 编排 | 接住研究请求、选流程、按顺序驱动其余角色 | 代码:engine/agents/factory.py、engine/orchestrator.py | 整条流程起不来或选错流程,后面所有角色都白跑 |
data | 流水线 | 取数:行情、财报、申报文件、新闻等 | markdown:instructions/data_agent.md | 后面所有环节拿到空值,且不一定报错 |
analysis | 流水线 | 解读:把取到的数据变成可判断的事实 | markdown:instructions/analysis_agent.md | 数据在,但没有被解释,研报段落空洞 |
modeling | 流水线 | 建模:组织估值假设并调用确定性算子 | markdown:instructions/modeling_agent.md | 假设质量下降;算子本身仍会拒绝不成立的输入 |
synthesis | 流水线 | 汇总:把多条结论合并成一致口径 | markdown:instructions/synthesis_agent.md | 各章节口径漂移(币种、报告期、单位互相矛盾) |
report | 流水线 | 成稿:写成章节化的研究报告制品 | markdown:instructions/report_agent.md | 制品缺章或格式不合格,前面对的部分也没法交付 |
bull | 辩论 | 把看多理由讲到站得住脚 | markdown:instructions/bull_agent.md | 多头理由退化成没有数字的套话 |
bear | 辩论 | 把看空理由讲到站得住脚 | markdown:instructions/bear_agent.md | 风险被低估,结论偏向单边 |
judge | 辩论 | 裁决多空双方,给出方向性判断 | markdown:instructions/judge_agent.md | 分歧没有被收敛,或收敛到没有依据的一侧 |
2717499 的 finrobot_desktop/finrobot/engine/agents/instructions/ 目录清点(8 个 .md 文件)+ Lead 的代码定义,与官方 README 的「9 agents」表述一致。流水线是「一条命令跑完一类研究」的入口。它和开放式对话的差别在于:每一步都是类型化步骤,带校验器和重试,过程可复现。
| 流水线 | 命令行 | 产物 | 适合什么时候用 | 注意点 |
|---|---|---|---|---|
equity_research | finrobot research <ticker> | 完整的 13 章研究制品(封面、投资论点、公司概览、财务分析、估值、近期新闻、敏感性、催化剂、技术与进阶、竞争格局、财务数据、股权与治理、免责声明) | 要做一份能拿给人看的完整研究 | 链路最长、调用次数最多,单次成本与耗时也是七个里最高的 |
dcf | finrobot dcf <ticker> | 折现现金流估值(含 WACC 与逐年预测) | 想要一个可由假设复算的内在价值 | 会在股利模型更合适时自动切换到 DDM;要强制用 DCF 需加 --force-dcf |
ddm | finrobot ddm <ticker> | 股利折现模型结果 | 分红稳定、现金流平稳的标的(公用事业、成熟蓝筹) | 不适用低分红或不分红标的;股利政策变化会直接改变结论 |
lbo | finrobot lbo <ticker> | 杠杆收购模型(退出倍数与债务安排) | 按收购视角测算回报区间 | 属情景推演,不是对股价的预测 |
comps | finrobot comps <ticker> --peers A,B | 可比公司分析(倍数对照) | 需要一个相对估值的锚 | 同业名单要自己给(--peers);倍数口径与财年差异需人工对齐 |
earnings_analysis | finrobot earnings <ticker> | 业绩期回顾 | 财报发布前后的快速复盘 | 结果高度依赖指引与预期数据的可得性 |
ic_memo | finrobot ic-memo <ticker> | 投资委员会备忘录 | 按投委会口径整理成一页决策材料 | 它是把已有分析重新组织,不额外产生新的计算 |
dcf / ddm / comps);要完整交付用 research;三个估值入口都对同一套确定性算子,差别在于选哪种方法与输出组织方式。skills/ 下的 SKILL.md),按岗位分组:财务分析 11、私募股权 10、股票研究 9、投资银行 9、LSEG 合作 8、财富管理 6、S&P Global 合作 3;用 finrobot skill list 与 finrobot skill search <关键词> 浏览。它们是方法论提示词,不是自动化流水线,别把两者混为一谈。多数改动不需要碰 Python。因为角色行为是 markdown,改一份给人看的文件就能调整分析口径——但有三件事必须同时做,否则你会得到一个「看起来生效、其实没生效」的结果。
在 finrobot_desktop/finrobot/engine/agents/instructions/ 下找到对应角色的 *.md,在它的约束范围内调整要求(例如让 report 强制每段带数字、让 bear 必须引用一条可核算的风险)。预期表现:下一次运行时该角色的输出风格与详略发生变化,而其它角色不受影响。
一个角色的输出是下一个角色的输入,而下游按字段解析。改了上游的字段或段落结构,下游会解析不到。预期表现:改完跑一次完整流水线,检查整条链路是否仍能产出完整制品;只改一个章节跑通过不代表没问题。
把「改了哪个文件、期望什么变化、实测到什么变化」记下来。上游仓库更新时这份记录决定你能不能顺利合并。预期表现:升级后能逐条判断哪些改动被覆盖、哪些需要重新应用。
V0 是论文背后的那份代码,官方把它定位为教学与复现。它的价值是「小到能读完」——智能体定义、工具注册、数据接入三块都能从头读到尾。
| 层 | 模块 | 内容 | 适用场景 | 注意点 |
|---|---|---|---|---|
| 角色库 | finrobot_autogen/finrobot/agents/agent_library.py | 10 个预定义角色,每个带系统提示词与工具清单:Software_Developer、Data_Analyst、Programmer、Accountant、Statistician、IT_Specialist、Financial_Analyst、Artificial_Intelligence_Engineer、Market_Analyst、Expert_Investor | 想学「一个金融智能体怎么被描述出来」 | Expert_Investor 工具最全(申报文件、绘图、文本长度、PDF 生成),年报 notebook 用它 |
| 会话结构 | agents/workflow.py | 5 种拓扑:SingleAssistant(单个助手 + user proxy 执行)、SingleAssistantRAG(带检索代理)、SingleAssistantShadow(配一个中途获得扩展工具的影子智能体)、MultiAssistant(多角色群聊)、MultiAssistantWithLeader(指定一个角色统领) | 想理解多智能体是怎么被组织起来的 | 拓扑越复杂,链路越难定位失败环节;教学代码不以保证稳定性为目标 |
| 工具注册 | toolkits.py | 把普通 Python 函数(或整个类)注册成工具,绑定到 caller / executor 一对上:LLM 提议调用、另一个代理真正执行 | 要接自己的函数或私有数据 | 这是「模型不直接执行代码」这条安全边界的实现方式,值得单独读一遍 |
| 数据接入 | data_source/ | Finnhub(行情/新闻/基础财务)、FMP(报表/比率/申报文件 URL)、SEC EDGAR(申报文件与 10-K 解析)、yfinance(行情与历史)、Reddit(情绪)、FinNLP(新闻与社交,git 子模块) | 要接一个具体数据源时 | FinNLP/ 是子模块,目录为空时要先 git submodule update --init --recursive |
| 教程 | tutorials_beginner/、tutorials_advanced/ | 13 个 notebook:入门 7 个(年报、预测、RAG 问答、财报电话会与申报文件检索、两个 Ollama 本地模型示例),进阶 6 个(交易策略、OpenBB、两个多模态图表示例等) | 想先看效果再决定要不要深入 | 两个 lmm_* 多模态 notebook 需要配置支持视觉的模型;notebook 必须在自己的目录里跑,否则读不到 ../OAI_CONFIG_LIST |
官方 README 的「Research foundation」段落保留了论文期的抽象分层与调度设计。把它们当成设计语言没问题,但当成「现成可调的模块」就会在代码里找不到。下表逐条对照。
| 论文 / README 里的表述 | 它是什么 | 当前仓库里的对应物 |
|---|---|---|
| 四层架构(金融 AI 智能体层 / 金融 LLM 算法层 / LLMOps 与 DataOps / 多源 LLM 基座) | 论文期的抽象分层,用来讲清楚「一个金融 AI 系统由哪些部分组成」 | 仍是 README 的框架描述;当前实际结构是「桌面壳 → FastAPI → PydanticAI 智能体 → 7 条流水线 → 32 个算子 → 7 个数据提供方 → SQLite 制品库」 |
| 感知 → 大脑 → 行动(Perception / Brain / Action) | 论文期对单个智能体闭环的描述:先接收多模态数据、再推理、最后执行 | V2 的对应物是流水线链路 data → analysis → modeling → synthesis → report,外加 bull ↔ bear → judge 的辩论分支 |
| Smart Scheduler:Director Agent / Agent Registration / Agent Adaptor / Task Manager | 论文期设想的「为每个任务挑更合适模型」的调度层 | 当前仓库没有这套调度器的实现:在固定 commit 的文件树里按 scheduler / director / adaptor 检索不到对应模块;V2 用类型化流水线 + 流水线注册表来选流程 |
| Financial CoT(金融链式推理) | 让智能体把复杂金融问题拆成逻辑步骤的提示词范式 | V0 保留了这套提示词脚手架(finrobot_autogen/finrobot/agents/prompts.py);V2 把「拆步骤」变成了显式的流水线步骤 |
| 多智能体协作 / 投资小组式辩论 | 论文与实验里讨论的多角色协作与立场对抗 | V2 落成 3 个辩论角色(bull / bear / judge)+ 5 个流水线角色,是当前可运行的形态 |
| FinRobot Pro(商业产品,finrobot.ai) | 官方在 README 里介绍的同名商业产品,另有托管版 V2 | 与本机可跑的开源代码是两条路径;本站没有核验其条款与功能清单,只记录「存在这样一个产品」 |
编排同时放大能力与成本:链路越长,能覆盖的任务越多,出错后定位也越难。下表按「任务复杂度 → 要不要上流水线」给判断,不是结论。
| 你的任务长什么样 | 建议 | 为什么 | 注意点 |
|---|---|---|---|
| 一次只问一件事(某只标的的某个指标) | 单次调用或直接调算子就够 | 任务边界清晰,不需要分工 | 若要可复算,优先直接调用确定性算子而不是让模型转述 |
| 同一只标的需要行情 + 财报 + 新闻 | 值得上流水线 | 三条数据链路可以各自校验,最后再汇总 | 数据源口径(币种、财年、单位)要在汇总前对齐 |
| 一份要交付给他人的完整研报 | 值得上完整流水线 | 13 章制品本身就是按章节分工的产物 | 链路最长,建议先跑通最小流水线再加章节 |
| 结论怕被单一路径带偏 | 加上辩论角色 | 看多与看空各自成立,分歧点会暴露出来 | 调用次数明显上升,成本也随之上升 |
| 预算敏感、只想先试一下 | 先跑最小流水线或零依赖实验 | 编排会让模型调用次数成倍增加 | 零依赖实验(直接调算子)不产生模型费用,见首次运行页 |
| 要求口径稳定、结果可复现 | 固定流程 + 固定模型 + 固定种子 | 环节越少,口径漂移点越少 | 服务商侧模型更新也会改变口径,需记录版本 |
| 要做成定期执行的例行研究 | 固定编排 + 失败降级设计 | 一次搭好可以重复跑 | 必须提前设计某一环失败时是中断还是降级 |
编排最怕的不是报错,而是「安静地跑完但结论不对」。下表按排查优先级排列,并把每一类对应到 V2 的真实机制上。
| 现象 | 大概在哪一层 | 怎么定位 | 降级做法 |
|---|---|---|---|
| 整条流程跑完,但某一环其实没拿到数据 | 数据层(data 角色) | 逐环节看返回内容,而不是只看最后那份报告 | 让该环节失败即中断,或显式标记「本环节无数据」 |
| 某个数据提供方不可用 | 数据层(7 个 provider + 健康状态) | 看该 provider 的健康状态与是否有降级警告 | 由故障切换接管;至少确认两个提供方可用,避免单点 |
| 数字看起来正常但追溯不到计算 | 叙述层(LLM 写的部分) | 拿报告里的数字回算子输出里找 | 关键数字改走确定性算子;叙述只当线索 |
| 方法行凭空少了几行 | 输出与制品层 | 读警告通道,里面会写明「哪个方法行被降级隐藏、为什么」 | 按警告补齐缺的输入(如同业制品、历史估值带),不要用 0 或均值顶上 |
| 同一份报告里币种或报告期前后不一致 | 审计算子(币种口径 / TTM 期间) | 看审计警告;6 个审计算子里有两个专管这类问题 | 把口径固定为单一事实来源后再重跑 |
| 多空双方各说各话,没有收敛点 | 辩论层(bull / bear / judge) | 对比双方引用的数字是否来自同一份估值输出 | 要求双方各自引用同一套算子输出;否则让 judge 只保留有数字支撑的部分 |
| 给银行股算出了现金流类估值 | 流程层(行业类目判断) | 看估值聚合器是否把 DCF / EV-EBITDA / P-FCF 撤下 | 银行与保险改用 P/B、P/E 与 DDM;判断错类别时人工纠正后重跑 |
| 长流程超时 | 运行层 | 分辨是模型侧慢还是数据源侧慢 | 拆成两段跑:先把数据落盘,再做分析 |
共同点是「任务能拆成步骤、且中间结果值得保留」,而不是「一次性问答」。下面每条都写清了它负责到哪、你还要补什么。
把取数、建模、成稿串成一条可重复的链路。适合研究频率高、每次都要重复同样准备动作的场景;估值假设仍需你确认。
先把 10-K、公告里的结构化信息抽出来再做人工复核。适合信息量大、人工通读成本高的场景;关键数字要回原文核对。
用确定性算子算内在价值,并把「增长率改一点、估值变多少」讲清楚。适合需要交代假设来源的场合。
让看多与看空各自成文,再由裁决角色收敛。适合结论容易被单一路径带偏的判断场景。
按 --peers 指定同业名单,做倍数对照。适合需要相对估值锚点的研究任务。
每一步都有类型化输出与警告通道,便于事后复盘「哪一步带偏了结论」。适合需要交代研究过程的团队。
想理解一个金融智能体系统是怎么组织的,可以读它的角色指令、流水线定义与算子接口,作为自己项目的参考实现。
智能体会给你一段像样的文字,但「像样」不等于「可用」。下面这张表按「先查什么、再查什么」排序,前两步决定后面还要不要看。
| 顺序 | 查什么 | 合格的样子 | 不合格的信号 | 怎么处理 |
|---|---|---|---|---|
| 1 | 缺数据时有没有留下痕迹 | 缺项对应方法行消失并带警告,写清缺了什么 | 结果看起来齐全,但某些章节明显空洞且没有警告 | 按警告补齐输入后重跑,别硬用这一版 |
| 2 | 数字能不能回溯 | 估值类数字能对应到确定性算子的输出 | 模型直接口述一个数字,找不到计算过程 | 把该段当观点;需要数字就自己调算子复算 |
| 3 | 口径是否统一 | 币种、报告期、单位在全篇一致,且标明来源时间 | 同一指标两次出现不同单位或不同财年 | 固定单一事实来源后重跑;必要时人工统一口径 |
| 4 | 结论有没有越界 | 只给研究结论与不确定性,不给交易指令 | 出现「建议买入」这类直接交易表述 | 直接判定不合格,不作为任何用途使用 |
| 补查 | 中间步骤是否可读 | 章节之间有明确的推理链与引用 | 只有一段流畅总结、没有过程 | 要求补充过程,或改用带步骤的流水线 |
| 补查 | 审计警告有没有被忽略 | 警告被逐条看过并回应 | 警告存在但没人读过 | 把警告当必读项:它就是系统告诉你哪不可信的地方 |
分开代际看:当前生产版 V2 是 9 个 Agent(1 个 Lead 编排 + 5 个流水线角色 data / analysis / modeling / synthesis / report + 3 个辩论角色 bull / bear / judge);教学版 V0 是 10 个预定义角色配 5 种会话拓扑。两代数量不同不是「升级了数量」,而是两套完全不同的组织方式——V2 是类型化流水线,V0 是 AutoGen 会话拓扑。数量与分组以固定 commit 的仓库目录为准。
因为 V2 的 8 个角色各自有一份 markdown 指令文件(在 engine/agents/instructions/ 下),角色的行为要求写在那里面;只有 Lead 编排角色是 Python 定义的。这样调分析口径的改动门槛很低,但要注意下游按字段解析上游输出,改了结构要跑一次完整流水线验证。具体文件名与字段以官方仓库为准。
不能。它属于论文期的调度设计(Director Agent / Agent Registration / Agent Adaptor / Task Manager),官方 README 仍保留这段介绍,但在固定 commit 的仓库里检索不到对应模块的实现。现在负责「选哪条流程」的是类型化流水线加流水线注册表。看到文章让你去调 Smart Scheduler,那是照着论文写的,不是照着代码写的。
不一定。任务能一次讲清时,单次调用成本更低、也更好排查;只有任务天然分叉(行情 + 财报 + 新闻)或需要交叉校验时,编排才划算。编排的主要代价是调用次数成倍增加与链式失败——上游拿不到数据,下游会安静地基于空值继续推理。
当研究材料可以,当决策依据不行。系统会把数字交给确定性算子、把叙述交给模型,并在算不出可信结果时拒绝计算;但假设是否合理、方法是否适用、方向性判断是否成立,仍然需要你自己判断。不构成投资建议,也不等同于可直接照做的交易方案。
可以,需要 Python 基础。角色层面加一份 *.md 指令并在注册处登记;流水线层面要按现有类型化步骤的契约写步骤与校验器。建议先跑通一条现成流水线再动手,否则很难分清新引入的问题与原有问题。接口细节以官方仓库的实现与测试为准。
它能让分歧显性化,但不自动提高正确率。看多与看空各自成文之后,还需要一个裁决角色把没有数字支撑的部分剔除;如果双方引用的是不同口径的数据,辩论只会把混乱放大。可靠性的来源始终是「数字可复算 + 口径统一」。
流程本身是市场无关的,卡点在数据层:官方的 7 个数据提供方以美股为主(FMP、SEC EDGAR、Finnhub、yfinance 等),没有 A 股数据源。实测中代码层的代码校验是接受 600519.SS、0700.HK 这类后缀的,但那一步只证明「不拦」,不等于取得到数据——接入 A 股需要自己替换数据提供方。