第二章:大语言模型(LLM)基础 —— Agent 的大脑
2.1 什么是大语言模型?
大语言模型(Large Language Model, LLM) 是 AI Agent 的核心引擎。简单理解:
LLM 就是一个超级"文字接龙"高手。你给它一段文字,它能预测接下来最合理的文字,而且它读过互联网上海量的文本,所以"接"得特别聪明。
对 JS 开发者的类比
// LLM 的本质行为可以类比为:
function llm(input) {
// 基于海量训练数据学到的"模式"
// 预测最合理的输出
return mostLikelyCompletion(input);
}
// 例如:
llm("JavaScript 是一种")
// → "广泛使用的编程语言,主要用于Web开发..."主流 LLM 一览(2025-2026)
| 模型 | 厂商 | 特点 | API 价格参考 |
|---|---|---|---|
| GPT-5 | OpenAI | 最新旗舰,深度推理能力极强 | 较高 |
| GPT-5.3 Instant | OpenAI | GPT-5 系列轻量版,速度快 | 中等 |
| GPT-4o | OpenAI | 综合能力强,性价比高 | 中等 |
| Claude Opus 4.6 | Anthropic | 当前最强推理+编码模型 | 较高 |
| Claude Sonnet 4 | Anthropic | 代码能力出色,速度与质量均衡 | 中等 |
| Gemini 2.5 Pro | 多模态强,上下文超长 | 中等 | |
| DeepSeek-V3 | DeepSeek | 性价比极高,中文优秀 | 低 |
| Qwen 2.5 | 阿里 | 中文优秀,可本地部署 | 低/免费 |
| Llama 3.3 | Meta | 开源,可本地部署 | 免费 |
💡 模型更新很快:OpenAI 在 2025 年底发布了 GPT-5,Anthropic 的 Claude 已到 Opus 4.6 版本。选择模型时关注官方最新发布。
2.2 理解 LLM 的关键概念
Token(令牌)
LLM 不是按"字"或"词"处理文本的,而是按 Token 处理。
// 英文大约 1 token ≈ 4 个字符 ≈ 0.75 个单词
"Hello, world!" → ["Hello", ",", " world", "!"] // 4 tokens
// 中文大约 1 token ≈ 1-2 个汉字
"你好世界" → ["你好", "世界"] // 约 2-4 tokens为什么你需要关心 Token?
- API 按 Token 计费(输入 + 输出)
- 每个模型有 上下文窗口 限制(能处理的最大 Token 数)
| 模型 | 上下文窗口 |
|---|---|
| GPT-4o | 128K tokens |
| GPT-5 | 1M tokens |
| Claude Sonnet 4 | 200K tokens |
| Claude Opus 4.6 | 200K tokens |
| Gemini 2.5 Pro | 1M tokens |
Temperature(温度)
控制输出的"创造性":
// temperature = 0:确定性输出,每次结果一样(适合 Agent 任务执行)
// temperature = 0.7:有一定随机性(适合创意写作)
// temperature = 1.0+:非常随机(适合头脑风暴)
const response = await openai.chat.completions.create({
model: "gpt-4o",
temperature: 0, // Agent 场景推荐用 0 或很低的值
messages: [{ role: "user", content: "你好" }]
});System Prompt(系统提示词)
告诉 LLM "你是谁"、"你该怎么做":
const messages = [
{
role: "system",
content: "你是一个专业的前端开发助手,精通 JavaScript 和 React。回答要简洁,给出代码示例。"
},
{
role: "user",
content: "如何用 React 写一个计数器?"
}
];消息角色
LLM API 使用不同角色来组织对话:
const messages = [
{ role: "system", content: "..." }, // 系统设定(Agent 的"人设")
{ role: "user", content: "..." }, // 用户输入
{ role: "assistant", content: "..." }, // AI 的回复
{ role: "tool", content: "..." }, // 工具执行结果(Agent 场景)
];2.3 动手实战:调用你的第一个 LLM API
方案一:使用 OpenAI API
1. 获取 API Key
- 访问 https://platform.openai.com/
- 注册/登录 → API Keys → Create new secret key
- 复制保存好(只显示一次)
💡 国内用户可以使用兼容 OpenAI 格式的服务:DeepSeek(api.deepseek.com)、智谱AI、阿里通义等
2. 创建项目
mkdir my-first-agent && cd my-first-agent
npm init -y
npm install openai3. 编写代码
// chat.mjs
import OpenAI from 'openai';
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY, // 从环境变量读取,不要硬编码!
// 如果使用 DeepSeek,取消下面的注释:
// baseURL: 'https://api.deepseek.com/v1',
});
async function chat(userMessage) {
const response = await openai.chat.completions.create({
model: 'gpt-4o', // 或 'deepseek-chat'
temperature: 0,
messages: [
{
role: 'system',
content: '你是一个友好的编程助手,擅长用简洁的方式解释技术概念。'
},
{
role: 'user',
content: userMessage
}
],
});
return response.choices[0].message.content;
}
// 运行
const answer = await chat('用一句话解释什么是闭包?');
console.log(answer);4. 运行
# 设置环境变量(Windows PowerShell)
$env:OPENAI_API_KEY="sk-your-key-here"
# 运行
node chat.mjs方案二:使用 Ollama 本地运行(免费)
如果暂时没有 API Key,可以用 Ollama 在本地运行开源模型:
1. 安装 Ollama
从 https://ollama.com/ 下载安装。
2. 拉取模型
# 拉取 Qwen 2.5(中文好,体积适中)
ollama pull qwen2.5
# 或者拉取更小的模型(低配电脑)
ollama pull qwen2.5:3b3. 编写代码
Ollama 兼容 OpenAI API 格式,只需改 baseURL:
// chat-local.mjs
import OpenAI from 'openai';
const openai = new OpenAI({
baseURL: 'http://localhost:11434/v1', // Ollama 本地地址
apiKey: 'ollama', // Ollama 不需要真实 key,随便填
});
async function chat(userMessage) {
const response = await openai.chat.completions.create({
model: 'qwen2.5',
temperature: 0,
messages: [
{ role: 'system', content: '你是一个友好的编程助手。' },
{ role: 'user', content: userMessage }
],
});
return response.choices[0].message.content;
}
const answer = await chat('JavaScript 中 == 和 === 有什么区别?');
console.log(answer);2.4 流式输出(Streaming)
聊天应用中,用户不想等 AI 全部生成完再看到结果,而是希望"打字机效果"逐字显示。这就是 Streaming(流式输出):
// stream.mjs
import OpenAI from 'openai';
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
async function chatStream(userMessage) {
const stream = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [
{ role: 'system', content: '你是一个编程助手。' },
{ role: 'user', content: userMessage }
],
stream: true, // 开启流式输出
});
// 逐块处理
for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content || '';
process.stdout.write(content); // 逐字打印,不换行
}
console.log(); // 最后换行
}
await chatStream('用 JavaScript 实现快速排序,并解释原理');💡 Electron 应用中,流式输出特别重要。你可以通过 IPC 将 stream 的每个 chunk 发送到渲染进程,实现流畅的打字效果。第 10 章会详细实现。
2.5 多轮对话
AI Agent 需要维护对话历史,实现多轮对话:
// multi-turn.mjs
import OpenAI from 'openai';
import * as readline from 'readline';
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
// 对话历史(这就是最简单的"记忆")
const messages = [
{ role: 'system', content: '你是一个 JavaScript 专家。回答简洁明了。' }
];
async function chat(userMessage) {
// 将用户消息加入历史
messages.push({ role: 'user', content: userMessage });
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages: messages, // 传入完整对话历史
});
const assistantMessage = response.choices[0].message.content;
// 将 AI 回复也加入历史
messages.push({ role: 'assistant', content: assistantMessage });
return assistantMessage;
}
// 简单的命令行交互
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
function askQuestion() {
rl.question('你: ', async (input) => {
if (input.toLowerCase() === 'exit') {
rl.close();
return;
}
const answer = await chat(input);
console.log(`AI: ${answer}\n`);
askQuestion();
});
}
console.log('开始对话(输入 exit 退出):\n');
askQuestion();运行后你可以这样对话:
你: 什么是 Promise?
AI: Promise 是 JS 中处理异步操作的对象...
你: 那 async/await 呢?
AI: async/await 是 Promise 的语法糖...(它记住了上文在讨论异步)
你: 给我一个结合两者的例子
AI: (它记住了在讨论 Promise 和 async/await)...2.6 API 调用最佳实践
错误处理
async function safeChatCall(messages) {
try {
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages,
});
return response.choices[0].message.content;
} catch (error) {
if (error.status === 429) {
// 速率限制 - 等待后重试
console.log('请求太频繁,等待后重试...');
await new Promise(r => setTimeout(r, 5000));
return safeChatCall(messages); // 重试
}
if (error.status === 401) {
throw new Error('API Key 无效,请检查配置');
}
throw error;
}
}安全准则
// ❌ 绝对不要这样做
const openai = new OpenAI({
apiKey: 'sk-abc123...', // 硬编码 API Key
});
// ✅ 正确做法:从环境变量读取
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
// ✅ Electron 应用中:使用 .env 文件 + dotenv
// npm install dotenv
import 'dotenv/config';
// 然后在 .env 文件中:OPENAI_API_KEY=sk-xxx
// .env 文件加入 .gitignore !控制成本
// 1. 限制 max_tokens(最大输出长度)
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages,
max_tokens: 1000, // 限制输出不超过 1000 tokens
});
// 2. 使用更便宜的模型处理简单任务
// 简单任务用 gpt-4o-mini,复杂任务再用 gpt-4o
// 3. 监控用量
const usage = response.usage;
console.log(`本次消耗: 输入 ${usage.prompt_tokens} + 输出 ${usage.completion_tokens} = ${usage.total_tokens} tokens`);2.7 结构化输出(JSON Mode)
Agent 开发中经常需要 LLM 输出结构化数据(JSON),而不是自然语言:
// structured-output.mjs
import OpenAI from 'openai';
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
async function extractInfo(text) {
const response = await openai.chat.completions.create({
model: 'gpt-4o',
response_format: { type: 'json_object' }, // 强制 JSON 输出
messages: [
{
role: 'system',
content: `你是一个信息提取助手。将用户输入的文本提取为以下 JSON 格式:
{
"name": "人名",
"action": "做了什么",
"time": "什么时候",
"location": "在哪里"
}
缺少的信息填 null。`
},
{
role: 'user',
content: text
}
],
});
return JSON.parse(response.choices[0].message.content);
}
const info = await extractInfo('张三昨天在公司写了一份报告');
console.log(info);
// { name: "张三", action: "写了一份报告", time: "昨天", location: "公司" }💡 结构化输出是 Agent 开发的基础能力。在后面的 Function Calling 和工具调用中会大量使用。
2.8 小结
本章你学到了:
- ✅ LLM 的基本概念:Token、Temperature、上下文窗口
- ✅ 消息角色:system、user、assistant、tool
- ✅ 使用 OpenAI SDK 调用 API(也适用于 DeepSeek 等兼容服务)
- ✅ 使用 Ollama 本地运行模型(免费方案)
- ✅ 流式输出(Streaming)
- ✅ 多轮对话与对话历史管理
- ✅ API 安全和成本控制
- ✅ 结构化输出(JSON Mode)
练习
- 尝试用 OpenAI SDK 或 Ollama 运行本章的代码示例
- 修改 system prompt,让 AI 扮演不同角色(前端专家、产品经理、测试工程师)
- 实现一个简单的多轮对话 CLI 工具
下一章我们将深入学习提示词工程(Prompt Engineering),掌握与 LLM 高效沟通的技巧——这是开发高质量 Agent 的关键能力。