资讯动态

Multica 的 AI 代理开发契约:AGENTS.md 仓库指南详解——架构分层、状态管理硬规则与数据库迁移约束

发布时间:2026/9/6 18:31:51 来源:尧图企业网站定制
Multica 的 AI 代理开发契约AGENTS.md 仓库指南详解——架构分层、状态管理硬规则与数据库迁移约束【免费下载链接】multicaMake humans and AI agents work as one team — open-source and self-hostable.项目地址: https://gitcode.com/GitHub_Trending/mu/multicaAGENTS.md 是 Multica 仓库为 AI 代理以及任何新加入的工程师编写的「单一入口」开发指南它声明了 Go 后端 pnpm/Turborepo 前端 monorepo 的整体架构并给出状态管理、包边界、数据库迁移四类不可妥协的硬规则。读完后你将掌握 Multica 各目录的职责划分、React Query 与 Zustand 的状态分工依据、跨 web/desktop 共享代码的边界约束以及迁移系统刻意放弃整体事务的设计原因。AGENTS.md 的定位指针文档而非规则本体AGENTS.md 开头就声明了自己的角色Single source of truth:This file is a concise pointer document. All authoritative architecture, coding rules, and conventions live inCLAUDE.mdat the project root.也就是说这份文件是「快速参考 指针」完整的权威规则在同级目录的 CLAUDE.md 中例如命令列表以 Makefile、package.json、pnpm-workspace.yaml 为准。对 AI 代理来说这种分层设计是刻意为之——代理先读 AGENTS.md 建立仓库心智模型需要更深规则乐观更新四条件、API 兼容性、UUID 处理、测试分层表等时再跳转 CLAUDE.md避免两份文档互相复制后失同步。架构总览Go 后端 共享包分层的前端 monorepoAGENTS.md 的 Quick Reference 给出了一张目录级架构图Go backend monorepo frontend (pnpm workspaces Turborepo) with shared packages. - server/ - Go backend (Chi router, sqlc, gorilla/websocket) - apps/web/ - Next.js frontend (App Router) - apps/desktop/ - Electron desktop app - apps/mobile/ - Expo / React Native iOS app (read apps/mobile/CLAUDE.md first) - apps/docs/ - Fumadocs documentation site - packages/core/ - Headless business logic (Zustand stores, React Query hooks, API client) - packages/ui/ - Atomic UI components (shadcn/Base UI, zero business logic) - packages/views/ - Shared business pages/components - packages/tsconfig/ - Shared TypeScript config - packages/eslint-config/ - Shared ESLint config这条描述可以与仓库实际内容一一印证后端server/go.mod 中声明了github.com/go-chi/chi/v5 v5.3.0、github.com/gorilla/websocket v1.5.3与 AGENTS.md 的「Chi router、gorilla/websocket」一致sqlc 代码生成由make sqlc驱动Makefile 中的sqlc:目标注释为 Regenerate sqlc code。工作区pnpm-workspace.yaml 只声明了apps/*与packages/*两组 glob与目录树一一对应根 package.json 的dev:web/build/typecheck等脚本全部通过turbo ... --filter调度engines要求node 22与 CLAUDE.md 中「CI runs Node 22」的表述吻合。移动端是孤岛文档特意注明进apps/mobile/之前先读 apps/mobile/CLAUDE.md。根 package.json 里build/typecheck/test/lint全部带--filter!multica/mobile从源码结构看移动端确实被显式排除在统一的 Turborepo 流水线之外拥有独立的 React 版本与构建管线。CLAUDE.md 进一步补充了一条依赖方向规则共享包以原始.ts/.tsx源码导出、由消费方应用编译依赖方向是views - core ui且core与ui必须保持相互独立。状态管理criticalReact Query 管服务端Zustand 管客户端这是 AGENTS.md 中标注 critical 的章节四条规则逐条展开React Query 拥有全部服务端状态——issues、members、agents、inbox、workspace 列表等一切来自 API 的数据Zustand 拥有客户端/视图状态——视图过滤器、草稿、模态框、桌面端 tab 状态当前 workspace 身份由路由驱动仅向平台层镜像用于请求头、存储命名空间、WebSocket 重连所有 Zustand store 必须放在packages/core/禁止出现在packages/views/或各 app 目录WS 事件更新 React Query 缓存store 只允许用于「清空客户端自己持有的指针」且必须带单一响应者/自事件守卫。仓库中的实际代码印证了第 3 条Zustand 的create()调用集中在packages/core/下的各域例如 view-store.ts、actor-issues-view-store.ts、my-issues-view-store.ts 与 config store。而 CLAUDE.md 对第 4 条给出了更严的操作定义WebSocket 事件只能 invalidate 或 patch Query 缓存绝不许把服务端 payload 镜像进 Zustand只有当「本客户端自己可能触发了该事件」时才允许清理 active session、selection 等客户端指针且必须通过 self-initiated guard 防止自己发的消息又把自己清理掉。这条规则的工程动机从仓库结构也能看出web 与 desktop 共享同一套packages/core/的 hooks 和 stores如果 WS 事件写 Zustand 缓存数据两端各自实现一次守卫很容易在 Electron 多窗口每个渲染进程一个 WS 连接场景下产生竞争——而「单一响应者 自事件守卫」正是为多窗口环境设计的。版本层面pnpm-workspace.yaml 的catalog:段锁定了tanstack/react-query: ^5.96.2与zustand: ^5.0.0即文档中的 React Query 指 TanStack Query v5。包边界hard rules用依赖方向换取三端共享AGENTS.md 的四条硬边界包/目录硬约束packages/core/零react-dom、零localStorage、零process.envpackages/ui/零multica/core导入packages/views/零next/*、零react-router-dom路由一律走NavigationAdapterapps/web/platform/Next.js API 的唯一落点这组约束的本质是core与ui互不依赖views依赖两者于是同一份业务代码能同时被 Next.jsweb和 Electrondesktop两个平台编译。CLAUDE.md 补充了对应的正向做法与额外约束core中持久化要用StorageAdapter而非localStorage让桌面端可以换成自己的存储packages/views/使用NavigationAdapter、useNavigation()和AppLink做路由抽象apps/desktop/src/renderer/src/platform/是react-router-dom的唯一接线处每个 workspace 必须在自己package.json中声明直接导入的外部依赖共享依赖版本统一走pnpm-workspace.yaml的catalog:机制apps/mobile/例外直接钉住 Expo/React Native 相关版本。「零react-dom、零localStorage、零process.env」这条规则之所以值得单独强调是因为这三样恰好是 headless 包在 SSRNext.js 服务端渲染和 Electron 主进程环境下最容易踩的雷SSR 阶段没有window.localStorageElectron 中process.env的注入方式与浏览器完全不同。把约束钉死在包边界上而不是依赖开发者自觉是该仓库共享代码规模能做大的前提。数据库迁移hard rules禁外键 索引必须 CONCURRENTLYAGENTS.md 给出两条迁移硬规则它们都能在源码中找到落点1. 禁止外键与级联Never add database foreign keys or cascading actions. Enforce relationships and perform dependent cleanup explicitly in the application layer, using transactions when the operation must be atomic.即关系校验与依赖清理全部显式写进应用代码当清理必须与父操作原子提交/回滚时用应用层事务。CLAUDE.md 的表述一致禁止FOREIGN KEY/REFERENCES、级联删除、级联更新。2. 每个索引必须CREATE [UNIQUE] INDEX CONCURRENTLY且单独成文件Every index created by a migration, including unique indexes and indexes on new tables, must useCREATE [UNIQUE] INDEX CONCURRENTLY. Keep each concurrent index build in its own single-statement migration file.仓库的迁移目录大量遵循该模式例如 170_skill_label_lookup_index.up.sql、418_seat_capacity_due_index.up.sql 等均使用CREATE INDEX CONCURRENTLY。为什么必须单独成文件答案在迁移执行器源码里。server/cmd/migrate/main.go 的注释写得很直白// We deliberately do NOT wrap the loop in a single transaction: the // repo already ships migrations using CREATE INDEX CONCURRENTLY, // which Postgres rejects inside a transaction block.迁移循环刻意不包在单一事务里同时用pg_advisory_lock固定一条pgxpool.Conn做会话级锁避免锁挂在被回收的随机连接上。因为 PostgreSQL 拒绝在事务块内执行并发建索引所以每个 CONCURRENTLY 语句必须独占一个单语句迁移文件。CLAUDE.md 还补充了一条容易被忽略的规则条件跳过的迁移仍会记入schema_migrations因此台账只证明顺序、不证明每条 SQL 都执行过后续涉及「条件存在的对象」的迁移必须写幂等 DDLIF EXISTS/IF NOT EXISTS。server/cmd/migrate/README.md 就给出了一个真实运维案例迁移 371 在pg_bigm可用时建 bigram 索引、否则回退pg_trgm索引一旦回退索引被误删需要手工在事务外逐条执行CREATE INDEX CONCURRENTLY恢复并用pg_index的indisvalid/indisready/indislive三个标志验证后才可恢复流量。命令速查从文档到可运行的验证管线AGENTS.md 给出的最小命令集make dev # Auto-setup start everything pnpm typecheck # TypeScript check pnpm test # TS unit tests (Vitest) make test # Go tests make check # Full verification pipeline对照仓库实现这些命令的真实行为是Makefile 的dev:目标注释为 Bootstrap this checkout end-to-end: create env if needed, ensure DB, migrate, start services——即自动建环境、确保数据库、跑迁移、起服务test:目标会在跑 Go 测试前先确保目标库存在且迁移已应用check:目标执行 Run typecheck, TS tests, Go tests, and Playwright E2E for the current checkout实际委托给 scripts/check.sh其内部管线为typecheck → 单测 → Go 测试 → E2Echeck.sh 开头注释即 Full verification pipeline: typecheck → unit tests → Go tests → E2Epackage.json 的test脚本是turbo test --filter!multica/mobile即 Vitest 单测经 Turborepo 调度且排除移动端与文档中「TS unit tests (Vitest)」对应。CLAUDE.md 在此基础上给出完整的开发环境命令族make up/status/list/down/destroy/worktree-env等及其细节make up把每个开发环境登记到~/.multica/dev/在锁下分配 API/Web/Desktop 端口与数据库名并通过DATABASE_URL而非docker exec验证数据库worktree 之间共享一个 PostgreSQL 容器用.env.worktree隔离库名与端口。此外 CI 环境为 Node 22 最新 Go 1.26 patch pgvector/pgvector:pg17PostgreSQL 服务。总结AGENTS.md 作为指针文档的价值在于「少而硬」它把 Multica 真正容易出错的四件事——目录职责、服务端/客户端状态归属、共享包依赖方向、迁移 DDL 约束——压缩成一张速查表其余细节通过 CLAUDE.md 与 Makefile/pnpm-workspace.yaml 这三个「单一事实源」继续下钻。如果你在 AI 代理协助下向这个仓库提交代码值得逐字对照的正是文中两个 (hard rules) 章节包边界违反会让三端共享代码退化迁移规则违反则可能让CONCURRENTLY建索引在事务里直接失败或阻塞线上写入。【免费下载链接】multicaMake humans and AI agents work as one team — open-source and self-hostable.项目地址: https://gitcode.com/GitHub_Trending/mu/multica创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价