一、我们正在经历什么

2026 年,一个数据正在被反复引用:84% 的开发者已经在日常工作中使用 AI 编程工具(Stack Overflow 2026 Developer Survey)。这个数字在三年前还是 33%。

但比数据更值得关注的是使用方式的质变

三年前,我们谈论的是 GitHub Copilot 的代码补全——它在你敲下 function 后帮你补完函数体。两年前,Cursor 带来了上下文感知的对话式编程——你可以选中一段代码,让它解释、重构或添加测试。而今天,我们正站在一个新的分水岭上:从”AI 辅助编程”到”AI 自主开发”的跨越。

这个变化的标志性事件是 Vercel AI SDK 6 的发布。它在 2026 年 Q2 正式推出了 ToolLoopAgent 抽象——一个让 AI 能够自主思考、规划、调用工具、接收反馈、并迭代执行的编程框架。Thomson Reuters 仅用 3 名开发者、2 个月时间,就基于它构建了服务 1,300 家会计事务所的 AI 法律助手 CoCounsel。

作为前端开发者,我们正处于这场变革的最佳观察位置。因为 AI Agent 的最终交互界面不是命令行,不是 IDE 插件,而是浏览器中的 UI。前端工程师不再只是”用 AI 写代码的人”,而是”为 AI 构建交互界面的人”。

本文将作为”前端 + AI Agent 开发实战”系列的第一篇,从概念到代码,用实战项目带你完成第一次范式跃迁。

二、AI Agent 到底是什么

2.1 不是所有的 AI 工具都叫 Agent

在深入代码之前,我们必须先厘清一个关键概念。当前市面上有三种不同层次的 AI 编程工具,它们常被混为一谈:

工具类型 典型代表 工作方式 自主程度
代码补全器 GitHub Copilot、Tabnine 基于光标上下文,预测下一行代码 无自主性,完全被动响应
对话助手 Cursor Chat、Claude Code 你提问,它回答;你指定任务,它执行 单轮对话,无持续记忆
AI Agent Vercel AI SDK Agent、LangChain Agent 接收目标后自主规划步骤、调用工具、迭代执行 多步推理,工具使用,目标驱动

用一句话总结:Copilot 帮你写一行代码,Chat 帮你写一个函数,Agent 帮你完成一个目标。

这个区别不是语义游戏,而是架构层级的差异。一个真正的 AI Agent 具备四项核心能力:

1
2
3
4
5
6
7
8
9
10
11
┌──────────────────────────────────────────────────┐
│ AI Agent 核心能力 │
├──────────┬──────────┬──────────┬────────────────┤
│ 感知 │ 规划 │ 执行 │ 反思 │
│ Perceive │ Plan │ Execute │ Reflect │
├──────────┼──────────┼──────────┼────────────────┤
│ 理解用户 │ 分解任务 │ 调用工具 │ 评估执行结果 │
│ 意图 │ 制定步骤 │ 操作外部 │ 决定继续/ │
│ 解析上下文 │ 确定依赖 │ 系统 │ 修正/完成 │
│ 结构化输入 │ 动态调整 │ 获取反馈 │ 学习并优化 │
└──────────┴──────────┴──────────┴────────────────┘

2.2 Agent 的决策循环

Agent 的核心工作模式是一个循环——学术界称之为 ReAct 模式(Reasoning + Acting),工业界称之为 Tool Loop

1
2
3
4
5
6
7
8
9
10
11
12
用户输入目标

思考(Reason):我应该用什么工具?以什么顺序?

行动(Act):调用工具,获取结果

观察(Observe):分析工具返回的数据

反思(Reflect):目标完成了吗?需要调整方案吗?

如果未完成 → 回到思考步骤
如果已完成 → 生成最终结果

这套机制使得 Agent 不仅能执行单一操作,还能处理需要多步推理的复杂任务。举个前端开发的例子:

用户说:”帮我在项目中添加一个用户登录页面”

传统 Chat:生成一个 Login.tsx 文件,结束。
AI Agent

  1. 思考:需要登录页面、路由配置、状态管理、API 对接、表单验证
  2. 执行:搜索现有项目结构,理解路由和状态管理方案
  3. 执行:创建 Login.tsx,配置路由
  4. 执行:添加 useAuth hook,对接登录 API
  5. 执行:添加表单验证逻辑
  6. 执行:运行 lint 和测试,修复发现的问题
  7. 反思:验证所有文件正确生成,报告完成

这就是 Agent 的价值——它不只是”生成代码”,而是”完成软件开发任务”。

三、前端为什么需要 Agent

3.1 前端开发的破碎化困境

现代前端开发面临一个结构性矛盾:工具链高度碎片化,但用户体验要求高度一体化。

一个典型的前端项目至少涉及:

  • 框架和路由(React Router / Next.js App Router / Vue Router)
  • 状态管理(Zustand / Jotai / Pinia / Redux)
  • 样式方案(Tailwind CSS / CSS Modules / styled-components)
  • 数据获取(React Query / SWR / tRPC / GraphQL)
  • 表单处理(React Hook Form / Zod / Yup)
  • 构建工具(Vite / Turbopack / Rspack)
  • 测试框架(Vitest / Playwright / Testing Library)

组合爆炸使得任何一个”非标准需求”都意味着大量的样板代码和配置工作。Agent 恰恰适合解决这类问题——它可以在理解项目上下文的基础上,自主组合这些工具。

3.2 Agent 在前端场景中的具体应用

不是所有前端任务都适合交给 Agent。根据我的实践,以下场景是 Agent 的黄金使用区:

高价值场景:

  1. 项目脚手架与配置 — “初始化一个带 Tailwind + React Router + Zustand 的项目”——传统方式要跑 5 个命令,Agent 一步完成
  2. CRUD 页面生成 — “给我生成一个用户管理页面,包含列表、搜索、分页、新增/编辑弹窗”
  3. 代码迁移与重构 — “把项目中的 class 组件全部改写成函数组件 + hooks”
  4. 重复性开发任务 — 批量生成测试用例、Storybook stories、API mock
  5. 文档与代码同步 — “根据组件代码更新 API 文档”

不适合的场景:

  • 创新性架构设计(需要深度领域知识)
  • 性能极度敏感的核心渲染逻辑
  • 安全关键的鉴权与加密(需要人类审查)

3.3 前端工程师的角色变迁

引入 Agent 之后,前端工程师的核心工作不再是”写代码”本身,而是:

1
2
3
4
5
6
7
旧范式:需求 → 设计 → 编码 → 测试 → 部署

80% 时间在这里

新范式:需求 → 设计 → 定义 Agent 目标 → 审查输出 → 集成 → 部署
↑ ↑
给 Agent 下指令 审查+微调(20% 时间)

换句话说,前端工程师正在从”代码生产者”转变为”AI 系统的编排者”和”质量把控者”。这听起来像威胁,但实际上是解放——你可以把精力放在更有价值的架构决策和用户体验设计上,而不是跟 Webpack 配置死磕。

四、技术选型:为什么是 Vercel AI SDK 6

4.1 市场格局

目前前端接入 AI Agent 有三个主流方案:

方案 定位 优点 缺点
Vercel AI SDK 6 全栈 AI 应用框架 提供商无关、流式原生、Agent 抽象成熟、UI 框架集成 学习曲线较陡,文档仍在完善
LangChain.js AI 编排框架 生态丰富、工具链完整、多模型支持 抽象层较厚,前端体验不如 SDK
直接调用 API 底层方案 最灵活、无额外依赖 需自己处理流式、工具调用、错误重试等

对于前端开发者,Vercel AI SDK 6 是最佳切入点。理由有三:

  1. 它对前端最友好 — 提供了 React/Vue/Svelte/Angular 的 hooks 和组件
  2. 流式响应内置支持 — AI 生成内容逐字出现在 UI 上是刚需,SDK 原生处理
  3. Agent 抽象最成熟ToolLoopAgent 是当前生产级实现中最完善的

4.2 Vercel AI SDK 6 架构速览

1
2
3
4
5
6
7
8
9
10
11
12
┌──────────────────────────────────────────────────┐
│ Vercel AI SDK 6 │
│ 月下载 2000万+ | 包体积 ~50KB │
├──────────────┬───────────────┬────────────────────┤
│ AI SDK Core │ AI SDK UI │ AI SDK Agents │
├──────────────┼───────────────┼────────────────────┤
│ • generateText│ • useChat() │ • ToolLoopAgent │
│ • streamText │ • useCompletion│ • Human-in-Loop │
│ • tool() │ • useObject() │ • Multi-Agent │
│ • 结构化输出 │ • 生成式 UI │ • MCP 集成 │
│ • 25+ 模型 │ • 框架无关 │ • 自动修复 │
└──────────────┴───────────────┴────────────────────┘

三个模块各司其职:

  • Core:统一的模型调用接口,屏蔽不同提供商的 API 差异
  • UI:前端 hooks,处理流式消息和 UI 状态
  • Agents(SDK 6 新模块):Tool Loop 抽象,定义一次,到处使用

五、实战:构建一个智能项目脚手架 Agent

理论讲够了,让我们动手。

5.1 项目目标

我们将构建一个 Project Scaffold Agent——一个能够理解用户需求、自动初始化项目结构、安装依赖、生成配置文件的 AI Agent。

当用户说:”帮我创建一个带身份认证的 Next.js 博客项目”,Agent 将:

  1. 分析需求:Next.js 项目 + 身份认证 + 博客功能
  2. 创建项目:运行 create-next-app
  3. 配置认证:安装 NextAuth.js,生成配置
  4. 创建数据库 Schema:生成 Prisma schema
  5. 生成博客功能:文章列表、详情页、Markdown 渲染
  6. 验证结果:检查文件结构是否完整

5.2 项目初始化

1
2
3
4
5
6
7
8
9
# 创建项目
mkdir project-scaffold-agent && cd project-scaffold-agent
pnpm init

# 安装核心依赖
pnpm add ai @ai-sdk/openai zod

# 安装项目脚手架工具
pnpm add -D typescript @types/node tsx

创建 tsconfig.json

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"]
}

5.3 定义工具:给 Agent 装上手脚

Agent 的能力边界由它所拥有的**工具(Tools)**决定。我们先定义三个核心工具:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// src/tools/filesystem.ts
import { tool } from 'ai';
import { z } from 'zod';
import { writeFile, mkdir } from 'fs/promises';
import { join } from 'path';

// 工具 1:创建目录
export const createDirectoryTool = tool({
description: '在项目中创建一个新目录。如果父目录不存在会自动创建。',
parameters: z.object({
path: z.string().describe('相对于项目根目录的路径,如 "src/components"'),
}),
execute: async ({ path }) => {
const fullPath = join(process.cwd(), path);
await mkdir(fullPath, { recursive: true });
return { success: true, created: fullPath };
},
});

// 工具 2:写入文件
export const writeFileTool = tool({
description: '将内容写入指定文件。会自动创建不存在的父目录。',
parameters: z.object({
path: z.string().describe('文件路径,如 "src/app/page.tsx"'),
content: z.string().describe('文件内容'),
}),
execute: async ({ path, content }) => {
const fullPath = join(process.cwd(), path);
await mkdir(join(fullPath, '..'), { recursive: true });
await writeFile(fullPath, content, 'utf-8');
return { success: true, written: fullPath, size: content.length };
},
});

// 工具 3:执行 shell 命令
export const executeCommandTool = tool({
description: '在项目目录中执行一个 shell 命令。用于安装依赖、运行脚本等。',
parameters: z.object({
command: z.string().describe('要执行的命令'),
cwd: z.string().optional().describe('工作目录,默认为项目根目录'),
}),
execute: async ({ command, cwd }) => {
const { execSync } = await import('child_process');
try {
const output = execSync(command, {
cwd: cwd || process.cwd(),
encoding: 'utf-8',
timeout: 60000,
});
return { success: true, output: output.slice(0, 2000) };
} catch (error: any) {
return { success: false, error: error.message };
}
},
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// src/tools/project-reader.ts
import { tool } from 'ai';
import { z } from 'zod';
import { readdir, readFile } from 'fs/promises';
import { join } from 'path';
import { glob } from 'glob';

// 工具 4:查看项目结构
export const readProjectStructureTool = tool({
description: '查看当前项目的目录结构和文件列表。',
parameters: z.object({
path: z.string().default('.').describe('要查看的目录路径'),
depth: z.number().default(2).describe('遍历深度'),
}),
execute: async ({ path, depth }) => {
const fullPath = join(process.cwd(), path);
const files = await glob('**/*', {
cwd: fullPath,
ignore: ['node_modules/**', '.git/**', 'dist/**'],
maxDepth: depth,
nodir: false,
});
return { path, fileCount: files.length, files: files.slice(0, 100) };
},
});

// 工具 5:读取文件内容
export const readFileTool = tool({
description: '读取项目中某个文件的内容。',
parameters: z.object({
path: z.string().describe('文件路径'),
}),
execute: async ({ path }) => {
const fullPath = join(process.cwd(), path);
try {
const content = await readFile(fullPath, 'utf-8');
return { path, content: content.slice(0, 5000) };
} catch {
return { path, error: 'File not found' };
}
},
});

5.4 创建 Agent:给手脚装上大脑

有了工具,接下来创建 Agent 的”大脑”——系统提示词和 Agent 实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// src/agent.ts
import { ToolLoopAgent } from 'ai';
import { openai } from '@ai-sdk/openai';
import { stepCountIs } from 'ai';
import {
createDirectoryTool,
writeFileTool,
executeCommandTool,
} from './tools/filesystem';
import {
readProjectStructureTool,
readFileTool,
} from './tools/project-reader';

const SYSTEM_PROMPT = `你是一个专业的前端项目脚手架助手。

你的核心能力:
1. 理解用户的项目需求,拆解为具体的技术步骤
2. 使用提供的工具来创建目录、写入文件、执行命令
3. 在操作前先查看项目状态,避免重复工作
4. 确保生成的项目结构符合最佳实践

工作流程:
1. 首先使用 readProjectStructure 了解当前项目状态
2. 规划需要创建的文件和安装的依赖
3. 按依赖顺序执行操作(先创建目录结构,再写文件,最后安装依赖)
4. 验证结果:再次查看项目结构,确认所有文件已正确生成

最佳实践:
- Next.js 项目使用 App Router,页面放 src/app/
- 组件放 src/components/,按功能分子目录
- 使用 TypeScript 严格模式
- 配置文件使用 ESM 格式
- 安装依赖时使用 pnpm`;

export const scaffoldAgent = new ToolLoopAgent({
model: openai('gpt-4o'),
system: SYSTEM_PROMPT,
tools: {
createDirectory: createDirectoryTool,
writeFile: writeFileTool,
executeCommand: executeCommandTool,
readProjectStructure: readProjectStructureTool,
readFile: readFileTool,
},
stopWhen: stepCountIs(15), // 最多执行 15 步,防止无限循环
temperature: 0.3, // 较低的温度以获得更可预测的输出
});

关键设计决策解读:

为什么 stopWhen: stepCountIs(15) Agent 可能陷入”修了又修”的循环。设置最大步数既是安全阀,也是成本控制——每步都消耗 token。

为什么 temperature 设为 0.3? 脚手架任务需要确定性。高温度会让 Agent 生成不一致的代码风格。

5.5 交互入口:给 Agent 一个命令行界面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// src/index.ts
import { scaffoldAgent } from './agent';
import * as readline from 'readline';

async function main() {
console.log('🤖 Project Scaffold Agent 已就绪');
console.log('描述你想要的项目,Agent 将自动创建它。');
console.log('示例:"创建一个带 Tailwind CSS 的 Next.js 博客项目"');
console.log('---');

const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});

const askQuestion = () => {
rl.question('\n📝 你想要创建什么项目?\n> ', async (input) => {
if (input.toLowerCase() === 'exit') {
console.log('再见!');
rl.close();
return;
}

console.log('\n⚙️ Agent 正在分析和执行...\n');

try {
const result = await scaffoldAgent.generate({
prompt: input,
onStepFinish: (step) => {
// 实时反馈:显示 Agent 正在做什么
const toolCalls = step.toolCalls || [];
toolCalls.forEach((call: any) => {
console.log(
` 📍 步骤 ${step.stepNumber}: 调用 ${call.toolName}(${JSON.stringify(call.args).slice(0, 80)}...)`
);
});
},
});

console.log('\n✅ 项目创建完成!');
console.log('\n📋 Agent 总结:');
console.log(result.text);
console.log('\n📊 统计信息:');
console.log(` 总步骤数: ${result.steps?.length || 0}`);
console.log(` 总 Token 消耗: ${result.usage?.totalTokens || 0}`);
} catch (error: any) {
console.error(`\n❌ 出错: ${error.message}`);
}

askQuestion();
});
};

askQuestion();
}

main();

5.6 运行效果

1
2
3
4
5
# 设置 API Key
export OPENAI_API_KEY="sk-..."

# 运行 Agent
npx tsx src/index.ts

运行示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
🤖 Project Scaffold Agent 已就绪
描述你想要的项目,Agent 将自动创建它。
示例:"创建一个带 Tailwind CSS 的 Next.js 博客项目"
---

📝 你想要创建什么项目?
> 创建一个带 Markdown 博客功能的 Next.js 项目,使用 Tailwind CSS

⚙️ Agent 正在分析和执行...

📍 步骤 1: 调用 readProjectStructure({path: ".", depth: 1})
📍 步骤 2: 调用 executeCommand({command: "pnpm create next-app@latest my-blog ...
📍 步骤 3: 调用 executeCommand({command: "pnpm add tailwindcss @tailwindcss/...
📍 步骤 4: 调用 writeFile({path: "my-blog/tailwind.config.ts", content: "...
📍 步骤 5: 调用 createDirectory({path: "my-blog/posts"})
📍 步骤 6: 调用 writeFile({path: "my-blog/src/app/page.tsx", content: "...
📍 步骤 7: 调用 writeFile({path: "my-blog/src/lib/posts.ts", content: "...
📍 步骤 8: 调用 readProjectStructure({path: "my-blog", depth: 3})

✅ 项目创建完成!

📊 统计信息:
总步骤数: 8
总 Token 消耗: 4,521

六、进阶:集成前端 UI

Agent 的后端能力验证通过后,下一步是给它一个优雅的前端界面。

6.1 使用 useChat Hook 构建对话界面

Vercel AI SDK 提供了 useChat hook,三行代码就能接入 Agent 的流式响应:

1
2
3
4
5
6
7
8
9
10
// app/api/chat/route.ts (Next.js API Route)
import { scaffoldAgent } from '@/agent';

export async function POST(req: Request) {
const { messages } = await req.json();

const stream = await scaffoldAgent.stream({ messages });

return stream.toDataStreamResponse();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// app/page.tsx (Next.js 页面)
'use client';

import { useChat } from 'ai/react';

export default function ChatPage() {
const { messages, input, handleInputChange, handleSubmit, isLoading } =
useChat({
api: '/api/chat',
});

return (
<div className="flex flex-col h-screen max-w-3xl mx-auto p-4">
<h1 className="text-2xl font-bold mb-4">Project Scaffold Agent</h1>

<div className="flex-1 overflow-y-auto space-y-4 mb-4">
{messages.map((m) => (
<div
key={m.id}
className={`p-4 rounded-lg ${
m.role === 'user'
? 'bg-blue-100 ml-12'
: 'bg-gray-100 mr-12'
}`}
>
<div className="font-semibold mb-1">
{m.role === 'user' ? '你' : 'Agent'}
</div>
<div className="whitespace-pre-wrap">{m.content}</div>

{/* 展示工具调用详情 */}
{m.toolInvocations?.map((tool) => (
<div
key={tool.toolCallId}
className="mt-2 p-2 bg-white rounded border text-sm"
>
<span className="text-purple-600 font-mono">
🔧 {tool.toolName}
</span>
<pre className="text-xs mt-1 text-gray-500">
{JSON.stringify(tool.args, null, 2)}
</pre>
{tool.result && (
<div className="mt-1 text-green-600">✓ 执行成功</div>
)}
</div>
))}
</div>
))}

{isLoading && (
<div className="text-gray-400 p-4">Agent 正在思考...</div>
)}
</div>

<form onSubmit={handleSubmit} className="flex gap-2">
<input
value={input}
onChange={handleInputChange}
placeholder="描述你想要创建的项目..."
className="flex-1 p-3 border rounded-lg"
/>
<button
type="submit"
disabled={isLoading}
className="px-6 py-3 bg-blue-600 text-white rounded-lg disabled:opacity-50"
>
发送
</button>
</form>
</div>
);
}

6.2 人工审批:危险操作的二次确认

生成代码可以自动,但执行命令(尤其是 rm -rfgit push --force)必须有人的审批。AI SDK 6 的 needsApproval 机制正好解决这个问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 对危险操作添加审批
export const executeCommandTool = tool({
description: '执行 shell 命令',
parameters: z.object({
command: z.string(),
}),

// 自动判断是否需要审批
needsApproval: async ({ command }) => {
const dangerous = ['rm -rf', 'git push --force', 'DROP TABLE', 'DELETE FROM'];
return dangerous.some((pattern) => command.includes(pattern));
},

execute: async ({ command, cwd }) => {
// 执行逻辑同上
},
});

前端自动展示审批 UI:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 在消息渲染中处理审批
{m.toolInvocations?.map((tool) => {
if (tool.state === 'call' && tool.needsApproval) {
return (
<div key={tool.toolCallId} className="p-3 bg-yellow-50 border border-yellow-300 rounded">
<p className="text-yellow-800 font-medium">⚠️ 需要你的审批</p>
<p className="text-sm text-yellow-600">
Agent 想要执行:<code className="bg-yellow-100 px-1">{tool.args.command}</code>
</p>
<div className="flex gap-2 mt-2">
<button
onClick={() => addToolResult({ toolCallId: tool.toolCallId, result: 'approved' })}
className="px-3 py-1 bg-green-600 text-white rounded text-sm"
>
批准
</button>
<button
onClick={() => addToolResult({ toolCallId: tool.toolCallId, result: 'rejected' })}
className="px-3 py-1 bg-red-600 text-white rounded text-sm"
>
拒绝
</button>
</div>
</div>
);
}
// ... 正常工具展示
})}

七、进阶话题:多 Agent 编排

单个 Agent 适合处理单一范畴的任务,但真实项目往往涉及多个领域。这时需要多 Agent 编排——不同 Agent 各司其职,通过协调器串联:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// 定义专业化 Agent
const uiAgent = new ToolLoopAgent({
model: openai('gpt-4o-mini'),
system: '你是 UI 组件专家。只负责生成 React 组件代码。',
tools: { writeFile: writeFileTool, readFile: readFileTool },
});

const apiAgent = new ToolLoopAgent({
model: openai('gpt-4o-mini'),
system: '你是 API 开发专家。只负责生成 API 路由和数据库 Schema。',
tools: { writeFile: writeFileTool, executeCommand: executeCommandTool },
});

const architectAgent = new ToolLoopAgent({
model: openai('gpt-4o'),
system: '你是系统架构师。接收用户需求,分解为 UI 和 API 任务,协调两个专业 Agent。',
tools: {},
});

// 编排器
async function orchestrate(userRequest: string) {
// 第一步:架构师分析需求并分解
const plan = await architectAgent.generate({
prompt: `将以下需求分解为 UI 和 API 两个子任务:${userRequest}
输出格式:{ uiTask: string, apiTask: string }`,
});

// 第二步:并行执行两个专业 Agent
const [uiResult, apiResult] = await Promise.all([
uiAgent.generate({ prompt: plan.uiTask }),
apiAgent.generate({ prompt: plan.apiTask }),
]);

// 第三步:汇总结果
return {
ui: uiResult.text,
api: apiResult.text,
summary: `完成:生成了 UI 组件和 API 接口`,
};
}

多 Agent 架构的优势在于:

  • 专业化:每个 Agent 专注于自己擅长的领域,输出质量更高
  • 并行化:独立任务可以同时执行,速度更快
  • 成本优化:复杂任务用强模型(gpt-4o),简单任务用弱模型(gpt-4o-mini)
  • 可维护性:修改一个 Agent 不影响其他 Agent

八、生产环境考量

从 Demo 到生产,需要考虑以下关键问题:

8.1 成本控制

AI Agent 的 token 消耗可能迅速膨胀。以下策略可以有效控制成本:

策略 效果 实现
模型分层 简单判断用 gpt-4o-mini 根据任务复杂度动态选择模型
限制步数 防止无限循环 stopWhen: stepCountIs(n)
缓存系统提示词 减少重复 token 使用 prompt caching(OpenAI/Anthropic 均支持)
结果缓存 相同输入复用结果 Redis 缓存生成的项目模板
批量任务合并 减少 API 调用次数 一次调用生成多个文件

8.2 安全边界

Agent 拥有文件系统和命令执行权限,安全隔离至关重要:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 路径沙箱:限制 Agent 只能在指定目录内操作
import { resolve } from 'path';

const PROJECT_ROOT = resolve(process.cwd());

function sanitizePath(inputPath: string): string {
const resolved = resolve(PROJECT_ROOT, inputPath);
if (!resolved.startsWith(PROJECT_ROOT)) {
throw new Error(`禁止访问项目外的路径: ${inputPath}`);
}
return resolved;
}

// 命令白名单:只允许安全的命令
const ALLOWED_COMMANDS = [
/^pnpm /,
/^npm /,
/^npx /,
/^git /,
/^ls /,
/^node /,
];

function validateCommand(command: string): boolean {
return ALLOWED_COMMANDS.some((pattern) => pattern.test(command.trim()));
}

8.3 错误处理与重试

Agent 执行可能因网络、API 限制、工具失败等原因中断。健壮的 Agent 需要:

1
2
3
4
5
6
7
8
9
10
11
12
13
const result = await scaffoldAgent.generate({
prompt: userRequest,
maxRetries: 3, // 失败自动重试
abortSignal: AbortSignal.timeout(120_000), // 2 分钟超时
onError: async (error) => {
// 错误回调:记录日志、发送告警
console.error(`Agent 执行失败:`, {
error: error.message,
step: error.stepNumber,
toolName: error.toolName,
});
},
});

九、值得警醒的局限性

尽管 AI Agent 令人兴奋,但我必须诚实指出当前的局限:

9.1 不可靠的规划

Agent 有时会做出”看起来合理但实际行不通”的规划。比如试图在一个不存在的框架版本中使用某个 API。这要求开发者具备审查 Agent 输出的能力——你不能盲目信任它。

9.2 上下文窗口的限制

虽然现在 128K token 的上下文窗口已很常见,但 Agent 的多步执行会迅速消耗 token。当上下文接近极限时,Agent 的推理质量会明显下降。

9.3 “幻觉”依然存在

Agent 可能生成不存在的 npm 包名、虚构的 API 接口、或语义正确但逻辑有误的代码。这在脚手架场景相对可控(你可以直接运行验证),但在更复杂的业务逻辑中可能成为隐患。

9.4 不适合持续迭代

当前 Agent 模型是无状态的——每次调用都是全新的上下文。这使得持续的、迭代式的开发(比如三天时间逐步完善一个功能)体验不佳。这需要额外的记忆管理机制(如将关键信息写入项目文件)。

十、总结与展望

10.1 核心要点

本文从概念到代码,完成了一个完整的前端 AI Agent 实战项目。核心要点:

  1. AI Agent 不是升级版的 Copilot,而是一种全新的开发范式——从”人写代码”到”人定义目标”
  2. Vercel AI SDK 6 是目前前端接入 AI Agent 的最佳工具链,其 ToolLoopAgent 抽象成熟且生产可用
  3. 工具定义是 Agent 的核心——Agent 的能力上限由它所拥有的工具决定,精心设计工具比优化提示词更重要
  4. 安全边界不可忽视:路径沙箱、命令白名单、人工审批是生产环境的必备三道防线

10.2 前端工程师的未来定位

回到文章开头提出的问题:AI Agent 会让前端工程师失业吗?

我的判断是:不会,但会淘汰那些”只会照需求写组件”的工程师。

未来的前端工程师需要三种新能力:

  • AI 编排能力:能定义 Agent 目标、设计工具链、审查 Agent 输出
  • 架构决策能力:当 Agent 能生成代码时,你的人类价值在于”生成什么样的代码”
  • 全栈视野:Agent 弥合了前后端的工具差异,你需要理解整个系统而非局限于浏览器

在这个范式下,前端工程师不再是”程序员”,而是产品构建者(Product Builder)——用 AI 作为杠杆,用更少的代码创造更多的价值。

10.3 系列预告

本系列后续将涵盖:

  • 第二篇:Agent 工具设计模式——如何为你的项目定制工具集
  • 第三篇:多 Agent 编排实战——构建一个覆盖前后端的 AI 开发团队
  • 第四篇:Agent 的记忆与状态管理——让 Agent 拥有跨会话的记忆
  • 第五篇:生产级 AI Agent 应用的部署与运维

本文全部代码可在真实环境中运行。如果你跟着实战遇到了问题,欢迎在评论区讨论。下一篇见。