研究桌出现内存问题
Source: Dev.to
请提供您希望翻译的正文内容,我将为您翻译成简体中文。
为什么一家证券公司需要大脑,而不是另一个仪表盘
一位分析师倾身靠在桌子上问道:“我们对 XYZ Inc —— 那家上个季度提交了某些文件的公司——的当前立场是什么?”这应该只花三十秒,最多一分钟的时间。但负责该名称的那位分析师已经离职。于是,接下来是一段小而痛苦的探险。有人打开 Bloomberg 终端。另一个人搜索收件箱,寻找那份肯定已经通过邮件发送过的覆盖报告。第三个人记得一次财报电话会议的对话,却找不到文字稿。十二个浏览器标签页,二十五分钟后,画面终于从碎片中拼凑完整。
答案一直在那里。它只是分散在四个系统、两个收件箱以及一位分析师日益不可靠的记忆中。正是那一刻——那次不必要的探险——标志着本项目的起点。
开始
我的整个职业生涯都在担任研究分析师。从未写过一行 Python,但始终专注于构建基础设施,以解决日常工作中的摩擦。
- 同行比较繁琐 – 构建从 Bloomberg 和我们自己的估算数据库中提取数据的电子表格。
- 更新 PowerPoint 很糟糕 – 构建可以自动刷新的图表包(但需要外部第三方 昂贵 插件,因为 Excel 和 PowerPoint 在本质上互相厌恶)。
信息收集、上下文切换,以及始终与一团乱麻般的信息打交道,似乎是工作的一部分。我根本没有时间也没有知识去构建一个通用的研究工具,能够在我需要时提供我想要的一切。直到最新一代的 AI 编码工具出现。
我们所在的位置
这是关于为一家证券公司构建研究情报平台的七部分系列的第一篇稿件。它写于基础设施正在搭建之时——一次巨大的提交,涉及 79 个文件,代码行数超过 40 000 行——内容涵盖从图谱模式定义到实时数据连接器,再到第一代 AI 代理。
我会尽可能诚实地记录决策过程:架构选择、错误的转向、以及当一个干净的想法碰到混乱的现实时的瞬间。这第一章几乎不涉及代码,重点在于问题本身,以及为什么这个问题最终比最初看上去更有趣——也更顽固。
Source:
问题
证券公司的研究分析师在一种几乎看不见的认知负荷下工作,除非你开始对其进行映射。它们在脑中携带覆盖范围的全貌。它们知道哪些公司即将进入财报季。它们记得某发行人的首席财务官在六个月前的电话会议上说过谨慎的话。它们回想起在一位初级同事加入团队之前发生的评级变动。
这些知识是真实且有价值的。它几乎完全是 非结构化 的。
公司当然有工具:用于市场数据的终端访问、用于外发研究报告的分发平台、来自大量网站(彭博、FactSet,随你挑)的股票通知。数据是存在的,我们也拥有它们。缺失的却是它们之间的任何连接组织——没有办法提出跨系统边界的问题,没有办法展示公司在某一时刻全体所知道的情况。
看不见的成本不是单个浪费的查询,而是每一次、每一个问题、每位分析师都要从头重建上下文的复合拖累。
- 这位分析师在过去六个月发布了哪些评级变动?
- 自我们上次报告以来,这个发行人提交了哪些重大事件?
- 最近一次财报周期中关键的估计修正是什么?
这些问题都有答案。只是没有快速通道,而现有的路径又漫长且痛苦。
此时的诱惑是去寻找 SaaS 工具:Notion、Confluence、更好的内联网、在现有系统之上的更高级搜索层。我认真考虑过这条路线。问题在于,知识管理工具是围绕 文档和页面 设计的——已经被人合成的人工产物。而我们面对的是不同的东西:实体(公司、分析师、评级、事件、文件、报告、债券)之间密集的关系网。意义不在于单个文档,而在于事物之间的连接。
搜索索引会告诉你哪些文档提到了某家公司。它不会告诉你这家公司的覆盖分析师八个月前更换了,覆盖强度自更换后下降,最近三篇报告都在财报文件发布后一周内发布,以及上周二出现了一个重大事件但尚无人正式回应。这不是搜索问题。这是图谱问题。
Source: …
Into the unknown
我想坦诚地说出此刻的眩晕感。决定构建一个自定义的图谱平台,而不是从现有组件拼装而成,这并不是一个谦逊的承诺。这意味着要拥有模式(schema)、数据摄取管道、查询层、代理层、API以及界面。这也意味着当某件事在上午 7:45 、市场开盘前出现故障时,值班的就是你。我想到如果这真的一路走到生产环境,自己可能要承担的责任,就会感到身体不适。
我去寻找证据,证明这是一项正确的决定,而不是一种精心策划的范围蔓延。我研究了 Palantir 为机构知识管理所构建的系统,查看了 Cognite 在能源行业如何处理工业知识图谱。Databricks 有何天才之处?我阅读了所有能找到的关于这些公司如何使用基于图(以及其他)的方法来理解数据,更重要的是理解数据之间的 连接 的资料。
未完待续…
我一直回到一个结构性的观察上: 金融研究知识本质上是关系型的,而当你把它存储在平面结构中时,关系型知识会退化。 一份研究报告不仅仅是一个文档。它是分析师、公司、评级、日期、一组估计以及市场背景之间的关系。把这些关系剥离掉,你只剩下一个 PDF。保留它们,你就拥有了可以进行推理的东西。
Early schema sketches were humbling
我第一次尝试对领域建模时感觉很简洁——公司、分析师、报告、事件——直到我开始用它来回答真实的问题。模式并不知道分析师 覆盖 某家公司和分析师 已经覆盖 某家公司的区别。它也无法表示当前评级与已被取代的评级之间的差异。时间有效性确实很难建模,而我低估了这一点。
我同样低估了数据连接器会教会我多少领域知识。构建与监管文件流的集成迫使我去理解 “重大事件” 在实践中到底意味着什么,而不是理论上的含义。文件集成暴露了事件的 分类 与分析师实际 使用 之间的差距。
Early naive approach — the code that never shipped
# Flattening event data into a document store
def store_event(event: dict) -> None:
doc = {
"company": event["issuer_name"],
"date": event["published"],
"type": event["category"],
"text": event["body"]
}
search_index.add(doc)
# The problem: we've lost the relationship between the event
# and the company's coverage record, analyst assignment,
# and any notes published in response to it.
# Querying "what did we do after this event?" becomes impossible.
那段代码从未进入真实系统,但编写它的过程让我们清晰地认识到它为何不可行。
What worked
打开一切可能性的决定是:从一开始就坚持 图原生建模,而不是把图当作关系型系统之上的一层。
最终稳定下来的节点类型——Company、Analyst、Sector、CoverageRecord、ResearchNote、MaterialEvent、Filing、BondIssue、EstimateSnapshot——并非自上而下设计的。它们是通过询问 “分析师实际会问哪些问题?” 并逆向推导而产生的。每一种节点类型代表分析师所推理的对象。每一种边缘类型代表会改变问题答案的关系。
# Excerpt from graph/schema/nodes.py — illustrating the principle
# A CoverageRecord isn't just a link between Analyst and Company.
# It carries its own temporal properties and state.
@dataclass
class CoverageRecord:
analyst_id: str
company_id: str
rating: str
target_price: float | None
currency: str
coverage_start: date
Source: …
overage_end: date | None # None = currently active
is_primary: bool
last_note_date: date | None
coverage_end 字段看似简单,但它经历了三次模式迭代才最终确定。没有它,你无法回答:
- “在当前分析师之前,谁负责覆盖这家公司?”
- “覆盖的连续性如何?”
- “我们的体系中是否有公司在九十天内未被提及?”
模式本身就是对重要性的论证。 每个字段都是对该信息值得保留的声明。把模式真正做好是基础阶段最具智力挑战的部分。
代理架构遵循了相同的原则。系统不再是单一的通用助理,而是需要多个专精的角色:
- 公司快照代理 – 汇总完整的当前概况。
- 财报准备代理 – 在通话前收集所有相关信息。
- 重大事件监控 – 监视监管文件并将其推送给合适的分析师。
每个代理都很专注,但图谱为每个专注的代理提供了完整的关系上下文,因此一个聚焦的问题也能得到丰富的答案。
这带来了什么变化
这次提交奠定了基础——79 个文件,超过 40 000 行——几乎可以说是该项目有史以来最密集的单次推送。通常这会是警示信号;但在这里它反映了一个真实的事实:你不能只构建半个知识图谱。 模式、连接器、写入器、查询层——它们共同组成一个系统,只有协同工作才有效。
如果让我重新来,我会更早开始数据连接器的工作,并把它视为 领域研究 而非纯粹的工程实现。每个连接器都会让你了解它所触及的数据。例如,债券数据的整合改变了我对覆盖宇宙中固定收益部分如何建模的认识。如果我先完成那部分整合,就能设计出更好的初始模式。
更深层的教训: 知识基础设施从来不是单纯的技术问题。它关乎人们的思考方式、他们需要了解的内容以及何时需要了解。正确的架构应当映射真实的认知工作——而不是仅在技术上孤立地优雅。
仪表盘、代理、API——这些都是对研究台可能形态的表达。图谱本身就是这个想法。
接下来:图数据库的选择过程看似技术决策,实际上是对运营现实的探讨——答案让我大吃一惊。
贵组织中目前仅存于某人脑海的最有价值的知识是什么?要把它转化为可共享的资产,需要做些什么?
本系列 “构建研究蜂巢” 的第 1 部分,共 7 部分