关于 kcp-agent — KCP navigation planner
kcp-agent 是 Knowledge Context Protocol 的参考 Agent,根据任务和 knowledge.yaml 生成可检查的知识加载计划,并可据此回答。其规划过程无需 LLM,采用确定性规则并对访问限制 fail-closed。
主要功能
- 01按任务相关性规划知识单元
- 02按信任、时间和预算筛选
- 03生成可审计的加载计划
- 04可选调用 Claude 合成回答
- 05支持回答依据核验
适用场景
- 01在读取知识前检查加载计划
- 02按上下文窗口预算选择内容
- 03依据指定知识单元回答问题
- 04核验回答主张是否有依据
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
5收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| env | string | 否 | 用于联邦上下文选择的运行时环境(dev/test/staging/prod) |
| role | string | 否 | 用于受众定位的 Agent 角色(默认:agent) |
| task | string | 是 | 要为其规划知识加载的任务 |
| as_of | string | 否 | 用于时间评估的 ISO 日期(默认:今天,UTC) |
| attest | string | 否 | Agent 可提供的证明提供方,与清单的 trusted_providers 匹配 |
| budget | number | 否 | 按请求付费单元的支出上限 |
| follow | boolean | 否 | 跟随符合条件的联邦引用(默认 false) |
| strict | boolean | 否 | 失败时关闭:丢弃不符合条件的单元,而不是将其列出 |
| methods | array | 否 | Agent 可结算的支付方式,例如 ["free","x402"](默认仅 free) |
| currency | string | 否 | 预算货币(默认:USDC) |
| manifest | string | 是 | knowledge.yaml 的路径、目录或 HTTPS URL |
| max_depth | number | 否 | follow=true 时要跟进的联邦跳数(默认:1) |
| max_nodes | number | 否 | 遍历期间获取的清单总数上限(默认:64) |
| max_units | number | 否 | 选中单元的数量上限(默认:5) |
| credentials | array | 否 | Agent 持有的凭据类型,例如 ["mtls","api_key"] — 用于开放受访问控制的单元 |
| context_budget | number | 否 | 计划加载到调用方上下文窗口的 Token 上限;超出预算的单元将跳过,并附带计算过程 |
| allow_private_hosts | boolean | 否 | 允许获取 loopback、private、link-local 主机以及 http://;默认 false — 失败时拒绝 |
详细介绍
kcp-agent
🧾 看它运行 — 交互式 KCP playground · 阅读揭晓
Knowledge Context Protocol 的参考 Agent。
竞技场 → — 未经修改、完整打包的真实规划器, 在浏览器中实时运行,与常见竞品正面对决。世界上最具确定性的 Agent。每个决策都有据可依。
KCP 定义了知识如何声明自身,以便 Agent 能够浏览它。kcp-agent 是另一半:端到端使用 KCP 的 Agent。给定一项任务和一个 knowledge.yaml,它会生成一份可检查的加载计划——要加载哪些单元以及加载顺序、跳过哪些单元及具体原因、如何在联邦中选择子清单,以及整个过程的成本——然后还可选择仅依据这些单元回答任务。
其有价值且新颖的核心是无需大模型且具有确定性。该计划是一份行动前审计产物——将可信渲染原则(“清单可以影响 Agent 知道什么,但绝不能影响它做什么”)扩展到整个 Agent 循环。只有最后的综合步骤会调用模型。
discover → verify signature → trust-gate → score units by task → federate (context + agent_identity)
→ temporal filter → budget (payment + rate_limits) → emit load plan → [follow] → [answer]
安装
npm install
npm run build
原生可执行文件
CI 会交叉编译自包含二进制文件(目标环境无需 Node/Deno),适用于
Linux x64/arm64、macOS x64/arm64 和 Windows x64——可从某个版本发布页面或任意 CI 运行中的
kcp-agent-natives 构件获取。也可以自行构建:
npm ci && npm run build
deno compile --allow-read --allow-env --allow-net --node-modules-dir=auto \
--output kcp-agent dist/cli.js
使用
plan — 可检查的加载计划(无需 API 密钥)
node dist/cli.js plan "how do I deploy to production?" --manifest ./path/to/knowledge.yaml --env prod
Plan for: "how do I deploy to production?"
companyx-knowledge-hub v1.0.0 · kcp 0.24 · env prod
Trust: · no manifest attestation requirement
Load plan (2 units):
● 1. front-door (score 4) overview.md free
● 2. deploy-guide (score 3) docs/deploy.md free
Budget: tier default
Federation:
→ platform-engineering needs github_pat before fetch [acquire github_pat]
· platform-engineering-dev context ["dev","test"] excludes env 'prod'
Skipped (2):
· auth-guide: no task-relevance match
每个阶段都对应规范中的一个层面:查询评分(§15)、时间有效性(§4.22)、Agent
证明(§3.2)、联邦 context + agent_identity(§3.6),以及付费/速率限制
(§4.14/§4.15)。Agent 无法证明身份的受限单元会列出,但标记为不可加载——默认拒绝,并附上原因。
为上下文窗口分配预算。 向模型提供内容时,Token 才是真正稀缺的资源,因此使用
--context-budget <n> 指定上限——它与金额 --budget 的工作方式完全相同:
按分数贪心选择;如果某个单元会超出上限,就会跳过并在原因中列出计算过程(over context budget: 1,240 tokens would exceed remaining 800 of 4,000),而分数较低但更小的单元仍有机会入选。由于规划器会在获取内容之前处理元数据(行动前审计),单元大小取自声明的 size_tokens(准确)或 bytes/4
(标记为估算);既未声明任何一种大小的单元仍会纳入,但会计为未测量(投影值是下限)——除非启用了 --strict,此时会默认拒绝该单元。--context-budget
可与 --budget 结合使用:单元必须同时符合两个上限。
机器可读计划
当其他 Agent 或集成要使用计划时,请使用 --json。输出会在顶层保留计划字段,并添加:
{
"schemaVersion": 1,
"kind": "plan"
}
kind 为 plan、tree(使用 --follow 时)或 trace(使用 --trace 时)。人类可读输出不属于兼容性接口。成功的 JSON 命令以 0 退出;规划器或清单错误会将诊断信息写入 stderr,并以非零状态退出。
ask — 先规划,再通过 Claude 回答
export ANTHROPIC_API_KEY=... # or: ant auth login
node dist/cli.js ask "how does an agent get started here?" --manifest ./knowledge.yaml
ask 会运行相同的规划器,仅加载符合加载条件的单元,并让 Claude 根据这些单元作答——将单元内容视为知识,而非指令。需要 @anthropic-ai/sdk(可选依赖)和密钥;plan 两者都不需要。
ask --loop — 经审计的批判循环
node dist/cli.js ask "who won, and what does it mean for infrastructure?" \
--manifest ./knowledge.yaml --loop --methods free,x402 --budget 0.50
确定性评分器采用词汇匹配,因此,如果任务的措辞与发布者使用的词汇不同,就可能漏掉相关单元。--loop 可以弥补这一差距,同时不牺牲确定性——模型提出,计划决定:
plan → LLM gap critique (metadata only) → term gate → re-plan → … → load → answer
快速批判模型(默认为 claude-haiku-4-5,可通过 --loop-model 更改)会查看计划的元数据摘要——ID、意图、评分、跳过原因,绝不包含单元内容——并提出额外的小写搜索词。确定性关卡会对这些词进行清理、去重并限制数量;任务字符串随之扩展;规划器从头重新规划。当批判模型不再提出词语、某一轮没有新增单元,或达到 --max-rounds(默认为 3)时,循环收敛。随后,综合阶段会根据最终计划中的合格单元回答原始任务。
批判模型永远不能做的事:开放访问关卡、改变信任/时效/受众决策,或花费资金——搜索词只影响相关性评分;循环收敛前不会加载或付费获取任何内容,最终计划的预算计算也会像单轮模式一样严格控制支出。每一轮都会被记录(提出的词语、接受项、拒绝项、新增单元、完整的重新规划产物)——使用 --json 时,计划链就是审计日志。
同一循环也可用作库(runLoop / askLoop,支持注入批判模型),而 skills/kcp-navigator/SKILL.md 则将这一规范打包为可移植的技能,供自行驱动 CLI 的 Agent 使用。
ask --ground — 验证答案,揭示无法证实的内容
node dist/cli.js ask "who won, and what does it mean?" --manifest ./knowledge.yaml --ground
计划的默认拒绝关卡决定哪些内容可以加载;溯源验证将同样的规范扩展到哪些内容可以断言。综合生成后,答案中的每条主张都会由一个独立验证器检查——它会单独调用一个不同于生成器的模型——该验证器必须将主张归因于某个已加载单元,否则就返回空结果。最终产物分为两部分:
Grounded (2/3 claims):
● The award went to the Nordic bid.
↳ chipfab-exclusive · sha 9f2c1a0b7e34
Unsubstantiated (1): — could not be grounded in a loaded unit
○ The datacenter runs on hydro power.
no loaded unit supports this claim
⚠ partial-unsupported — 1 claim(s) could not be substantiated
只有在所引用的单元确实已加载且其内容哈希匹配时,主张才会获得溯源支持——因此,即使验证器错误归因(或受到提示词注入),引用了从未加载的单元,也无法让主张获得溯源支持:归因只是提议,溯源支持则需经过裁定。不受支持的主张会被揭示出来,而非悄然删除——这是“每项决策都经得起辩护”中诚实的那一面。每个揭示的缺口也是给发布者的信号:该任务需要清单未提供的证据。揭示的列表设有上限,以防受损的生成器用虚假缺口将其灌满。
--ground-rounds <n> 会形成闭环:揭示的缺口会生成改写词语,Agent 重新导航以尝试找到缺失的证据,然后再次进行溯源验证,最多进行 n 轮。三项彼此独立的限制保证循环终止,其中任一项都足以令其停止:词语关卡具有吸收性(一个词语一旦被接受,就会永久保留,因此重新导航只能从有限的合格集合中增加单元)、轮数上限,以及进展保护(某一轮没有新增单元时即停止)。循环不可能振荡——已加载集合只会单调增长,或循环停止。任何非 grounded 的终止状态(partial-unsupported、partial-budget、partial-rounds)仍会揭示剩余缺口。受损的验证器最多只能扩大合格集合内的导航范围——它永远无法越过关卡、指定 URL,或超出预算支出。
assess — 决定哪些内容可以付诸行动
计划中的各道关卡决定哪些内容可以加载;依据 grounding 决定哪些内容可以断言;
assess() 决定结论是否达到置信度阈值,从而可以付诸行动。
它在综合之后运行——置信度是输出的属性,这正是它在结构上不可能成为预选级联中的第 14 道关卡的原因。
import { assess } from "kcp-agent";
const verdict = await assess(task, answer, loadedUnits, {
threshold: 0.7, // org policy — caller-supplied, never manifest data
severity: "critical",
evaluator, // optional: makeProviderEvaluator(provider) — a separate judge
});
// { gate: "confidence", passed, score, threshold, signals[], detail, asOf }
信任立场与 grounding 相同:置信度是一种提议(答案自身通过 extractSelfReport 提供的
Confidence: 0.82 格式自我报告,和/或注入的评估器给出的判断);关卡以确定性方式裁决——
默认采用 min 聚合,对任何无法测量的内容均采取失败关闭策略。每个裁决都会原样保留原始
signals[],以便随着时间推移,依据实际结果校准阈值。裁决沿用各关卡的
二元结果加书面理由约定,但它是独立的下游产物——DecisionTrace 和
一致性测试向量均不受影响。
执行环节位于 kcp-harness:它的
harness_assess MCP 工具会运行此关卡,并通过审批工单将关键任务中未通过裁决的情况发送给
指定的人类,同时将裁决作为证据附上。
kind: skill — 受治理的程序,与知识分开设关
规范 §4.3a(v0.26.1)在普通知识之外新增了第二类单元:kind: skill 标记的是 Agent 可以
执行的内容——操作手册、脚本、程序等,而不只是可以阅读的内容。默认情况下,技能采用失败关闭策略:
除非清单中明确授予 load_eligible: true,否则 kind: skill 单元不具备调用资格;
其权限由 action_scope(可触及的 tools、paths、
capabilities)限定。该机制作为独立关卡 skill_eligibility 运行,并插入预选级联中的相关性关卡之后——
级联共有十四道关卡,而非十三道。
units:
- id: restart-web-service
kind: skill
load_eligible: true
action_scope:
tools: ["shell.exec"]
paths: ["/opt/web-service"]
capabilities: ["service.restart"]
未获授权的技能仍会纳入计划——Agent 可以看到它的存在,以及它为何与任务匹配,
遵循与其他所有关卡相同的先审计、后行动原则——但该技能会被暂缓加载(loadEligible: false),或者在 --strict 下被彻底移除;此时会具体归因于 skill_eligibility,
而非通用的严格模式截断。规划技能始终安全;调用技能则是另一项需明确授权的决策。请参阅下文的
受治理技能演示,以及
符合规范的实现指南,
了解移植实现必须复现的确切关卡约定。
演示 — 二十个场景,无模拟数据
node examples/demos.js # all twenty, narrated
node examples/demos.js --list # newsstand · transition · vault · org · audit · trace · loop · grounding · seal · incident · leash · summer · milky-way · moved-world · deja-vu · borrowed-memory · context-window · dogfood · second-opinion · governed-skill
node examples/demos.js vault # one at a time
| 演示 | 展示内容 | 规范 |
|---|---|---|
| 报刊亭 | 0.40 USDC 的上限:按评分购买,并在原因中列出计算过程以说明跳过的项 | §4.14 |
| 过渡期 | 同一个问题,三个 --as-of 日期;由取代关系决定重叠日 | §4.22 |
| 保险库 | 付款永远不会打开授权关卡——手持 x402,仍会失败关闭 | §4.11/§4.14 |
| 组织 | 联邦 context 按环境切片;agent_identity 会在获取前规划凭证 | §3.6 |
| 审计 | 对两个 --json 规划进行差异比较:能力开关具体移动了哪个关卡,以及其价格 | — |
| 循环 | 使用脚本化评论器的审计式批评循环:注入会被驳回,条款会重新规划,预算保持不变 | — |
| 依据 | ask --ground:引用未加载单元的主张会失败关闭;闭环会重新导航,并根据真实字节为其提供依据 | — |
| 03:00 警报 | 波及四个联邦参与方的零日漏洞——证明、签名 CERT、取代关系、作为强制关卡的 TLP:AMBER,以及情报预算(examples/incident/) | 全部 |
| 借来的牵引绳 | 脚本化的外部 MCP 客户端通过 stdio 重新规划事件——关卡相同、账本相同——随后由 kcp_replay 捕获其伪造的产物 | — |
| 封印 | 签名清单验证通过;签名后追加一个单元 → 规划前失败关闭 | §3.2 |
| 夏日计划 | 一家人跨越四个联邦参与方度假——签名枢纽、时刻表取代关系、身份关卡保护的无障碍登记表、x402 旅游详情,以及被 validate lint 捕获的 not_for 陷阱(examples/summer/) | §3.6/§4.11/§4.22 |
| 银河系 | 整个企业文档体系——覆盖八个领域的签名枢纽:按环境切片的开发镜像、日期已过的未来法规、仅供人类查阅的 HR 文档、经 HSM 证明的配方、设有身份关卡且采用订阅费率层级的 ERP 供应商,以及 CSRD 年度交接(examples/milky-way/) | §3.6/§4.14/§4.22 |
| 迁移的世界 | 情景记忆:记录答案时不保存字节,按任务重叠度召回,然后重放——只要固定版本仍有效,就仍有依据;源一旦移动,依据便立即漂移 | — |
| 似曾相识 | 经记忆验证的复用:针对未变更清单的相同输入,可证明规划相同;新增选项无法命中;清单发生漂移时则拒绝复用 | — |
| 借来的记忆 | MCP 会话去重:kcp_load 不会再次提供调用方已持有的字节(带 SHA 确认的存根),并会重新提供任何已发生漂移的单元 | — |
| 上下文窗口 | --context-budget:令牌上限,按评分贪心选择,超预算单元会连同计算过程一起跳过;大小取自声明的 size_tokens 或 bytes/4 | — |
| 自用测试 | Agent 验证并导航自己的仓库 | §2 |
| 第二意见 | 在低置信度结论被采取行动前,由 assess() 设置关卡 | — |
| 受治理的技能 | kind: skill 程序在获得明确的 action_scope 授权、具备调用资格前会失败关闭 | §4.3a |
每个演示所叙述的事实,都由正式发布的 CLI 和库的真实输出解析或计算得出——没有任何硬编码——而且 test/demos.test.ts 会在 CI 中运行全部二十个演示,因此叙述本身就是回归测试套件。所有内容均可离线运行;无需 API 密钥。
本仓库描述自身
本仓库以 KCP 测试自身:根目录下的 knowledge.yaml 声明 README、源模块、演示清单和 CI 工作流为知识单元,并联合到 KCP 规范自身的清单。因此,Agent 可以导航自己的仓库:
node dist/cli.js plan "how does the planner score units?" --manifest .
test/manifest.test.ts 确保清单内容可靠——可解析、指向现有文件,并能合理地进行规划。
选项
| 标志 | 含义 |
|---|---|
--manifest <loc> | knowledge.yaml 的路径、目录或 HTTPS URL(必填) |
--env <name> | 用于联邦 context 选择的运行时环境(dev/test/staging/prod)。默认拒绝:不提供时,永不跟随带有 context 标签的引用 |
--as-of <date> | 用于时间评估的 ISO 日期(默认:今天,UTC) |
--max-units <n> | 所选单元的数量上限(默认 5) |
--strict | 默认拒绝:丢弃不符合条件的单元,而不是列出它们 |
--role <role> | Agent 声明的受众角色(默认:agent) |
--methods <list> | Agent 可结算的支付方式,例如 free,x402 |
--credentials <list> | Agent 持有的凭据类型,例如 api_key,oauth2 |
--attest <provider> | Agent 可提供的证明提供方 |
--budget <amount> | 按请求付费单元的支出上限——按分数贪心选择,跳过会超出上限的单元(并显示计算过程)。整个联邦遍历共用一个上限,而非每个清单各自一个 |
--currency <code> | 预算货币(默认 USDC) |
--context-budget <n> | 计划加载到模型上下文窗口中的 Token 上限——按分数贪心选择,跳过会超出上限的单元(并显示计算过程)。可与 --budget 配合使用:单元必须同时符合两项上限 |
--follow | 获取并规划符合条件的联邦引用(默认拒绝:永不获取受门控或被排除的引用) |
--max-depth <n> | 要跟随的联邦跳数(默认 1;隐含启用 --follow) |
--max-nodes <n> | 整个遍历中获取的清单总数上限(默认 64;默认拒绝的扇出上限) |
--allow-private-hosts | 允许获取环回、私有、链路本地主机及 http:// 地址——默认关闭(阻止 SSRF 攻击内部地址或元数据地址) |
--no-verify | 跳过清单签名验证 |
--require-signature | 除非每个清单都带有已验证的签名,否则失败 |
--trust-key <loc> | 用于验证的固定 ed25519 公钥(路径、URL 或内联值) |
--trace | (plan)显示决策跟踪:逐个单元展示门控级联——每个单元依次经过的所有门控 |
--json | 以 JSON 格式输出计划(对于 ask,也输出答案) |
--correlation-id <id> | 由调用方提供的不透明 ID,会回显到 --json 封装中,以便将计划产物关联到调用方的决策链或审计日志 |
--help | 打印用法和选项参考(也可使用 -h;在任何子命令后均可使用) |
--once | (watch)运行一次验证/规划周期后退出,而不是持续监视 |
--diff | (watch)报告与上一周期相比的变化 |
--task <task> | (watch)每个周期都要重新规划的任务 |
--publisher <name> | (init)写入脚手架清单的发布者名称 |
--from-llms-txt <loc> | (init)根据现有的 llms.txt 起草 knowledge.yaml——URL 或路径 |
--dry-run | (init)打印生成的 knowledge.yaml,而不是写入文件 |
--force | (init)覆盖现有的 knowledge.yaml |
--model <id> | (ask)模型 ID:provider/model(例如 openai/gpt-4o、anthropic/claude-opus-4-8)——默认 claude-opus-4-8 |
--base-url <url> | (ask)OpenAI 兼容端点的基础 URL(覆盖提供方默认值) |
--api-key <key> | (ask)API 密钥——可替代环境变量 ANTHROPIC_API_KEY / OPENAI_API_KEY |
--loop | (ask)经审计的批判循环:规划 → 大模型差距批判 → 术语门控 → 重新规划 |
--max-rounds <n> | (ask --loop)批判轮数上限(默认 3) |
--loop-model <id> | (ask --loop)批判模型——默认 claude-haiku-4-5 |
--ground | (ask)根据已加载的单元验证答案中的每项声明;指出未经证实的声明 |
--ground-model <id> | (ask --ground)验证模型——默认 claude-haiku-4-5 |
--ground-rounds <n> | (ask)闭环溯源:发现差距时重新导航以查找证据(默认 0) |
--check-gaps | (replay)重新导航今天的清单,检查已溯源答案中发现的差距是否已弥合 |
--memory <dir> | (remember/recall)情景记忆目录——每个产物对应一个按哈希寻址的条目 |
--replay | (recall)根据今天的清单重新验证每段回忆的经历(命中项已发生漂移时以 1 退出) |
--limit <n> | (recall)返回的经历数量上限 |
--public-url <url> | (serve)可访问此服务的公共 URL——根据清单声明的 serving.mcp(§3.12)进行自检;不匹配时在启动时发出警告 |
test/docs.test.ts 会确保这张表内容准确:parseArgs 接受的每个标志都必须出现在这里和 cli.ts 的头部,反之亦然。 |
validate — 检查 knowledge.yaml
node dist/cli.js validate . # or a path, directory, or URL
错误是会误导 Agent 或导致 Agent 失败的结构性问题(重复的 ID、不安全或缺失的路径、指向不存在目标的 superseded_by,以及任何 Agent 都无法满足的证明要求);警告则是会削弱导航能力的声明(没有触发条件、已过期且没有后继项的单元)。错误时退出码为 1——任何发布清单的仓库都应在 CI 中运行此命令。
replay — 重新验证已保存的计划或基于依据的回答
node dist/cli.js plan "task" --manifest . --json > plan.json
node dist/cli.js replay plan.json # exit 0 identical · exit 1 drifted
plan --json 生成的产物会固定清单的 sha256,并回显每项规划器输入。replay 会重新获取每份清单(包括 --follow 树中的每个节点),比较字节,使用已保存的输入重新运行纯规划器,并针对每份清单报告一致或已偏移,同时指出发生变化的字段。计划是证据;重放则是交叉质询。手动编辑产物也会导致偏移:重新计算出的计划将与之不符。
replay 会自动检测基于依据的回答产物(来自 ask --ground --json),并改为逐条交叉质询其中的声明:重新读取每条有依据声明所引用的单元,并将其 sha256 与固定值重新比较,结果为依据仍有效、已偏移(字节已更改)或已消失(单元已移除)。如果任何引用不再成立,则退出码为 1,因为过时的回答不能被视为已验证。使用 --check-gaps 时,它会重新导航今天的清单,以检查此前发现的缺口是否现已弥合(清单已补入回答之后缺失的证据)——缺口有其生命周期,而记忆是一份可针对变化后的世界重新验证的计划。
remember / recall — 将情景记忆作为可重放的计划
node dist/cli.js ask "who won the exclusive story" --manifest examples/fjordwire --ground --json > ans.json
node dist/cli.js remember ans.json --memory .kcp-memory # log the episode (unit bytes stripped)
node dist/cli.js recall "the exclusive story winner" --memory .kcp-memory --replay
这里的记忆不是摘要或嵌入向量,而是计划/基于依据的回答产物本身,**去掉了唯一会让它在保留后变得危险的内容:单元字节。**如果在记忆日志中缓存受限或付费内容,之后调用 recall 时就能绕过访问门槛读取这些内容。因此,remember 只保留重放所需的信息——每个单元的 id、path、sha256 和引用表——并删除所有 content 字段。条目以去除内容后的产物进行哈希寻址,因此重复记录同一回答具有幂等性。
recall 会按词汇任务词项的重合度匹配过去的事件(使用规划器评分时采用的同一分词器),并按重合度排序。由于字节已被删除,召回的事件本身不提供新鲜度保证:使用 --replay 时,每个命中项都会根据今天的清单重新验证——有效(每个引用的单元都仍符合固定字节)、已偏移(某个引用已变化——退出码为 1)或无法验证(无法执行重放)。不使用 --replay 时,每个命中项都会报告为 无法验证——记忆绝不会谎称过时的回答仍然正确。记忆是一份可针对变化后的世界重新验证的计划。
memory-validated reuse — 保持确定性的缓存
向 plan 或 ask 传入 --memory <dir>,即可将情节日志变为缓存,其正确性依赖于与其他一切相同的属性:计划是 (manifest bytes, task, options) 的纯函数。规则是 召回(精确匹配)+ 重放(新鲜度)= 复用,任何不符合这一规则的情况都会安全失败。
node dist/cli.js plan "how do I deploy" --manifest . --memory .kcp-memory # records + reports determinism
node dist/cli.js plan "how do I deploy" --manifest . --memory .kcp-memory # ♻ provably identical to episode …
node dist/cli.js ask "how do I deploy" --manifest . --ground --memory .kcp-memory # reuses a clean grounded answer, skips the model
plan --memory 会记录每个计划;如果此前有情节使用相同的任务、清单和选项运行过,它会报告今天的清单是否与之逐字节相同(♻ 可证明相同),或是自那时起已发生漂移——这是一种确定性/审计信号,绝不会在 sha 变化后悄然复用。缓存键包含生效的 --as-of 日期,因此未固定日期的计划只有在同一天内才符合复用条件;使用不同能力(--role、--budget、……)运行会形成不同的计划,而非缓存命中。
ask --ground --memory 才是真正发挥复用价值的地方:调用模型前,它会查找相同请求对应的缓存有依据的答案并重放该答案——重新读取每个引用的单元,并重新核对其固定的 sha256。只有在所有引用仍然有效时,才会返回存储的答案(♻ 已复用,不调用模型);如果任何被引用的单元已发生漂移或不复存在,答案就会重新计算,绝不会提供过期内容。由于导入时已剥离单元字节,召回的答案绝不可能将受限内容偷偷带过下一道访问门槛——复用会实时通过防护重新读取这些单元。记忆就是一份可针对变化中的世界重新验证的计划。
mcp — 向任意 MCP 客户端提供规划器
node dist/cli.js mcp # stdio transport
它提供四种工具:kcp_plan(可检查的加载计划)、kcp_load(计划以及符合加载条件的单元内容,因此调用方 Agent 的模型可自行综合——kcp-agent 在此无需 API 密钥)、kcp_validate 和 kcp_replay(通过网络对保存的计划产物进行交叉审查)。kcp_plan/kcp_load 支持 CLI 的完整能力选项——role、methods、credentials、attest、budget——因此无论是哪个 MCP 客户端,证明和凭证门槛的判定都与命令行上的判定完全一致。借用规划器的 Agent 不必具备确定性;只要向具备确定性的对象发起请求即可。例如,可在 Claude Code 中注册:
claude mcp add kcp -- node /path/to/kcp-agent/dist/cli.js mcp
会话去重。 kcp_load 接受 known 参数——调用方已持有的单元,格式为 [{id, sha256}]。sha 仍匹配的单元会以 unchanged 存根形式返回(不提供字节,只确认 sha),而非再次提供其内容,从而在多轮会话中节省调用方的上下文窗口;响应会报告 deduped 和 bytesSaved。这是情节记忆在调用方一侧的实现,且不改变原有特性:服务保持无状态(调用方的窗口就是会话),仅当 sha 完全匹配时才会生成存根——任何漂移都会重新提供新鲜字节;由于 kcp_load 每次调用都会重新规划并重新执行门槛检查,调用方后来已无权访问的单元只会被直接省略,绝不会被伪装成存根偷偷带回。
knowledge.yaml 是成熟版 llms.txt
llms.txt 解决了同一问题中较简单的那一半——告诉 Agent 网站包含什么——并被发布者采用。它只是一个扁平的链接列表,也只能做到这一点。
同一个网站,双向转换:
# Acme Docs kcp_version: "0.30"
project: "Acme Docs"
> Everything you need to integrate Acme. intent: "Everything you need to integrate Acme."
## Guides units:
- id: "quickstart"
- [Quickstart](/quickstart): path: "quickstart"
Get running in five minutes intent: "Get running in five minutes"
audience: [agent, human]
triggers: ["guides", "quickstart"]
转换现有文件——结果确定、无需调用模型,且绝不会覆盖已有的清单:
kcp-agent init --from-llms-txt https://acme.dev/llms.txt --dry-run
kcp-agent discover <url> 也会在回退到爬取前检查 /llms.txt,并提示你升级。
升级带来的好处,都是 llms.txt 无法表达的:
| llms.txt | knowledge.yaml | |
|---|---|---|
| 存在什么 | ✅ 链接列表 | ✅ 带有意图和触发条件的单元 |
| 面向谁 | ❌ | audience、not_for、角色限制 |
| 何时有效 | ❌ | valid_from / valid_until、替代关系 |
| 是否真实可信 | ❌ | 独立的 ed25519 签名 |
| 成本是多少 | ❌ | payment、预算、速率限制 |
| 指向什么 | ❌ | 联邦到其他发布者的清单 |
| Agent 可以用它做什么 | ❌ | kind: skill / playbook、action_scope、load_eligible |
转换会将这些项目全部标记为待办事项,而不是凭空编造。若转换后的清单擅自声称适用对象或有效期,就等于断言了你从未说过的内容。
签名
清单可以声明一个 signing 区块(方案为 ed25519,包含密钥和独立签名 URL——参见规范仓库自身的清单)。如果存在,kcp-agent 会在制定计划前验证清单原始字节的签名:无效签名始终会导致失败关闭;无法验证的签名(密钥无法访问)会发出警告,除非指定了 --require-signature。支持:JSON 签名信封({algorithm, public_key, signature})、原始 base64/hex 签名,以及 PEM / SPKI-DER / 32 字节原始密钥。使用 --trust-key 固定发布者密钥,防止清单为自身背书。
网络边界
清单是不可信输入,它会选择 Agent 随后要获取的 URL——联邦引用、签名和密钥位置、远程单元内容。所有远程读取都会经过一个受保护的获取函数(src/fetch.ts),默认采用失败关闭策略:
- SSRF / 混淆代理——远程地址仅允许使用
https://;拒绝环回、私有、链路本地和云元数据地址(例如169.254.169.254)。主机名会通过 DNS 解析并逐一检查所有地址;重定向由客户端手动跟随,防止公共主机将 Agent 引向私有地址。使用--allow-private-hosts可允许本地/内部清单。 - 扇出——深度和循环已受到限制;现在
--max-nodes(默认值为 64)会限制单次--follow获取的清单总数,防止恶意枢纽扩散到数百万个清单。 - 响应大小——每次读取都会以流式方式接受 8 MiB 上限检查,超出后即中止,并设置整个交互的超时时间,防止恶意端点耗尽内存。
通过 MCP 使用时,默认启用此保护——外部客户端正属于不可信调用方的情况。
编写便于 Agent 查找的触发词
评分器是基于词汇且确定性的——它会将意图、触发词和 id/path 与任务中的词语进行匹配;不使用模型,也不使用嵌入。这正是它的特点(可复现、可审计、免费),但也有一个实在的结果:一个单元只能通过其清单声明的词语被找到。 一个来自实际使用场景的漏匹配案例:
task: "sovereign compute award and infrastructure implications"
· datacenter-power: no task-relevance match ← the story's best infrastructure angle
该单元的触发词是 [datacenter, power grid, capacity, Nordics],意图中却从未提到 “infrastructure”——词汇完全没有重合,得分为 0,因此被跳过。应该修改清单,而不是规划器:
- 围绕 Agent 会提出的问题编写触发词,而不是内容中的名词。 “infrastructure”“energy costs”“where does the compute run”——也就是任务中的表达方式——比文章中的词汇更有效。
- 意图中也要加入问题相关的词语:意图会计分,因此 “How the power grid limits sovereign compute infrastructure” 可以被找到,而 “Live Nordic datacenter power-grid feed” 则不行。
- 发布前,使用自己的清单运行
kcp-agent plan,并输入预期任务——跳过原因会准确说明真实 Agent 会漏掉什么,以及为什么。
库
import { loadManifest, plan, synthesize } from "kcp-agent";
const manifest = await loadManifest("./knowledge.yaml");
const p = plan(manifest, "how do I deploy?", { env: "prod", capabilities: { paymentMethods: ["free", "x402"] } });
// p.selected / p.skipped / p.federation / p.budget / p.trust — a pure, inspectable artifact
const { answer } = await synthesize(p); // optional LLM step
import { assess } from "kcp-agent"; // post-synthesis confidence gate
const verdict = await assess("how do I deploy?", answer, [], { threshold: 0.7 });
设计
- 确定性规划器(
src/planner.ts)——纯函数,经过全面的单元测试(npm test),不执行 I/O,也不使用模型。计划可复现、可审计。 - 独立的 KCP 客户端(
src/client.ts)——从路径、目录或 HTTPS URL 解析knowledge.yaml。不依赖规范仓库的内部实现。 - 联邦跟随器(
src/follow.ts)——围绕纯规划器的异步外壳:递归获取符合条件的引用,遇到失败即拒绝,并检测循环、逐跳验证签名。 - 签名验证(
src/verify.ts)——通过 WebCrypto 对确切的清单字节进行 ed25519 验证。 - 综合层(
src/synthesize.ts)——唯一会调用模型的部分;仅加载已规划的单元并回答任务。 - 置信度关卡(
src/assess.ts)——综合之后,根据调用方提供的阈值,对自报置信度和/或评估器置信度进行裁定;过程确定性,遇到失败即拒绝。 - MCP 服务(
src/mcp.ts)——通过 stdio 进行无依赖的 JSON-RPC 通信。
规范符合性
该 Agent 以KCP 0.25 为目标,并端到端使用以下子集。(规范仓库自身的清单目前声明 kcp_version: 0.21——这些层的清单彼此兼容。)
| 规范层 | 章节 | 位置 |
|---|---|---|
| 查询评分(意图/触发词/id+path) | §15 | planner.ts scoreUnit |
受众与 not_for / not_for_strict 定向 | §4.20 | planner.ts 相关性/负向路由关卡 |
| 访问权限是授权维度——付款不能替代访问权限 | §4.11 | planner.ts 访问权限关卡 |
| 时效有效性与替代关系 | §4.22 | planner.ts temporalStatus |
| Agent 认证要求 | §3.2 | planner.ts 信任关卡 |
联邦 context + agent_identity | §3.6 | planner.ts + follow.ts |
| 付款方式与层级 | §4.14 | planner.ts planPayment |
| 速率限制层级 | §4.15 | planner.ts planBudget |
| 清单签名(ed25519) | 签名区块 | verify.ts |
发现(knowledge.yaml、.well-known/) | §2 | client.ts |
每一行都对应到 CI 测试,这些测试会在
docs/conformance.json 中列出,并在网站上呈现为
Receipts;如果引用的测试消失或更名,test/docs.test.ts 会使构建失败。
一致性向量
vectors/ 将规划器的决策固化为可移植的 (manifest, task, options) → expected outcome 测试用例——确定性核心的行为以数据而非代码的形式呈现。test/vectors.test.ts 用于验证参考规划器能否复现每个测试用例;任何第二种实现(用于构建 2–5 MB 静态二进制文件的 Go/Rust 移植版,或第三方实现)只要行为相同,即符合规范。两个独立实现通过相同的向量,就验证了规范,而不只是代码——这是证明协议没有歧义的最有力方式。测试集由参考规划器生成(npm run gen:vectors),因此预期结果绝不会由人工编写;该测试集已作为规范性 KCP 一致性套件提议上游采纳。
尚未涵盖:单元之间的依赖链、hints.load_strategy、合规性/审计区块。
指南
- 快速入门——你的前十分钟 — 从头到尾完成安装 → 规划 → 提问 → 验证 → 提供服务 → 回放。
- 10 分钟内让你的仓库变得易于导航 — 从零开始,创建一个实际规划可用的清单,并在 CI 中确保其准确性。
- 为你的清单签名 — 使用 ed25519 对确切字节签名、封装、密钥固定,以及默认拒绝的生命周期。
- 将规划器接入 Claude Code — 通过 MCP 使用
kcp_plan/kcp_load/kcp_validate,无需 API 密钥。 - 为你的 Agent 提供记忆 — 将答案记录为可回放、不含字节的片段;按任务回忆、通过回放验证,仅在有效时复用。
- 通过会话去重降低上下文成本 — 了解 MCP
调用方如何向
kcp_load传递known单元,避免反复消耗上下文窗口。 - 构建符合规范的实现 — 将规划器流水线作为规范,并了解如何使用这些向量验证第二种实现(例如 Go 实现)。
许可证
Apache-2.0 · 由 eXOReaction AS 提议,托管于 Cantara 之下。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。