拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Cairn协议API深度指南:Fact图、Intent认领与Reason Lease的并发一致性设计

Cairn协议API深度指南:Fact图、Intent认领与Reason Lease的并发一致性设计

Cairn协议API深度指南:Fact图、Intent认领与Reason Lease的并发一致性设计

【免费下载链接】CairnA AI general-purpose state-space search engine, validated first on autonomous penetration testing.项目地址: https://gitcode.com/gh_mirrors/cairn2/Cairn

Cairn(衍迹)是一个面向 AI 的通用状态空间搜索引擎,已在自主渗透测试场景完成验证。这篇文章带你深入它的协作探索协议 API:Fact 图如何做到只增不改的一致性、Intent 认领(claim)机制如何避免多个 Agent 重复劳动、Reason Lease 又如何保证项目级推理互斥——这正是 Cairn 多 Agent 并发协作不"打架"的三大核心设计。

一、Cairn 协议是什么:黑板架构的三个原语

Cairn 把"从起点到终点的探索"建模为一张有向图。多个消费者(人或 Agent)并发读取完整图、各自声明探索方向、各自产出新事实,最终由某个消费者判断终点已达成。这套协议是经典**黑板架构(Blackboard Architecture)**的现代化重构,完整定义见官方协议文档 server-protocol.md。

图中只有三个原语:

原语图中的角色一句话理解
Fact节点已确认的客观事实,只增不改
Intent边已声明的探索方向,带认领与心跳状态机
Hint图外输入人工策略建议或 Agent 间传递的态势评估

一个关键设定:系统不做任何推理和决策,只负责图的一致性维护。所有判断都交给读图的消费者,Server 只做"守门员"。

上图是 Cairn 的运行时界面:左侧 Origin → Goal 之间不断长出新的 Fact 与 Intent,右侧面板可以看到每个 Fact 是由哪条 Intent 产出、由哪个 Worker 执行的——图本身就是完整的审计日志。

二、Fact 图:只增不改节点与"超边"语义

Fact 的设计只有两条铁律:

  • 只增不改:状态变化通过追加新 Fact 表达。例如"shell 断了"不是去修改旧 Fact,而是新增一条f025: "host-A shell 已断开"。事实的时序本身就携带了状态演化信息;
  • 描述是提炼而非原始数据:扫描结果这类大体积输出,Fact 只写关键洞见加文件引用,保证图轻量、原始数据仍可追溯。

Intent 的from字段是一个数组,这是协议里很精巧的一个设计:当多个已知事实共同支撑一次探索时,全部列入from,这条 Intent 在图上等价于一条超边,完整保留"多事实 → 一次探索"的因果关系,而不必被迫选一个主 Fact 丢失上下文。实现上,from列表存放在独立的intent_sources表中(见数据库 schema db.py):

f002 ──┐ ├──(intent)──→ f006 f004 ──┘

另外两条容易忽略的约束:from不能包含goal;项目创建时系统会自动写入origin与goal两个特殊 Fact(见创建逻辑 projects.py)。

三、Intent 认领:heartbeat 协议如何防止重复劳动

这是并发协作的核心问题:Agent A 正在探索"SQL 注入",Agent B 读到图后不能又去探索同一方向。Cairn 的解法是把每条未结论的 Intent 设计成一个带状态机的租约,状态由worker和last_heartbeat_at两个字段共同表达:

Intent 状态worker 含义
尚无结论,worker = null无人处理,等待认领
尚无结论,worker 有值有消费者正在处理
尚无结论,worker 心跳超时worker 自动清空为 null,可被重新认领
已结论(to ≠ null)worker 永久保留为产出者,不再参与超时逻辑

围绕这条状态机,协议提供三个接口(实现见 intents.py):

  • heartbeat(认领 + 续约):未认领时,任何消费者 heartbeat 即完成认领;已认领则只有持有者可续约,否则返回409 冲突。也就是说"认领"不是一个独立动作,而是 heartbeat 的自然语义;
  • release(主动释放):探索失败或决定放弃时,持有者立即释放,其他消费者可以马上接手,不必干等超时;
  • conclude(结论落定,原子操作):一次性完成"写入新 Fact + Intent 打上结论 + worker 永久保留"三件事,返回 Fact 和 Intent 的完整对象。

超时由全局设置intent_timeout控制。它的实现方式很值得一提:Server 采用惰性过期——每次读取或写入前顺手执行一条 UPDATE,把心跳超时的 Intent 的 worker 批量清空(见 services.py 中的expire_workers)。不需要后台定时器,任何一次 API 调用都顺带"打扫"过期的锁,简单且无遗漏。

四、Reason Lease:项目级推理互斥

Explore 解决的是"一条边谁来探",还有一个更高层次的问题:谁来读整张图做全局判断(是否已完成?下一步该探索什么方向?)。这就是reason任务,它的并发约束由项目级 Reason Lease表达:单个项目同一时刻最多只有一个 reason 在运行,跨项目则允许并行。

Lease 生命周期只有三个接口(实现见 projects.py):

  1. claim:project.reason为空则认领成功,写入 worker、trigger、started_at;被他人占用且未超时返回 409;同一 worker 重复 claim 幂等返回,天然支持重试;
  2. heartbeat:仅持有者可续约,更新last_heartbeat_at;
  3. release:持有者主动释放,立即回到无人状态;已为空时幂等。

Lease 会直接出现在GET /projects和GET /projects/{id}的project.reason字段中,前端和其他消费者一眼就能看出"谁正在对整个项目做 reason 判断"。它同样受reason_timeout超时保护,走的是同一套惰性清理(expire_reason_leases)。

一个微妙的设计区分:Reason Lease不是图数据,不产生 Intent/Fact,不参与因果推理,它只是项目级协调状态——正如协议文档强调的,这类状态"不是事实,不属于图"。

五、并发一致性:三道防线汇总

把上面两条线索合起来,Cairn 的并发一致性靠的是三道防线,全部由 Server 单点裁决:

防线机制防住什么
🛡️ 原子写conclude / complete / claim 都在单个事务内完成"校验 + 写入"两个消费者同时结论落定、同时完成项目
🛡️ 租约 + 心跳worker 字段 + 409 冲突 + 超时自动清空死锁(持有者崩溃)与重复执行
🛡️ 硬停止项目切stopped时,Server立即清空所有 open Intent 的 worker 和 reason lease,并拒绝后续探索写操作(403)停止后旧 claim 还"活着"导致的僵尸任务

第三道防线尤其重要:stopped的语义是硬停止——claim 立即失效而非等超时,消费者收到 403 或读到状态变化后应立刻取消本地任务。这样项目恢复active后能马上重新认领,不必空等。

在架构层面还有一层收口:Dispatcher 是唯一的协议写入者。Agent Worker 只接收渲染好的 prompt、返回结构化输出,不直接 claim、不直接 heartbeat;Dispatcher 代它完成认领、续约、结论落定与释放(协议客户端见 client.py,reason 任务的 lease 封装见 reason.py)。写入口单一,一致性边界清晰。

六、上手实践:消费者的典型流程

理解了机制,实际使用时的节奏是这样的(完整清单见 server-protocol.md 末尾的"消费者典型使用流程"):

  1. 读图:GET /projects/{id}拿结构化数据用于调度判断;GET /projects/{id}/export?format=yaml拿图快照渲染给 Agent;
  2. 初始态:facts 只有 origin/goal 时,可声明一条保留的bootstrapintent(from=["origin"],description="bootstrap")直接尝试解题,走同样的 claim → heartbeat → conclude/release 生命周期;
  3. 有未认领 Intent:heartbeat 认领 → 执行探索 → 成功则 conclude、失败则 release;
  4. 无未认领 Intent:claim reason lease → 读图推理 → 产出 complete 或新 intent →无论成败都 release;
  5. 判断有误:completed 项目可调用reopen撤销完成态,纠错信息落为新 Fact,继续探索。

超时参数(intent_timeout/reason_timeout)通过GET/PUT /settings调整,心跳周期通常配置为略小于超时值,给抖动留足余量。

七、关键文件导航 📂

内容路径
协作协议完整定义(含 YAML 导出示例)docs/specs/server-protocol.md
Dispatcher 调度与任务模型设计docs/specs/dispatcher-design.md
Intent 心跳/释放/结论 API 实现cairn/src/cairn/server/routers/intents.py
Reason lease、complete、reopen 实现cairn/src/cairn/server/routers/projects.py
惰性超时清理(expire_workers / expire_reason_leases)cairn/src/cairn/server/services.py
SQLite schema(facts / intents / intent_sources)cairn/src/cairn/server/db.py
Dispatcher 协议客户端cairn/src/cairn/dispatcher/protocol/client.py
运行示例配置dispatch.example.yaml

一句话总结:Cairn 协议用"Fact 只增不改 + Intent 租约 + Reason Lease"三件套,把多 Agent 并发探索收敛为一组短小原子接口——没有中央调度、没有 Agent 间直接通信,一致性完全由 Server 单点兜底。这也是它能支撑多个 Agent 并行渗透、互不干扰的关键所在。

【免费下载链接】CairnA AI general-purpose state-space search engine, validated first on autonomous penetration testing.项目地址: https://gitcode.com/gh_mirrors/cairn2/Cairn

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

返回列表