Cerebras知识库架构的三大杀手锏,你绝对想不到Slack才是核心


一台装了15,000个日常问题的企业知识库,上线3个月就成了全公司最火的内部工具——你猜它凭什么没变成第二个“没人用的维基百科”?

Cerebras内部知识库日均处理15000次查询,通过融合Slack、代码仓库、数据库等多源数据,结合向量检索、全文搜索与重排序技术,构建了一套可扩展的企业级语义搜索系统。本文解析其数据提取、嵌入存储及混合检索架构。

信息从来不会乖乖待在一个地方

每个公司都有那么几个“信息黑洞”。你问个问题,同事甩给你五个链接,点开一看,三个已过期,两个权限不对。然后有人拍桌子:“咱们把所有东西都搬到一个平台上!” 这个提议每季度准时出现一次,像闹钟一样精准。

可惜现实是个不听话的小孩。工程师写代码顺手在GitHub里留了个注释,产品经理在Jira里塞了一堆状态更新,运营团队在Slack里聊出了整套故障处理流程。没人会特意跑回“中央文档库”再誊抄一遍。那个传说中的“唯一真理来源”,通常活不过三个月。

我们设计系统的第一原则就是:别让用户改习惯。数据在哪儿生成的,我们就在哪儿把它捞出来。Slack的聊天记录、代码仓库的提交、Wiki的页面、甚至某些团队自己搭的小数据库——统统直接对接,绝不强迫用户多动一下手指头。

知识库的骨架就这么简单

整个系统说到底就干三件事:把数据收进来、让人查得到、顺便管好权限别乱套。听起来平平无奇对吧?但真正动手的时候,坑一个接一个。

最核心的部件是一张Postgres表。别被“核心”俩字吓到,它就是个大仓库,每个条目存三样东西:一段文本的向量表示(就是数学上的那个“意思”)、一段精简摘要、以及一堆乱七八糟的元数据,比如来源、时间戳、作者之类。

这张表的接口极其统一。不管数据是从哪儿来的——Slack里的一句吐槽、代码库里的一段函数、还是运维手册里的一页说明——进了这张表之后,查询方式都一样。我们内部的其他开发团队想加个新数据源?写个几行代码的插件就行了,不用动整个系统的根基。

Slack才是真正的信息大熔炉

要是问我哪个数据源最头疼,绝对是Slack。全公司最鲜活的工程讨论全在里面,但也是最难搞的。一条消息可能是“好的收到”,也可能是几百字的死锁分析,信息密度天差地别。直接用原始文本做向量检索?试过了,效果惨不忍睹。

短消息在向量空间里总是占便宜。“好的谢谢”这种话,离什么查询都“不远”,但屁用没有。长消息虽然信息量大,反而经常因为向量被稀释而排到后面。我们一开始也觉得奇怪,后来想明白了:向量相似度只管“意思近不近”,它分不清“意思近”和“信息多”是两码事。

所以我们搞了个组合拳。全文搜索抓精确匹配——工程师贴了个报错日志,那必须精确命中。向量搜索抓同义转换——问“恢复卡住了”和答“检查点挂起”的人用的词完全不同,但意思能对上。逆文档频率专门给生僻词加权,“CKPT_PREFETCH”这种配置项一出现,权重直接拉满。最后加了个时间衰减,上周的答案肯定比半年前的靠谱,毕竟基础设施天天在变。

每条消息都得盘一遍

光搜原始消息还不够。一条Slack线程可能横跨两个小时、七八个人,最后那个“设置CKPT_PREFETCH=4”的解决方案藏在一堆闲聊底下。我们让一个轻量级LLM把整条线程读一遍,提炼出几个关键信息:这是个什么问题?大概在聊什么?最后解决了没?涉及哪些系统或代码?

这一步做完,每条线程就变成了一份结构化的“小卡片”。卡片里有问题陈述、简要总结、解决方案和涉及的代码引用。然后我们只把这张卡片送去生成向量,而不是原始对话。实验数据很明确:这么做之后检索准确率往上蹿了一大截。

但还有一个漏洞:线程里某些关键的单条发言可能在总结里被淹没了。解决方案叫“突发”(Bursting),就是把同一个作者的连续发言打包成一组,单独判断要不要嵌入。如果这组发言够长、含有关键词、或者被人点了表情符号,就单独生成向量存进去。这样那条关键的“漏网之鱼”也能被搜到。

代码库也得塞进去

最开始团队里有人反对给代码做向量索引。大家说:“有grep就够了啊,搞那么复杂干嘛?” 这个质疑很合理。但后来参考了Cursor团队的实践,发现语义搜索在大型代码库里确实有用——尤其是当你记不清精确的函数名、只记得“那个处理内存分配的地方”的时候。

我们用了CocoIndex这个开源框架来处理代码仓库。核心思路是按语法结构切分:优先按类切,太大了就按方法切,还不行就再细拆。一个文件可能生成好几个不同粒度的向量,从文件级到函数级全覆盖。每次代码提交之后,系统只重新处理变动的部分,不会把整个仓库重算一遍。有些仓库超过40GB,全靠这套增量更新机制才能跑得动。

内部仓库越来越多之后,我们干脆把配置权限下放给各个团队。他们自己提交一个配置文件,指定哪些路径要索引、哪些要忽略,系统自动接入。运维负担几乎降到了零。

每个团队都是自己的数据管家

有些团队早就有了自己的内部数据库,存着设备监控、编译耗时之类的关键数据。他们不想把数据搬进Slack或者Wiki,只想让知识库能直接查这些表。这个诉求很合理。

我们的做法是把“自定义数据源”做成插件接口。某个团队在自己的代码仓库里开一个Pull Request,提交一个几十行的小Python脚本。这个脚本的任务就是从他们的数据库里读数据,然后转成和标准嵌入表一模一样的格式,写进去。

只要数据进了那张表,后面的查询、排序、权限控制全部自动生效。其他部分一行代码都不用改。这个设计后来被好几个团队用起来了,大家省了迁移数据的力气,我们也没多背任何维护债。

查个问题还得先做计划

用户输入一个问题之后,系统不会立刻满世界乱搜。我们加了一个“计划”环节,让一个轻量LLM先判断:这个问题大概归哪个项目管?哪些数据源可能有答案?要不要搜代码?要不要查最近合并的Pull Request?还是应该找找谁懂这方面?

计划器看完用户的问题和当前项目范围之后,会列出一个工具清单。执行器拿到清单之后,把每个工具调用并行发出去,等所有结果回来再汇总。这种并行设计把响应时间压得很低,用户压根感觉不到背后有这么多步骤在跑。

工具本身很多样:有专门搜Slack的、有基于ripgrep精确搜代码的、有查历史Pull Request的、还有一个叫“who_knows”的专门问“这事儿该找谁”。每个工具各司其职,互不干扰。

排名这事不能只看一家之言

多个检索器返回的结果怎么合并成一份排名?我们用了一个叫“倒数排名融合”(RRF)的老方法。这个方法的核心思想是:看一个文档在多少份结果列表里都排得靠前,而不是只看它在某一个列表里排第几。一个文档可能在向量检索里排第一,但在全文搜索里根本没出现,那它的综合得分其实没那么稳。

如果某个文档在六个检索器里都进了前二十,那它大概率是真的相关。反之,只在向量检索里冒个头,其他五个都找不到,就很可疑。RRF的平滑常数让“共识”比“单项冠军”更重要。

融合之后,我们再把结果交给一个小规模的重排序模型,让它给每个文档打个0到10的分数。最后保留前十名。但排名结束之后还有一步:如果匹配到的是Wiki里被截断的一段,我们会把前后相邻的段落也拉回来,保证用户能看到完整的上下文,而不是孤零零的一句话。

MCP接口把选择权交还给调用者

我们给MCP(模型上下文协议)做的集成里,暴露的不是一个包办一切的“回答问题”端点,而是几个独立的检索工具。这些工具很纯粹,几乎不带LLM逻辑,就是为了让客户端能快速、便宜地调用。

每个工具对应一种检索方式:search_slack、search_code、search、who_knows。输入输出都是规整的JSON结构,没有任何隐藏的副作用。Claude Code或者其他MCP客户端拿到这些工具之后,自己来决定调用顺序和组合方式。

这种设计的妙处在于:检索层只管“找出证据”,至于怎么用这些证据,那是客户端的事。我们不做任何假设。这样一来,既支持了复杂的Agent工作流,也保留了最轻量的单次查询场景。

Web界面走的是全自动流水线

在Web端,用户看到的是一个输入框和一个回答。但背后的流程和MCP的原子化工具完全不同:Web端跑的是完整的“计划-执行-综合”流水线,全程自动,不劳用户操心。

计划器选工具,执行器并行调用,综合器拿到所有证据之后写最终答案。这个综合器会读出“Slack里有人说设置这个参数,但那个参数在最新版本里已经废弃了,建议改用新的那个”——这种跨源融合的能力,是单一数据源永远做不到的。

最终呈现给用户的答案自带引用来源。点一下就能跳回原始上下文,方便验证真伪。这种“结论+出处”的组合,极大降低了用户对AI回答的不信任感。

项目机制让搜索范围自动收敛

早期版本有个致命问题:搜完所有东西的结果就是一锅大杂烩。编译器工程师搜“性能优化”会看到数据中心运维的机房散热手册,完全鸡同鸭讲。我们很快意识到,在企业环境里,“搜所有”等于“搜不到”。

解决方案叫“项目”(Project)。每个项目是一组数据源的命名集合:某些Slack频道、某些代码仓库、某些Wiki空间。一个刚入职的编译器团队新人,登录之后选择“Compiler”作为默认项目,从此之后的每次搜索都只在这个范围内进行。他不需要知道基础设施团队有哪些频道、那个叫“infra-ops”的仓库是干什么的——通通不需要。

同一个数据源可以挂在多个项目下面,比如那个全公司共享的“故障通报”频道,既是平台团队的项目内容,也是运维团队的项目内容。数据只存一份,项目只是逻辑指针。这套机制上线之后,搜索结果的相关性提升肉眼可见。

回头看看这一路踩过的坑

整个项目做下来,最大的教训就是:千万别试图让用户改变习惯来迁就你的系统。信息在哪,你的系统就该在哪——反过来绝对行不通。那些想把所有东西塞进一个“完美平台”的想法,最后都被现实打脸了。

混合检索不是花架子。全文搜索、向量搜索、时间衰减、词频加权——每个技术单独拎出来都有短板,但组合在一起就稳得多。尤其是在企业环境里,数据质量参差不齐,单一检索方式根本扛不住。

另一个容易被低估的点是“默认值”的设计。新员工入职第一天,面对几十个频道和上百个仓库,他根本不知道该查哪个。项目机制和默认范围让“第一次搜索”就能有不错的结果,这直接决定了用户会不会用第二次。

最后,把检索和推理解耦让我们保持了极大的灵活性。MCP客户端可以自由组装工具,Web端可以走完整的自动化流水线,两者共享同一套底层。这种架构选型带来的长期收益,远超我们最初的预期。