来自Cerebras的实战经验,我们是如何构建知识库的

admin 2026-07-19 04:43:28 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: Cerebras分享了构建内部知识库CerebrasKnowledge的实战经验。核心思路是在数据所在之处与之相遇,直接从Slack、代码仓库等平台摄取数据,而非强制统一存储。系统采用混合搜索策略,结合全文搜索、嵌入搜索、逆文档频率和时间衰减,并通过倒数排名融合与重排序模型提升结果相关性。文章还介绍了Slack线程处理、代码嵌入维护、自定义数据源、MCP集成及项目限定范围搜索等具体实践,旨在为快速增长的组织提供高效、灵活的信息检索方案。 综合评分: 87 文章分类: 实战经验


cover_image

来自Cerebras的实战经验,我们是如何构建知识库的

Cerebras Cerebras

ThinkInAI社区

2026年7月17日 12:57 上海

在小说阅读器读本章

去阅读

⬆️关注 ThinkInAI 星科社区,最及时最干货的AI内容分享

员工每天向我们的内部知识库提出超过 15,000 个问题。自 3 个月前上线以来,它已经成为公司内部采用最广泛的工具之一。人类、自动化流程和智能体都在使用它。

在 Cerebras,我们的团队横跨数据中心运营、芯片设计、硬件、训练、推理、云平台等多个领域。随着每年数百名新员工加入,我们的沟通渠道里开始充斥着同样的问题:

我们构建 Cerebras Knowledge,是为了帮助人们将人与系统连接到有用的信息。

在数据所在之处与之相遇

在组织内部查找信息很难。数据分散在各种工具中,而且大约每个季度都会有人提出同一个“绝妙”的解决方案:把所有内容都记录在一个平台里,这样所有信息就都在同一个地方。当然,所谓“单一事实来源”的梦想在实践中很少奏效。

信息会在最方便、最符合使用习惯的地方产生:文档中的建议修改、Slack 里的讨论串、GitHub 中的代码引用,以及 Jira 里的状态元数据。这些平台都是为各自的特定领域量身打造的,并经过多年的产品工程和数据分析优化。在 Google Docs 里讨论一个 pull request 会是非常糟糕的体验。

因此,我们开始设计一个尽量不改变现有行为的系统。在数据收集侧,这意味着直接从各个平台提取数据。

知识库的剖析

我们的知识库提供三样东西:

核心是一个单一的 Postgres 表,用于存放来自许多来源的嵌入、原始摘要和元数据。系统会持续从公司各处摄取数据,并维护一个可供查询的数据存储。

我们想要一个简单的数据接口,但它又能够处理大多数形式的数据。我们也希望 Cerebras 的其他开发者能够构建自定义连接器。最终结果刻意保持简单:每个来源,从 Slack 讨论串到网表,都会进入同一个嵌入表,而该表中的任何内容都可以立即通过同一个接口查询:

每个数据源都会定义数据是什么、如何连接,以及应该以什么频率获取。无论生成的嵌入行来自 Slack、代码仓库、文档系统还是自定义数据库,它们都遵循同一套接口。

我们如何处理非结构化的 Slack 对话

Slack 是我们在设计时最需要重点考虑的数据源。全公司最新的工程讨论都发生在这里。

我们最初测试过,直接对原始文本做简单嵌入是否已经足够好。很快我们就意识到,仅靠向量搜索不足以匹配所有相关数据。

Slack 消息带来了几个挑战:

我们需要一种混合方法。我们构建了 Slack 数据摄取流程,让每个主题帖都能同时通过多种搜索技术被检索到,而每种技术都会弥补其他技术的不足:

  • 全文搜索能抓住嵌入会模糊掉的精确词元:

    错误字符串、标志名称、主机名。当工程师粘贴一条原始错误消息时,精确的词法匹配几乎总是最有力的证据,任何语义相似度都不应该排在它前面。

  • 嵌入搜索能捕捉改写表达。

    提问者说“restore hangs after manifest load”,回答者说“checkpoint stalls on the NFS mount”,两者可能完全没有共同词汇。向量相似度能把一个问题和一条用不同措辞写成的答案连接起来。(1)

  • 逆文档频率能把信号和填充内容区分开来。

    一条围绕罕见词元(例如某个冷门配置标志)写成的短消息,应该获得更高排名。“sounds good, thanks!” 在嵌入空间里与许多查询都很接近,但一旦考虑词项稀有度,得分就会接近于零。

  • 时间衰减体现了 Slack 答案会过期。

    两个主题帖可能都能回答同一个问题,而六个月前的那个可能描述的是已经不存在的基础设施。在相关性其他方面相同的情况下,更新的主题帖胜出。

任何单一评分器都不会被单独信任。每种技术都会为同一语料库生成自己的排序视图,而这些视图会在查询时融合在一起(见重排序)。

Socket 模式

为了实时收集数据,我们在工作区中安装了一个 Slack 机器人,并以 Socket 模式运行它。Slack 会通过持久化的 WebSocket 将每条消息事件推送给我们,因此我们无需轮询 Web API,也不会消耗其速率限制,就能获得实时更新。

当事件到达时,我们会立即确认接收,使用稳定的事件 ID 对其去重,并将该消息标记给摄取消费者处理。

摄取消费者不会孤立地保存一条新消息。它会解析该消息所属的线程,并从 Slack API 重新获取整个对话,包括父消息和每一条回复。然后,它会将整个线程作为一行写回。因此,对现有线程的一条回复会重新拉取父消息以及所有同级回复,从而确保已存储的内容、参与者列表和最后活动时间戳始终反映完整对话。

我们系统中的每个 Slack 频道都有自己的数据源。这为数据新鲜度提供了细粒度的调优能力。例如,团队可以选择更频繁地摄取一个繁忙的事故频道。

线程和消息

原始 Slack 文本一落库即可进行关键词搜索,因为我们在原始内容上维护了一个 Postgres 全文(GIN)索引。不过,为了实现有用的向量搜索,我们还会做一些额外处理。(8)

在蒸馏过程中,LLM 会从完整线程中提取结构化数据:

我们会对这些数据点进行嵌入,并写入共享的嵌入表。原始转录文本不会被直接嵌入。在我们的实验中,当线程被规范化为一致格式后,准确率显著提升。(7,9) 额外的元数据也为语义匹配提供了更有用的信号。

拆分

到这个阶段,Slack 搜索已经不错了,但我们仍然反复遇到同一个问题:长线程中的重要消息并不总是能在线程级摘要中得到体现。

为了增强单条消息的信号,我们使用拆分。一次拆分是指来自同一作者的一组连续消息。我们会将线程主题作为上下文前置,然后对单个拆分进行嵌入(2),因为有时答案就藏在某条偏题消息里,而它的词汇从未进入线程摘要。拆分嵌入让这条消息本身也能被找到。

为了防止低信号数据进入数据库,每个拆分都会根据一组加权信号进行评分,并且必须超过阈值后才会被嵌入:

蒸馏完成后,符合条件的片段会被嵌入,并与线程级记录一起存储在 embeddings 表中。

代码仓库

一开始,我们曾讨论是否有必要对代码仓库做嵌入。随着 Claude Code 和其他命令行工具的兴起,在“只需要 grep 就够了”看似成立的情况下,创建代码嵌入反而显得有些反直觉。在与业内其他人交流,并阅读了 Cursor 关于大型代码库中语义搜索的发现后,我们决定尝试一下。

我们有许多内部仓库,其中一些超过 40 GB。我们主要关心的是如何高效地让它们保持最新。

使用 @cocoindex_io(https://x.com/@cocoindex_io) 维护代码嵌入

经过几轮实验后,我们最终选择了 CocoIndex,这是一个开源文档嵌入框架,专注于对代码库进行向量化。

对于每个仓库,我们会使用按从粗到细排序的特定语言正则边界来拆分代码。拆分器会先尝试更高层级的边界,例如类。如果生成的分块仍然过大,它会退回到方法边界,再退回到更小的代码块。我们对生成的分块做嵌入,并将向量写入 Postgres。单个文件可能会在不同粒度级别生成多个嵌入,例如文件级记录和函数级记录。

CocoIndex 会在 Postgres 中跟踪同步元数据。每次提交时,它只会重新嵌入并重新导出发生变化的代码块,而不是重新计算整个代码库。这个方式对我们尤其有效,因为同步状态和嵌入存储都在同一个数据库里。

随着代码库数量增加,我们把仓库接入迁移到了配置文件中,团队可以自行提交这些配置,包括文件路径级别的允许列表和拒绝列表。

自定义数据源

有些团队已经有自己的数据库,不想为了参与知识库而把数据迁移到 Slack 或文档系统中。他们希望能在现有表之上使用同样的查询界面。

为支持这一点,我们把自定义数据源视为插件脚本。团队可以提交一个拉取请求,其中包含一个小型 Python 模块,知道如何从其系统中读取数据,并输出形状与我们的嵌入表一致的行,同时附带一个匹配的数据源条目。

只要脚本使用与其他嵌入行相同的模式写入共享数据库,栈中的其余部分就无需改动。数据会与 Slack、代码和文档一起变得可查询,系统其他地方不需要任何特殊处理。

规划与工具扇出

对于每个查询,我们首先运行一个简短的规划步骤,由 LLM 判断哪些工具和数据源可能相关。主要工具包括:

规划器会基于我们已建立索引内容的简洁描述来工作:有哪些项目、每个项目中有哪些可用数据源,以及每个数据源擅长回答什么问题。给定用户查询和当前作用域后,它会输出工具选择,执行器会将这些选择并行扇出,规范化为统一的证据格式,并传递给最终的综合 LLM。(4)

重排序

一篇文档可能仅仅因为与查询共享了一些词汇,就出现在靠前位置,但它回答的却是另一个问题。在重排序之前,我们会使用倒数排名融合(reciprocal rank fusion,RRF)来合并各个检索器之间不兼容的结果列表。对于每篇文档,只要它出现在某个列表中,我们就为它加上 weight / (60 + rank) 的分数;默认权重为 1.0,平滑常数为 60。

平滑常数让“共识”比单个强票更重要:一个文档如果在多个检索器中都出现在靠前位置,就可能胜过一个只在其中一个检索器里排名第一的文档。随后,我们会把重复的 chunk 合并回同一个来源,限制每个文件可贡献的结果数量,最终得到一个更多样化的前二十名结果。

我们会把原始查询和这些候选结果发送给一个小型重排序模型。它会给每个文档打一个 0 到 10 分的分数,然后我们保留前十名。(6)

一旦最终排名确定,我们会把上下文重新补回给获胜结果。例如,如果匹配到某个 wiki 小节,我们会拉取它相邻的两个小节,这样由切分导致分散的标题、前置条件和注意事项就不会丢失。这能给读者一个完整的片段,而不是一段缺少重要上下文的孤零零段落。

因此,搜索的输出是一个丰富的证据包:结果来自不同检索器的融合,在来源层面去重,针对实际问题重排序,然后才用周边上下文进行扩展。

MCP

在 MCP 集成中,我们把检索构建块作为直接可用的工具暴露出来,而不是把它们隐藏在一个“回答这个问题”的端点后面。这些工具有意设计得简单,并尽可能不依赖 LLM,这样客户端就能快速、低成本地查询它们。(5)

每个 MCP 工具都对应一个底层检索原语,例如 search_slack、search_code、search 或 who_knows。工具的输入和输出都很窄、结构化且稳定,因此任何客户端或智能体都可以轻松调用它们,而不必在工具内部嵌入额外的编排逻辑。

大多数工具会运行一条查询流水线,例如向量搜索、词法搜索或 ripgrep,应用轻量级评分启发式规则,然后返回原始证据行。

Claude Code 或任何兼容 MCP 的智能体会成为编排引擎。它决定调用哪些工具、以什么顺序调用,以及如何把结果组装成最终答案或代码编辑。检索层本身并不依赖这些 LLM 决策来处理请求。

Web UI

在 Web UI 中,同样的工具也存在,但它们被连接到一条完整的查询流水线,会针对每个用户问题端到端运行。UI 智能体负责规划器和执行器步骤。

  • 规划器:一次轻量级 LLM 处理会检查查询和当前项目,然后选择要调用哪些检索工具,例如 search、search_slack 和 subsystem_index。
  • 执行器:系统会并行发散这些工具调用,收集结果,并把它们规范化为统一的证据 schema,其中包含分数、时效性和来源提示。
  • 综合:最后一次 LLM 处理会接收类型化的证据包和原始问题,然后生成 UI 中显示的答案,包括引用、注意事项以及跨来源综合。

从用户视角看,Web UI 就是“提一个问题,然后得到一个答案”。在底层,它运行的是同一套“规划器 → 执行器 → 综合器”模式,而 MCP 客户端可以显式地复现这一模式。

组织

随着语料库不断增长,“随时随地搜索一切”很快就不再有用了。编译器团队的工程师不希望在搜索结果中看到基础设施运行手册,反之亦然。项目是我们让搜索默认具备相关性的方式。

项目与限定范围搜索

我们引入了项目,作为组织查询所覆盖工作空间的主要方式。项目是一组有名称的数据源集合:特定的 Slack 频道、代码仓库、内部数据库,以及与某个团队或计划相关的文档空间。

项目被刻意设计得很轻量。同一个数据源,比如共享的事故频道或中心平台仓库,可以被多个项目引用,而不是被重复复制。

入职引导与默认设置

在入职引导过程中,系统会提示用户选择或创建一个符合其工作方式的默认项目,例如机器学习训练基础设施、编译器或数据中心运营。

这个默认项目会存储在用户资料中,并自动用于限定查询范围。新工程师无需先弄清哪些 Slack 频道、代码仓库或文档空间重要,就能获得高信噪比的答案。

最后的思考

归根结底,这个知识库之所以有效,是因为它在人们的信息本来所在之处与他们相遇,而不是强迫所有内容都进入一个僵化的系统。通过结合多种搜索技术,我们可以快速呈现证据。最终得到的是一种搜索体验:它足够灵活,能够适应真实的公司数据;也足够结构化,能在 Cerebras 持续增长的过程中保持实用。

如果你读到了这里,并且对此感兴趣,AI/Growth 团队正在招聘;如果你感兴趣,可以联系 @learnwdaniel(https://x.com/@learnwdaniel)


加入ThinkInAI社区

#

如果你也对AI充满兴趣,欢迎加入我们的ThinkInAI社区,在这里,你可以:

  • 获取最新AI工具资讯
  • 参与实战经验分享
  • 结识志同道合的伙伴
  • 共同探讨AI应用方向

扫描文末二维码,加入ThinkInAI社区,一起拥抱AI新时代!


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:ThinkInAI社区 Cerebras Cerebras《来自Cerebras的实战经验,我们是如何构建知识库的》

第35篇全栈AI聊聊ai挖洞 网络安全文章

第35篇全栈AI聊聊ai挖洞

文章总结: 文章探讨AI在安全研究中的价值,指出AI擅长信息整理、路径梳理和假设生成,但最终判断仍需人工。强调合法研究流程:先建目标地图,再生成假设清单,人工最
评论:0   参与:  0