几乎每个团队都经历过这样的循环:资料越攒越多,找答案却越来越难。接口规范躺在某篇文档里,课程内容分散在几十篇教程里,流程制度隔三差五更新一版——东西都在飞书 Wiki 里,可真要用的时候,大家还是习惯性地翻目录、搜关键词,搜不到就转头去问那个最熟悉项目的同事。而被问的那个人,往往上周刚回答过一模一样的问题。
把大模型接进一个聊天框,一个下午就能做完。真正花功夫的地方在后面:授权范围怎么控制,几百篇文档怎么持续同步,文档更新了索引怎么跟上,回答里的每句话能不能指回出处,系统出了问题从哪里查起。这个项目做的就是把这一整条链路走完,最终交给你一套真能跑起来的系统——成员在网页和飞书里直接提问,系统从团队自己的知识库里检索资料,给出带引用的回答,不满意的答案可以追溯到任何一篇飞书原文。

你要做的,是这样一套东西
整套系统分成四个部分,各自独立又彼此咬合。
面向普通成员的是两个入口:一个 Web 问答端,飞书登录、会话管理、连续追问、引用展示、明暗主题全都齐备;一个飞书 Bot,把同样的问答能力直接搬进团队每天泡着的聊天工具里。面向管理员的是一个管理台,知识库同步、文档索引、权限范围、服务探活、运行诊断集中在一处。底下撑着它们的是后端数据底座:FastAPI 和 LangGraph 驱动的 Agent 流程,PostgreSQL 存文档元数据,Milvus 存向量索引,Redis 处理事件去重和短状态。
这套东西没有一点玩具项目的影子。同步任务要持久化、能断点续跑;飞书 Webhook 事件要校验、去重、失败重试;检索要先按用户权限过滤才能进向量库;数据库结构变更一律走 Alembic 迁移。这些在真实项目里一个都绕不开的问题,在这里你会挨个遇到,也挨个解决。
一切从飞书身份开始
既然资料都在飞书,身份自然也交给飞书。用户通过飞书登录完成授权后,系统就能认出他是谁,并且只在他的权限范围内访问 Wiki 和文档。这套身份信息贯穿全局——同步任务、网页问答、飞书 Bot 用的是同一份用户数据,一处登录,处处生效。

登录进来就是对话界面,没有多余的引导页。会话列表、连续追问、引用来源、明暗主题都收在这一个页面里,成员从提问到核对出处,全程不用跳去任何后台。这里我们选择使用飞书账号登录(因为后续需要引入飞书知识库)。


不知道,就说不知道
接下来我们从一个"失败"的提问看起。
新开一个会话,问:"vector 和 list 的区别是啥?"此时系统还没同步任何资料,页面干脆利落地告诉你:知识库里没有依据。

这恰恰是大多数问答产品栽跟头的地方。模型肚子里有的是通用知识,随手就能编出一段头头是道的解释,可团队没法判断这段话到底是不是出自自己的资料,更不敢拿它当结论。RAG Agent 的做法是先检索、再决定答不答:检索结果撑不起这个问题,就明说没有依据,或者反过来向用户要补充信息。回答永远停在资料能够支撑的范围之内。

对技术规范、课程资料、流程制度这类内容来说,这条边界就是系统的立身之本。团队成员要的不是一段漂亮的回答,而是一个敢直接引用、能继续核对的答案。
一个 Wiki 链接,带进一整个知识库
那么资料从哪来?团队的积累通常长这样:一个飞书 Wiki 知识空间,按阶段和主题层层展开,几十上百篇文档嵌在目录树里。

把这一整棵树接进系统,管理员只需要做一件事:粘贴 Wiki 链接。
动手之前可以先瞟一眼管理台总览。Chat 和 Embedding 两路模型服务各有独立的探活入口,通不通直接写在页面上。先确认依赖都活着,后面同步万一出问题,排查范围立刻缩小一半。


确认无误,创建同步任务:粘贴 Wiki URL,选一个目标知识库,点启动。


接下来系统会自己干活:从 Wiki 根节点出发递归发现所有文章,逐篇读取、解析、建立索引。任务全程记录自己跑到哪了——正在处理哪篇文档、完成了多少、失败了哪些、切出了多少分块。管理员关掉页面去忙别的,任务照跑不误;过一阵再回来看,进度和历史记录一条不少。


跑完的文章会出现在文档列表里,标题、状态、分块数、原文链接一目了然。哪篇失败了、为什么失败,也明明白白标着;想核对内容,点原文链接直接跳回飞书。

文档怎样变成可检索的知识
同步进来只是第一步,真正的工作发生在水面之下。
每篇飞书文档进入系统时,标题、原文 URL、章节路径、更新时间这些元数据都会完整保留下来。正文按章节语义切成适合检索的片段,经 Embedding 转成向量后写进 Milvus;元数据和同步记录落在 PostgreSQL;Redis 则负责短状态和飞书事件去重。三样存储各司其职,谁也别想替代谁。

这条流水线的意义在于可回溯:任何一个知识片段,都能说清它来自哪篇文档、位于哪个章节、什么时候同步进来的。往后回答要标出处也好,管理员要查一篇文档有没有完成索引、切成了几块也好,靠的都是这里留下的线索。
提问之后,答案和出处一起抵达
资料就位,再回头看提问这条链路。用户的问题进来后,系统先按他当前的知识范围过滤一遍资料,然后才去向量索引里找相关片段。找出来的片段连同问题一起送进 LangGraph 驱动的问答流程,模型在生成回答的同时,把每个结论对应的来源也一并标出来。

还记得开头那个被谢绝的问题吗?同步完图解 C++ 教程之后,把"vector 和 list 的区别"再问一遍——这一次,知识库里有底气了。

回答下面跟着引用来源。用户点一下就能打开原文,看清这段解释出自哪篇文档的哪一节,确认无误再接着追问。

事情到这里还没完。每次回答都会留下一份运行记录:检索覆盖了多少内容、置信度多高、引用落在哪些位置、回答有没有足够的支撑。用户觉得答案好或不好,随手点个反馈,这些信号会汇总到管理端,帮管理员看清资料哪里有缺口、检索哪里不对劲、模型调用有没有异常。
知识库有名字,资料也有边界
一个团队的资料很少只有一种。业务资料、技术文档、项目规范、流程制度,各有各的读者群,混在一起迟早出事。管理端的做法是给每个知识库起名字,再挂上知识范围,由范围决定哪些角色能检索到哪些内容。

这样一来,不同团队、不同角色可以共用同一套系统,检索时各看各的资料。关键在于权限过滤发生在检索阶段——越权的内容根本到不了模型眼前,而不是寄希望于模型"懂事"。
网页里能问,飞书里也能问
Web 端适合坐下来连续对话、翻引用、管资料,但团队的日常沟通发生在飞书里,问答能力理应跟着人走。管理员在飞书开放平台配好应用之后,成员在聊天窗口里直接 @ Bot 就能提问。


两个入口背后是完全同一套东西:同一批资料、同一条检索链路、同一套权限判断和引用逻辑。工程上值得说道的是消息的处理方式——飞书 Webhook 收到事件后只做校验、解密、持久化,然后立刻返回,真正的问答交给后台 worker 慢慢执行。事件去重、失败重试、dead-letter 手动重投全部内置,一次网络抖动丢不了任何一条消息。
系统跑起来之后,还能一直看得清楚
知识库会不断更新,模型服务也难免波动,一个要长期服役的系统必须把自己摊开来给人看。管理台把健康检查、同步任务、文档索引、用户权限和诊断信息集中在一处:某次问答跑过哪些步骤、检索到了哪些片段、调用了哪个模型、用户留下了什么反馈,逐项可查。真遇到说不清的异常,还能导出一份脱敏诊断包,拿着它慢慢定位。

这套系统,拆成 25 课带你从零写完
上面看到的一切,都收录在配套课程里,而且不是给你一份现成代码对着讲——整个项目按真实研发顺序拆成 25 个 milestone,你跟着课程一个一个把它们写出来。
M00 先带你把整个系统跑起来:从零启动本地环境,完成第一次带引用的真实问答,先看到终点长什么样。
M01 到 M02 搭出 Web 和 API 的最小骨架,再把一次性脚本产品化成可追踪的同步任务。
M03 到 M06 沉下去做数据底座:Redis 任务状态、Milvus 向量库、飞书 OAuth 登录、用户角色与访问入口。到这里,系统有了地基和门禁。
M07 到 M12 走通知识入库这条链路:读取飞书 Wiki、解析文档、语义切块、写入索引、同步任务失败记录,最后做出管理台的同步与文档列表。
M13 到 M17 是 RAG 的核心段落:LLM 与 Embedding 客户端、基础问答闭环、Query Rewrite、Rerank、引用答案与拒答——"不知道就说不知道"的能力就诞生在这里。
M18 到 M21 把质量变成可验证的东西:Golden Set 分层评估、Agent Graph 节点化编排、Trace 可回放记录、知识范围权限过滤。
最后 M22 到 M24 收尾:飞书 Bot 消息入口与事件可靠性、Web Chat 流式会话与反馈,以及运营、质量门禁和一次完整的本地重放。
每一课的形态都一样扎实:明确的源码锚点、可以照着敲的命令、定向测试、机制图解、真实页面截图,正文按"这一阶段做什么、动手实现、运行验证、刚才发生了什么、测试"五段展开。参考源码开放在 GitHub(CppTrainingHub/ragagent),每个 milestone 有对应的阶段代码,你可以从任何一课切进去跟着做。哪些结论靠单元测试就能站稳,哪些必须连真实模型和飞书租户才能确认,课程里也分得清清楚楚——没有拿 mock 冒充通过的环节。
课程结束时,仓库里躺着的是你自己的系统
这 25 节课走下来,最重要的就是能独立搭出一套生产可用的系统,而不是照着教程跑通个 Demo 就完事。从数据库表结构设计、切块粒度选择,到拒答节点控制和 Trace 记录,每个环节都是你亲自写代码、调试、踩坑出来的。面试时聊起这个项目,不管面试官追问哪个细节,你都能顺着实现逻辑和测试数据讲明白。
整个系统涵盖的模块非常完整:在权限控制上,接了飞书 OAuth,把用户身份、角色和知识库权限绑在一起,在检索阶段就拦截越权访问;在知识处理上,实现了飞书 Wiki 的递归读取、解析、语义切块、向量索引以及同步任务;在问答链路上,走通了 Query 改写、混合检索、Rerank、引用生成和拒答判断,并且用 Golden Set 评估指标来验证优化效果。工程化方面,Webhook 去重、失败重试、任务持久化、Trace 回放和诊断导出这些保障系统稳定性的模块也都做了,前端也是用 React 和 Vite 从零搭出来的问答页和后台管理系统。
做完这个项目,你对 AI 系统的视角会彻底改变。不再只看“它能不能答出这个问题”,而是会习惯性地考虑回答的可追溯性、系统的边界在哪、出了故障怎么排查。这门课适合有 Python 和基础后端经验、想把 AI Agent 完整落地一次的人,过程需要耐下心来面对真实的输出和报错,愿意刨根问底的人收获会最大。
夜雨聆风