Archyl Harness

编程代理对您的代码仓库了如指掌——却对您的架构一无所知。它们会重写另一个代理此刻正在重构的服务,引入团队两年前在 ADR 中明令禁止的依赖,并让文档继续描述一个早已不存在的系统。

Archyl Harness 解决了这个问题。它把任何编程代理——Claude Code、Codex、Cursor、您的 CI 机器人,或 Archyl 自己的托管代理——包裹进一个基于您已文档化架构的受管控循环中:

模块 作用 工具
Context 只把与当前任务相关的那部分架构交给代理——元素、决策、Guardrails、负责人 find_relevant_context
Plan 把功能需求转化为遵循您的 C4 模型和 ADR 的实现计划 plan_work
Guard 在违规变更被写入之前,拦截违反合规规则的改动 Guard 钩子 + run_conformance_check
Evolve 闭合循环:工作结果沉淀为元素记忆,架构变更请求草稿让模型保持同步 finish_work_session

代理运行的循环:

plan_work ──▶ start_work_session ──▶ code (Guard watches every write)
                                          │
finish_work_session ◀─── heartbeat ◀──────┘
      │
      ├─▶ leases released
      ├─▶ outcome pinned to the touched elements (memory)
      └─▶ draft Architecture Change Request (optional)

而且,由于每个会话都会对它触及的 C4 元素持有咨询式租约(advisory lease),在同一个服务上工作的两个代理会在冲突发生之前看见彼此——既在各自的简报中,也实时体现在您的架构图上。

刻意设计为可选

harness 需要你主动启用:仅仅因为你把架构记录了下来,它不会自行开启。代理只有在你做了以下三件事之一时才会进入这个循环——用 ?profile=coding 连接 MCP 服务器、安装讲授该协议的 archyl-harness 技能,或者加上 Guard 钩子。撤销它们,该仓库中的代理就会完全恢复到原来的行为。

Archyl 的其他能力都不依赖它。上下文检索、影响分析、归属关系、一致性检查、漂移检测和记忆系统,全部可以从完整的工具目录中使用,完全不需要工作会话。把 Archyl 当作一份代理可以读取的架构文档来用,并且完全跳过本指南,同样是受支持的用法。

两半要分开采用,是因为它们被允许做的事情不同。记录的权威来自人的策展:一条 ADR、一条一致性规则、一份获批的变更请求,之所以带有状态,是因为有人把它放了进去;而一条错误的条目只会静静地待在那里,直到有人读到并修正它。协议则不同,它发出的是代理会照着执行的指令——那是另一种性质的风险,值得一次审慎的决定,而不是一个默认值。

这条界线不只画在产品外围,也画在产品内部。代理可以读取记录,也可以写入记录,但它们写下的内容只会以带日期和署名的上下文回到后续代理面前,绝不会成为规则。只有 ADR 和一致性规则会被当作约束呈现,而代理记录的内容要取得这一地位,唯一的路径要经过人:写成 ADR,或者通过一份有人批准的架构变更请求。

五分钟配置

您需要一个已完成架构文档化的 Archyl 项目(如果项目是空的,请先运行 AI 驱动的发现),以及一个具备 write 权限范围的 API 密钥,可在 个人资料 → API 密钥 中创建。

方式 A —— 一条命令

在代码仓库根目录执行:

curl -fsSL https://raw.githubusercontent.com/archyl-com/agent-skills/main/templates/setup.sh | bash

脚本会询问您的 API 密钥和项目,然后完成下面的全部配置。到此完成——可直接跳到 您的第一个会话

方式 B —— 逐步配置

1. 使用 coding 配置档连接 MCP 服务器。 在代码仓库中创建或补充 .mcp.json

{
  "mcpServers": {
    "archyl": {
      "type": "http",
      "url": "https://api.archyl.com/mcp?profile=coding",
      "headers": { "X-API-Key": "${ARCHYL_API_KEY}" }
    }
  }
}

?profile=coding 很关键:它把工具面从 189 个收窄到编程代理真正需要的 16 个,从而让代理的上下文保持精简、选择一目了然。

2. 安装插件(Claude Code):

/plugin marketplace add archyl-com/agent-skills
/plugin install archyl-developer@archyl-marketplace

这会安装各项技能(包括向代理传授会话协议的 archyl-harness)以及 Guard 钩子

3. 启用 Guard。 在代理运行的环境中导出两个变量:

export ARCHYL_API_KEY=arch_...
export ARCHYL_PROJECT_ID=<your project uuid>

Guard 只需要这些。它采用 fail-open 策略:缺少这些变量(或没有网络)时它什么也不做,因此绝不会中断您的工作流。

您的第一个会话

向代理提出任意变更需求——比如*“给公开 API 加上限流”*。装好 harness 之后,会发生这些事:

开始编码前,代理先声明本次工作:

▶ start_work_session(task: "add rate limiting to the public API",
                     agentName: "claude-code/vincent")

# Harness Session
- Session ID: 4c2e…
- Gate: warn
  - error-level guardrail applies: no-direct-db-from-handlers
- Leased elements: container `ApiGateway`, component `RateLimiter`
- Conflicts: none

## Most relevant elements
- ApiGateway (container) — handles all public traffic …
## Related decisions (respect these)
- ADR-017: All throttling is enforced at the gateway [accepted]
## What previous sessions did here
- ApiGateway (claude-code/sarah, 3 days ago): extracted auth middleware …

代理现在知道该在哪里动手、哪些决策对它构成约束,以及上一个代理在这里做过什么——而无需通读整个代码仓库。

编码过程中,Guard 会拿代理即将写入的每个文件比对您的合规规则。critical 级别的违规会连同规则及其修复建议一起拦截写入;代理随即调整并继续。

完成之后,代理闭合循环:

▶ finish_work_session(sessionId: "4c2e…",
    summary: "Added token-bucket rate limiting in ApiGateway middleware",
    decisions: ["limits configured per-plan in Redis"],
    createChangeRequest: true)

租约被释放,摘要作为记忆固定在 ApiGateway 上供下一个代理使用,同时一份架构变更请求草稿进入 Archyl,由人来评审 C4 模型该如何更新。

每条决策都作为独立的记忆存储:之后的会话可以取代它、重新确认它,或任其自然过期,而不会影响本次会话留下的其他内容。决策会以带日期和署名的上下文返回给后续代理,而不会作为规则。只有 ADR 和一致性规则会被当作约束呈现给代理,而变更请求正是一条决策取得该地位的途径。

观察您的代理:Fleet 控制台

打开 Agent Hub → Fleet 即可看到正在进行的工作:多少智能体在干活、哪些 C4 元素当前被租用,以及每个活跃会话一张卡片,写明它的任务、持有的元素、它的 gate 和心跳的新鲜度。结束的会话会连同各自上报的摘要落入最近会话

Fleet 控制台:每个智能体会话的实时状态,以及各自持有的元素

心跳停止的会话会被标记,并在 30 分钟后自行过期。你也可以在这里取消它,租约会立即释放。

同样的信息会出现在你真正会看的地方——图上。智能体持有的每个元素都会带上写着它名字的徽章,点击它就等于问它在做什么:声明的任务、它还持有些什么,以及它上次报到是多久以前。

画布上正在工作的智能体——徽章写明它是谁,气泡说明它在做什么

对于 Archyl 的托管智能体,你还可以引导正在运行的智能体——在运行页面写一条消息,它会被注入到下一个推理步骤。

门禁(Gate)

每个会话都以一次预检判定开始:

Gate 含义 代理行为
allow 无冲突,无 error 级别的 Guardrails 继续执行
warn 另一个会话持有目标元素的租约,或存在适用的 error 级别 Guardrail 继续执行,但要逐条处理列出的原因
deny 仅在 exclusive: true 时出现——目标元素已有人在处理 不要绕开它;向用户报告

对于绝不能与他人并发的变更——数据库结构迁移、契约变更——请使用 exclusive: true

Guard 配置

变量 默认值 用途
ARCHYL_API_KEY 启用 Guard 所必需
ARCHYL_PROJECT_ID 启用 Guard 所必需
ARCHYL_API_URL https://api.archyl.com 自托管部署
ARCHYL_GUARD_BLOCK critical critical 拦截 critical 级违规;high 同时拦截 high 级;off 关闭拦截

除了环境变量之外,也可以在仓库根目录放一个可提交的 .archyl.json,用它承载非敏感的那一半:{ "apiUrl": "…", "projectId": "…" }。API 密钥请仍然放在环境变量中。

记忆

会话的工作结果只是记忆中自动产生的那一半。代理和团队成员也可以主动写入记忆

▶ remember(projectId: …, element: "ApiGateway", kind: "pitfall",
    content: "The gateway strips custom headers longer than 8KB — payloads must go in the body.")
  • remember 把一条事实固定到某个元素(或整个项目)上,类型为 noteconventionpitfall。它适合记录在代码和模型里都看不出来的知识:部署上的怪癖、历史原因、脆弱之处。
  • recall 按关键词、元素或类型检索全部记忆——工作结果、笔记、约定、陷阱。排序会把语义和字面词一起考量,因此一个询问“rate limiting”的代理,也能找到别人写在“throttling”名下的那条笔记。请带上自己的 sessionId,这样之后才能把功劳记到提供给您的那些记忆上。
  • find_relevant_contextstart_work_session 会自动附上相关元素的最新记忆,下一个代理因此可以从前面几位学到的东西接着往下走。

写入记忆是去重的:重述一条已经存在的事实不会再存一份副本,而是确认已有的那条(响应中会给出 deduplicated: true)——因为代理重申自己学到的东西是佐证,而不是噪音。与已有记忆相近但并不相同的记忆则会被存下来,并通过 similarTo 回报给写入方,好让作者有意识地做替换,而不是在无声中制造矛盾。

记忆同样从使用中学习。会话结束时,usedMemories 会点名这次会话真正依赖过的记忆。这条引用就是最强的信号:被引用的记忆保住自己的排名,而一条被提供给五个会话、却没有任何一个会话点名的记忆,则会作为噪音被降权。系统不会自动删除任何东西——被忽略的记忆会进入复审队列,交由人来判断。

记忆有自己的生命周期,因此它保持为真,而不是不断堆积。当 recall 给出的某条记忆被证明准确时,就用 confirm_memory 再确认一次——它的新鲜度计时会重置,继续排在更旧的信息前面。当事实发生变化时,不要让两个版本同时存活:remember(supersedes: "Old title") 会替换旧记忆,被替换的记忆退出检索,但仍保留在历史记录和图谱中。所有未经确认的记忆会在排序中缓慢衰减(半衰期 45 天),而对于即将修改代码的代理,陷阱始终排在普通笔记之前。

记忆之间会形成一张知识图谱,风格类似 Obsidian。给一条记忆加上 title,它就变得可寻址:任何其他记忆都能在正文里用 [[Title]] 引用它。链接同样能按名称解析到 C4 元素([[ApiGateway]])和决策([[ADR-17]])——指向尚不存在的标题的链接会保持待定,等那条记忆被创建的那一刻自动挂上。每条记忆都会列出自己的反向链接,因此知识可以双向查阅——而且 recall 会顺着链接走:排在最前面的匹配结果会把通过 wiki 链接相连的邻居一并带上,并标记为 via

记忆还会察觉架构在它脚下移动。当一条记忆所钉住的元素发生变化时,这条记忆会被标记为待复核:recall 仍会返回它,但附上 [VERIFY — the element drifted since this was written],并且是排名下降而不是消失。关于一个此后被拆分的服务所写的事实并不会自动变错——它只是在有人过目之前不再可信。

记忆与其他敏感内容列一样静态加密,并可从界面管理:Agent Hub 中的记忆面板,以及图上详情面板里按元素划分的区块。这个面板是为分诊而生的——左侧栏统计需要复核的、正被忽略的和已经陈旧的,再把其余按类型分开,每一行都带一条彩色脊线,一眼说明该信它几分。

项目记忆:约定、陷阱与成果,按可信程度分诊

切到知识地图回答另一个问题:不是我们知道什么,而是哪里知道。每个 C4 元素一格,显示项目对它知道些什么、这份知识有多新——包括那些还没有人写过一个字的元素,而那通常才是更有用的一半。

知识地图:项目对每个元素知道什么,以及哪里一无所知

在 CI 中

同样这几个模块可以通过 GitHub Actions 在您的流水线中运行:generate-context 会提交一份 archyl.txt 简报,供无法访问 MCP 的代理使用;conformance-check 依据您的规则对拉取请求进行门禁;auto-cr 则根据已合并的变更提交架构变更请求。

故障排查

Fleet 控制台里看不到任何会话。 代理是在没有 harness 协议的情况下连接的。请检查插件是否已安装(archyl-harness 技能负责传授该协议),以及 MCP URL 是否包含 ?profile=coding——面对 189 个工具的完整目录,代理往往会四处探索而不是遵循这个循环。

Guard 从来不拦截任何东西。 这是设计使然,它采用 fail-open。请确认代理运行的环境中同时导出了 ARCHYL_API_KEY ARCHYL_PROJECT_ID,并且您的项目中存在 critical 严重级别的合规规则

会话一直卡在活跃状态。 会话在最后一次 heartbeat 之后 30 分钟过期,并自动释放其租约。若要立即释放,请在 Fleet 控制台中取消该会话。

支持哪些代理? 任何支持 MCP 的工具都能用上 Context、Plan 和会话协议。Guard 钩子和技能目前面向 Claude Code;其他代理可以通过 run_conformance_check 或 CI actions 来执行同样的规则。