知识库(Wiki)
Spark Work AI-Native 知识库(Wiki)完整指南:空间 / 页面 / 双链 / 版本四件套的领域模型与落库表,统一写入原语(expectedVersion CAS 乐观锁 + 正文原子落盘 + FTS 同事务 + 失败回滚),12 个 mcp__spark_wiki__ 工具的只读与审批分组,零预注入下的四层上下文预算(常驻 800 / search top 8 / read 3000 token 每页 / 单轮总闸 8000,均带服务端硬上限),对话沉淀管道的三条人审入口与水位线,抽取的三条硬约束(无来源不入库、不猜内容、敏感内容前置拦截),候选区人工确认晋级,技能提议闭环与 Repo Wiki 扫描重建,五个设置分组逐项说明,以及知识库与长期记忆的分工边界。附速查表、8 条常见问题与 10 行排查表。
知识库(Wiki)是 Spark Work 里「沉淀成篇知识」的那一层:把对话里验证过的结论、项目里的约定、踩过的坑,写成可检索、可双链、可回看版本的页面,再由 Agent 在需要的时候按需取用。
它和长期记忆是两套互补机制,先记住这条分工,后面所有细节都是它的推论:
| 维度 | 长期记忆 | 知识库 Wiki |
|---|---|---|
| 进上下文的方式 | 每轮自动注入摘要 | 零预注入,要 Agent 主动检索才会进来 |
| 粒度 | 一条事实 / 一条守则 | 一篇成体系的知识页 |
| 谁能写 | 后台自动抽取 + 人工面板 | 人工直接编辑 + Agent 走审批写 |
| 典型内容 | 偏好、项目决策、行为守则 | 方案、教程、踩坑记录、仓库结构说明 |
一句话:记忆是「它记得你」,知识库是「它读得懂你的资料」。
1. 它由什么组成
五个核心概念,加上两个「草案态」的容器:
| 概念 | 说明 | 落库表 |
|---|---|---|
| 空间 Space | 知识的隔离边界,按 scope 分三类(见第 2 节) | wiki_space |
| 页面 Page | 一篇知识,带类型、树结构、置顶、归档与版本号 | wiki_page |
| 双链 Link | 页面之间的引用关系,支持正向出链与反向链接查询 | wiki_link |
| 版本 Revision | 每次写入留下的正文快照,可回看历史 | wiki_revision |
| 全文索引 | contentless FTS5 表,中文逐字预分词 | wiki_fts |
| 候选区 Candidate | 从对话抽取出来、还没被人工确认的知识草案 | wiki_candidate |
| 技能提议 Proposal | 从知识页生成、还没被人工确认的 SKILL.md 草案 | wiki_skill_proposal |
候选与提议都只是草案容器:没有人工确认,什么都进不了正式知识页,也装不成技能。 这是整条链路最重要的设计约束。
另一条容易被忽略的边界:检索通道只有 wiki_fts 全文索引一条(contentless FTS5 + 中文逐字预分词),本质是关键词匹配,首期不含向量语义召回——「搜『组件写法』要召回『偏好函数式组件』」这类需求暂时做不到。
2. 空间:这份知识谁能看到
scope 有三个取值,和记忆系统同构,但正文落盘位置不同(记忆只看 user / project / agent,知识库多留了一个 team 枚举值,当前未启用):
| scope | 可见范围 | 正文落盘位置 |
|---|---|---|
project | 仅该工作区;跟随代码目录 | 工作区仓库内(随仓库一起走) |
user | 跨项目共享 | ~/.spark-agent 下 |
agent | 仅该 Agent 角色 | ~/.spark-agent 下 |
team | 预留枚举值,当前未启用 | — |
project 空间的正文落在仓库里,这一点和记忆一致:知识跟着代码走,换一台机器克隆下来就能读到。候选确认时会按目标空间重建服务栈,保证 project 空间的正文真的写进仓库目录,而不是错落到用户目录。
3. 页面:类型、树、置顶与归档
页面有五种类型(写入时可选,树里用不同色点区分):
| 类型 | 界面标签 | 适合放什么 |
|---|---|---|
knowledge | 知识 | 结论性的、结构化的知识 |
experience | 经验 | 踩坑记录、排查过程 |
pattern | 模式 | 可复用的做法与范式 |
reference | 参考 | 外部资料线索、接口速查 |
note | 随笔 | 还没成型的碎片 |
页面的组织能力:
- 层级树:页面可挂在父页面下,目录树用 1px 引导线呈现层级;支持拖动改父级。
- 排序:手动排序 / 按标题 / 最近更新三种;置顶段恒在最前,段内按所选方式排,选择会记住。
- 置顶:常用页固定在树顶,不参与普通排序。
- 归档:归档后退出默认列表,可随时取消归档复原;归档不是删除。
- 版本号:每次写入递增,配合
expectedVersion做乐观锁(见第 5 节)。
4. 双链与版本
- 双链:正文里写
[[页面名]]建立引用;正向出链随页面保存,反向链接(谁引用了我)由wiki_backlinks实时查询。这让你能从「这个方案提到了哪几个模块」和「这个模块被哪些方案引用过」两个方向翻知识。 - 版本快照:每次正文写入都留一份 revision,页面详情里可打开「版本历史」回看并在需要时回滚。版本是正文级快照,不是整页 diff。
5. 写入原语:为什么知识库不怕写坏
所有写入(人工编辑、Agent 写入、候选确认、技能提议落地)都收敛到同一套写入原语,渲染端不允许自己拼装存储语义:
- 先正文后数据库:正文先写临时文件再
rename原子落盘,避免出现半截文件。 expectedVersionCAS 乐观锁:提交时带上读取到的版本号,如果中途被别人改过,写入被拒并提示刷新,不会静默覆盖。- FTS 同事务维护:全文索引和主表在同一个事务里更新,不会出现「页面写了但搜不到」。
- 失败回滚:数据库事务失败时回滚已落盘的正文,并回传结构化的失败原因(而不是抛一个没人处理的异常)。
- 回执带
indexReady:写操作的回执显式告诉调用方索引是否就绪,便于上层判断。
6. 零预注入与四层上下文预算
知识库从不预注入上下文。Agent 看到的只有一小段能力声明和工具 schema,正文要它自己检索、自己读。为了不让一次检索把上下文吃满,读取路径上有四道闸门:
| 层 | 约束对象 | 默认 | 服务端硬上限 |
|---|---|---|---|
| L0 常驻 | 能力声明 + 工具 schema | 常驻 ≤ 800 token 告警 | 4000 |
| L1 检索 | wiki_search 返回条数与摘要字数 | top 8 / 摘要 240 字 | top 20 / 1000 字 |
| L2 正文 | wiki_read 单页正文 | 3000 token / 页 | 8000 |
| L3 单轮总闸 | 同一轮内所有 wiki 工具注入之和 | 8000 token | 20000 |
三条实际行为值得记住:
- 超出 L2 不是截断不告知:返回里带
truncated与nextOffset,模型按需续读,而不是被静默切碎。 - 超出 L3 是拒绝继续读:并提示先总结,防止一个会话被知识库持续吃满。
- 越界是拒绝写入而不是静默钳制:设置里能调,但调不出服务端硬上限;越界直接报错,避免你以为调大了其实没生效。
另外还有一项「工具瘦身」(budget/helpDisclosure,默认关):开启后只在常驻里留核心五件套,低频工具收进 wiki_admin 二级入口,实测常驻从 1086 token 降到约 780。
7. Agent 工具面:12 个工具
mcp__spark_wiki__ 命名空间下共 12 个工具,按「要不要审批」分成三组:
| 组 | 工具 | 是否走审批 |
|---|---|---|
| 只读(5) | wiki_list_spaces、wiki_search、wiki_read、wiki_list、wiki_backlinks | 免审批,进白名单 |
| 写入(6) | wiki_write、wiki_update、wiki_archive、wiki_delete、wiki_restore、wiki_link | 走 canUseTool 审批 |
| 技能提议(1) | wiki_propose_skill | 产出草案,仍需人工确认 |
取用顺序是写进提示词的行为契约:wiki_list_spaces 知道有哪些空间 → wiki_search 拿 id 与摘要 → 只在确需全文时 wiki_read(id);禁止凭标题臆测内容,不要一次读多页,读完即总结。
两条引擎路径都挂同一组工具,语义完全一致:Claude SDK 路径走进程内 MCP server(直接访问本地数据库,没有子进程);Codex CLI / Claude CLI 路径走 spark_wiki stdio 子进程,经本地 Platform Bridge 回主进程。
8. 对话沉淀:从会话到知识页
对话沉淀是「把聊出来的东西变成资产」的管道:
触发入口只有三条,且都保留人审:
| 入口 | 设置项 | 默认 | 说明 |
|---|---|---|---|
| 显式沉淀 | extract/manual | 开 | 你主动发起的一次沉淀 |
| 里程碑收尾 | extract/milestone | 开 | 任务收尾时的一次沉淀 |
| 空闲触发 | extract/idle | 关 | 空闲 N 分钟后自动跑 |
| 定时触发 | extract/schedule | 关 | 按固定间隔自动跑 |
extract/enabled 是后台自动触发的总闸,它只管 idle 与 schedule 两条自动路径——关掉它,显式沉淀与里程碑收尾仍然可用(这条语义曾经被实现错过一次,现在是对齐的)。
管道内部有三条硬约束,方向都是「宁可少抽,不可抽错」:
- 无来源不入库:每条候选必须标注来自哪一轮对话(
turnIndex)与依据片段(excerpt);轮次号不在本次采样集合里的条目整条作废,不允许凭空捏造的知识。 - 不猜内容:解析失败、字段缺失、类型不符一律作废该条,绝不启发式补全。
- 敏感内容前置拦截:疑似凭据形态的正文在解析阶段就丢弃,不进候选区。
抽取产物的字段也有上限,防止一次刷屏:单次最多 8 条候选;标题 ≤ 80 字、摘要 ≤ 240 字、正文 ≤ 4000 字、依据片段 ≤ 300 字、标签 ≤ 6 个。
水位线防重复抽取:抽取状态记在 wiki_extraction_state 里,只处理上一轮之后的新对话;失败会记下原因,界面上能解释「上次为什么没抽出东西」。
候选区是人工门:默认保留 14 天、上限 200 条。每条候选展示目标空间、轮次与依据片段,你可以确认晋级成正式页面,也可以拒绝。确认时会按目标空间重建服务栈,保证正文落对位置。
9. 技能提议:知识页 → 技能草案
一条已经确认的知识页,可以就地转成技能草案:生成 SKILL.md(做什么、怎么用)与 PURPOSE.md(为什么需要它),并回写来源页便于追溯。
草案会挂在「技能提议」视图里等你确认——确认后才落盘安装进技能库,拒绝可以填原因并回填到来源页。未确认的提议不会出现在技能列表里。
10. Repo Wiki:把仓库本身变成知识
Repo Wiki 是独立 Tab:扫描本地仓库,生成「总览 / 目录 / 技术栈」三件套的结构化知识页,让 Agent 第一次进项目就有地图。
| 设置项 | 默认 | 说明 |
|---|---|---|
repo/enabled | 开 | 关闭后 Repo Wiki Tab 隐藏 |
repo/mode | manual | 扫描重建的触发方式 |
repo/ignoreGlobs | node_modules、dist、build、out、.git | 扫描时跳过的目录 |
repo/staleCommits | 20 | 距页面生成后又累积多少个提交算「过期」 |
两个保护机制:
- 漂移检测:对照 git 提交数判断页面是否过期,过期可一键重建。
- 所有权三态:页面分「可重建」「人工接管」「已忽略」。人工接管过的页面不会被重建覆盖,重建只处理仍标记为「可重建」的页面。
11. 设置项
入口:知识库视图左栏底部的「知识库设置」,或设置页的知识库分组。所有键都在 category = wiki 下,分五组:
| 分组 | 关键项 | 默认 |
|---|---|---|
| 上下文预算 | budget/helpDisclosure(工具瘦身)、budget/readMaxTokens、budget/turnTotal、budget/searchLimit、budget/summaryChars、budget/residentLimit、budget/noiseWarnPct | 关 / 3000 / 8000 / 8 / 240 / 800 / 40% |
| 沉淀与抽取 | extract/enabled、extract/manual、extract/milestone、extract/idle、extract/idleMinutes、extract/schedule、extract/scheduleIntervalMinutes、extract/modelProfile、extract/redact、candidate/ttlDays、candidate/maxPending | 关 / 开 / 开 / 关 / 30 / 关 / 360 / 空 / 开 / 14 / 200 |
| 空间与存储 | space/autoCreate、store/exportIndex、store/bodyLocation | 开 / 开 / 默认 |
| Repo Wiki | repo/enabled、repo/mode、repo/ignoreGlobs、repo/staleCommits | 开 / manual / 见上 / 20 |
| 界面偏好 | ui/defaultView、ui/candidateBadge、ui/pinNav | list / 开 / 关 |
数字型设置的服务端硬上限见第 6 节。
12. 界面:在哪里操作
| 位置 | 能做什么 |
|---|---|
| 顶部 Tab | 「知识库」与「Repo Wiki」切换(repo/enabled 关闭时 Repo Wiki 隐藏) |
| 左栏 252px | 空间切换器 → 过滤框(⌘K)→ 层级树;底部固定「归档 · 候选区 · 技能提议 · 知识库设置」 |
| 主区顶栏 46px | 面包屑 + 检索框 + 版本历史 + 更多操作 |
| 主区内容 | 阅读态(页面正文)/ 空态 / 检索结果 / 候选区 / 技能提议区 / Repo Wiki 面板 |
| 右侧 | 页面编辑与版本历史(打开页面后) |
速查表
| 项目 | 内容 |
|---|---|
| 工具命名空间 | mcp__spark_wiki__,共 12 个工具(5 只读 + 6 写入 + 1 技能提议) |
| 只读工具 | wiki_list_spaces / wiki_search / wiki_read / wiki_list / wiki_backlinks |
| 写入工具 | wiki_write / wiki_update / wiki_archive / wiki_delete / wiki_restore / wiki_link |
| 工具瘦身后常驻 | 5 件套 + wiki_admin 二级入口;实测常驻 1086 → 约 780 token |
| 页面类型 | knowledge / experience / pattern / reference / note |
| 空间 scope | project(落仓库)/ user / agent(落 ~/.spark-agent)/ team(预留未启用) |
| 正文存储 | markdown 文件为事实源,先 .tmp 后 rename |
| 索引与元数据 | wiki_space / wiki_page / wiki_link / wiki_revision / wiki_fts(contentless,CJK 预分词) |
| 写入保护 | expectedVersion CAS + 失败回滚 + FTS 同事务 + 回执带 indexReady |
| 上下文预算 | 常驻 ≤ 800(L0)、search top 8、read 3000 token/页、单轮 8000 token;硬上限 4000 / 20 / 8000 / 20000 |
| 沉淀入口 | 显式沉淀与里程碑收尾(默认开)、空闲与定时(默认关,受 extract/enabled 总闸管辖) |
| 抽取硬约束 | 无来源不入库(turnIndex 必须在采样集合内)· 不猜内容 · 敏感内容前置拦截 |
| 候选与抽取上限 | 候选区保留 14 天 / 上限 200 条;单次抽取最多 8 条,标题 ≤ 80 字、摘要 ≤ 240 字、正文 ≤ 4000 字 |
常见问题
知识库和长期记忆到底该用哪个?
按「是否每轮都要知道」分。几乎每轮都该遵守的(偏好、守则、项目决策)放记忆,它每轮自动注入;要用的时候才去查的(方案、教程、踩坑记录、仓库结构)放知识库,它零预注入、按需检索。两套并存不冲突。
知识库里的东西会被别的项目看到吗?
取决于空间:project 只在该工作区可见(正文落在仓库目录里,随代码走),user 跨项目共享,agent 按角色隔离,三者互不可见。
Agent 会不会自己往知识库里写东西?
会写,但写不出「正式知识」。它有六个写入工具,每一个都走审批;自动沉淀出的内容只进候选区,必须人工确认才晋级成页面。技能提议同理,未确认不会落盘。
为什么知识库内容不会把我的上下文撑爆?
因为零预注入加服务端强制裁剪:常驻只有能力声明与工具 schema(开工具瘦身可压到约 780 token),检索只回摘要、正文分页读取,同一轮还有总闸。这些都是服务端行为,不依赖模型自觉。
搜索为什么有时只命中关键词、不能语义召回?
检索只有 FTS5 全文一条通道,没有向量通道,所以本质是关键词匹配。
排查表
| 现象 | 排查方向 |
|---|---|
| Agent 说找不到知识库 | 确认会话所在引擎是否挂上了 mcp__spark_wiki__ 工具;开启工具瘦身后部分工具收进 wiki_admin,需要二级调用 |
| 搜不到明明存在的页面 | 全文检索是关键词匹配,先换个更贴近正文的短词;再确认页面没有被归档 |
| 抽取一直不产出候选 | 检查是否只用了纯执行型回合(需要助手产生文本内容);确认显式沉淀/里程碑入口被触发;看 wiki_extraction_state 里的失败原因 |
| 候选确认失败 | project 空间的候选需要目标工作区可写;确认仓库目录权限正常 |
| 正文写不进仓库 | project 空间正文落在工作区仓库内,检查该目录是否只读或已被外部程序占用 |
| 常驻 token 超阈值告警 | 打开「工具瘦身」,或降低常驻预算告警阈值以下的工具集 |
| 读取被拒绝并提示先总结 | 触发了单轮总闸(默认 8000 token),先让 Agent 总结已读内容再继续 |
| Repo Wiki 页面一直显示过期 | 距上次生成后又累积提交数超过 repo/staleCommits,一键重建或调整该阈值 |
| 重建后人工内容不见了 | 该页面没有被标为「人工接管」;先接管再重建 |
| 改了设置好像没生效 | 数字型设置越界会被拒绝写入而不是被钳制,检查是否收到越界报错 |