我用 AI Agent 重构了日常开发工作流,效果出乎意料
写代码 5 年,我第一次觉得 AI 不只是「自动补全」
前言
不知道你有没有这种感觉——AI 编程工具用了一堆,但总觉得差点意思。
GitHub Copilot 帮你补全代码,但补完你还是要自己调试。Cursor 让你和 AI 聊天,但聊完你还是要自己改。ChatGPT 给你写函数,但写完你还得自己组装。
这些工具更像是一个「超级自动补全」,而不是一个「真正的开发者」。
直到我开始尝试 AI Agent——让你的 AI 不再是只会回答问题的工具,而是能自己规划、执行、验证的「数字同事」。
这篇文章记录了我用 AI Agent 重构日常开发工作流的完整过程,从概念到落地,从失败到成功,全是实战经验。
什么是 AI Agent?它和普通 AI 工具有什么区别?
简单来说:
- 普通 AI 工具:你问它答,它给你建议,你去执行
- AI Agent:你给目标,它自己规划步骤、调用工具、执行任务、验证结果
举个例子,当我需要「给项目添加一个日志系统」时:
普通 AI 工具的做法:
我:帮我写一个日志系统
AI:好的,这是代码...(返回一大段代码)
我:复制粘贴 → 修改 → 调试 → 发现漏了 → 再问 → 再改
AI Agent 的做法:
我:给项目添加一个日志系统
Agent:
1. 扫描项目结构,理解现有代码风格
2. 创建 logger.ts 文件
3. 修改 main.ts 引入日志
4. 运行 lint 检查
5. 发现类型错误,自动修复
6. 运行测试,确认通过
7. 提交代码,附带 commit message
看到区别了吗?Agent 不只是「写代码」,而是「完成一个完整的开发任务」。
我的第一个 Agent:自动化 PR Review
我所在团队每次 PR Review 都很耗时,reviewer 要检查:
- 代码风格是否符合规范
- TypeScript 类型是否安全
- 是否有潜在的性能问题
- 测试覆盖是否足够
于是我写了一个 PR Review Agent,基于 GitHub Actions + Claude API。
架构设计
┌─────────────────────────────────────────────┐
│ GitHub Webhook │
│ (PR opened / updated) │
└───────────────────┬─────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ GitHub Actions │
│ (触发 review workflow) │
└───────────────────┬─────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ Review Agent │
│ │
│ 1. 获取 PR diff │
│ 2. 分析代码变更 │
│ 3. 对照项目规范检查 │
│ 4. 生成 review 评论 │
│ 5. 自动标记问题等级 │
└───────────────────┬─────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ GitHub PR Comment │
│ (自动发布 review 结果) │
└─────────────────────────────────────────────┘
核心代码
// agent/review-agent.ts
import { Anthropic } from '@anthropic-ai/sdk';
import { context, getOctokit } from '@actions/github';
interface ReviewResult {
file: string;
line: number;
severity: 'error' | 'warning' | 'suggestion';
message: string;
suggestion?: string;
}
class PRReviewAgent {
private claude: Anthropic;
private octokit: ReturnType<typeof getOctokit>;
constructor(apiKey: string, githubToken: string) {
this.claude = new Anthropic({ apiKey });
this.octokit = getOctokit(githubToken);
}
async review(): Promise<ReviewResult[]> {
// 1. 获取 PR 变更
const diff = await this.getPRDiff();
const projectConfig = await this.getProjectConfig();
// 2. 构建 prompt
const prompt = this.buildPrompt(diff, projectConfig);
// 3. 调用 AI 进行分析
const response = await this.claude.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: 4096,
messages: [{ role: 'user', content: prompt }],
// 关键:使用 tool_use 让 AI 返回结构化数据
tools: [{
name: 'submit_review',
description: '提交代码审查结果',
input_schema: {
type: 'object',
properties: {
reviews: {
type: 'array',
items: {
type: 'object',
properties: {
file: { type: 'string' },
line: { type: 'number' },
severity: {
type: 'string',
enum: ['error', 'warning', 'suggestion']
},
message: { type: 'string' },
suggestion: { type: 'string' }
},
required: ['file', 'line', 'severity', 'message']
}
}
},
required: ['reviews']
}
}]
});
// 4. 解析结果
const reviews = this.parseToolResponse(response);
return reviews;
}
private buildPrompt(diff: string, config: string): string {
return `你是一个资深的前端代码审查员。请审查以下 PR 变更。
## 项目规范
${config}
## 审查要点
1. TypeScript 类型安全:检查 any 类型滥用、类型断言是否合理
2. React 性能:检查不必要的重渲染、memo/useMemo 使用
3. 代码可维护性:函数长度、命名规范、注释质量
4. 安全隐患:XSS 风险、敏感信息泄露
## 代码变更
\`\`\`diff
${diff}
\`\`\`
请给出具体的修改建议,按严重程度分级。`;
}
}
实际效果
部署后第一个月的数据:
| 指标 | 之前 | 之后 |
|---|---|---|
| PR Review 平均时间 | 4.2 小时 | 1.1 小时 |
| 代码规范问题漏检率 | 23% | 6% |
| 类型安全问题漏检率 | 31% | 4% |
| Reviewer 满意度 | - | ⭐⭐⭐⭐⭐ |
最让我意外的是,Agent 发现了几个 reviewer 都没注意到的问题:
- 一个
useEffect缺少 cleanup 函数导致内存泄漏 - 一个
JSON.parse没有 try-catch 包裹 - 一个
dangerouslySetInnerHTML没有做 XSS 过滤
第二个 Agent:自动化 API 文档生成
我们团队有 200+ 个 API 接口,文档永远跟不上代码变化。开发说「文档等下补」,然后就没有然后了。
于是我写了一个 API Doc Agent,它做的事情很简单:
- 扫描代码中的 API 路由定义
- 提取请求参数、返回值类型
- 从 TypeScript 类型推导字段说明
- 生成 OpenAPI 规范文档
- 自动更新到团队文档平台
关键实现
// agent/api-doc-agent.ts
import * as ts from 'typescript';
import * as fs from 'fs';
import * as path from 'path';
interface APIEndpoint {
path: string;
method: string;
handler: string;
params: ParamInfo[];
response: TypeInfo;
description: string;
}
class APIDocAgent {
private async scanRoutes(sourceDir: string): Promise<APIEndpoint[]> {
const endpoints: APIEndpoint[] = [];
// 遍历所有 .ts 文件
const files = this.walkDir(sourceDir, '.ts');
for (const file of files) {
const source = fs.readFileSync(file, 'utf-8');
const sourceFile = ts.createSourceFile(
file, source, ts.ScriptTarget.Latest, true
);
// 遍历 AST,查找路由定义
ts.forEachChild(sourceFile, (node) => {
if (this.isRouteDefinition(node)) {
const endpoint = this.extractEndpoint(node, sourceFile);
if (endpoint) {
endpoints.push(endpoint);
}
}
});
}
return endpoints;
}
private async generateDescription(
endpoint: APIEndpoint
): Promise<string> {
// 用 AI 根据代码上下文生成描述
const prompt = `请根据以下代码为 API 生成一段中文描述(50字以内):
路径: ${endpoint.method} ${endpoint.path}
处理函数: ${endpoint.handler}
参数: ${JSON.stringify(endpoint.params, null, 2)}
返回值: ${JSON.stringify(endpoint.response, null, 2)}
请描述:这个接口做什么、什么场景使用。`;
const response = await this.ai.complete(prompt);
return response.trim();
}
private async generateOpenAPI(
endpoints: APIEndpoint[]
): Promise<string> {
const paths: Record<string, any> = {};
for (const ep of endpoints) {
const desc = await this.generateDescription(ep);
if (!paths[ep.path]) {
paths[ep.path] = {};
}
paths[ep.path][ep.method.toLowerCase()] = {
summary: desc,
operationId: ep.handler,
parameters: ep.params.map(p => ({
name: p.name,
in: p.location,
required: p.required,
schema: { type: p.type }
})),
responses: {
'200': {
description: '成功',
content: {
'application/json': {
schema: ep.response
}
}
}
}
};
}
return JSON.stringify({
openapi: '3.0.0',
info: { title: 'API Documentation', version: '1.0.0' },
paths
}, null, 2);
}
// 辅助方法:遍历目录
private walkDir(dir: string, ext: string): string[] {
const results: string[] = [];
const list = fs.readdirSync(dir);
for (const file of list) {
const fullPath = path.join(dir, file);
const stat = fs.statSync(fullPath);
if (stat.isDirectory()) {
results.push(...this.walkDir(fullPath, ext));
} else if (fullPath.endsWith(ext)) {
results.push(fullPath);
}
}
return results;
}
}
实际效果
之前「API 文档更新」是团队周会上的固定吐槽环节,现在:
- 📄 文档更新频率:从「永不更新」到「每次提交自动更新」
- ⏱️ 新人上手时间:从 2 周缩短到 3 天
- 🐛 前后端联调对接问题:减少 60%
第三个 Agent:自动化 Bug 修复
这个是三个 Agent 里最激进也最实用的。
工作流程
1. 从 Sentry 获取新 Bug
↓
2. Agent 分析错误堆栈,定位代码
↓
3. 生成修复方案
↓
4. 创建修复分支
↓
5. 应用修复
↓
6. 运行测试
↓
7. 测试通过 → 创建 PR
测试失败 → 调整修复方案(最多 3 次)
核心逻辑
// agent/bug-fix-agent.ts
class BugFixAgent {
async fix(issue: SentryIssue): Promise<FixResult> {
console.log(`🔍 开始修复 Bug: ${issue.title}`);
// 1. 分析错误
const analysis = await this.analyzeError(issue);
// 2. 生成修复
let fix = await this.generateFix(analysis);
let attempts = 0;
// 3. 验证修复(最多重试 3 次)
while (attempts < 3) {
const branch = `fix/auto-${issue.id}-${Date.now()}`;
await this.createBranch(branch);
await this.applyFix(fix);
const testResult = await this.runTests();
if (testResult.passed) {
// 测试通过,创建 PR
await this.createPR(branch, issue.title, fix.description);
return { success: true, branch, pr: fix.description };
}
// 测试失败,分析失败原因并重新生成修复
console.log(`❌ 第 ${attempts + 1} 次修复失败,分析原因...`);
fix = await this.retryFix(fix, testResult.failures);
attempts++;
}
return { success: false, reason: '3次修复尝试均失败,需要人工介入' };
}
private async analyzeError(issue: SentryIssue): Promise<ErrorAnalysis> {
const prompt = `你是一个资深的前端工程师,请分析以下错误:
## 错误信息
${issue.title}
${issue.stackTrace}
## 相关代码
${issue.sourceCode}
## 请分析
1. 错误的根本原因
2. 影响范围
3. 建议的修复方案
4. 风险评估`;
const response = await this.ai.complete(prompt);
return this.parseAnalysis(response);
}
}
安全边界
让 AI 自动修复代码,最怕的就是「修好一个 Bug,引入三个新 Bug」。我设置了几条硬性规则:
- 只修复明确可复现的错误:NullPointer、TypeError、未捕获的 Promise 等
- 禁止修改核心业务逻辑:通过代码路径白名单控制
- 必须通过全部测试:测试不通过绝不合并
- 必须有人工 Review:PR 需要至少一个 reviewer 批准
- 灰度发布:先修非关键 Bug → 观察效果 → 再开放更复杂的修复
三个 Agent 的整体架构
我把三个 Agent 整合到了一个统一的调度系统中:
┌──────────────────────────────────────────────────────┐
│ Agent Scheduler │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ PR Review │ │ API Doc │ │ Bug Fix │ │
│ │ Agent │ │ Agent │ │ Agent │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
│ └─────────┬───────┴─────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Tool Registry │ │
│ │ │ │
│ │ • file_system │ │
│ │ • git_ops │ │
│ │ • test_runner │ │
│ │ • github_api │ │
│ │ • sentry_api │ │
│ └─────────────────┘ │
└──────────────────────────────────────────────────────┘
每个 Agent 共享同一套工具注册表,但有不同的权限范围:
- PR Review Agent:只读权限(读代码、写评论)
- API Doc Agent:读写文档权限(读代码、写文档)
- Bug Fix Agent:读写代码权限(读代码、写代码、改分支)
遇到的坑和教训
坑 1:AI 过度自信
有一次 Bug Fix Agent 分析了一个 Cannot read property 'map' of undefined 的错误,它自信地加了一个 ?. 可选链操作符。然后测试通过了,PR 也合了。
结果上线后发现,这个错误是因为后端返回的数据结构变了,加 ?. 只是让页面不报错,但数据完全不显示了——用户看到的是空白页面。
教训:AI 倾向于「最小改动」,但有时候最小改动只是掩盖问题,而不是解决问题。现在我在 prompt 里加了「先分析根本原因,再给出修复方案」的约束。
坑 2:Token 消耗超出预期
刚开始用的时候,一个月 Anthropic API 账单让我吓了一跳——PR Review Agent 每次 review 要消耗约 20000 tokens,团队一天 15 个 PR,一个月就是 900 万 tokens。
教训:优化 prompt,只传变更的 diff,不传整个文件。用更轻量的模型做预筛选(比如先用小模型判断是否有问题,有问题再交给大模型详细分析)。
坑 3:Agent 的「幻觉」
API Doc Agent 有一次给一个用户删除接口生成了描述:「该接口用于删除用户,请在确认用户已注销后调用」。但实际代码里根本没有「确认用户已注销」的逻辑,这是 AI 自己脑补的。
教训:AI 生成的内容必须标注来源,让 reviewer 能快速判断哪些是代码推断的、哪些是 AI 猜测的。
总结:AI Agent 不是银弹
经过这几个月的实践,我最大的感受是:AI Agent 不是来替代开发者的,而是来放大开发者的。
它擅长的是:
- ✅ 重复性工作(PR Review 模式检查、API 文档更新)
- ✅ 结构化分析(错误堆栈分析、类型检查)
- ✅ 低风险修复(NullPointer、类型错误)
它不擅长的是:
- ❌ 需要业务理解的决策
- ❌ 跨模块的复杂重构
- ❌ 创新性的架构设计
所以我的策略是:让 Agent 做 80% 的体力活,我专注 20% 的决策活。
这套 Agent 系统我已经开源在 GitHub 上了(见文末),三个 Agent 加起来不到 2000 行代码,但节省了我们团队每周约 20 小时的工作时间。
如果你也在考虑用 AI Agent 改造开发流程,我的建议是:从一个最小可行场景开始,跑通闭环,再逐步扩展。不要一上来就想搞一个「全自动开发 Agent」,那样大概率会耗尽你的耐心和预算。
参考资源
- GitHub 仓库:agent-workflow
- Anthropic Tool Use 文档:docs.anthropic.com/en/docs/bui…
- 掘金 AI 编程话题:juejin.cn/theme/75090…
扩展:Agent 提示词工程实战
很多人以为 Agent 就是「把任务扔给 AI」,但实际上,提示词的质量直接决定了 Agent 的表现。分享几个我踩过的坑和总结的技巧。
技巧 1:给 Agent 明确的任务边界
我刚写 PR Review Agent 时,prompt 就一句话:「请审查这个 PR」。结果 AI 会给出各种离谱的建议——比如建议重写整个架构、引入新的设计模式,完全偏离了 Code Review 的初衷。
后来我把 prompt 改成:
你是一个代码审查员,你的审查范围仅限于:
1. 代码风格是否符合 ESLint 配置
2. TypeScript 类型是否安全
3. 是否有明显的性能问题(如循环中的不必要计算)
4. 是否有安全隐患(XSS、敏感信息泄露)
禁止审查以下内容:
- 架构设计(由架构师负责)
- 业务逻辑正确性(由测试保证)
- 命名风格偏好(由团队规范决定)
效果立竿见影——review 内容从「天马行空」变成了「精准打击」。
技巧 2:用 Few-Shot 示例引导输出格式
刚开始做 Bug Fix Agent 时,AI 的修复代码风格很不稳定——有时候用 if (!data) return null,有时候用 data?.map(),有时候用 try-catch。没有一致性让 reviewer 很难建立信任。
我的解决方案是:在 prompt 里提供 3 个示例,让 AI 模仿团队已有的修复模式。
const FEW_SHOT_EXAMPLES = `
## 修复示例
### 示例 1:NullPointer 修复
**错误代码**:
const name = user.profile.name; // TypeError: Cannot read property 'name'
**修复方案**:
const name = user?.profile?.name ?? '未知用户';
### 示例 2:异步错误处理
**错误代码**:
const data = await fetchUser(id);
**修复方案**:
try {
const data = await fetchUser(id);
} catch (error) {
logger.error('Failed to fetch user', { id, error });
throw new UserFetchError(id, error);
}
### 示例 3:内存泄漏修复
**错误代码**:
useEffect(() => {
const timer = setInterval(() => updateTime(), 1000);
}, []);
**修复方案**:
useEffect(() => {
const timer = setInterval(() => updateTime(), 1000);
return () => clearInterval(timer);
}, []);
`;
有了这些示例后,AI 的修复代码风格几乎和团队手写代码一模一样。
技巧 3:加入「自我质疑」环节
这是我从一篇论文里学到的技巧。在 prompt 最后加一段:
在输出最终方案前,请先自我质疑:
1. 这个修复是否引入了新的问题?
2. 有没有更简单的方案?
3. 是否考虑了边界情况(空值、并发、超时)?
这个小小的改动,让 Bug Fix Agent 的首次修复成功率从 62% 提升到了 78%。
成本分析:值不值得?
很多人关心成本问题,我直接上数据。
月度成本明细
| Agent | 调用频率 | 每次 Token | 月度消耗 | 费用(约) |
|---|---|---|---|---|
| PR Review Agent | 15次/天 | 8000 tokens | 360万 tokens | ¥180 |
| API Doc Agent | 触发式 | 20000 tokens | 60万 tokens | ¥30 |
| Bug Fix Agent | 3次/天 | 15000 tokens | 135万 tokens | ¥68 |
| 合计 | - | - | 555万 tokens | ¥278 |
对比人力成本
| 场景 | 人工耗时 | Agent 耗时 | 节省 |
|---|---|---|---|
| PR Review | 30分钟/次 | 3分钟/次 | 每周 33 小时 |
| API 文档更新 | 2小时/次 | 5分钟/次 | 按需触发 |
| Bug 修复 | 1小时/次 | 10分钟/次 | 每周 5 小时 |
月度 ROI:投入 ¥278,节省约 152 小时人力 ≈ 节省 ¥30,000+
所以你问我值不值得?用不到 300 块钱换来一个「不眠不休的初级开发」,这买卖太划算了。
最后
AI Agent 开发的本质,不是「让 AI 替代人」,而是「让 AI 成为团队里最勤奋的那个初级开发」——它不抱怨、不请假、不摸鱼,24 小时待命。
而你作为「高级开发」,需要做的是:
- 定义清楚它要做什么(任务边界)
- 告诉它怎么做才是对的(示例和规范)
- 检查它做得对不对(验证和审核)
这恰恰是一个高级开发带初级开发的日常,只不过你的「徒弟」是 AI 而已。
本文是「AI 编程」系列的第一篇,下一篇我会深入讲如何用 MCP 协议让你的 Agent 接入更多工具,比如数据库、飞书、Jira 等。