ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

1人AI全栈开发实战:多Agent协作 + React 19 + Elysia + DevOps自动化

1人AI全栈开发实战:多Agent协作 + React 19 + Elysia + DevOps自动化

一个人真能撑起从前三到五人团队的研发全流程吗?我这半年用实际项目验证了这条路:多 Agent 协作 + React 19 + Elysia + DevOps 自动化,把“全栈”从一种技能标签变成了一套可复用的工程范式。这篇文章不聊宏大的“AI 取代程序员”,只讲我实际踩通的技术选型、协作分工和部署细节,以及那些文档里不会写、只有跑在真实业务里才会暴露的坑。

1. 单人研发范式的整体设计与思路拆解

1.1 为什么“全栈”必须重新定义

传统意义上,一个人做全栈意味着你要同时掌握前端框架、后端服务、数据库、部署运维,还要能处理缓存、消息队列、日志监控这些中间件。我见过太多人花几年时间把 Vue 和 Node 练到熟,结果一碰到 Docker 和 CI/CD 就崩溃。关键问题在于:人脑的上下文窗口有限,任务切换的成本极高。

所谓“1 人 = AI 全栈”,并不是让 AI 替你把代码全写了,而是让 AI 承担记忆、检索、部分决策和重复劳动,把人的精力从“怎么写”解放到“该写什么”上。我实践下来,这套范式的核心逻辑是:

  • 把需求拆成可并发执行的子模块,交给不同角色的 Agent 并行推进;
  • 用类型安全的全栈框架(React 19 + Elysia)把前后端契约固化,减少 Agent 之间的理解偏差;
  • 用 DevOps 流水线把测试、构建、部署变成无人值守的自动步骤,消灭“最后一公里”的人工失误。

这套组合拳打下来,一个人不但能写代码,还能同时扮演产品经理、架构师、前端开发、后端开发、测试和运维的角色。关键是你要懂怎么“指挥”,而不是怎么“亲自动手”。

1.2 技术选型背后的逻辑:为什么是 React 19、Elysia 和多 Agent

选 React 19 而不是 Vue 或 Svelte,我考虑了三件事。第一,React 生态的 AI 训练语料最丰富,Agent 生成 React 代码的准确率明显高于其他框架,这一条在实践里几乎可以直接决定研发效率;第二,React 19 的use()、Action、useOptimistic等新特性大幅简化了数据获取和状态管理,让 Agent 生成的代码更短、更不容易出错;第三,Server Components 让前后端边界更清晰,Agent 更容易判断“这段逻辑该放客户端还是服务端”。

Elysia 是 Bun 生态里的 TypeScript 后端框架,选它的核心原因就两个字:共情。Elysia 的 Eden 全栈类型推断能做到前端直接获得后端的类型安全 API 调用,不需要生成 OpenAPI 文档再去同步到前端。这意味着 Agent 前后端分开写代码,也不会出现接口字段对不上的低级 bug。配合 Bun 原生支持的 TypeScript 运行和极快的启动速度,本地开发几乎零等待。

至于多 Agent,我把它理解成一个“虚拟团队”,每个人设不同角色、不同上下文、不同工具权限。下面这张表是我目前最常用的成员配置:

Agent 角色核心职责常用工具集上下文重点
架构师拆解需求、定义接口和数据库 Schema项目根目录ARCHITECTURE.md、DATABASE.md全局约束和依赖关系
前端 Agent实现 React 19 组件、页面逻辑组件目录、package.jsonUI 框架和组件规范
后端 Agent实现 Elysia 路由、业务逻辑src/server、数据模型文件API 契约和字段校验
运维 Agent编写 Dockerfile、CI/CD、监控告警部署目录、DevOps配置环境和部署约束
审查 AgentCode Review、安全检查、性能优化建议代码扫描工具、测试用例全量代码上下文

每个 Agent 都跑在自己的“会话”里,通过文件系统、Git 分支和自动测试结果进行通信,而不是靠大量投喂对话记录。我把这种协作方式叫做“文件即接口”——A Agent 的产出物是 B Agent 的输入契约,谁都不用猜对方在想什么。

2. 多 Agent 编排的核心细节与实操要点

2.1 Agent 之间如何分工与同步,才能不打架

多 Agent 协作最怕的不是某个 Agent 写不出代码,而是两个 Agent 同时改了同一个文件导致冲突。我一开始用共享一个目录的方式让“前端 Agent”和“后端 Agent”并行干活,结果一天能炸三四次 Git 冲突,而且冲突解决起来非常痛苦,因为两边都以为自己的版本是对的。

后来我采用了一个简单策略:按目录和 Git 分支隔离工作区。具体是这样拆的:

  • frontend/目录归前端 Agent 独享,它只在这个目录下增删改;
  • backend/目录归后端 Agent 独享;
  • 公共的types/目录由架构师 Agent 在项目启动时一次性生成,之后任何 Agent 都只能读不能写;
  • 前端 Agent 和后端 Agent 各自从main分支拉出独立 feature 分支,完成一个阶段后提 PR,由审查 Agent 合并。

关键一步是:在需求拆解阶段就把接口定义写死。比如我让架构师 Agent 先输出整份types/api.ts,里面写好GET /posts/:id返回什么、POST /auth/login接收什么字段,然后前端和后端都基于这份类型文件开发。这样即使两边 Agent 完全“失联”,最后合代码时也大概率能跑通。这个套路背后有个很深的体会:多 Agent 协作的本质是接口设计,而不是对话热度。

2.2 给 Agent 下指令的提示词模板与上下文注入

很多人用 AI 编程时最大的问题是:上下文交代得不够,或者一次交代太多。我总结出一套比较稳的提示词结构,分四层:

第一层,角色定义。明确告诉 Agent 它是什么角色,比如“你是资深 React 19 前端工程师,熟悉 Server Components 和 Server Actions”。

第二层,项目背景。把ARCHITECTURE.md里跟它相关的段落摘出来给它,重点说明技术栈、目录结构、代码风格(比如“组件用函数声明,不要匿名导出”、“样式用 Tailwind,不用 CSS Modules”)。

第三层,任务清单。把任务拆成颗粒度合适的步骤,每步附上验收标准。比如“实现PostList组件,要求:使用useOptimistic处理点赞;从api/posts获取数据,类型来自types/api.ts;加载时显示骨架屏”。

第四层,禁止事项和约束。比如“不要修改tsconfig.json”、“不要引入额外依赖”、“不要在服务端组件里使用useEffect”。

我把这套结构放进了一个prompts/目录,每个任务单独一个文件。执行的时候用 CLI 工具把提示词注入到 Agent 的会话开头。实测下来,结构化提示词比那种“帮我写一个登录页面”的效率至少翻一倍,而且返工率大幅下降。

2.3 上下文窗口不够用?用文件系统做外部记忆

大模型上下文窗口再大也有限,尤其是多轮对话后容易出现“早期记忆丢失”。我的补救办法是:把关键决策和进度写进项目根目录的AGENTS.md和TASKS.md文件里。

  • AGENTS.md记录角色分工、技术选型、目录约定、公共工具函数说明;
  • TASKS.md记录当前迭代的任务列表、已完成事项、未决问题;
  • 每个子任务完成后,要求 Agent 更新对应文件,把结果“固化”下来。

这样即使开了一个全新的会话(上下文归零),只要把AGENTS.md和TASKS.md喂进去,新 Agent 就能快速恢复状态。之前碰到的“换了会话 AI 就不认识自己写的代码”的坑,基本被这个动作填平了。操作上几乎是白嫖地低成本,但收益非常务实。

3. 核心代码实现:React 19 + Elysia 的前后端联调实录

3.1 React 19 新特性如何在项目里落地

React 19 最大的变化是用use()取代了繁琐的useEffect + fetch状态机,配合 Server Components,普通页面可以直接在服务端取数,再把数据传给客户端组件。加上 Action 和useOptimistic之后,很多逻辑代码量直接砍半。

我项目里有个高频场景:帖子列表 + 点赞功能。以前要写useState(列表)、useEffect(加载)、单独的onClick里再fetch修改状态,还得自己处理 loading 和错误。React 19 的写法可以更收敛,用示例代码更直观:

// app/posts/page.tsx (Server Component) import { getPosts } from "@/server/actions"; import PostList from "./PostList"; export default async function PostsPage() { const posts = await getPosts(); return <PostList posts={posts} />; }
// app/posts/PostList.tsx (Client Component) "use client"; import { useOptimistic, useTransition } from "react"; import { likePost } from "@/server/actions"; export default function PostList({ posts }: { posts: any[] }) { const [optimisticPosts, setOptimisticPosts] = useOptimistic(posts); const [, startTransition] = useTransition(); function handleLike(postId: string) { startTransition(async () => { setOptimisticPosts((prev) => prev.map((p) => (p.id === postId ? { ...p, likes: p.likes + 1 } : p)), ); await likePost(postId); }); } return ( <ul> {optimisticPosts.map((post) => ( <li key={post.id}> <span>{post.title}</span> <span>❤️ {post.likes}</span> <button onClick={() => handleLike(post.id)}>赞</button> </li> ))} </ul> ); }

注意useOptimistic的返回值其实不只是 optimistic 状态,useTransition返回[isPending, startTransition]。这里把likePost定义在@/server/actions是因为它本质上是一个 Server Action,前端调它不需要自己写 fetch,更不需要处理 JSON 序列化和 CSRF。这个写法对 AI Agent 尤其友好:因为 AI 特别擅长帮你在这种高度抽象的框架约定下生成代码,比让它自己拼 fetch 函数可靠得多。

我让后端 Agent 定义 Server Action 时,特意要求它把“输入校验”放在函数内部完成,用 Zod 直接解析。解析失败抛出带status的错误,客户端用error状态捕获并提示。这样整个链路的类型是通的,无论前端还是后端 Agent 都不会猜错字段名。下面是 Server Action 的一个典型形貌:

// server/actions.ts "use server"; import { z } from "zod"; import { db } from "@/db"; import { revalidatePath } from "next/cache"; const LikeSchema = z.object({ postId: z.string().uuid(), }); export async function likePost(input: unknown) { const result = LikeSchema.safeParse(input); if (!result.success) { throw new Error("Invalid postId"); } const { postId } = result.data; await db.post.update({ where: { id: postId }, data: { likes: { increment: 1 } }, }); revalidatePath("/posts"); }

这一套跑起来之后,前端的交互代码短得离谱,而且所有错误路径都清晰可测。后端 Agent 写这类函数几乎不用我怎么审查,因为类型系统已经把住了接口大关。

3.2 Elysia 路由与类型安全的端到端体验

后端我用 Elysia 主要是因为它的“端到端类型安全”不用额外引 Swagger 或 OpenAPI 生成器,Eden 直接通过 TypeScript 类型推断把后端路由的请求和响应结构“投影”到前端。Elysia 的写法风格接近“链式”,Agent 生成出来的代码一眼就能看出请求要什么字段。

我项目里有一块用户资料模块,后端定义长这样:

// server/index.ts import { Elysia, t } from "elysia"; const app = new Elysia() .get("/users/:id", ({ params }) => { const user = findUser(params.id); if (!user) { return { error: "User not found" }; } return { id: user.id, name: user.name, email: user.email }; }, { params: t.Object({ id: t.String() }), response: t.Object({ id: t.String(), name: t.String(), email: t.String(), error: t.Optional(t.String()), }), }); export type App = typeof app;

前端直接用 Eden 生成 API 客户端:

// lib/server-api.ts import { edenTreaty } from "@elysiajs/eden"; import type { App } from "../../server"; const api = edenTreaty<App>("http://localhost:3001"); // 调用时类型完全自动推导 const { data, error } = await api.users.get({ params: { id: "abc" } }); if (error) { console.log("请求失败"); } else { console.log(data.name); // 自动提示是 string }

这样前端和后端是天然“同构”的。前端 Agent 看到users.get就知道传什么入参,根本不用翻接口文档;后端 Agent 改字段的时候,如果前端某处引了不存在的字段,TypeScript 会在 CI 阶段直接报错。我踩过最痛的一个坑是早期用 Node Express 接任意数据库,前后端各写一份 DTO,结果那个月至少有两周时间都在跟“字段多一个字母”的 bug 搏斗。换了 Eden 之后,这整类问题基本从根上消失了。

3.3 数据库与缓存:AI 生成代码时最容易翻车的地方

前面账号一直没提数据库,是因为这块单独值得总结。AI Agent 写数据库层时有一个通病:喜欢自动加CREATE DATABASE、INSERT INTO这种标本级的 SQL,而且偏好用“内存里随便一个对象数组”来模拟数据。这在原型阶段没问题,一旦要接真实库就会炸。

我给后端 Agent 的项目规范里明确约束:数据库访问必须统一走 Prisma,禁止手写 SQL;连接串一律从环境变量读取;生产环境只读 Replica,写请求必须经过 Car API。这样 Agent 能发挥它“善于套模板”的优势,把精力放在业务查询的优化上,而不是四处发散造一些不稳定的数据访问方案。

另外缓存我直接用 Redis,但只做热点数据的透传。Agent 写缓存逻辑时我会要求它严格控制 key 的过期时间,带上版本号。一个特别容易被忽略的问题:给 Elysia 的响应体加了response校验 schema 之后,如果缓存内容缺失某个必填字段,接口会直接 500。这个坑我修了半小时,最后发现是缓存里的旧对象不包含新增的emailVerified字段。经验就是:缓存对象永远要完整过一遍 response validation,最好让 Agent 在缓存写入前做一个parse,吃不准就重查数据库。

4. DevOps 自动化:单人团队如何做到“零手工部署”

4.1 一套完整 CI/CD Pipeline 到底该长什么样

一个人维护一套系统,最忌讳的是“上线靠熬夜”。我目前所有项目都走 GitHub Actions,配合 Vercel(前端)和 Fly.io(后端),另外在云服务器上跑 Docker Compose 来部署一些简单工具。对单人范式来说,CI/CD 管道必须做到“提交即测试、合并即部署”。

下面这套 pipeline 是我反复迭代得比较稳的版本,放在.github/workflows/main.yml里:

name: CI/CD on: push: branches: [main] pull_request: jobs: lint-and-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v1 with: bun-version: 1.1.30 - run: bun install - run: bunx prisma generate - run: bun run lint - run: bun run test preview-deploy: needs: lint-and-test if: github.event_name == 'pull_request' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Deploy preview run: ./scripts/preview-deploy.sh env: DATABASE_URL: ${{ secrets.DATABASE_URL }} production-deploy: needs: lint-and-test if: github.event_name == 'push' && github.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Deploy production run: ./scripts/prod-deploy.sh

我把 pipeline 本身也交给 AI 维护:每加一个环境变量或新服务,直接在DevOpsAgent 的会话里描述需求,它会帮我改.github/workflows/下的 YAML。唯一要手工重点盯的是 secrets 的权限控制和作用范围,这个不能全信 AI。

4.2 环境隔离与数据安全:数据库迁移的一次“滑铁卢”

有段时间我以为数据库迁移只要prisma migrate deploy就万事大吉,结果某天下午发布一个新功能,迁移脚本里一个drop column直接把生产环境用户表的一列历史数据清空了。那次事故之后,我给自己定了三条铁律:

第一,生产数据库只能由汽车 CI/CD 执行迁移,本地环境严禁直接连生产库执行migrate dev;第二,每次迁移前先备份,脚本里强制调用数据库服务商提供的 snapshot 接口;第三,所有迁移必须经过审查 Agent 检查,重点看有没有drop、delete、alter这类危险操作。

后来我把这三条写进了AGENTS.md的“禁止事项”里,让 AI 在生成迁移文件时就默认遵守。实践证明,靠流程约束比靠人克制更重要,尤其是一个人干活时,凌晨一点犯困的手绝对比不过一套强制备份的脚本。

4.3 可观测性:一个人要怎么看完日志、指标和告警

没有团队的时候,日志和监控几乎等于没人看。但一人全栈最大的风险点恰恰是“没有第二双眼睛盯着”,所以我把可观测性做成了“无事发生就不看”的系统。

我的方案是 Sentry(前端错误追踪)+ Grafana 仪表盘(系统指标)+ Telegram Bot(告警通知)。关键业务错误通过catch块主动上报,服务端异常由日志聚合自动接入。告警规则只保留两类:一是“错误率连续 5 分钟超过 1%”,二是“核心接口 P95 延迟 > 2 秒”。其他告警消息一律不推送,否则过不了三天我就会把通知关掉。

具体的Sentinel策略是这样实现的:

  • 前端全局错误边界里主动Sentry.captureException;
  • 后端 Elysia 包一层自定义OnError钩子,把异常连同请求体、路由、用户 Id 一起发送到 Sentry;
  • GitHub Actions 每晚跑一次端到端冒烟测试(前端调真实 API),失败则直接推送告警。

这套可观测体系虽然搭建成本不高,但对单人研发来说,它是安全感来源。我印象很深刻的是有次升级依赖后,某个静态页面偶发 500,白天根本没人发现,凌晨三点冒烟脚本跑挂推送了告警,我早上起来看到消息,花十分钟定位到是某个第三方库的 breaking change 改了返回值结构。如果没有这套提醒机制,这个问题可能要在线上挂了一周后,被真实用户发现了才知道。

5. 实操过程重构实录:从零到一跑通这个范式

5.1 用提示词启动项目:架构师 Agent 的第一份产出

假设我要开发一个“团队周报生成器”小工具。第一步不是我写代码,而是启动“架构师 Agent”会话,给它一份高颗粒度的需求描述。实际提示词长得像这样:

你是这个项目的架构师 Agent。请根据以下产品需求,输出一份 ARCHITECTURE.md 和 TASKS.md。 技术栈约束: - 前端 React 19 + Next.js 15 (App Router) - 后端 Elysia + Bun - 数据库 Prisma + PostgreSQL - 部署 Vercel + Fly.io 产品需求: 1. 用户输入团队成员名单,系统自动汇总本周 Git 提交记录。 2. 支持自定义周报模板,生成 Markdown 文件。 3. 每周一自动运行一次,产出推送至企业微信群。 输出要求: - 列出前后端模块拆分清单(目录到文件级别)。 - 定义全部 API 路由、请求参数、响应 Schema。 - 定义数据库模型和关键索引。 - 拆成 5 个可并行执行的子任务,标注依赖关系。 - 每个子任务写明验收标准。

架构师 Agent 的输出通常会在十分钟内完成,而且质量远超我自己从零画架构。然后我把它生成的ARCHITECTURE.mdcommit 到仓库,作为前端、后端、运维三个 Agent 的“共同宪法”。

5.2 前端与后端 Agent 并行开工:Git 分支与契约驱动

按照ARCHITECTURE.md拆分好的任务,我会为“前端 Agent”和“后端 Agent"各自开一条分支。前端 Agent 专注实现页面和交互,后端 Agent 专注实现路由和数据库操作。因为接口 Schema 和类型文件已经在types/里写死,两边写到一半完全不需要沟通。

其中前端这块,允许 Agent 先调 Mock 数据把组件搭建起来,等后端分支合并进main,再跑一次端到端联调。联调时只要类型没问题,代码几乎不用怎么改。这个流程我跑了好几个项目,得出的核心经验是:类型系统就是多 Agent 协作的“接口协议”。哪怕两个 Agent 从没见过对方,只要它们都遵循同一份types/文件,产出的代码就像同一个人写的一样严密。

5.3 联调与部署:把兜底工作交给审查 Agent

前端和后端分支合并后,我会启动“审查 Agent”做一次全代码扫描。审查 Agent 的上下文里放着AGENTS.md、ARCHITECTURE.md和两份分支的 diff,它需要找出三类问题:潜在的类型漏洞(比如any滥用)、资源泄漏(比如监听器没清理)、安全风险(比如 SQL 注入、未授权访问)。

审查 Agent 会直接在 PR 评论里列出问题清单,并且附带修改建议。我一般会把其中“明确且安全”的建议直接让另一个“修复 Agent”自动执行,剩下“含糊或涉及业务判断”的才手工介入。这样可以保证单人团队也拥有“代码评审”环节,而不是自己写完自己上线,结果线上出 bug 还得自己怒问“谁写的这段代码”。

部署阶段则完全依靠第四节那套 CI/CD。我把脚本约定为:preview-deploy.sh推预览环境,prod-deploy.sh推生产环境。生产环境部署前有个“人工确认按钮”,在 GitHub Actions 的environment块里配置required_reviewers,哪怕单人也强制点一下“approve”,避免大半夜无意识触发危险上线。

5.4 日常沟通路径:我如何跟这群“虚拟同事”协作

光会写提示词还不够,还要管理协作节奏。我目前的桌面端主要用 Terminal + tmux,每个 Agent 一个独立会话窗口。虽然看起来是“一个人在敲命令”,实际上并行任务都在跑。为了记住每个 Agent 干到哪一步,我在TASKS.md里维护了一个看板:

任务编号任务名负责人状态完成标准
T-001需求拆分架构师 Agent✅ 已完成输出架构文档
T-002数据库模型后端 Agent🔄 进行中prisma schema 迁移通过
T-003周报列表页前端 Agent🔄 进行中联调可访问
T-004定时任务后端 Agent⏳ 待开始每晚执行成功
T-005CI/CD 配置运维 Agent⏳ 待开始生产部署成功

一开始我会频繁去看各会话的 stdout,后来发现这样效率反而低。现在我只在任务开始、中途有异常上报、以及任务结束时这三类时机关注 Agent 输出,其余时间让它们自己跑。每完成一个任务,要求对应 Agent 在TASKS.md里更新状态,这样我随时打开文件就能知道全局。

6. 常见问题与排查技巧实录

6.1 Agent 陷入死循环怎么办:切断上下文比继续追问更有效

多 Agent 编程中最高频的“卡死”不是假死,而是 AI 在一个错误代码路径里反复修复,结果越修越离谱。比如前端 Agent 写的useOptimistic调用总是类型报错,它自己不断调整类型断言,最后把整个组件改成一团乱麻,性能反而更差。

我的处理策略很粗暴:一旦发现同一个文件被连续修改超过三次且测试仍然失败,立刻终止当前会话。然后新开一个空白会话,把TASKS.md中该任务最近的日志和该文件的报错信息原样贴进去,让新 Agent 以“旁观者”身份重新审视。由于新会话没有之前的错误上下文污染,它往往一眼就能看出类型不匹配的根因。

还有一个实战技巧:多数模型的输出长度限制是 token 数,不是行数。如果一个文件超过 300 行,要求 Agent “重写整个文件”很容易截断。我习惯先让 Agent 输出一份“改动计划”,按 diff 片段分步提交,每步只改 20~30 行。这样即使一个片段有误,也不会破坏整个文件结构。

6.2 生产环境白屏或接口 500:怎么快速定位是前端的锅还是后端的锅

单人维护的项目里,前端和后端往往分别部署在不同平台(比如 Vercel + Fly.io),出现“页面打不开”这类问题时,最怕的就是前后端互相推锅。我建立了一个“定位三连”的排查清单,基本能十分钟内锁定问题层:

第一,看 Sentry 和日志:如果前端有 JavaScript 报错或网络请求失败,说明大概率是前端或接口问题;如果只有后端日志出现 500,那后端大概率脱不了干系。

第二,直接调用线上 API:用 curl 或者写一段简单的 Node 脚本调生产环境的接口(带真实 token),看返回结构是否符合Elysia的 response schema。如果接口通了,那问题就在前端的解析或渲染层。

第三,检查 CI 最近一次成功部署的时间:如果页面在部署后才开始白屏,直接看那次部署的 diff。这通常能很快发现是某个依赖版本升级导致的不兼容,或是某个环境变量没有注入到前端运行时。

我印象最深的一次排障是:自测接口一切正常,预览环境也正常,但线上用户反馈一直报“网络错误”。查了半天发现是 Vercel 的 Serverless 函数有最大执行时间限制,我某个需要同步大量外部数据的接口跑超时了。因为本地和预览环境数据量小,根本不会触发这个限制。从那以后,我开始在代码里对耗时接口做分页和异步任务拆分,而不是傻等同步返回。这种“本地测不出,线上才爆炸”的问题,最需要的就是一套能独立验证线上环境的诊断手段。

6.3 依赖升级导致的隐藏雷区:用锁文件和定期审计兜底

AI Agent 有一个不太好的倾向:碰到依赖缺失或版本冲突,它会主动修改package.json拉一个新版本。事情的是非曲直先不论,关键是这类“偷偷升级”的行为特别容易在升级某个底层库后引发连锁反应。尤其是 Elysia 这种包含类ere和微调框架结构的库,一个 minor 版本升级就可能改变路由编译后的错误码语义。

我的防线是两层:

第一,锁文件全量提交。Bun 的bun.lockb和 npm 的package-lock.json都必须入库,Agent 任何情况下都不能绕过锁文件安装依赖,更不允许直接改锁文件里的版本号。

第二,每周跑一次npx npm audit或bun audit,把依赖安全报告丢给“运维 Agent”,让它自动生成升级补丁 PR。但升级 PR 不会自动合到main,必须经过测试环境和审查 Agent 的双重标准。这样能避免“为了补一个漏洞却引入另一个更隐蔽的问题”。

6.4 当 AI 生成的代码与业务逻辑冲突时,宁可重写也不要强行 patch

我前阵子做一个权限系统,后端 Agent 自己发挥(或者叫“幻觉”)出了一套组织架构,跟实际业务的组织层级完全对不上。当时我试图通过给后端 Agent 追加一轮上下文,让它“只修改某个方法”,结果三次补丁后代码已经变得几乎不可读——既有早期的错误设计,又有后来的强行覆盖。

最后我花了一个晚上,把跟权限相关的整个模块删掉,让后端 Agent 带着最新的AGENTS.md和业务说明从头重写。这次重写不仅代码更简洁,而且因为有了第一次的经验教训,AI 生成的路径恰好符合真实业务逻辑。我的启发是:如果 Agent 偏离了主干设计,别试图在枝丫上做“微创手术”,推倒重来反而成本更低。很多问题上,AI 的创造力是优势,但一旦收敛到错误方向上,它造成的破坏力也是惊人的。及时止损,是主线流程里非常关键的决策。

7. 值得聊几句的额外经验

7.1 把“编码规范”喂给 Agent,代码可读性翻倍

最初我让 AI 写前端代码,它喜欢把所有逻辑塞在一个大组件里,看着就头大。后来我在AGENTS.md里明确写了编码规范:组件文件不超过 200 行、函数不超过 30 行、超过阈值必须拆文件、样式类名必须语义化。之后 Agent 生成的代码结构好了不少。这些看似“装饰性”的约束,在长线维护时比什么都值钱。

7.2 让 AI 生成“测试替身数据”,比手动 mock 快得多

在前后端并行开发时,前端 Agent 没法等后端接口真正可用。我让它基于types/api.ts自动生成一份 mock 数据文件放在mocks/目录,然后本地启动一个轻量 mock server。后端代码合并后,再切到真实接口。这个“自动造数”的能力帮我把联调时间压缩到很短。

通常我会让前端 Agent 这样写 mock 数据(用的 mock 库是msw):

import { http, HttpResponse } from "msw"; export const handlers = [ http.get("/api/posts", () => { return HttpResponse.json([ { id: "1", title: "首发文章", likes: 10 }, { id: "2", title: "AI 全栈实践", likes: 88 }, ]); }), ];

这段代码本身就是后端 Agent 在接口 Schema 里顺手生成的。前端 Agent 拿到后直接注册到msw,环境变量里配一个USE_MOCK=true就切换整套数据源。这类“让 Agent 配套生成测试替身”的用法,是整套范式里被低估的加速器。

7.3 单人研发范式的最终天花板:其实还是你自己

最后想坦诚说一点:这套“1 人 = AI 全栈”的范式并不能解决所有问题,它能解决的是“研发执行效率”,不能解决的是“产品判断力”。我见过一些人让 AI 疯狂生成代码,最后堆了一堆没人要的功能。真正值钱的部分依然是你对需求的理解、对业务全局的判断,以及对系统边界的把握。

我在实际项目里反复体会到,提示词写得越清楚,AI 交付的质量就越高。而提示词的质量,直接取决于你本人是不是真懂技术、懂业务。所以别把 AI 当成“偷懒神器”,它是为勤奋的全栈工程师准备的杠杆。如果你愿意把精力从“手写模板代码”挪到“设计接口与任务分解”上,一个人的产出确实可以顶一个小团队。

如果你正准备尝试这条路,我的建议是从一个小规模项目开始,先跑通“架构师 → 前端/后端 → 审查 → 部署”的完整闭环。哪怕项目最后没上线,试一试这套工作流本身,就已经能让你对“工程化”和“AI 协同”产生全新的认知了。

返回列表