Ai Agent实践
大模型是什么
大模型(LLM,Large Language Model)本质上是一个接受文本输入、返回文本输出的函数。从工程角度来说,你不需要理解它内部的神经网络结构,只需要知道:
- 给它一段文字(Prompt),它会返回一段文字(Completion)
- 它的能力来自在海量文本上的预训练,具备语言理解、推理、生成能力
- 通过 HTTP API 调用,和调用任何后端接口没有本质区别
大模型就像一个能理解自然语言的超级函数,你传入参数(问题、指令),它返回结果(回答、代码、分析)。
核心概念
Token
Token 是大模型处理文本的基本单位,既不是字符,也不是单词,而是介于两者之间的”词片”。
- API 按 Token 计费,输入和输出分别计价
- 模型有最大上下文长度限制,DeepSeek-chat 支持 64K tokens
- Token 数量影响响应速度和成本
快速估算规则(不用装 tiktoken,这个精度够用):
● 英文:1 token ≈ 4 个字符
● 中文:1 个汉字 ≈ 1.5~2 tokens,按 0.6 token/字估算
● 代码:比文字消耗更多 token
上下文窗口
大模型每次调用都是无状态的——它不记得上一次对话。要实现多轮对话,需要每次都把完整的历史记录作为输入传给模型:
1 | 第一轮:[用户:"你好"] → 模型回复 |
上下文窗口的限制带来了一个工程问题:对话太长超过限制时怎么处理?
温度参数
Temperature 控制模型输出的随机性,取值范围 0~2:
| Temperature | 特点 | 适用场景 |
|---|---|---|
| 0 | 确定性输出,每次结果几乎相同 | 代码生成、数据提取、分类 |
| 0.2~0.5 | 低随机,结果稳定但有轻微变化 | 客服问答、摘要 |
| 0.7 | 中等随机,有创造性但不失控 | 通用对话(默认值) |
| 1.0~1.5 | 高随机,创意性强但可能跑偏 | 写作、头脑风暴 |
消息角色
OpenAI 兼容 API(DeepSeek、Qwen、Claude 等都支持)使用三种角色:
1 | messages: [ |
API调用
申请 API Key
以 DeepSeek 为例:
- 访问 platform.deepseek.com
- 注册登录后,进入「API Keys」页面
- 点击「创建 API Key」,复制保存(只显示一次)
Key 格式类似:sk-xxxxxxxxxxxxxxxxxxxxxxxx
安全注意事项:
- 不要把 API Key 提交到 Git
- 项目根目录创建 .env 文件存储
- .gitignore 里加上 .env
Fetch调用
1 | import 'dotenv/config' |
LangChain.js调用
实际项目里推荐用 LangChain.js,好处是屏蔽底层 HTTP 细节、统一接口、换模型只改配置不改代码,有链式调用、记忆、工具等生态
1 | // langchain-basic.js |
流式输出(Streaming)
非流式调用要等模型生成完整响应后才返回,长文本场景下用户体验差。流式输出让内容像打字机一样逐字出现
SSE(text/event-stream)
chunked + plain text
● res.body.getReader() 获取 ReadableStream 的读取器
● TextDecoder 把 Uint8Array 转成字符串
● 用 buffer 拼接跨 chunk 的数据,防止 SSE 消息被截断
● 每条 SSE 消息格式:event: xxx\ndata: xxx\n\n
总结
● 大模型本质是一个 HTTP 接口,调用方式和普通后端接口没有本质区别
● Token 是计量单位,成本要从第一天就重视,不要等上线了才发现账单爆了
● 每次调用都是无状态的,多轮对话靠手动把历史记录拼进请求里
● Temperature 控制随机性,生产环境用低值保稳定,创意场景再调高
● 用 LangChain.js 封装调用,换模型只改 .env 里的配置
提示词工程
含糊的指令会得到含糊的结果。
Few-shot 提示
Few-shot 是在提示词里加几个”输入→输出”的配对例子,教会模型你想要的格式和风格。
1 | import { HumanMessage, AIMessage, SystemMessage } from '@langchain/core/messages' |
思维链(Chain of Thought)
结构化输出
1. Prompt 约束 + 容错解析
2. withStructuredOutput
LangChain.js & LangGraph
为什么需要LangChain.js & LangGraph
- 每次都要手写消息格式、处理流式解析、管理对话历史
- 多步骤的 AI 流程(先分析、再检索、再生成)要自己串联
- 换个模型要改好几处代码
- 复杂的条件分支逻辑写起来乱
LangChain.js 解决前两个问题,LangGraph 解决后两个。
1 | 原始写法:fetch → 解析 → 手动拼接历史 → 再 fetch → ... |