AI Agent 开发学习指南
基于 Node.js / TypeScript + Vercel AI SDK + DeepSeek
1. 核心概念理解
在写代码之前,先把几个核心概念理解清楚,后续所有代码都是围绕这些概念展开的。
1.1 什么是 LLM
LLM(Large Language Model,大语言模型)就是 ChatGPT、Claude、DeepSeek 这类模型。 它的本质是一个函数:输入一段文字(Prompt),输出一段文字(Response)。
输入(Prompt)→ [LLM] → 输出(Response)
1.2 消息角色(Role)
每条消息都有一个角色,这是和 LLM 沟通的基本结构:
| 角色 | 说明 | 示例 |
|---|---|---|
system |
给 AI 的"人设说明书",定义它的行为方式 | "你是一个代码助手,只用中文回复" |
user |
用户发送的消息 | "帮我写一个排序函数" |
assistant |
AI 的回复(也可以手动填入,用于多轮对话) | "好的,这是一个冒泡排序..." |
💡 重要:LLM 本身没有记忆。每次调用都是全新的,多轮对话需要你手动把历史消息带上。
1.3 Token 是什么
Token 是 LLM 计费和计算的基本单位,大约:
- 1 个英文单词 ≈ 1-2 个 token
- 1 个中文字 ≈ 1-2 个 token
- 1000 个 token ≈ 750 个英文单词
DeepSeek 的 deepseek-chat 模型价格(2025年):
- 输入:¥0.001 / 1K tokens(约 750 个汉字)
- 输出:¥0.002 / 1K tokens
学习阶段花费极低,10 块钱能跑几千次对话。
1.4 什么是 AI Agent
普通 LLM 调用:用户问 → AI 答,一问一答结束。
AI Agent:AI 可以自主决策、调用工具、多步执行,直到完成目标。
用户:"帮我查一下明天北京的天气,如果下雨就帮我发邮件提醒同事"
Agent 执行过程:
步骤1:调用天气 API 查询北京天气 → 结果:明天有雨
步骤2:调用邮件 API 发送提醒邮件 → 结果:发送成功
步骤3:回复用户:已查到明天有雨,已发邮件通知同事
这种"思考 → 行动 → 观察 → 再思考"的循环叫 ReAct 循环,是 Agent 的核心模式。
2. 环境搭建
2.1 初始化项目
mkdir my-ai-agent
cd my-ai-agent
npm init -y
# 安装核心依赖
npm install ai @ai-sdk/deepseek zod
# 安装开发工具
npm install -D tsx typescript @types/node dotenv
2.2 配置 TypeScript
创建 tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"strict": true,
"outDir": "./dist"
}
}
2.3 配置环境变量
创建 .env 文件(不要提交到 git!):
DEEPSEEK_API_KEY=你的DeepSeek API Key
创建 .gitignore:
.env
node_modules/
dist/
2.4 获取 DeepSeek API Key
- 访问 platform.deepseek.com
- 注册账号,进入 API Keys 页面
- 创建新的 API Key,复制填入
.env文件
2.5 运行方式
# 直接运行 ts 文件(推荐开发阶段使用)
npx tsx index.ts
3. 基础:LLM 调用
3.1 最简单的文本生成
import { generateText } from 'ai'
import { createDeepSeek } from '@ai-sdk/deepseek'
import 'dotenv/config'
const deepseek = createDeepSeek({
apiKey: process.env.DEEPSEEK_API_KEY,
});
async function main() {
// 非流式交流、适合需要完整响应的场景(如摘要生成)
const result = await generateText({
model: deepseek('deepseek-v4-flash'),
system: '你是一个代码助手,回答要简洁,用中文回复。',
messages: [
// 另一种传递 system 信息的方法
// {
// role: 'system',
// content: '你是一个代码助手,回答要简洁,用中文回复。',
// },
{
role: 'user',
content: '用一句话解释什么是Nodejs?',
},
],
})
console.log(result);
console.log(result.text);
}
main();
3.2 流式输出(Streaming)
流式输出让 AI 的回复像"打字机"一样逐字出现,而不是等全部生成完再显示。 做聊天界面时必须使用流式,否则用户体验很差。
import { streamText } from 'ai'
import { createDeepSeek } from '@ai-sdk/deepseek'
import 'dotenv/config'
const deepseek = createDeepSeek({
apiKey: process.env.DEEPSEEK_API_KEY,
});
async function main() {
// 流式输出
const result = streamText({
model: deepseek('deepseek-v4-flash'),
// 使用 system 选项 进行编写,安全性更高
system: '你是一个技术博主,擅长写通俗易懂的技术文章。',
messages: [
{
role: 'user',
content: '用100字介绍一下 RAG 是什么',
},
],
});
// 字一个个打印出来,模拟打字机效果
for await (const chunk of result.textStream) {
process.stdout.write(chunk)
}
// 流结束后获取完整信息
console.log(await result.output);
const usage = await result.usage
console.log('输入 tokens:', usage.raw.prompt_tokens);
console.log('输出 tokens:', usage.raw.completion_tokens);
}
main();
3.3 generateText vs streamText 的选择
| 场景 | 推荐方式 |
|---|---|
| 后台批量处理、提取信息 | generateText |
| 用户界面、聊天对话 | streamText |
| 生成结构化数据 | generateText + Output |
import { generateText, Output } from 'ai'
import { createDeepSeek } from '@ai-sdk/deepseek'
import { z } from 'zod'
import 'dotenv/config'
const deepseek = createDeepSeek({
apiKey: process.env.DEEPSEEK_API_KEY,
});
async function main() {
// 待分析的用户评论文本
// 这是一条关于耳机的真实评论,包含优点、缺点和总体结论
const userReview = `
这款耳机音质很棒,低音够劲,佩戴也舒适。
但是续航只有6小时,有点短,而且价格偏贵。
总体来说还是值得买的。
`
// 调用 AI 生成文本(这里实际是生成结构化对象)
const result = await generateText({
// 指定使用的模型:DeepSeek 的 v4 flash 版本(速度快,适合简单任务)
model: deepseek('deepseek-v4-flash'),
// 配置输出格式:要求 AI 输出符合 Zod Schema 定义的 JSON 对象
output: Output.object({
// 使用 Zod 定义期望的结构
schema: z.object({
// 情感倾向:只能是 '正面', '负面', '中性' 之一
sentiment: z.enum(['正面', '负面', '中性']).describe('整体情感倾向'),
// 评分:1 到 5 的整数
score: z.number().min(1).max(5).describe('评分 1-5 分'),
// 优点:字符串数组
pros: z.array(z.string()).describe('优点列表'),
// 缺点:字符串数组
cons: z.array(z.string()).describe('缺点列表'),
// 一句话总结:字符串
summary: z.string().describe('一句话总结'),
})
}),
// 提示词:告诉 AI 需要做什么,并将用户评论内容传入
prompt: `分析以下用户评论,提取结构化信息:\n\n${userReview}`
});
// 打印 AI 返回的解析后的对象(会自动符合上面定义的 schema)
console.log(result.output);
}
main()
💬 评论 0
还没有评论,快来抢沙发吧~