S&P500 Agent MVP 上线:基于 SEC 数据回答金融问题
我做出了一个基于 10 年 SEC 数据回答金融问题的 AI agent,并最终解决了流式输出难题,让它既实时又可验证。
更新(2026): S&P 500 Agent 已下线。本文保留为当时 MVP 首发记录。Sydney 现在聚焦博客内容和 Chandler 的产品。 体验当前 Sydney →
Hi there,
很开心分享:自从我上一篇写到做 S&P500 Agent 的 挣扎 以来,MVP 版本 终于可用了! :D 下面我来讲讲这个最小可行版本能做什么,以及它是怎么做出来的。
这个 MVP 现在能做什么?
- 覆盖过去十年数据:agent 的数据库包含公司过去 10 年向 SEC EDGAR 提交的 facts。挺不错吧?
- 答案可靠:因为回答是基于真实 SEC 提交数据做 grounding,答案质量更可信。
- 便于核查:agent 在最终回答里总会附带引用数据。如果你持怀疑态度,可以自己核对!
- 能处理半复杂问题:例如 “Compare the revenue of Apple and Microsoft between 2020 - 2022?” 或 “How did Microsoft's operating margin change from 2020 to 2022?” 为什么说“半复杂”?因为 agent 需要先“推理”把大问题拆成小问题,去数据库逐项检索,再拼回完整答案。
- 比如第一个问题,它需要分别找出 2020、2021、2022 每家公司收入,再做对比。
- 几乎是最新数据:截止时间到 2024 年 8 月。之后提交到 SEC 的数据,这个 MVP 版本还没有。
- HTML 流式输出:Streaming 终于跑通了!Yay! :D 后来发现 DRF 和 React 本身都支持 streaming,结合 langgraph 后我们有了响应式对话流,而且展示格式也更易读。我在 html streaming 上卡了很久。
技术实现一瞥
如果你还读到这里,说明你大概想知道这个 MVP 具体怎么搭出来的,以及我如何解决之前提到的一些难点。那我们来一点技术细节!
- 数据瘦身:我没有直接塞完整 10-K/10-Q 原文,而是使用公司提交给 SEC 的 “Facts”。这样数据库体量明显更小——不到 2GB!下面是一些上市公司提交样例:
"AccruedRoyaltiesCurrent": {
"label": "Accrued Royalties, Current"
},
"AccumulatedDepreciationDepletionAndAmortizationPropertyPlantAndEquipment": {
"label": "Accumulated Depreciation, Depletion and Amortization, Property, Plant, and Equipment"
},
"AccumulatedOtherComprehensiveIncomeLossNetOfTax": {
"label": "Accumulated Other Comprehensive Income (Loss), Net of Tax"
},
"AccumulatedOtherComprehensiveIncomeLossOtherThanTemporaryImpairmentNotCreditLossNetOfTaxAvailableforsaleDebtSecurities": {
"label": "Accumulated Other Comprehensive Income (Loss), Other than Temporary Impairment, Not Credit Loss, Net of Tax, Available-for-sale, Debt Securities"
},
"AdditionalPaidInCapitalCommonStock": {
"label": "Additional Paid in Capital, Common Stock"
这也意味着我不需要上大规模高速向量库(那通常很贵,约 $600 - $700/月)。
2. 主数据库采用 Cloud SQL PostgreSQL:我用 Cloud SQL PostgreSQL 做主库。因为原本就已在 GCP 上用 Cloud Run 做 CI/CD,继续用 Google 的栈更顺手。对我来说这是全新概念,所以我需要学习如何把数据库从本地迁移到云上,以及如何配置后端通过私网 IP 连接 Cloud SQL。GCP 文档在这方面帮了我很多。
3. React + Django 成功合体:这是我第一次把 React 前端 + Django Rest Framework(DRF)后端 + Cloud SQL 数据库成功部署上线。过程全是 trial-and-error,但 ChatGPT o1-preview 和 Anthropic Claude 3.5 Sonnet 给了很大帮助。它们确实很强,尤其是你给足上下文时。
4. Agent 本身更智能:agent 基于 Langgraph 构建,核心有两个工具:Google Search 与 Financial Question Answering tool。它会根据问题自动判断该用哪个。
5. SQL 查询是怎么生成的?
把用户的泛化问题转成适配数据库的 SQL,并不直接。其中一个主要原因是:公司向 SEC 提交财务 facts 时使用的财务概念/术语,对普通用户并不直观。
比如“revenue”可能对应多个 facts:
- Revenue
- Revenue from Contract with Customer, Excluding Assessed Tax
- Revenue from related Parties
- Deferred Revenue
- etc...
并且跨公司标签不统一。比如 Apple 用 "Revenue from Contract with Customer, Excluding Assessed Tax",Tesla 用 "Revenue"。
又比如你问“operating margin”,这可能不是公司直接提交的 fact。它们提交的可能是 total revenue 和 Operating Income (Loss)。
还有一种情况是公司更名,所以 SQL 也要同时覆盖旧名与新名。
那我如何让机器为这种宽泛问题选对 fact/label?
我用 Weaviate 的 hybrid search 先检索最相关的 facts/labels,再把结果传回 LLM。
6. 分步拆解测试非常关键
正式上生产前,我把流程拆成步骤逐项测试:
1. 本地 DRF 后端 + 本地数据库测试。
2. Docker 容器后端 + 本地数据库测试。
3. PostgreSQL 迁移到 Cloud SQL 并测试。
4. Docker 容器后端 + Cloud SQL 测试。
5. React 前端本地测试。
6. React 前端 + 生产后端 + Cloud SQL 测试。
7. React 前端迁移到 Wordpress 生产环境。
8. 端到端测试。
这个分步法我是踩坑后学会的。最开始我跳过了一些步骤,按大块测试,结果 LLM 无法准确定位具体是哪一层出了问题。
接下来做什么?
- 解决冷启动:目前 agent 回答首个问题会稍慢,我正在找成本可控的方案。
- 把中间推理过程显示给用户:像 “Compare the revenue of Apple and Microsoft between 2020 and 2022” 这种复杂问题,最终答案生成需要时间。若能实时展示 agent 正在执行的步骤,用户体验会更好。
- 补充 10-K/10-Q 文本内容:计划加入更多来自 10-K/10-Q 的相关文本,提供更细的回答。
这次先写到这里。欢迎去 试用 MVP 版本并告诉我你的看法!你有做过金融数据或 SEC filings 相关项目吗?很想听听你的经验——欢迎留言,或直接给我发邮件(chandler@chandlernguyen.com)。
致敬,
Chandler





