周四上午十点,老李的座机响了。电话那头是销售总监老孙,语气里压着怒火。
“你们那个智能客服怎么回事?星光科技的张总刚打电话来骂人——他们还在用我们去年采购的那套 API v2,照着咱们 AI 给的‘最新配置参数’改了自己的系统,结果全线报错。人家合同里写明了用 v2 接口,你们 AI 给的却是 v3 的参数!”
老李握着保温杯的手一紧:“不可能啊,产品手册是最新的……”
“最新的就对吗?客户用的是旧版本!你拿新版本的菜谱教人家做旧版本的菜,能不出事?”
挂了电话,老李把小王叫到工位前,把经过一说。小王沉默了片刻,然后叹了口气。
“老李,你是不是又把产品手册直接覆盖更新了?”
“对啊,v2 升 v3,旧文档留着干嘛?容易混淆。”老李理直气壮。
“问题就在这儿。你以为‘latest’是一个版本号,但其实它掩盖了一个事实——知识是活的,不同的人需要在不同的时间点获取对应版本的知识。你把 v2 的文档覆盖了,就等于把去年签的那批客户扔进了信息黑洞。”
老李不服:“不就是覆盖了个文件吗?我们以前写代码,改完直接替换,哪那么多讲究?”
小王忍不住笑了:“老李你想啊,你家祖传的菜谱,你妈把鱼香肉丝的配方改良了,把旧菜谱扔了。结果你二姨来串门,说‘我就喜欢老配方那个味儿’,你怎么办?你说‘对不起二姨,被覆盖了,没法做了’?”
知识也有“保质期”
“知识跟牛奶一样,有保质期。”小王在玻璃上画了一条时间轴,“API v2 在 2023 年 3 月发布,2024 年 11 月被 v3 取代。但在 2023 年 3 月到 2024 年 11 月之间签的客户,他们的合同里写的都是 v2。对他们来说,v2 的文档才是‘正确’的知识——即便它已经‘过期’了。”
“知识库必须能回答‘2023 年 8 月的 API 鉴权方式是什么’这种带时间维度的问题。如果你把旧版本删了,就等于把过去的事实抹掉了。AI 只能拿最新的文档去套,自然牛头不对马嘴。”
老李若有所思:“那我们公司有些政策也是分时间段的,比如 2023 年的年假政策和 2024 年的不一样。”
“对!这种‘时间敏感的真理’——技术规范、法律法规、公司制度——全都有保质期。你不能用今天的规矩去判昨天的案子。”
Git 不止管代码,也能管知识
“那怎么管?”老李抱起胳膊,“总不能每次更新都手工备份一份,那不成档案室了?”
“Git。”小王敲了敲桌子,“代码怎么管,知识就怎么管。”
“Git 管的是代码,我们那些 Word 和 Markdown 文档也能用?”
“太能了。Git 天然就是为版本管理设计的。你看——”小王打开终端,敲了几行命令。
# 初始化知识库版本仓库
cd company-knowledge-base
git init
# 创建 v2 版本的 API 文档
echo "# API v2 鉴权方式" > api-auth.md
git add api-auth.md
git commit -m "feat: API v2 鉴权文档,2023年3月发布"
git tag "api/v2.0" # 打标签,方便以后快速定位
# 后来升级到 v3,不覆盖,而是新增一个版本
git checkout -b api-v3
echo "# API v3 鉴权方式(2024年11月起)" > api-auth.md
git add api-auth.md
git commit -m "feat: API 鉴权方式升级到 v3,注意与 v2 不兼容"
git tag "api/v3.0"
# 客户问 v2 的问题时,可以随时切回旧版本
git show api/v2.0:api-auth.md # 精确取出 v2 的文档内容“看到没有?每一次更新都是一次 commit,重要的版本打上 tag。旧版本不会被覆盖,它们安静地躺在仓库里。什么时候需要,用 tag 一秒找回。”
老李盯着命令行,眼睛渐渐亮了:“这不就是把我们代码仓库那套搬过来了嘛!”
“本来就是。你的代码不会因为重构了就把旧分支删掉,知识也一样。”
图:知识版本像代码分支一样演进,每个重要节点打上 tag
老李的“那用户怎么知道查哪个版本”
“逻辑我懂了,”老李追问,“但用户提问的时候,他不知道自己该用哪个版本啊?他只会说‘我的 API 鉴权怎么配’。”
“这就需要在 RAG 检索的时候,给知识库加一个时间过滤器。”小王调出一段示意代码:
# 根据用户合同中的版本号,检索对应版本的知识
def search_with_version(question, user_contract_version):
# 1. 解析用户应该使用哪个知识版本
target_tag = f"api/{user_contract_version}" # e.g., "api/v2.0"
# 2. 从 Git 仓库中检出对应版本的文档
docs = git_checkout_docs(tag=target_tag, path="api-auth.md")
# 3. 在指定版本的文档中进行语义检索
results = vector_search(question, docs)
return results
# 例如:星光科技的合同约定使用 v2,自动检索 v2 文档
answer = search_with_version("API 鉴权怎么配置", user_contract_version="v2.0")“如果用户没指定版本呢?”老李问。
“默认用最新版本,但在回答中明确标注‘本回答基于 API v3.0,如果您使用其他版本,请说明’。把选择权交给用户。”
变更通知与回滚:当新知识翻了车
“还有一个场景,”小王补充道,“你刚发布了 v3 文档,结果发现里面有个严重错误——比如把端口号写错了。如果只有 latest,用户已经看到错误信息了,你连补救的机会都没有。”
“但有了版本管理,”他在白板上画了一个回滚箭头,“你可以快速把‘当前版本’指回上一个 tag,然后从容修复。用户看到的始终是经过验证的稳定版本。就像你部署代码,发现线上炸了,第一件事是回滚到上一个稳定 commit,而不是在线 hotfix。”
# 知识回滚:如果 v3.0 文档有严重错误
git tag -d stable # 移除旧的 stable 指针
git tag stable api/v2.0 # 将 stable 指回 v2.0
# 通知下游 RAG 系统知识版本已变更
curl -X POST https://rag.internal/notify \
-d '{"knowledge": "api-auth", "version": "v2.0", "action": "rollback"}'“而且每次版本变更,都可以发一个通知给下游的 RAG 索引服务,让它重新向量化新版本的文档,同时让旧版本的向量过期——但不是删除,而是加上‘适用于 2023-03 至 2024-10’的时间标记。这样检索时就能自动过滤。”
老李沉默了好一会儿。他拧开保温杯,枸杞的香气漫了出来,但他没喝。
“那……我们现在的知识库,是不是所有文档都是裸奔的 latest?”
“大部分是。”小王诚实地点头。
“你给我全量迁到 Git 仓库,”老李把保温杯顿在桌上,“所有面向客户的 API 文档、合同条款、合规政策,必须打 tag。旧版本一个都不许丢。”
他站起来走到门口,又转过身,表情别扭得像在努力咽下一颗酸葡萄。
“那什么……你刚才说的时间标记,如果用户问‘2023 年 6 月的年假政策’,系统怎么自动匹配到那个时间段的知识版本?是靠 tag 名还是文档里的元数据?你给我展开讲讲。”
小王笑了。老李的保温杯还在桌上,枸杞沉沉浮浮,而那些曾经被粗暴覆盖的旧文档,终于在 Git 的仓库里找到了各自安稳的角落——每一个版本都被记住,每一段历史都能被精确地回访。

