作者:前端转 AI 深度实践者
【省流助手/核心观点】:前端开发者转 AI 工程,真正的分水岭不是“会不会调大模型 API”,而是能不能把模型放进一个可控的工程系统里。一个可交付的 AI 项目,至少要具备结构化输出、RAG、Tool Calling、Agent Loop、失败处理、可观测性、安全边界和测试场景。30 天训练的毕业项目,不应该追求炫,而应该追求清楚、可靠、可复盘。
很多前端开发者开始学 AI,第一目标通常是:
我想把大模型接进项目里。
这是一个好起点。
但如果 30 天后,你只是会写:
await client.chat.completions.create({
model: "xxx",
messages: [{ role: "user", content: "帮我总结一下" }]
});
那还不够。
因为真实 AI 工程不是“调一下模型,然后把文本显示到页面上”。
真实 AI 工程要面对:
- 模型输出不稳定。
- 用户问题不标准。
- 资料检索不准确。
- 工具参数会出错。
- 外部接口会失败。
- 高风险操作不能直接执行。
- 线上问题需要排查。
- 团队需要能维护。
所以第 30 篇不再引入一个新概念。
我们做一件更重要的事:
把前面学过的能力,组合成一个可交付的小项目。
1. 痛点:只会调 API,离交付 AI 工程还差很远
很多 AI demo 的代码长这样:
async function askAi(question: string) {
const response = await llm.chat(question);
return response.text;
}
这段代码不是没用。
它能帮你迈出第一步。
但它不能回答工程问题:
- 模型返回 JSON 失败怎么办?
- 答案有没有引用来源?
- 用户问订单时,数据来自哪里?
- 工具调用失败后怎么停?
- 高风险操作谁来确认?
- 用户反馈“AI 不靠谱”时怎么排查?
如果这些问题都没有答案,它就只是一个 demo。
能交付的 AI 工程项目,必须把模型、数据、工具、流程、安全、日志和测试组合起来。
2. 毕业项目:AI 客服 Agent
这个毕业项目可以叫:
AI 客服 Agent
它不需要一开始就接真实大模型,也不需要接真实数据库。
你可以用 mock 数据、mock 模型和本地页面完成。
重点不是“看起来多智能”。
重点是它有没有 AI 工程项目该有的结构。
它至少应该能处理:
- 查询订单状态。
- 查询售后政策。
- 判断是否需要创建客服工单。
- 对高风险操作进行确认。
- 遇到失败时重试、降级或停止。
- 输出 trace、事件日志和运行报告。
这听起来不像一个玩具 demo。
它已经开始像一个系统。
3. 30 天应该怎么拆?
可以按 4 个阶段推进。
第 1 周:会调模型,但不相信模型
第 2 周:接入 RAG,让答案有依据
第 3 周:接入 Tool Calling,让系统能办事
第 4 周:补 Agent Loop、失败处理、安全和可观测性
每周的目标不是“学更多概念”,而是交付一个能跑的切片。
第 1 周:结构化输出和兜底
你要做到:
- 模型返回结构化 JSON。
- 程序能校验输出。
- 解析失败时能兜底。
- 页面能展示成功态和错误态。
第 2 周:RAG 和引用来源
你要做到:
- 用户问题能检索知识库。
- 答案带引用来源。
- 资料不足时拒答。
- 能看见命中的 chunks。
第 3 周:Tool Calling 和工具 Schema
你要做到:
- 模型能提出工具调用。
- 程序能校验工具名和参数。
- 工具有风险等级和权限要求。
- 高风险工具不会自动执行。
第 4 周:Agent 工程化
你要做到:
- Agent 能按计划多步执行。
- 失败时能 retry、fallback、pause、stop。
- 每次运行有 trace 和结构化事件。
- 至少覆盖 6 个测试场景。
4. 错误做法:把所有东西塞进一个函数
很多毕业项目会写成这样:
async function runAiCustomerService(question: string) {
const prompt = `你是一个客服助手,请回答:${question}`;
const answer = await llm.chat(prompt);
return answer;
}
或者稍微复杂一点:
async function runEverything(question: string) {
const intent = await llm.chat(`判断用户意图:${question}`);
const docs = await searchDocs(question);
const order = await getOrderStatus(question);
const answer = await llm.chat(`
意图:${intent}
资料:${JSON.stringify(docs)}
订单:${JSON.stringify(order)}
请回答用户。
`);
return answer;
}
这种写法一开始很快,但后面会很痛。
因为 Prompt、检索、工具调用、权限、失败处理、日志、最终回答全混在一起。
一旦用户说“答案不对”,你很难判断到底是哪一层出了问题。
5. 正确做法:把 AI 项目拆成 7 层
一个可交付的 AI 客服 Agent,可以拆成 7 层:
用户输入
-> 意图识别 / mockModel
-> RAG 检索 searchDocs
-> 计划生成 createPlan
-> 工具执行 runToolSafely
-> 失败处理 handleStepFailure
-> 最终回答 + 运行报告
代码目录可以这样组织:
src/ai-customer-agent/
mock-data.ts
tools.ts
tool-registry.ts
rag.ts
planner.ts
executor.ts
safety.ts
observability.ts
demo.ts
注意,这里最重要的不是文件多。
而是边界清楚。
每一层都能单独测试、单独替换、单独排查。
6. 最小类型设计:先把工程边界写出来
先定义毕业项目的核心类型:
type AgentTask =
| "check_order"
| "check_policy"
| "create_ticket"
| "cancel_order";
type PlanStep = {
id: string;
goal: string;
task: AgentTask;
toolName: string;
args: Record<string, unknown>;
status:
| "pending"
| "running"
| "done"
| "failed"
| "skipped"
| "paused"
| "fallback";
observation?: unknown;
error?: unknown;
};
type AgentRunResult = {
ok: boolean;
answer: string;
plan: PlanStep[];
events: AgentEvent[];
report: AgentRunReport;
};
这些类型会逼你思考:
- 任务类型有哪些?
- 每一步要调用什么工具?
- 步骤有哪些状态?
- 运行结果要返回什么?
- 排查时需要看哪些信息?
这就是工程化的价值。
7. 工具不是函数列表,而是能力契约
毕业项目至少要有 4 个工具:
getOrderStatus(orderId)
searchPolicy(keyword)
createSupportTicket(orderId, issue)
cancelOrder(orderId)
但不要只写函数。
还要写工具配置:
type ToolDefinition = {
name: string;
description: string;
riskLevel: "low" | "medium" | "high";
requiredPermission: string;
requiresConfirmation: boolean;
handler: (args: Record<string, unknown>) => Promise<unknown>;
};
const getOrderStatusTool: ToolDefinition = {
name: "getOrderStatus",
description: "查询订单物流状态,不用于取消订单或发起退款。",
riskLevel: "low",
requiredPermission: "order:read",
requiresConfirmation: false,
handler: async (args) => {
return {
orderId: args.orderId,
status: "shipping",
eta: "2026-05-10"
};
}
};
这份配置代表很多工程意识:
- 工具是做什么的。
- 参数需要什么。
- 风险有多高。
- 用户需要什么权限。
- 是否需要确认。
函数解决“怎么做”。
Schema 和配置解决“什么时候能做、谁能做、怎么安全地做”。
8. Agent 不能只会成功路径
毕业项目必须覆盖失败路径。
至少支持这些错误:
type ToolErrorType =
| "timeout"
| "not_found"
| "empty_result"
| "permission_denied"
| "confirmation_required"
| "invalid_arguments";
处理策略也要清楚:
const failureStrategies = {
timeout: "retry",
empty_result: "fallback",
not_found: "stop",
permission_denied: "stop",
confirmation_required: "pause",
invalid_arguments: "stop"
} as const;
这很重要。
真实用户不会只走你精心设计的成功路径。
他们会问错订单号,会没有权限,会遇到空政策,会触发高风险动作。
一个能上线的 AI 功能,必须能体面地失败。
9. 可观测性是毕业项目的必选项
毕业项目每次运行都应该返回:
type AgentRunPayload = {
answer: string;
report: AgentRunReport;
events: AgentEvent[];
plan: PlanStep[];
};
其中:
answer是给用户看的最终回答。report是给开发者看的运行摘要。events是可追踪的结构化日志。plan是 Agent 的执行过程。
这套输出会让你具备复盘能力。
用户说“AI 回答不对”时,你能看到:
- 创建了什么计划。
- 调用了哪些工具。
- 哪一步失败。
- 是否重试。
- 是否降级。
- 最终答案依据什么生成。
没有可观测性的 Agent,就是一个看起来很自信但无法复盘的黑盒。
10. 安全边界决定它能不能接真实业务
AI 客服 Agent 里最危险的工具是:
cancelOrder(orderId)
这个工具不能直接执行。
即使用户说:
帮我取消订单 A1001。
系统也应该先返回确认请求:
type ConfirmationRequest = {
toolName: "cancelOrder";
argsSummary: string;
message: string;
status: "pending";
};
用户确认后再执行。
这不是“AI 不够智能”。
这是系统负责。
任何有副作用、不可逆、会影响用户权益的工具,都必须有权限和确认。
模型可以建议动作,但程序必须掌握执行权。
11. 毕业项目的 6 个测试场景
一个合格的毕业项目,至少要覆盖这些场景:
- 普通用户查询订单成功。
- 订单不存在,Agent 停止并说明。
- 查询订单延迟补偿,结合订单和政策回答。
- 政策为空,Agent 降级且不编造。
- 普通用户创建工单,权限不足。
- 客服用户取消订单,先确认,确认后执行。
这 6 个测试很朴素,但覆盖了 AI 工程最重要的几类路径:
- 成功。
- 失败。
- 降级。
- 权限不足。
- 高风险确认。
- 可追踪输出。
如果你的项目能把这些跑清楚,就已经比很多“只有成功路径”的 AI demo 更扎实。
12. 生产环境避坑指南
1. 不要一开始就接真实模型和真实写入工具
先用 mockModel 和 mock data 跑通工程骨架。
等流程稳定后,再替换真实模型和真实后端。
2. 不要把工具越接越多
毕业项目 4 个工具就够。
工具少而清晰,比工具多而混乱更像工程项目。
3. 不要只验收最终答案
必须同时检查 answer、plan、events 和 report。
只看最终答案,很容易漏掉中间步骤的错误。
4. 不要把安全确认留到最后补
只要工具有副作用,权限和确认就应该从第一版设计进去。
后补安全边界,往往会改动整个执行链路。
5. 不要用“看起来聪明”当验收标准
验收标准应该是:
- 是否能稳定跑完 6 个测试场景?
- 失败时是否能停止或降级?
- 高风险操作是否会暂停确认?
- 每次运行是否可复盘?
13. 前端开发者这 30 天真正学到了什么
从前端转 AI 工程,不是把 JavaScript 忘掉,然后从零变成算法工程师。
更现实的路线是:把你的工程经验迁移过来。
你已经懂:
- 状态管理。
- API 契约。
- 表单校验。
- 错误态。
- loading 和 empty。
- 权限按钮。
- 确认弹窗。
- 埋点和日志。
- 前后端联调。
这些在 AI 工程里全部有对应物:
messages是状态。- Tool Schema 是 API 契约。
- 参数校验是表单校验。
empty_result是 empty state。confirmation_required是确认弹窗。traceId是 requestId。- Agent Loop 是状态和副作用循环。
- RAG 评估是质量回归。
所以你不是跨到一个完全陌生的行业。
你是在把已有工程能力,扩展到模型、检索和工具系统上。
14. 30 天后的下一步
完成毕业项目后,可以继续往这些方向深入:
- 把
mockModel换成真实大模型。 - 用 FastAPI 或 Node.js 把 Agent 封成后端服务。
- 做一个前端聊天页面。
- 接入真实向量检索。
- 把 events 写入数据库。
- 做一套 Agent 评测集。
- 增加更严格的权限和审计。
- 学习生产级 Agent 框架。
但无论往哪走,都不要丢掉这 30 天建立的底层判断:
AI 工程不是让模型独自表演,而是把模型、数据、工具、流程、安全和观测组合成可靠系统。
## 结语
30 天训练的终点,不是“学完了 AI”。
它只是把你从门口带到了第一块真正的工程地面上。
你已经不只是知道怎么调用模型。
你开始知道怎么约束模型,怎么给模型工具,怎么处理失败,怎么追踪过程,怎么保护高风险动作,怎么把一个 AI 功能做成能被团队维护的小系统。
这就是前端开发者转 AI 工程最重要的一步:
**从“让模型回答”,走向“让系统可靠”。**