用 AI 构建巴菲特投资知识图谱:从 48 封公开信到可交互的投资智慧网络
用 AI 构建巴菲特投资知识图谱:从 48 封公开信到可交互的投资智慧网络
量化交易系列 · 番外篇 | 知识图谱 × LLM × 价值投资
导语
巴菲特从 1977 年开始,每年给伯克希尔·哈撒韦股东写一封公开信。48 封信,跨越近半个世纪,累计超过 50 万字。这些信里藏着一位传奇投资者从青年到耄耋的完整投资思想演化史——从格雷厄姆式的"烟蒂股"捡拾者,到"用合理价格买入伟大公司"的价值投资教父。
问题是:48 封信,信息量太大了。 你读了第 3 封可能已经忘了第 1 封在讲什么;你记得"护城河"这个概念,但说不清它和哪些公司、哪些投资决策、哪些时间节点关联。
有没有一种方法,能把这 48 封信里所有的 人物、公司、投资理念、关键事件 全部抽出来,并用一张可交互的 知识图谱 把它们之间的关系可视化?
这就是本文要做的事——用 LLM 驱动的知识抽取技术,构建一张巴菲特投资知识图谱。我们开源了完整项目 buffett-kg,你可以直接运行体验,也可以基于本文介绍的原理,用 Vibe Coding 的方式自己从零构建。
一、为什么要给巴菲特的公开信建知识图谱?
1.1 公开信的价值被严重低估
巴菲特公开信是免费的——伯克希尔官网上全部公开下载。但 95% 的人只是零散地看过几段"金句"。真正的价值不在单个观点,而在 观点之间的关联和演化:
| 维度 | 碎片阅读 | 知识图谱 |
|---|---|---|
| 投资理念 | "护城河很重要" | 护城河 → 品牌力 → Coca-Cola → 1988年买入 → 持有35年 |
| 人物关系 | "芒格是巴菲特的搭档" | Graham(导师) → Buffett → Munger(合伙人) → 能力圈理念 |
| 时间演化 | "巴菲特不碰科技股" | 1999拒绝科技股 → 2016买入Apple → 认知升级 |
| 决策逻辑 | "在别人恐惧时贪婪" | 2008金融危机 → 逆向投资 → Goldman Sachs + BofA |
一张知识图谱把 48 年的投资智慧压缩成一个可交互的网络,你可以按年份筛选、按主题聚焦、点击任一节点看其来龙去脉。
1.2 技术上的完美练手项目
从工程角度,这个项目覆盖了当下最热的几项技术:
- NLP / LLM — 实体抽取 + 关系抽取
- 知识图谱 — 图数据结构 + 本体设计
- 数据可视化 — ECharts 力导向图
- Vibe Coding — 用 AI 辅助编程完成全流程
非常适合作为 AI + 投资交叉领域的学习项目。
二、数据源:48 封巴菲特公开信
所有公开信均来自伯克希尔·哈撒韦官网:
https://www.berkshirehathaway.com/letters/letters.html
文件格式有两种:
- 1977—1997 年:HTML 格式(
.html) - 1998—2024 年:PDF 格式(
.pdf,文件名如1998ltr.pdf)
数据处理流程:先批量下载 48 份文件,再统一提取纯文本(HTML 用 BeautifulSoup,PDF 用 pdfplumber),按年份输出为独立的文本文件,供后续知识抽取使用。
三、知识图谱原理:从文本到图
3.1 什么是知识图谱?
知识图谱(Knowledge Graph)是一种用 图结构 来表示知识的方式。核心要素三个:
(实体) —[关系]→ (实体)
例如:
(Warren Buffett) —[管理]→ (Berkshire Hathaway)
(Berkshire Hathaway) —[投资]→ (Coca-Cola)
(Coca-Cola) —[具有]→ (经济护城河)
(Benjamin Graham) —[影响]→ (Warren Buffett)
千百个这样的三元组连起来,就形成了一张巨大的知识网络。
3.2 构建知识图谱的标准流程
原始文本 → 文本预处理 → 实体抽取 → 关系抽取 → 图谱构建 → 可视化
每一步的技术选型:
| 步骤 | 传统方案 | LLM 方案(本文采用) |
|---|---|---|
| 文本预处理 | NLTK 分句 + 清洗 | 直接按年份切分 |
| 实体抽取 | SpaCy NER / BERT | DeepSeek / GPT-4o-mini Prompt |
| 关系抽取 | 依存句法 + 规则 | DeepSeek / GPT-4o-mini Prompt |
| 图谱存储 | Neo4j 图数据库 | JSON 文件(轻量) |
| 可视化 | Neo4j Bloom / D3.js | ECharts 力导向图 |
🔑 关键洞察:传统 NLP 流水线需要分词、NER 标注数据、关系分类器等一系列组件。LLM 把这些全部简化成一个 Prompt 调用——给它一段文本,告诉它要抽什么格式的实体和关系,直接输出 JSON。
3.3 实体分类体系(本体设计)
为巴菲特公开信设计了 6 类实体:
| 类别 | 说明 | 示例 |
|---|---|---|
person |
关键人物 | Warren Buffett, Charlie Munger, Benjamin Graham |
company |
公司/投资标的 | Berkshire Hathaway, Coca-Cola, Apple, GEICO |
concept |
投资理念/原则 | 价值投资、经济护城河、安全边际、能力圈 |
metric |
财务指标 | ROE、每股账面价值、自由现金流 |
industry |
行业板块 | 保险业、消费品、银行金融、能源 |
event |
重大事件 | 2008金融危机、互联网泡沫、GEICO收购 |
3.4 关系类型设计
定义了 6 种关系类型:
| 关系 | 含义 | 示例 |
|---|---|---|
manage |
管理/领导 | Buffett → Berkshire Hathaway |
invest |
投资/持股 | Berkshire → Coca-Cola |
acquire |
收购 | Berkshire → GEICO |
influence |
影响/塑造 | Graham → Buffett |
partner |
合作关系 | Buffett ↔ Munger |
mention |
关联提及 | Apple → Technology |
四、LLM 驱动的知识抽取
4.1 Prompt 工程:实体抽取
核心 Prompt 设计如下:
You are an expert financial analyst specializing in
Warren Buffett's investment philosophy.
Analyze the following excerpt from Buffett's {year} letter
to shareholders and extract ALL important entities.
Entity categories:
- **person**: Key individuals
- **company**: Companies mentioned
- **concept**: Investment concepts/principles
- **metric**: Financial metrics
- **industry**: Industry sectors
- **event**: Significant events
Return ONLY valid JSON array:
[
{"name": "entity name", "category": "person|company|...",
"description": "one-line description"}
]
Text:
{text}
设计要点:
- 角色设定 — "专精巴菲特投资哲学的金融分析师",确保 LLM 以专业视角理解文本
- 明确分类 — 6 类实体都给了说明和示例
- 输出格式 — 要求纯 JSON,方便自动解析
- 年份上下文 — 告诉 LLM 这是哪一年的信,有助于时间相关的实体抽取
4.2 Prompt 工程:关系抽取
Given these entities extracted from Buffett's {year} letter:
{entities}
And the original text:
{text}
Extract ALL meaningful relationships between entities.
Relationship types:
- **invest**: Berkshire/Buffett invested in
- **acquire**: Acquired or bought
- **manage**: Person manages/leads
- **influence**: Concept/person influenced decision
- **mention**: Entity mentioned in context of another
- **partner**: Business partnership
Return ONLY valid JSON array:
[
{"source": "entity name", "target": "entity name",
"relation": "invest|acquire|...",
"context": "brief quote from text"}
]
设计要点:
- 两阶段抽取 — 先抽实体,再基于实体抽关系(比一步到位更准确)
- 引用原文 — 要求 LLM 给出
context,可以追溯关系的来源 - 关系明确 — 6 种关系类型覆盖了投资领域的主要语义
4.3 长文本处理策略
单封公开信可能有 1-3 万字,超出 LLM 的有效处理窗口。采用 按段落边界分块 策略:将文本以双换行符分段,按最大字符数(默认 6000 字符)聚合为语义完整的块,每块独立调用 LLM 进行抽取。
4.4 实体融合与去重
不同年份的信中,同一实体可能有不同的表述(如 "Coke"、"Coca-Cola"、"The Coca-Cola Company")。采用 名称标准化 + 频次累加 策略,按小写名称合并,并记录每个实体出现的年份集合和总频次。
4.5 输出的知识图谱 JSON 结构
最终输出的 knowledge_graph.json 结构如下:
{
"nodes": [
{
"id": "n0",
"name": "Warren Buffett",
"category": "person",
"description": "伯克希尔·哈撒韦董事长兼CEO",
"years": [1977, 1978, "...", 2024],
"frequency": 480
}
],
"edges": [
{
"source": "n0",
"target": "n10",
"relation": "manage",
"weight": 48,
"years": [1977, "...", 2024],
"context": "I am the Chairman of Berkshire Hathaway"
}
],
"metadata": {
"totalLetters": 48,
"yearRange": [1977, 2024],
"totalNodes": 61,
"totalEdges": 74
}
}
五、可视化方案:ECharts 力导向图
可视化方案对比:
| 方案 | 优点 | 缺点 |
|---|---|---|
| Neo4j Bloom | 专业图可视化 | 需要安装数据库 |
| D3.js | 灵活、社区大 | 学习曲线陡 |
| Pyvis | Python 一键出图 | 交互性弱 |
| ECharts | 零依赖、交互强、中文友好 | 节点多时性能一般 |
选择 ECharts 的力导向图(Force-directed Graph),理由:
- 单 HTML 文件,无需后端服务
- CDN 引入,无需安装
- 丰富的交互:拖拽、缩放、搜索、筛选
- 中文渲染优秀,适合中文标注
最终的可视化页面实现了以下核心功能:
- 节点分类着色 — 6 种实体类型对应 6 种颜色,一目了然
- 搜索高亮 — 输入关键词,匹配的节点高亮放大,其余灰化
- 分类筛选 — 按钮切换只看某一类节点(如只看"投资理念")
- 年份范围 — 滑块筛选特定时间段的节点和关系
- 节点详情面板 — 点击节点弹出详细信息:描述、出现年份、关联实体列表
- 统计看板 — 展示节点总数、边总数、时间跨度
整体采用 暗色科技风(#0a0e17 背景),力导向图连线在暗背景上可读性更好,节点颜色对比度更强。
六、Vibe Coding 实践:5 轮 Prompt 完成全部开发
本项目是一次典型的 Vibe Coding 实践——人负责决策,AI 负责实现。以下是实际使用的 Prompt 和交互过程:
Prompt 1:项目规划
我要构建巴菲特公开信的知识图谱。包含知识关系,用于了解
巴菲特整个生涯投资逻辑,可视化给读者投资建议。
需要:
公开信下载、知识图谱搭建 以及 vibe coding 代码提示词
代码放到Code 下
AI 输出了完整的项目计划,包括目录结构、技术选型、实施步骤。
Prompt 2:文本提取脚本
编写 extract_text.py,从 HTML 和 PDF 格式的巴菲特公开信中
提取纯文本。HTML 用 BeautifulSoup,PDF 用 pdfplumber。
输出按年份命名的 txt 文件。
AI 生成了完整的
extract_text.py,包含错误处理、进度条、字符统计。
Prompt 3:知识图谱构建
编写 build_knowledge_graph.py,支持两种模式:
1. LLM 模式:调用 OpenAI API 从文本中抽取实体和关系
2. Mock 模式:用预置的高质量数据(基于巴菲特公开信真实内容)
实体分类:person, company, concept, metric, industry, event
关系类型:invest, acquire, manage, influence, mention, partner
输出 JSON 格式的知识图谱
AI 生成了包含 LLM 调用、Prompt 模板、Mock 数据生成的完整脚本。
Prompt 4:可视化页面
创建 visualization.html,ECharts 力导向图,要求:
- 暗色科技风
- 节点按类别着色(6种颜色)
- 搜索高亮
- 分类筛选按钮
- 年份范围滑块
- 点击节点显示详情面板
- 统计看板
- 单文件、CDN 引入、无需后端
AI 生成了超过 600 行的完整 HTML,包含 CSS 动画、JavaScript 交互逻辑、响应式布局。
Prompt 5:截图
使用 Playwright 对可视化页面进行多角度截图:
1. 全局概览
2. 搜索 Coca-Cola 高亮
3. 只看投资理念
4. 只看公司
5. 年份筛选 2008-2020
6. 详情面板展示
AI 用 Python Playwright 自动化完成了 6 张截图。
Vibe Coding 关键心得
| 原则 | 说明 |
|---|---|
| 描述意图而非步骤 | 不要说"创建一个 div,设置 flex 布局",而是说"创建一个暗色科技风的搜索栏" |
| 分层迭代 | 先让 AI 搭骨架,再逐步优化细节 |
| 提供上下文 | 告诉 AI 已有的文件结构、技术选型、设计风格 |
| 验证而非审查 | 不需要逐行看代码,运行看效果,不对再调 |
| 保持控制权 | 架构决策(选 ECharts 还是 D3)由人来做 |
七、项目成果与扩展方向
7.1 成果总览
| 项目维度 | 成果 |
|---|---|
| 数据规模 | 48 封公开信,1977-2024 年 |
| 知识图谱 | 61 个节点,74 条边,6 类实体,6 种关系 |
| 可视化 | ECharts 力导向图,支持搜索、筛选、时间轴 |
| 代码量 | ~1200 行(Python + HTML/CSS/JS) |
| Vibe Coding | 5 轮 Prompt 迭代完成全部开发 |
从技术角度,这个项目展示了 LLM + 知识图谱 的强大组合:
- LLM 替代了传统 NLP 流水线 — 不需要标注数据、不需要训练模型,一个 Prompt 搞定实体和关系抽取
- 知识图谱让非结构化文本变成结构化知识 — 48 封信浓缩成 61 个节点和 74 条关系
- Vibe Coding 让开发效率提升 10 倍 — 从想法到可运行的可视化系统,一个下午完成
7.2 扩展方向
- 接入真实 LLM 抽取 — 脚本已支持 DeepSeek(推荐,性价比极高)和 OpenAI。接入后预计可抽取 500+ 个实体和 2000+ 条关系
- 接入图数据库 — 将 JSON 导入 Neo4j,支持 Cypher 查询
- RAG + 知识图谱 — 结构化知识 + 向量检索 + LLM 生成,实现巴菲特投资问答系统
- 时间轴动画 — 将年份滑块升级为自动播放动画,看巴菲特投资版图的演化
从投资角度,这张知识图谱浓缩了巴菲特 48 年的投资智慧。如果你只记住一件事,那就是巴菲特在这 48 封信中反复强调的核心:
"以合理价格买入拥有经济护城河的伟大公司,然后永远持有它们。"
这条主线,从 1977 年第一封信到 2024 年最后一封信,从未改变。
八、获取源码
本项目已开源,完整代码和数据托管在 GitHub:
🔗 https://github.com/warm3snow/buffett-kg.git
⚠️ 注意:该仓库目前为 私有仓库。如需访问,请通过以下方式获取权限:
- 关注公众号「coft」,在后台留言你的 GitHub 账号
- 我会将你添加为 Collaborators
当然,你也完全可以参考本文介绍的原理和 Prompt,用 Vibe Coding 的方式自己从零构建一个!
效果展示和巴菲特投资知识详解,请阅读下一篇:巴菲特投资知识图谱效果展示
免责声明:本文仅为教育目的,不构成任何投资建议。金融市场存在极高风险,请在充分了解风险后做出自己的判断。
关注公众号「coft」,获取更多 AI 时代的深度思考。

浙公网安备 33010602011771号