AI驱动的多仓库开发简单模式
这里没有聪明的依赖图。没有锁文件,没有需要安装的特殊CLI。
博途PLC工程智能体 | AI智能体博途网关 | 梯形图转SCL | 自然语言生成梯形图 | 自然语言生成SCL | 逆向生成程序块文档 | 梯形图在线查看 | 博途编程文档MCP | AI模型价格对比 | AI工具导航 | ONNX模型库 | Vibe Coding教程 | PLC在线仿真器 | Tripo 3D | Meshy AI
特征团队通常拥有边界上下文,这些上下文经常跨越多个仓库,包含UI、API等逻辑。近年来,许多公司跳上了微服务架构的列车。这是件很酷的事情。微服务越多越好。但随着智能体软件开发的普及,由此产生的多仓库策略意味着"天堂"中的麻烦。代理的生产力与提供给它们的上下文的质量和完整性息息相关。理想情况下,该上下文包含来自整个边界上下文的信息:技能、指令、钩子等,以处理所有服务、UI应用程序和基础设施组件。
那么,如果你可以毫不费力地让AI代理在团队拥有的每个服务、UI和环境配置中获得完整的上下文可见性呢?而无需引入单体仓库?我和我的团队正面临着完全相同的挑战。我们在规范驱动开发方面相当先进,但希望进一步推进我们的智能体软件开发生命周期。
1、没有人谈论的问题
你有一个边界上下文。假设你正在构建一个在线书店。你的团队拥有:
bookstore-ui,一个Angular单页应用程序,客户在这里浏览和购买书籍。bookstore-api,一个Spring Boot微服务,处理目录、订单和库存。dev-env/acc-env/prd-env,三个环境配置仓库,包含Kubernetes清单、ArgoCD应用定义和部署脚本。
五个仓库,五个独立的Git历史记录,五个独立的CI/CD管道。每一个都很干净、结构良好,并且完全不知道其他仓库的存在。在这些目录中启动的代理也缺乏其他仓库的上下文。
这就是问题所在。
当你想发布一个功能时,比如一个新的"推荐书籍"部分,你(或代理)会触及API(新端点)、UI(新组件)和至少一个环境配置(更新的镜像标签)。三个仓库,三个分支,三个拉取请求。假设你实践规范驱动开发,最终目标将是为推荐书籍功能定义规范,代理一次完成实现,完全规范驱动,跨越整个边界上下文。
事实证明,有一种方法,而且它几乎简单得令人尴尬。
2、边界上下文:创意的根源
如果你在领域驱动设计上花过时间,你就知道边界上下文的概念:围绕属于一起的一组模型、服务和规则的清晰边界。在我们的例子中:书店的目录逻辑、订单处理、面向用户的UI:它们形成了一个上下文。它们一起演化,由同一个团队拥有,并共享一种通用语言。
大多数团队在设计层面就将此内化。他们在白板上画出边界,在接缝处定义API,沿着上下文线分配团队所有权。但当涉及到工具和工作区组织时,边界就消失了。每个仓库都生活在自己的孤岛中。边界上下文存在于团队的脑海中,在Confluence页面中,可能在电子表格中,但不在开发人员(现在是代理)实际工作的文件系统中。
如果边界上下文也是我们AI代理的工作区组织单元呢?
3、解决方案:带.gitignore的工作区仓库
整个事情分三步完成:
- 创建一个名为
bookstore-platform的轻量级Git仓库。这是你的上下文工作区。 - 将每个组件克隆到其中(
bookstore-ui、bookstore-api、dev-env、acc-env、prd-env)作为常规子目录。 - 将每个子目录添加到工作区的
.gitignore中。
三步完成。以下是结果的样子(此示例是使用GitHub Copilot完成的,但模式适用于所有编码代理工具)。
目录布局:
bookstore-platform/ ← 工作区仓库(拥有自己的Git历史记录)
├── .git/
├── .gitignore
├── .github/
│ ├── copilot-instructions.md
│ └── skills/
│ ├── release-ui/ ← 工作区级技能
│ │ └── SKILL.md
│ ├── release-api/ ← 工作区级技能
│ │ └── SKILL.md
│ ├── release-check/ ← 工作区级技能
│ │ └── SKILL.md
│ ├── git-branching-strategy/ ← 工作区级技能
│ │ └── SKILL.md
│ ├── api-run-e2e-tests/ ← 符号链接 → bookstore-ui技能
│ └── api-run-integration-tests/ ← 符号链接 → bookstore-api技能
├── README.md
├── bookstore-ui/ ← 独立Git仓库(Angular)
│ ├── .git/
│ ├── .github/
│ │ ├── copilot-instructions.md
│ │ └── skills/
│ │ └── run-e2e-tests/
│ ├── src/
│ └── ...
├── bookstore-api/ ← 独立Git仓库(Spring Boot)
│ ├── .git/
│ ├── .github/
│ │ ├── copilot-instructions.md
│ │ └── skills/
│ │ └── run-integration-tests/
│ ├── src/
│ └── ...
├── dev-env/ ← 独立Git仓库
│ ├── .git/
│ └── ...
├── acc-env/ ← 独立Git仓库
│ └── ...
└── prd-env/ ← 独立Git仓库
└── ...
.gitignore
# 组件仓库 — 每个都是独立的Git项目。
# 它们被克隆到此工作区以实现跨项目可见性,
# 但不会被工作区仓库跟踪。
/bookstore-ui/
/bookstore-api/
/dev-env/
/acc-env/
/prd-env/
每个子目录对工作区仓库的版本控制都是不可见的。bookstore-platform中的提交永远不会触及子项目。bookstore-api中的提交永远不会触及工作区。它们并排共存,完全独立。
工作区仓库本身几乎是空的。目前,它跟踪一个README、一个.gitignore和一个包含AI代理指令、技能以及可能其他工具定义的.github/目录。这就是它的全部职责。
4、简单胜过复杂:为什么不用Git子模块?
如果你曾经尝试过用git子模块来解决这个问题,你就知道其中的痛苦。你git submodule add每个仓库,提交一个.gitmodules文件,从此每个开发者都必须在clone、pull和checkout时记住--recurse-submodules。忘记一次,你就会盯着一个分离的HEAD,想知道哪里出了问题。
在日常工作中,子模块是持续摩擦的根源。它们将每个子项目固定到父仓库中的特定SHA,这意味着更新子模块本身就是一个提交。分支会发散,子模块指针在合并时会发生冲突,而入职新成员需要一个小讲座,讲解如何不破坏一切。CI/CD管道需要特殊的检出逻辑。围绕子模块的工具很脆弱。而根本的权衡是耦合:父仓库锁定到每个子项目的特定版本,而这正是你在子项目独立发布时所不想要的。
.gitignore工作区没有这些问题。你git clone每个仓库到工作区文件夹就完成了。每个目录都有自己的分支、自己的历史记录、自己的CI管道。没有特殊命令,没有指针提交,没有同步版本控制。工作区仓库甚至不知道子项目的存在,因为它们在.gitignore中。你需要共见性而非耦合,而.gitignore方法以零工具开销为你提供了这一点。
5、跨越工作区级别的技能
如果你正在使用AI编码代理,这部分最重要。
工作区仓库的.github/skills/目录是跨职能代理技能的天然之家:跨越你边界上下文中所有组件的指令和分步过程。没有单个仓库可以拥有这些,因为它们涉及跨仓库的协调。
在书店的例子中,工作区可能定义:
- release-ui: 更新
acc-env和prd-env的kustomization文件以引用最新的bookstore-ui镜像标签,然后打开一个拉取请求。 - release-api: 相同的事情,但针对Spring Boot API。
- release-check: 验证发布分支中的所有组件在所有环境中是否都处于最新标签。"我们是否忘记在生产中升级API?"
- git-branching-strategy: 在所有仓库中一致执行的共享分支模型。
这些技能编码了跨越仓库的团队知识,这种知识通常存在于团队wiki、Slack线程或某人的脑海中。将其放在工作区中使其可执行。代理可以阅读技能,理解过程,并执行它们。
工作区copilot-instructions.md提供了全局视角:
# 书店平台
此工作区包含书店边界上下文的所有组件。
每个子目录都是一个独立的Git仓库。
## 组件
- **bookstore-ui**:面向客户的店面Angular SPA。
- **bookstore-api**:用于目录、订单和库存的Spring Boot服务。
## 环境
- **dev-env**:开发环境(ArgoCD、清单、脚本)。
- **acc-env**:验收环境。
- **prd-env**:生产环境。
当代理打开此工作区时,它立即知道这里有什么,每个部分的作用,以及它们如何关联。这个上下文改变了代理能为你做的一切。显然,这个模式也可以类似地为Claude Code创建,对文件夹/文件命名进行轻微调整。
6、子组件技能和符号链接
每个子项目也应该有自己的.github/skills/,包含特定于组件的指令。bookstore-api可能有一个运行集成测试或构建新REST端点的技能。bookstore-ui可能有一个运行Cypress端到端测试或生成新Angular组件的技能。
诀窍是将这些子组件技能符号链接到工作区根目录。这样,当你从工作区根目录启动代理时,它会获取所有技能:既包括跨职能的工作区技能,也包括特定于组件的技能。
cd bookstore-platform/.github/skills/
ln -s ../../../bookstore-api/.github/skills/run-integration-tests api-run-integration-tests
ln -s ../../../bookstore-ui/.github/skills/run-e2e-tests api-run-e2e-tests
每个技能的真实来源都保留在自己的仓库中。工作区只是在一处展示它们,以便代理拥有完整的工具箱。将新技能添加到bookstore-api,将其符号链接到工作区,每个拉取工作区根目录最新版本的开发者/代理都会自动获得它。
7、代理优势
现代AI编码代理(GitHub Copilot、Claude Code以及不断增长的代理CLI列表)在你的工作目录树中运行。它们根据被允许查看的内容来索引文件、搜索代码、读取指令和执行技能。如果你打开一个仓库,代理只知道那个仓库。打开上面介绍的工作区根目录,它默认会看到所需的一切。
这在实践中为你带来了什么?假设开发者在bookstore-platform工作区根目录启动AI代理:
- 跨组件搜索: "在UI和API中查找
ISBN类型的所有引用。"一次搜索,全局视图。 - 发现跨服务不匹配: 代理可以看到API的响应DTO和使用它们的UI的TypeScript接口。它会注意到它们何时产生偏差。
- 运行跨职能技能: "将新API版本发布到验收环境。"代理读取
release-api技能,获取最新标签,更新acc-env中的kustomization文件,并打开拉取请求。开发者无需切换目录或仓库。代理也不必切换,所有技能和指令在会话开始时就已加载。没有丢失的上下文。 - 规划端到端功能: "我需要添加一个书籍愿望清单功能。"代理在一个对话中推理API更改、UI组件和环境配置。它在每个仓库中创建分支,搭建代码,并保持一切一致。
- 检查运行状态: "发布分支中的所有组件是否都处于最新版本?"
release-check技能会跨所有环境仓库运行并报告结果。
没有工作区时,代理一次只能看到一个仓库,即大象的一个切面。有了工作区,它就能看到整个动物。
8、特征团队和端到端能力
如果你的团队拥有一个边界上下文,工作区会给你一些具体的东西:
- 一个
cd命令进入你的世界:代码、配置、环境,全部在一个地方。 - 协调发布,无单体仓库开销: 每个仓库保持自己的CI/CD、自己的标签、自己的发布节奏。当你需要时,工作区的发布技能会在它们之间协调,但没有任何东西被耦合。
- 端到端功能开发: AI代理现在拥有你整个边界上下文的上下文,以及所有技能、指令和其他工具,以便进行最佳的端到端功能开发。
- 运维可见性: "生产中部署的API是什么版本?"代理检查
prd-env仓库的kustomization文件并告诉你,因为它就在工作区中。 - 多个团队可以有重叠的工作区: 如果你的边界上下文与另一个团队共享一个组件(比如一个共享的身份验证服务),每个团队都可以将其包含在自己的工作区中。没有冲突。它只是一个目录。仓库不知道也不关心有多少工作区引用它们。
- 规范和知识集中在中心空间: 规范是新的真实来源。通过将它们集中在一处,代理可以随时访问它们。传统开发人员也可以。技能记录了与边界上下文交互的最常见方式:开发、测试、发布过程等。
9、结束语
这里没有聪明的依赖图。没有锁文件,没有需要安装的特殊CLI。一个文件夹和一个.gitignore不会赢得架构奖,老实说,它几乎简单得让人难以认真对待。
但这就是重点。
Git子模块、单体仓库、多仓库编排工具:它们都增加了认知负担。它们要求团队中的每个开发者学习它们的机制、它们的故障模式、它们的解决方法。.gitignore工作区什么也不要求。克隆你需要的。正常工作。一切都在那里。
现在AI代理正在成为我们编写和交付软件方式的真实组成部分,"一切都在那里"比以前更重要。当你的代理可以看到完整的边界上下文、每个服务、每个UI、每个环境配置时,它就不再是一个花哨的自动补全,而是一个真正的协作者。它发布你的服务、检查你的部署、端到端地规划功能,并在你拥有的每个仓库中执行你的团队规范。这是迈向更完整的智能体软件开发生命周期的又一步。至少对我们来说是这样。
所有这一切,只是因为你把一些文件夹放在一起,并告诉Git忽略它们。
原文链接:A Simple Pattern for AI-Powered Multi-Repository Development
汇智网翻译整理,转载请标明出处