ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Kener 的 AGENTS.md:如何让 AI 编码 Agent 遵守跨数据库迁移与文档规范

Kener 的 AGENTS.md:如何让 AI 编码 Agent 遵守跨数据库迁移与文档规范
  • 可观测性
  • 后端
  • 前端
  • 运维

【免费下载链接】kener

Stunning status pages, batteries included!

项目地址:https://gitcode.com/gh_mirrors/ke/kener
点击查看免费下载

AGENTS.md 是 Kener 仓库中写给 AI 编码 Agent(Claude Code、支持 MCP 的 Agent 等)的行为契约,核心定义了三项硬约束:Svelte MCP 工具的使用流程、SQLite/PostgreSQL/MySQL 三数据库兼容的迁移编写规则,以及文档编写技能(documentation-writer)的强制调用时机。读完本文,你将理解这份 Agent 指令文件如何与 Kener 的 Knex 迁移、双进程架构和版本化文档系统实际落地,以及为什么这些约束在源码中能找到大量对应证据。

AGENTS.md 在仓库中的定位

Kener 是一个基于SvelteKit 2.x(Svelte 5)+ Node.js/Express的开源状态页应用,TypeScript 优先,提供实时监控、可用性追踪、事件管理与可定制仪表盘(CLAUDE.md)。仓库中为 AI 协作准备了三层指引文件,各司其职:

  • AGENTS.md:Agent 通用行为规则,包含 Svelte MCP 工具流程、数据库兼容性规则、文档技能入口,是跨工具(不限于 Claude Code)的通用约定;
  • CLAUDE.md:面向 Claude Code 的项目手册,描述项目是什么、开发命令、架构(双进程模型、路由分组、监控服务、构建系统)与关键编码约定;
  • docs/agents/下的三份协作文档:domain.md(单上下文 domain-doc 布局约定)、issue-tracker.md(GitHub Issues 作为 issue tracker,约定ghCLI 用法)、triage-labels.md(五个标准 triage 角色与仓库标签的映射表)。

这三层文件组合起来,让 Agent 在动代码之前就能知道:查 Svelte 语法去哪、写迁移必须遵守什么、改文档走哪个技能、issue 用什么标签、领域术语去哪查。

Svelte MCP 工具链:四步工作流

AGENTS.md 的第一部分要求 Agent 通过 Svelte MCP 服务器获取权威文档,而不是凭记忆猜测 Svelte 5 语法。四个工具及调用纪律如下:

工具职责AGENTS.md 规定的调用纪律
list-sections列出全部 Svelte/SvelteKit 文档章节(标题、use_cases、路径)必须最先使用;凡涉及 Svelte 或 SvelteKit 话题,会话开始时先调它定位相关章节
get-documentation按章节名取完整文档,支持单个或多个章节拿到list-sections结果后,必须分析use_cases字段,抓取所有与任务相关的章节,不能只取第一个
svelte-autofixer分析 Svelte 代码,返回问题与修改建议写 Svelte 代码提交给用户之前必须使用,且要反复调用直到无 issue 或 suggestion 返回
playground-link用给定代码生成 Svelte Playground 链接代码完成后先询问用户是否需要;若代码已写入项目文件则绝不调用

这套流程在仓库的 Agent 技能目录中有一一对应的 CLI 实现:.claude/skills/svelte-code-writer/SKILL.md 将上述 MCP 工具映射为npx @sveltejs/mcp命令——list-sections列出章节、get-documentation "$state,$derived,$effect"取 runes 文档、svelte-autofixer ./Component.svelte校验组件,并特别提示了 shell 下传递$state等 runes 代码时要把$转义为\$防止变量替换。该技能的 frontmatter 还要求"创建或编辑任何.svelte组件或.svelte.ts/.svelte.js模块时必须使用本技能",与 AGENTS.md 的svelte-autofixer强制条款互为呼应。

从仓库结构看,.claude/skills/下实际共有四个技能目录:documentation-writer、svelte-code-writer、ss-shadcn-svelte、tailwindcss。其中 ss-shadcn-svelte/SKILL.md 指导 Agent 在src/lib/components/ui/中挑选 shadcn-svelte 组件(先用scripts/detect.sh检测项目、再读组件文档、缺组件用npx shadcn-svelte add安装),tailwindcss/SKILL.md 则沉淀了 Tailwind CSS v4 的 utility-first 写法。这些技能的存在解释了 AGENTS.md 为什么只规定"流程纪律"而不展开具体技术细节——细节被下沉到了按需加载的技能文件里。

数据库兼容性规则:迁移必须在三种引擎上跑通

AGENTS.md 最有分量的部分是 Database compatibility rule(AGENTS.md 第 25–32 行)。它规定:所有数据库操作——迁移、查询、repository 函数——必须在 SQLite、PostgreSQL、MySQL 三种支持的数据库上都能工作;使用 Knex.js schema builder 与 query builder 抽象,除非包裹在 dialect-safe helper 或try/catch保护下,否则避免裸 SQL。具体到迁移文件,给出四条可执行规则:

  1. 用knex.schema.hasColumn/knex.schema.hasTable守卫保证幂等性;
  2. 使用 Knex 列类型(.string()、.integer()、.text()等),非必要不用裸ALTER TABLE;
  3. 迁移内部做数据播种时,用标准 Knex query builder(.insert()、.update()、.orderBy()、.first());
  4. 验证defaultTo()值与notNullable()约束在三种引擎上都生效。

规则背后的工程现实

先看连接配置。knexfile.ts 以DATABASE_URL唯一决定数据库类型,缺省回落到sqlite://./database/kener.sqlite.db;解析出sqlite时使用better-sqlite3客户端,postgresql用pg,mysql用mysql2,其余直接process.exit(1)(knexfile.ts)。也就是说,同一段迁移代码真的会在三个方言下执行,AGENTS.md 的规则不是纸面洁癖,而是部署现实。

更微妙的一点是 knexfile.ts 中注释说明的双连接池设计:Postgres/MySQL 下同一进程内存在 WEB 池(服务 SvelteKit 请求,DATABASE_POOL_MAX默认 10)和 WORKER 池(服务 BullMQ 后台任务与调度器,DATABASE_WORKER_POOL_MAX默认 5)两个池,隔离后台任务突发对页面加载连接的挤占;SQLite 没有真正的连接池,复用单连接。运行时路由实现在 src/lib/server/db/poolContext.ts——基于AsyncLocalStorage,队列处理器调用runWithWorkerKnex()包裹任务,repository 查询随之走 worker 池,上下文外(请求、启动、迁移)则落回 web 池。这解释了"repository 函数也要跨三库工作"这条规则为何同样重要:repository 是所有读写路径的最终落点,而入口正是 src/lib/server/db/db.ts 中那个由knexOb与workerKnexOb构成的单例(CLAUDE.md 也要求"Always use the db singleton")。

规则在真实迁移中的落地证据

/migrations/目录下 27 个迁移文件是这套规则的活教材。

幂等守卫(规则 1):20260124120001_monitor_alert_config_id.ts 在createTable前先hasTable("monitor_alerts_v2");20260831130000_add_oidc_support.ts 对users表每加一列都先hasColumn检查,down函数里删除前再检查一次。仓库中hasColumn/hasTable守卫在 25 个迁移文件中反复出现(如 20250111153517_init.ts 一处就有 10 处使用)。

try/catch 包裹的方言兜底(规则 2 的例外分支):20260124120001_monitor_alert_config_id.ts 把alter().unsigned()修正和外键添加都包进try/catch,注释写明"column may already be correct / foreign key may already exist"——因为不同引擎对重复alter、重名索引/外键的行为不一致。

SQLite 分支重建表(规则 2 的"必要时用裸 SQL"):最完整的案例是 20260325120000_multi_monitor_alerts.ts。该迁移要把monitor_alerts_config.monitor_tag从"一对一绑定监控器"改造为多对多,需要放开外键并置空列。Postgres/MySQL 走dropForeign+nullable().alter();而 SQLite 不支持ALTER COLUMN,于是up函数检查knex.client.config.client,在sqlite3/better-sqlite3分支里用PRAGMA foreign_keys = OFF→ 建新表 →INSERT ... SELECT迁移数据(monitor_tag置 NULL)→ 删旧表改名 → 重建索引的全套事务性重建流程,且裸 SQL 全部包在try/catch与事务中。

SQLite 专项跟进迁移:正因上次重建只完成了数据置空而无法改约束,仓库追加了 20260328120000_fix_sqlite_monitor_alerts_config_nullable.ts——文件头注释明确解释动机:"SQLite doesn't support ALTER COLUMN",因此只在 SQLite 客户端下用PRAGMA table_info检查notnull后重建表,其他数据库直接return。这种"一个跨库需求拆成两条方言特化迁移"的写法,正是 AGENTS.md 规则的典型产出形态。

迁移记录的自愈脚本:迁移文件从.js重命名为.ts后,老数据库的knex_migrations表里还记着旧文件名。scripts/fix-migration-ext.ts 是一个幂等修复脚本,把knex_migrations中%.js记录改名为.ts。package.json中migrate脚本被编排为vite-node scripts/fix-migration-ext.ts && npx knex migrate:latest,preseed同样先跑修复再迁移(package.json)。而生产入口 scripts/main.ts 在app.listen回调里先执行同名修复逻辑、db.migrate.latest()、再db.seed.run()——迁移与种子在进程启动时自动完成,无需手工干预。

数据种子与验证命令

迁移中做数据操作应走标准 query builder(规则 3),20260325120000_multi_monitor_alerts.ts 是示范:先select("id", "monitor_tag")拉取存量配置,按 100 条一批.insert()进 junction 表,再逐行.update()回填。种子数据独立放在/seeds/(knexfile.ts 配置seeds.directory),开发期npm run seed(自动先跑迁移)、npm run migrate单独跑迁移;验证规则 4(defaultTo()/notNullable()三引擎生效)的常规做法就是分别在三种DATABASE_URL下执行npm run migrate。

文档编写技能:documentation-writer 的强制入口

AGENTS.md 最后一段规定:当用户要求写或改文档时,必须遵循技能文件.claude/skills/documentation-writer/SKILL.md,优先短小、清晰、面向动作的文档,避免膨胀。这个"mandatory"级别在技能自身的 frontmatter 中同样声明("MUST be used whenever creating or editing documentation files in the src/routes/(docs)/docs/content/ directory or updating docs.json navigation")。

.claude/skills/documentation-writer/SKILL.md 的七条不可妥协规则值得摘录:

  1. 精简:删掉不帮助用户完成任务的重复与背景;
  2. 可操作:"做什么"优先于理论;
  3. 单一事实源:别处已有细节就链接过去,不复制;
  4. 保结构:保留有效 frontmatter 与标题锚点 ID;
  5. 示例可复制:最小、看起来经过验证、直接相关;
  6. 先搜再写:新增章节前确认内容是否已存在;
  7. 查代码:写文档前在src/中检索相关代码、注释与测试以保证准确。

技能还约束了文档系统的两个硬机制:

docs.json 版本化导航模型。Kener 的文档站点是版本化的(src/routes/(docs)/docs.json/docs.json) 中versions[].name为v4.x、slug为v4),侧边栏位于versions[].content.navigation.tabs[].sidebar,分组内含pages,页面路径用content字段。新增文档页必须挂进对应 tab 的 sidebar 路径。

强制版本化链接策略:v4 文档页的内部链接必须用显式 v4 路径/docs/v4/...,禁止在 v4 页面里使用/docs/alerting/...这类未带版本的捷径;定稿前需逐一验证每个内部链接解析到正确版本。配套规范还包括 frontmatter 必填title/description、H2/H3 使用自定义锚点(## Section {#section})、GitHub admonition([!NOTE]等)按需使用,以及一个九项 Review checklist(frontmatter 存在、步骤可复制、内容不重复、锚点稳定、导航已更新、内部链接正确、v4 链接合规、无过期内容、admonition 使用得当)。

SKILL.md推荐的标准页面结构也值得借鉴:短引言 → 最小配置/快速上手 → 必需变量选项表 → 验证步骤 → 高频故障排查,"只有当额外小节能实质性帮助用户完成任务时才添加"。这条"文档也要被 Agent 按技能约束"的规则,与 Svelte MCP、数据库规则一起构成了 AGENTS.md 的完整闭环:写代码查官方 MCP 文档、改数据库守三库兼容、写文档走精简技能。

实践验证:如何确认这些规则被执行

在本地验证 AGENTS.md 约束的落点,只需围绕 package.json 的脚本与 Node>=24.14.0环境(package.json):

npm run migrate # 先跑 fix-migration-ext.ts 再 knex migrate:latest npm run seed # 迁移自动先行,再执行 seeds/ npm run check # svelte-kit sync + svelte-check 类型检查 npm test # TZ=UTC 下跑 server 单测 + 浏览器组件测试 npm run test:server # 仅 Node 侧单测 npm run test:client # 组件测试(需一次性 npx playwright install chromium)

其中组件测试需先执行一次npx playwright install chromium(CLAUDE.md 明确说明);测试通过cross-env TZ=UTC vitest固定时区,这与 src/lib/server/startup.ts 中process.env.TZ = "UTC"的全局 UTC 约定一致——所有时间戳以 UTC 秒存储(CLAUDE.md 的 Key Conventions)。想复核"迁移三库兼容",就分别设置DATABASE_URL为sqlite://...、postgresql://...、mysql://...后执行npm run migrate,重点观察 20260325120000_multi_monitor_alerts.ts 这类含 SQLite 分支的迁移在各引擎下的行为是否一致。

小结:一份 40 行文档的工程价值

AGENTS.md 全文不长,但它把三类高频出错场景都钉死了标准答案:Svelte 语法不确定 → 先list-sections再get-documentation,提交前过svelte-autofixer;写迁移 →hasColumn/hasTable幂等守卫、Knex 类型优先、裸 SQL 必须有 dialect 分支或try/catch兜底、defaultTo()/notNullable()三引擎验证;改文档 → 强制走 documentation-writer 技能的精简规则与版本化链接策略。

仓库中的实际代码印证了这些规则不是空话:knexfile.ts 的三客户端分支、27 个迁移文件里密集的幂等守卫与 SQLite 重建表分支、scripts/fix-migration-ext.ts 的历史债务自愈、poolContext.ts 的 web/worker 池隔离,都是规则执行后的沉淀。对维护多数据库支持的 SvelteKit 项目而言,这份 AGENTS.md 展示了一个可借鉴的模式:用一份短小的 Agent 契约,把散落在注释、迁移和脚本里的隐性经验,变成 AI 与人类开发者共同遵守的显性纪律。

  • 可观测性
  • 后端
  • 前端
  • 运维

【免费下载链接】kener

Stunning status pages, batteries included!

项目地址:https://gitcode.com/gh_mirrors/ke/kener
点击查看免费下载

相关推荐

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

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进