open-seo 仓库的 Agent 协作指南:工程原则、审阅规则与安全边界
【免费下载链接】open-seoOpen source alternative to Semrush and Ahrefs项目地址: https://gitcode.com/GitHub_Trending/op/open-seo
本篇文章基于开源仓库 AGENTS.md(Agent guidance)展开,面向所有在本仓库内工作的 AI 编码 Agent(Claude Code、Codex 等)与维护者,梳理本仓库对 Agent 协作的工程约束、审阅流程与安全边界。读完你可以掌握:如何按本仓库的工程原则组织代码与数据、遇到小摩擦时如何记录 papercuts、审阅结论何时该沉淀为长期规则,以及哪些文件变更必须经过维护者明确批准。
一、AGENTS.md 在仓库中的角色
AGENTS.md 是本仓库给 AI Agent 的"第一份指令",它定义了 Agent 在本仓库内写代码、提交审阅、维护工具链时应遵守的约定。与它功能相似、但面向不同 Agent 产品的是 CLAUDE.md(为 Claude Code 提供相同原则,并额外补充了测试规范)。两个文件的存在说明:这类 Agent 指令文件是仓库协作控制面(review control plane)的一部分,其变更本身也需要受控。
AGENTS.md 的结构非常精简,由三部分组成:
- Engineering principles—— 写代码时的工程原则;
- Log papercuts—— 遇到仓库"小摩擦"时的记录约定;
- Preserve review learnings—— 审阅结论如何沉淀为长期规则。
这种"先给原则、再给过程约定、最后给变更边界"的结构,也是值得其他 AI 辅助开发仓库借鉴的模板。
二、工程原则:简单、扁平、少抽象
AGENTS.md 的第一部分定义了 8 条工程原则,核心思想可以概括为"在正确的地方做正确的事":
- 偏爱简单、可读、扁平的代码,尽量减少间接层(minimal indirection)。间接层增加认知负担,只有在真正防止"有意义漂移"(meaningful drift)时才抽象,避免投机性(speculative)或一次性使用的抽象层。
- 创建新 helper 或抽象之前,先搜索现有实现和已安装的库。这条与仓库实际的依赖管理一致:例如项目大量依赖 zod 做运行时校验、TanStack 系列做路由/查询/表单,而不是自研。
- 保持产品数据规范化、关系显式化。不要在 JSON 或文本里编码关系型数据来逃避 join。
- 新增应用后端功能时,默认采用分层结构:TanStack server function → service → repository。这一条在仓库中可以直接印证:看 src/serverFunctions/projects.ts 的写法,
createServerFn只负责请求入口与权限检查,真正的业务逻辑委托给ProjectService(如ProjectService.createProject、ProjectService.updateProject),而数据访问在 repository 层。 - schema 变更、查询和变更操作必须同时兼容 SQLite 和 Postgres。这也是为什么仓库同时维护了 drizzle(SQLite/D1)与 drizzle-pg(Postgres)两套迁移目录,并存在 schema-parity.test.ts 这类测试来保证两套 schema 的一致性。
- 使用惯用 TypeScript;用 Zod 校验不可信数据,并在信任边界(trust boundaries)收窄运行时值。信任边界的典型例子:所有外部输入在进入 handler 前都先过 validator。
- 优先使用项目已有的 helper 和库,而不是手写实现。
- 对服务端状态、路由和表单提交,优先使用 TanStack Query、Router 和 Form 的惯用模式。
源码印证:server function → service → repository
以项目管理的 server function 为例,src/serverFunctions/projects.ts 展示了一个典型的四步模式:
export const createProject = createServerFn({ method: "POST" }) .middleware(requireAuthenticatedContext) // 1. 认证中间件 .validator(createProjectSchema) // 2. Zod 校验(信任边界) .handler(async ({ data, context }) => { // 3. 权限检查 requireOrgPermission(context, { project: ["create"] }); return ProjectService.createProject(context.organizationId, data); // 4. 委托给 service });这里清晰地体现了三条原则:中间件负责上下文解析、validator 负责信任边界的 Zod 校验、handler 不直接触碰数据库而是委托 service。数据校验的细节沉淀在 src/types/schemas/projects.ts,例如createProjectSchema对项目名做了.trim().min(1).max(120)的限制,并有一个有趣的约束——languageCode必须伴随locationCode(hasLocationForLanguagerefine),否则报错 "A language requires a location."。这个"语言必须伴随地点"的配对校验,正是"在信任边界收窄运行时值"的实例。
源码印证:双数据库兼容
"兼容 SQLite 与 Postgres"不只是口头约定。仓库根目录同时存在 drizzle.config.ts(D1/SQLite)与 drizzle-pg.config.ts(Postgres),package.json 中db:generate脚本同时生成两套迁移:
"db:generate": "npm run db:generate:d1 && npm run db:generate:pg", "db:generate:d1": "drizzle-kit generate", "db:generate:pg": "drizzle-kit generate --config drizzle-pg.config.ts"而 src/db/schema-parity.test.ts 这类测试用于防止两套 schema 在演进中产生漂移。这意味着任何 Agent 提交的 schema 变更,都必须同时考虑两种方言的写法。
三、Log papercuts:把"小摩擦"记下来
AGENTS.md 要求 Agent 在遇到小的、不阻塞的仓库摩擦时——例如重试的工具调用、令人困惑的搭建步骤、不稳定的命令、过期的缓存、误导性的报错、不明显的坑——当场使用papercutsskill 并追加到.agents/PAPERCUTS.md,然后继续当前任务。
这条约定有几个关键边界:
- 只在当下记录(in the moment),不允许在会话结束后回头"挖掘"整段会话的 papercuts,也不允许在用户没有明确要求时发起大规模清理。
- 区分 papercuts 与真 bug:真实的 bug 和已跟踪的工作不算 papercuts;敏感数据绝不能记录(sensitive data must never be logged)。
- 本仓库当前工作区中尚未存在
.agents/PAPERCUTS.md,这正是设计意图——该文件由遇到摩擦的 Agent 在需要时创建,而不是预置的空模板。
这种做法的价值在于:把"踩坑经验"从 Agent 的一次性会话中沉淀为仓库的持久记忆,让后续的 Agent 无需重新踩同样的坑。
四、Preserve review learnings:审阅结论的沉淀与边界
第三部分针对代码审阅:当一次 merge-ready(或其它)审阅验证了某个发现后,只有在以下条件同时满足时才使用maintain-greptile-rules将其提升为长期规则:
- 该发现暴露的是反复出现或高风险的仓库不变量(recurring or high-risk repository invariant);
- 现有的
.greptile/上下文和自动化检查尚未覆盖这一不变量。
同时明确禁止:把一次性 bug 或个人偏好提升为永久审阅规则。这防止了规则库被低价值规则污染。
审阅控制面(review control plane)与变更边界
AGENTS.md 明确指出以下文件属于审阅控制面,对它们的任何变更都必须得到维护者的显式审阅:
.greptile/**AGENTS.mdCLAUDE.md.agents/skills/**.github/**
控制面文件会直接影响"谁来审、审什么、怎么审",因此是高风险区域。仓库还要求:
CODEOWNERS请求对这些文件的审阅;在仓库设置允许的情况下,开启 GitHub 对 code-owner 批准的要求(require code-owner approval);- 仓库专属规则放在
.greptile/;维护者应配置或保留一个最小化的、由组织强制执行的 Greptile 基线(baseline),覆盖外部贡献、密钥、认证、计费、CI 和规则篡改(rule-tampering)风险; - Agent 如果发现基线缺失或未经验证,必须上报,且未经用户明确授权不得修改 dashboard 或组织规则。
这条边界背后的安全考量:外部贡献者的代码提交、密钥泄露、认证/计费逻辑被篡改、CI 被注入、或者审阅规则本身被悄悄修改,都是高风险的供应链攻击面。把"谁可以改审阅规则"这个元问题单独拎出来管控,是 AGENTS.md 中最重要的安全设计。
与 CLAUDE.md 的关系
CLAUDE.md 是给 Claude Code 的镜像指令:工程原则部分与 AGENTS.md 完全一致,但额外增加了Testing一节,约定测试规范,例如:不为测试而测试、测试要覆盖"可能真实发生的核心行为或难以发现的边界情况"、在公共入口测试行为、静态导入被测模块(vi.mock会被提升,因此禁止无理由的await import()与vi.resetModules())、测试中不得重新声明生产类、一个测试对应一个不变量、不 mock ORM 构建链等。这解释了为什么仓库的测试文件(如 src/db/schema-parity.test.ts)普遍轻量且聚焦行为而非实现细节。
五、对 Agent 与维护者的实践清单
综合 AGENTS.md 的全部内容,可以在本仓库工作的 Agent 和负责审阅的维护者各总结一份实践清单。
Agent 应该做:
- 写扁平、可读的代码,先搜索已有实现再新建 helper;
- 新增后端功能走
server function → service → repository分层; - 在信任边界用 Zod 校验,保持 schema 对 SQLite/Postgres 双兼容;
- 遇到小摩擦当场用
papercutsskill 记录到.agents/PAPERCUTS.md,并继续当前任务; - 审阅发现满足"反复出现或高风险 + 现有检查未覆盖"时,才用
maintain-greptile-rules沉淀规则。
Agent 不应该做:
- 不创建投机性或一次性抽象层;
- 不在 JSON/文本中编码关系数据来逃避 join;
- 不把一次性 bug 或个人偏好提升为永久审阅规则;
- 不未经授权修改 dashboard 或组织规则,发现基线缺失只上报、不擅动;
- 不记录敏感数据到 papercuts。
维护者应该做:
- 对
.greptile/**、AGENTS.md、CLAUDE.md、.agents/skills/**、.github/**的变更保持显式审阅,配置 CODEOWNERS 并要求 code-owner 批准; - 将仓库专属规则存放在
.greptile/,保留组织级最小 Greptile 基线以覆盖外部贡献、密钥、认证、计费、CI 与规则篡改风险; - 在仓库实际演进过程中验证基线是否存在且可信。
六、总结
AGENTS.md 是一份"给 Agent 的工程宪法",它的价值不在于篇幅,而在于把三件事讲清楚了:怎么写出符合仓库风格的代码(扁平化、少抽象、分层明确、双数据库兼容、信任边界校验)、过程性经验如何沉淀(papercuts 即记即用,规则提炼谨慎克制)、审阅控制面如何防守(控制面文件变更需显式审阅,组织级基线不可被 Agent 私自改动)。对于任何想要深度参与 open-seo 开发的 Agent 或维护者,这份文件都是理解仓库协作契约的起点——配合 CLAUDE.md 的测试规范和 CONTRIBUTING.md 的贡献流程,可以快速对齐仓库的开发预期。
【免费下载链接】open-seoOpen source alternative to Semrush and Ahrefs项目地址: https://gitcode.com/GitHub_Trending/op/open-seo
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考