
Omi 的 AI Agent 协作治理体系一份根 AGENTS.md 如何约束 Claude Code 与 Codex 在大型开源仓库中可靠协作【免费下载链接】FriendAI that sees your screen, listens to your conversations and tells you what to do项目地址: https://gitcode.com/GitHub_Trending/fr/Friend导读Omi仓库项目名 Friend定位为看见你的屏幕、听见你的对话并告诉你该做什么的 AI 硬件是一个横跨 Flutter 移动端、Swift/TS 桌面端、Python 后端、C 固件与 Web 前端的超大型开源仓库。面对如此庞大的代码规模项目方将根 AGENTS.md 设计为面向所有 AI Agent 的单一真相源single source of truth它既是一份给 Claude Code、Codex 等代理的高层行为守则也是一个指向各组件细分指南的索引。本文将逐节拆解这份治理文档的设计意图并结合仓库中的尺寸棘轮检查器、检查清单、PR 预检与失败类 CLI 等源码实现说明规则如何被机械地编码成 CI 检查、而不是停留在散文里这一核心工程哲学。为什么 AI Agent 需要一份仓库级宪章在多人协作的软件仓库中人类开发者靠 Review、沟通与经验来保持一致性但每次会话都会重新加载上下文的 AI Agent 没有这种记忆。Omi 的做法是把代理需要遵守的规则显式写进版本库并让规则本身接受 CI 的约束。根 AGENTS.md 的开头就界定了自己的定位它是本仓库所有 Agent 指令的单一真相源Claude Code、Codex 及其他代理均适用它只承载高层指导 索引细节下沉到各组件指南按需just-in-time加载CLAUDE.md只是一个指向本文件的薄指针任何规则改动只允许落在AGENTS.md存在一个专门的 CI 检查.github/scripts/check_agents_md_lean.py强制本文件保持精简细节必须写进组件指南而不是堆在根文件里。这一分层设计解决了一个真实痛点根文件在每一次会话、每一个任务中都会被加载每一行都要被反复付费。无节制的指南最终会变成没人读的规则 没人维护的指针——这恰恰是 check_agents_md_lean.py 模块 docstring 里写明的设计动机。分层文档架构索引行 分量指南 按需参考根文档的核心骨架是一张Read Next索引表告诉正在某个组件工作的代理先去读哪一份指南正在处理先读后端 Pythonbackend/backend/AGENTS.md环境搭建、async/executors、WebSocket 规则、服务地图、日志安全、测试Flutter 应用app/app/AGENTS.md构建 flavor、l10n、原生桥、测试、agent-flutter UI 验证桌面 macOSdesktop/macos/desktop/macos/AGENTS.md构建/运行、命名 bundle、自测、发布管道、changelog桌面 Windows/Linuxdesktop/windows/desktop/windows/AGENTS.mdpnpm 版本锁定、构建/测试、CI 形态、Linux/Wayland 开发环境、发布管道Web 应用web/app/web/app/AGENTS.md环境搭建、质量门、测试、与桌面的 parity 边界固件omi/firmware/omi/firmware/AGENTS.md发布工作流产品行为PRODUCT.mdproduct/invariants/被锁定的不变量与守护测试跨 app/macOS/Windows 共享规则contracts/parity/README.md共享 fixtures、各平台一致性套件、分歧登记表fallback/fail-open 分支.github/agent-docs/fallback-telemetry.md何时调用record_fallbackApp 流程 / E2Eapp/e2e/SKILL.md、desktop/macos/e2e/SKILL.md这套结构的三个层次在 .github/agent-docs/doc-maintenance.md 中被明确为规则归属地根AGENTS.md—— 跨组件规则与索引仅此而已组件AGENTS.mdbackend/、app/、desktop/macos/、desktop/windows/、web/admin/、omi/firmware/—— 承载该组件的细节代理工作到该区域时就近加载.github/agent-docs/—— 偶尔需要、可被指向的参考文档例如fallback-telemetry.md、plan-catalog.md、doc-maintenance.md本身。代理永远有一个更便宜的放置位置组件指南是根文件的泄压阀.github/agent-docs/又是组件指南的泄压阀。尺寸棘轮check_agents_md_lean.py如何防止指南膨胀好规则必须有检查背书否则就会漂移。Omi 用 .github/scripts/check_agents_md_lean.py 对每一份AGENTS.md施加行数与字节数的双重棘轮ratchet# path - (max_lines, max_bytes). Ratchet down; never up. BUDGETS: dict[str, tuple[int, int]] { AGENTS.md: (180, 18_000), .github/AGENTS.md: (45, 4_500), app/AGENTS.md: (170, 11_500), backend/AGENTS.md: (350, 39_000), desktop/macos/AGENTS.md: (560, 47_000), desktop/windows/AGENTS.md: (127, 6_950), omi/firmware/AGENTS.md: (30, 1_500), web/admin/AGENTS.md: (25, 1_500), web/app/AGENTS.md: (55, 2_400), docs/AGENTS.md: (34, 1_309), }从实现细节可以读出几个关键设计棘轮只降不升预算只能随文件缩小而下调注释明确写着Never raise a budget to admit detail that has a home one level down。这意味着把细节下沉一级是唯一合法的扩容途径。每个新指南必须有预算检查器对发现但无预算条目与有预算但已删除的文件分别报错防止新指南无界落地或残留死条目。必须感知 gitignored 的兄弟 worktree仓库文档化的多 worktree 模式.claude/worktrees/会让每个 worktree 里都有一份被跟踪的AGENTS.md副本。检查器通过git ls-files --others --ignored找出被忽略目录并跳过它们避免把既非新增也不在 push diff 中的副本误报为违规git 不可用时退化为静态SKIP_PARTS列表node_modules、.build、.git而不是直接失败。自带自测self_test()用临时目录验证精简文件必须通过、超行数/超字节必须失败并模拟 gitignored worktree 场景验证发现逻辑——检查器自身也被测试保护。这份检查器对应的正是根文档Keep this file lean的维护要求二者构成散文规则 → 机械检查的闭环。Definition of Done提交前的 8 项验收清单根文档为每一次变更定义了统一的完成标准Definition of Done任何提交或 PR 在合入前必须逐条满足行为变了 → 测试必须变Bug 修复要带上能捕获该 bug 的回归测试新功能测试核心路径与主要错误路径no more。组件测试套件本地通过backend/test.sh、app/test.sh或组件文档记载的等价命令提交前必须本地跑过。必须亲自演练真实用户路径只编译通过或 lint 通过不算数如果实在无法演练必须明说而不是暗示它工作正常。验证证据落笔成文把跑过的命令及其输出写进 commit message 或 PR 描述。无孤儿延期新增的TODO/FIXME/HACK必须引用一个跟踪 issue或在合入前解决。文档随代码迁移setup、测试命令、服务边界、环境变量或与代理相关行为的变更必须在同一个 PR 内更新对应指南本文件、组件AGENTS.md或docs/doc/developer/。失败类声明起草fix:PR 正文前运行scripts/pr-preflight --suggest获取不变量引用与失败类指引每个fix:提交随后声明Failure-Class: FC-slug | new | none并用scripts/failure-class校验。PR 合同在开 PR 前通过运行make preflight它会执行与 CI 完全相同的确定性检查清单.github/checks-manifest.yaml起草 PR 正文后运行scripts/pr-preflight --pr-body-file /tmp/pr-body.md或--suggest获取可直接粘贴的不变量与失败类指引。值得注意的是第 8 条背后的清单即契约思想清单里每一项确定性 diff-scoped 检查若在 CI 中首次失败应被视为 manifest bug——修复 manifest.github/checks-manifest.yaml而不是给 workflow 加一次性步骤。新检查必须同时在local与ci两条 lane 注册。scripts/pr-preflight的实现印证了这一点它只是定位仓库根、解析 Python 环境后转发给 .github/scripts/pr_preflight.py真正的逻辑全部集中在被清单管理的确定性脚本里。Failure-Class以被违反的契约为修复单位根文档要求修复工作围绕被破坏的契约边界展开而不是症状出现的代码行定位失败的所有者、身份、状态转换或边界契约而不是再加一个 observer、fallback 布尔值或调用点特例若近期两个及以上修复共享同一原因则必须在同一 PR 内添加可复用的守护面typed 状态/策略模型、行为契约测试、故障注入 harness 或窄范围静态检查器回归测试必须通过可控接缝controllable seam执行生产行为——断言源码字符串出现顺序只是静态绊线要如实标注为 static checker不要把安全的 bug-fix PR 扩大成不可审查的迁移落地可执行的守护把高爆炸半径的后续工作显式跟踪起来。这套协议有完整的工具链支撑。scripts/failure-class 是一个 879 行的 Python CLI其 docstring 明确本 CLI 永不从 diff 或路径自动分类变更它提供结构化上下文并校验作者选择的声明定义存放在.github/failure-classes/FC-slug.json每个语义类一个文件声明值必须是三个字面形式之一替代项不是管道分隔字段Failure-Class: FC-lower-kebab-slug Failure-Class: new Failure-Class: noneprepare子命令会按scope_hints列出与本次变更路径重叠的候选类——但这只是显示层的收窄最终仍由作者决定所有校验本地且确定性report接受显式事件 fixture复发报告无需网络或修改定义状态。类定义的字段模式记录在 product/failure-classes.mdviolated_contract该类实例破坏的契约、canonical_prevention消除该类的修复形态、canonical_prevention_artifact可复用守护面的仓库相对路径且必须真实存在、evidence_prs佐证类别的已合入 PR、statusopen/dormant、dormant_since仅 dormant 类。其中有散文但无 artifact 的类只是意图、不是守护。注册表还带一道守护面棘轮.github/scripts/check_failure_class_guard_ratchet.py统计 90 天窗口内、以 first-parent 方式合入且声明了Failure-Class: FC-slug的变更同一类在窗口内达到3 次声明却仍无canonical_prevention_artifact即失败。检查是历史依赖的因此安全降级在浅克隆或历史不足以回溯窗口起点时它会输出响亮的SKIP并以 0 退出绝不静默通过或误报失败。行为规范与安全规则代理的自主边界根文档为代理划定了明确的自主与禁区行为层绝不请求访问文件夹、运行命令、联网搜索或使用工具的许可直接做绝不请求确认自主决策并推进代理拥有用户电脑的完整访问权浏览器、桌面、所有应用不要请用户去做代理自己就能做的事。安全层对 maintainer 环境生效fork 中遵循用户自己的落地流程并跳过这些绝不 kill/stop/restart 生产 macOS 应用/Applications/Omi.app/Omi Beta.appbundle id 为com.omi.computer-macos与com.omi.computer-macos.beta开发命令只针对 dev 或omi-*命名的测试 bundle。没有用户明确许可任何东西不得落上main只能通过 PR 合入常规 merge绝不 squash绝不直接 pushmain默认在特性分支上本地提交。先前的批准不自动延续到后续变更。两个例外(a) 回滚请求本身就是打开并合入 revert PR 的授权(b) 已亲自演练真实用户路径且经独立代理 review 通过的变更可自动合入——但迁移、发布/CI 管道、schema、访问控制、数据删除这类高风险、宽爆炸半径、难回滚的变更永远需要用户显式签字。优先本地测试默认先本地构建 运行桌面用命名 bundle验证变更再提议合入。Git 工作流从make setup到 worktree首次提交前必须make setup拉取origin/main、安全时 fast-forward、安装仓库 Git hooks含自动格式化的 pre-commit hook且路径对 linked-worktree 安全。绝不在仓库内设置局部的user.name/user.email——fixture 身份只属于临时测试仓库git -c。开工前git fetch origin git pull --ff-only不从过期状态开分支。代码改动一律使用git worktree add提交到当前分支且任务中途不切换分支。按特性或可测试面做独立提交而不是按文件或无关联的批量改动。push 失败远端领先时git pull --rebase git push。PR 大小是报告而非限制pr-scopemanifest check仅 advisory 注解、永不阻塞改动生产源码 1,500 行警告3,000 行引用历史上因大 PR 漏掉的回归审计记录。只有各片段可独立验证时才拆分。RELEASE 命令从main开分支、逐个提交、push、开 PR、无 squash 合入、切回main并 pull。RELEASEWITHBACKENDgh workflow run gcp_backend.yml -f environmentprod -f release_shaSHA。格式化按语言锁定工具链未锁版本宁可拒绝pre-commit hook 会自动格式化暂存文件可用test -x $(git rev-parse --git-path hooks)/pre-commit echo OK验证。它拒绝格式化而不是用未锁定工具链重新格式化语言手动命令Dartapp/dart format --line-length 120 filesPythonbackend/scripts/backend-python-format --write filesARBapp/lib/l10n/jq --indent 4 . file tmp mv tmp fileC/C固件clang-format -i filesSwiftdesktop/macos/Desktop/desktop/macos/scripts/swift-format-wrapper.sh format -i filesWebweb/npx prettier --write files配套约束*.gen.dart/*.g.dart为自动生成文件禁止手动格式化SwiftDesktop/Sources/Generated/下的文件排除在格式化范围外。逃逸阀是OMI_SKIP_WEB_FORMAT1与OMI_SKIP_DART_FORMAT1。这一未锁定工具链宁可拒绝的规则源于真实事故——仓库注释里记载浮动版本的 Prettier 曾把web/frontend里固定为 ^2.8.8 的文件重写成 CI 拒绝的形状一天之内污染了四个 PR。测试策略棘轮增长、有界 push gate、hermetic CI覆盖率靠棘轮而非强制每个 bug 修复补上能捕获它的回归测试新功能测核心路径与主要错误路径no more一年后仍然有意义的微型测试胜过十个脆弱的大测试。push gate 预算scripts/pre-push 是有界的本地验收门刻意小于 CI宽后端选择上限 40 个文件只用桌面 debug 编译。不要往里塞完整套件、release 编译或仅 CI 的工具链锁定。CI 才是完整测试的权威。CI 测试必须 hermetic无在线服务、网络、sleep 或顺序依赖——且 hermetic 测试必须进 CI放在组件 runner 能发现它们的位置依赖在线服务的测试留在 CI 外并在 PR 里说明你是如何运行的。后端以机制强制测试发现manifest checkbackend-test-discovery会对任何未被已验证 runner 发现的测试文件报错。新的 fail-closed 门必须自带 legacy-principal 测试——用既有/未迁移的 principal无状态文档、旧 API key、已发布客户端断言其预期回退没有这种测试的门曾在上线第一天就坏过。与所断言代码同 PR 重写的测试是可疑的PR 正文必须引用外部来源平台文档、线上契约、测量为新期望值背书。部署与发布管道每道门都有 break-glass 逃生舱桌面hourly candidate → signed-smoke Beta → 手动 Stable细节见desktop/macos/AGENTS.md的 Release Pipeline。后端gcp_backend.yml是主栈参数environment、release_sha、release_version、mode、deploy_targets没有branch。生产release_sha需要首次尝试的 Release Eligibility 证明。desktop-backend 走desktop_backend_prod.yml。固件Omi CV1见omi/firmware/AGENTS.md。关键原则是每个被门控的表面都有逃生舱门坏了永远不是卡住的理由被阻塞于逃生舱桌面候选无法切出Desktop Swift Build Tests红色/抖动desktop_auto_release.yml的release_modebreak_glass后端部署无 Release Eligibility 证明gcp_backend.yml的skip_eligibility_prooftrue、break_glass_confirmdeploy-without-proof、break_glass_reason逃生舱只放宽证据要求绝不放宽代码必须先合入main也绝不绕过自身的显式确认就触达 stable/prod 指针。每次使用都要记录跟踪 issue——反复使用说明这道门本身就是缺陷。文档维护把规则写成机械的、有检查背书的根文档最后一部分集中阐述文档自身的治理而 .github/agent-docs/doc-maintenance.md 提供了操作级细节机械地写规则并用检查背书只有弱代理无需判断就能应用的规则才可靠。用个好名字是愿望*.g.dart是生成的、永远别编辑才是规则。优先把规则编码成带清晰失败信息的脚本或 CI 检查——被强制执行的规则不会漂移被请求的行为才会。每个被引用的路径必须存在check_agent_doc_references.py强制执行这一点重命名导致指针失效会在 CI 失败而不是在数月后误导代理。新增检查的注册纪律在 .github/checks-manifest.yaml 同时注册local与ci两条 lane按需脚本与无阻塞受众的定时任务都是死检查必须引用真实合入的 PR 或事故作为依据——没有真实实例就没有检查并在 PR 中说明为何它不是已有的共享原语。文档与代码同 PR 更新setup/测试命令/服务边界/环境变量变更 → 更新对应指南架构/核心流程/API 变更 → 更新 Mintlify 文档docs/doc/developer/产品方向或锁定不变量 → 更新PRODUCT.md/product/invariants/及守护测试。指南被误读导致缺陷上线时在修复 PR 中收紧指南把规则机械到同一误读无法复现的程度或补一个能捕获它的检查。值得一提的还有根目录之外的分层docs/AGENTS.md明确docs/是公开 Mintlify 站点docs.omi.me的源码而非内部 wiki设计笔记、runbook、不变量、flag 表、kill switch 等禁止以临时名义放入其中——它们必须放在所属代码旁backend/docs/、desktop/macos/docs/、.github/agent-docs/、product/invariants/或私有跟踪器里。总结治理体系的三条主线回看整份根 AGENTS.md 及其源码实现可以提炼出 Omi 约束 AI Agent 协作的三条主线分层 棘轮根文件只放跨组件规则与索引细节下沉到组件指南check_agents_md_lean.py用只降不升的预算保证每层都精简让代理每次会话加载的上下文成本可控。规则即检查从失败类声明、PR 预检到 manifest 清单凡是能用脚本或 CI 表达的要求都不依赖代理的判断力make preflight与 CI 执行同一份确定性清单保证本地与远端收敛。契约优先于症状Definition of Done、Failure-Class 边界修复、回归测试必须走可控接缝——整套体系反复强调修复被违反的契约并留下可复用守护面而非堆叠特例与 fallback。对希望让 AI 代理深度参与大型开源仓库维护的团队而言这份文档与其配套脚本提供了一个完整可复制的范本先建立代理永远需要重新学习的规则的显式载体再用版本化、被 CI 背书的机械检查让规则不漂移。【免费下载链接】FriendAI that sees your screen, listens to your conversations and tells you what to do项目地址: https://gitcode.com/GitHub_Trending/fr/Friend创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考