AI 智能体的知识库一定要上向量数据库吗?一个近千万字 SQLite 库的治理实战

AI 工作日志 作者头像野生码农 阅读 10 min
返回板块 GEO 源码全文 ✓
AI 智能体的知识库一定要上向量数据库吗?一个近千万字 SQLite 库的治理实战

AI 智能体的知识库一定要上向量数据库吗?一个近千万字 SQLite 库的治理实战

起因:一次聊天捅破了四层窗户纸

10 月 11 号晚上,我和军师(我的 AI 总架构师,基于 Kimi Code)本来只是闲聊。聊着聊着,话题收敛到一个判断:配置体系、知识库、记忆体系,表面是三件事,实际上是同一件事——AI 的记忆问题。

当时我们的家底是这样的【实测 2026-10-11】:

指标 数值
条目数 1795 条
总字数 近 995 万字
库文件 87.9 MB
检索引擎 SQLite FTS5(trigram 分词)
向量检索 没有

1795 条文档量级,FTS5 全文检索毫秒级返回,离 SQLite 的极限差着两个数量级。所以"要不要上向量库"这个问题,我们前后讨论了三遍,结论都是维持原状。理由不是省钱,是一个更底层的判断:

战略层的知识,根本不需要大数据库。

一个董事长做一个值钱的决策,依据的不是海量语料,是几张纸。一个人一辈子沉淀下来的经典判断,数据量大不到哪去。大企业老板案头的战略决策文件,就是几个小文档。我自己这套系统就是实证:全部战略级内容 = 一页态势纸(64 行)+ 一份章程(127 行),就这么多。

真正大的、会膨胀的是工具文献类的固有知识——那类东西的作用是"查询",要求是信息精准、检索准确,而不是语义联想。所以我们的路线是:分级分类存储,分场景调用,而不是堆一个更大的库。

但"不上向量库"不等于"没问题"。这一晚连查出四个真问题。

问题一:治理字段建了没人填,0/1784

entries 表早就预留了五个治理字段——document_class(文档分类)、confidence(可信度)、valid_until(有效期)、source_url(来源)、fetched_at(采集时间)。我打开 Navicat 一看,填充数:

document_class 已填: 0 / 1784
confidence     已填: 0 / 1784
valid_until    已填: 0 / 1784
source_url     已填: 0 / 1784
fetched_at     已填: 0 / 1784

根因很快查到:索引器 sync() 只从 front matter 里取 title/category/tags,根本没读这五个字段。字段是死字段,闸门从来没运转过。

修法不是"提醒大家记得填",是机器闸——不填就不许入库:

def ingest_gate_check(path: str, meta: dict) -> str | None:
    """入库闸门:返回拒收原因,放行返回 None。"""
    dclass = str(meta.get("document_class") or "").strip()
    vu = str(meta.get("valid_until") or "").strip()
    if dclass and dclass not in VALID_DOCUMENT_CLASSES:
        return f"document_class 非法值 {dclass!r}(可选: decision/canon/timely)"
    if dclass == "timely" and not vu:
        return "timely 条目必须填 valid_until(YYYY-MM-DD)"
    if path.startswith(CANON_DIR_PREFIX) and dclass != "canon":
        return "常识库分区条目必须标 document_class: canon"
    return None

分类只设三档,多了没人记得住:

document_class 内容 valid_until
decision 战略决策、裁定(常青) 不填
canon 常识经典、基础概念(常青) 不填
timely 会过时的时效信息 必填

上闸当天实测:故意丢进去三个违规文件(缺分类、timely 缺有效期、分类拼错),三条全部被拒收、原因逐条正确;合规文件正常入库。闸门不是写在文档里的,是跑在代码里的。

问题二:聊出来的共识,根本没进库

这是我个人觉得最典型的一个坑。10 月 9 号我们开会定过一条规矩:任务卡发出前,AI 必须先复述三行——干什么、验收标准、动哪些文件——我过目了才发。当场拍板"从建议升级为硬闸"。

10 月 11 号我抽查:开发团队的章程文件里 grep "复述/三行",零命中。这条闸只活在会议记录里,而执行干活的 AI 实例读的是章程文件——对它来说,这条规矩从来没存在过。

这暴露的是入库时机问题。定下来的触发器:

  1. 共识达成——聊天中确认"以后就这么干",当场落成规则文档入索引;
  2. 拍板/冻结——态势纸一行状态 + 台账详情 + kb 可检索,三处落点缺一不可;
  3. 外部采集——入库时当场填齐治理字段,填不齐不入库。

一句话:只活在会话里的共识,等于没共识。

问题三:新鲜度治理,90 天一刀切被我自己否了

第一版方案里,时效类条目有效期默认 90 天。我当场把这个设计否了——不同内容衰减速度根本不一样:模型价格 30 天就过期,Python 语法十年不变,项目计划不按日期过期而是被新决定取代。

更关键的是维护成本:定时批量给 1800 条存量做回源核验,90% 的条目一年没人查一次,为它们做核验是纯浪费。

改成触发式核验:谁检索命中,谁看这条的采集时间和有效期;可疑才回源核验;验完必须回填——有效就刷新有效期,失效就作废。作废操作很轻:把 front matter 里 valid_until 改成过去日期,检索结果立刻标 [已过期]。

定时任务只保留零成本的曝光:kb stats 报过期条数,SQL 查询,不占任何模型调用。

问题四:Navicat 三连抓包——时间字段的教训

我直接用 Navicat 连上库文件抽查(SQLite 是文件库,没有账号密码,直连 .db 文件),连抓三个:

① 日期格式不统一。 1775 条是 2026-10-11,混着 20 条早期导入的紧凑格式 20260424。

② created_at 只写不更新。 sync 的 UPDATE 语句漏了 created_at——就算把源文件改了,库里也不跟着改。"文件即真相源"的原则破了个洞。

③ 时间精度只有天。 我干了三十多年开发,不能接受这个。同一天上午下午晚上三轮修改,天粒度连先后顺序都排不出来;出了问题要排查,没有时间线怎么查?

军师的回应是当晚全部修掉:

  • 时间精度升到秒级 ISO(2026-10-11T22:04:28);
  • 时间来源有优先级:front matter 带时分就采用;只有日期就拼接文件系统真实时刻(创建时间/修改时间——文件不会撒谎);文件日期与 front matter 日期对不上时,整条信文件;
  • 存量 1795 条全部回填,非标格式清零;
  • 回归测试 13 个用例全过。

还有个小插曲:查询日志它第一版写成了 jsonl 文件,我问了一句"都上数据库了为什么还用文件记日志",改成了库里的 query_log 表。遥测数据的消费者是库内查询,就该进库——顺手用文件是肌肉记忆,不是设计。

记忆隔离的真相:不是更大的上下文,是分级按需调用

很多人做 Agent 记忆,第一反应是把更多东西塞进上下文。我们的做法相反——记忆隔离靠的是分类检索,按需调用:

层 载体 加载方式 上下文占用
L0 章程层 AGENTS.md 每会话自动注入 恒占,<200 行硬预算
L1 岗位层 岗位 agent.md + 技能 岗位激活时加载 按需
L2 文档层 docs/(SOP/台账/登记册) L0 一行指针,按需读 按需
L3 检索层 kb.db(FTS5) 查询制,不自动加载 零
L4 冷归档 _archive 不检索不加载 零

战略层住 L0/L2,就那一屏纸;知识层住 L3,查的时候才进门;垃圾住 L4,永不见面。每个 Agent 实例只看到它岗位该看的,这就是隔离——不需要向量相似度,需要的是分类纪律。

配套的配置治理也一样:配置文件分 P0/P1/P2 三级管控,登记册在册 146 件;AI 写配置的三大毛病(记流水账、滥用绝对禁词、小毛病就加枷锁)用 lint 脚本机器闸卡死,违规不落盘。此前一轮治理把 108 条负向禁令改写成正面模板——禁令只留给有故障台账证据的红线,其余一律写"应该怎么做"。

调用侧也补了埋点:每次检索落 query_log 表(时间/查询词/命中数),一个月后"哪些场景在查、哪些词查不到"用数据说话,不靠感觉。

可抄走的清单

  1. 先审计再建设:打开你的库,跑一句 SELECT COUNT(*) FROM entries WHERE document_class IS NULL,治理字段零填充的,先修索引器再谈别的;
  2. 入库闸门代码化:非法分类、缺有效期的文件,拒收比提醒管用一万倍;
  3. 共识三处落点:章程一行 + 台账详情 + 可检索库,只活在会话里的共识等于没共识;
  4. 新鲜度触发式核验:谁用谁验、验完回填,定时只曝光不普查;
  5. 时间用秒级 ISO,来源优先级:front matter > 文件系统时刻;
  6. SQLite 文件库直连 Navicat 抽查——这是人对 AI 最便宜有效的审计通道,AI 报一百遍"已验证",不如自己进去看一眼。

收尾

这一晚的全部改动落在 7 个 git commit 里(21:55 到 22:51,不到一小时):入库闸门、触发式核验、调用埋点、时间精度升级、存量迁移。 pytest 从 9 个用例涨到 13 个,全绿。

回到标题的问题:AI 知识库一定要上向量库吗?我们的答案是——检索精度的问题用分类和闸门解决,语义联想的需求等常识库建起来再评估。sqlite-vec 混合检索方案在候排里躺着,但它的启动条件是"第一批常识条目入库",不是"感觉库大了"。

战略层几页纸,知识层按需查,垃圾层不见面。小而准,比大而全值钱。

素材点

  • 治理字段 0/1784 的审计命令(一句话查出"建了没人填");
  • ingest_gate_check 闸门函数全文(可直接抄);
  • 四级记忆表(L0-L4 与上下文占用对照);
  • "复述三行"硬闸零命中案例:会议裁定不落配置=没裁定;
  • Navicat 直连 SQLite 做 AI 审计的玩法;
  • 108 条禁令改正面模板的配置治理口径。
野生码农头像

关于作者 · 野生码农

把 AI 真放进生产环境的独立开发者。自研本地知识库、数字员工团队、软考备考系统、量化交易四套系统,全程公开复盘。

看他的平台账号 →
相关

继续阅读