Agent初步

认识Agent的基础概念和工作流程
2025/2/18
Agent
1. 基础概念
Agent 是一个基于 LLM 的“决策循环系统”
它的核心不是模型,而是:
决策循环(Decision Loop)
1.1 Agent 的整体结构
第一层:LLM 能力层
包括:
- 文本生成
- function call(结构化输出)
- structured output
- streaming
- reasoning
例如:
- OpenAI 的 GPT 模型
- Anthropic 的 Claude
这一层提供:
输入:context
输出:token 或 function call
模型本身:
不会调用工具 不会记忆 不会执行代码
它只是一个概率预测器。
第二层:上下文管理层(Context Layer)
Context 不仅仅是聊天记录,而是**Context =System Prompt+User Input+History+Tool Results+检索内容**
本质:
每次请求送给模型的 token 集合
Agent 的第一职责就是:
管理 context
第三层:Tool 层
Tool 是什么?
LLM 可以调用的外部能力
它本质是:
function xxx(args): result
例如:
- 查天气
- 查数据库
- 调用搜索引擎
- 执行代码
- 调用支付 API
但需要注意的是,Tool ≠ Function Call
区别:
| 概念 | 属于哪层 |
|---|---|
| Function Call | 模型能力 |
| Tool | 你封装的函数 |
Function Call 是模型“请求调用”。
Tool 是你真实执行的能力。
第四层:决策循环层(Agent 核心)
这是最关键的。
Agent 本质是:
while (not finished):
1. 调用模型
2. 判断是否需要工具
3. 调用工具
4. 把结果加入 context
这叫:ReAct 模式,ReAct = Reason + Act
核心思想:
Thought
Action
Observation
第五层:Orchestration(编排层)
这是框架层。
例如:
- LangChain
- LlamaIndex
- Microsoft 的 Semantic Kernel
它们做什么?
- 管理 Tool
- 自动循环
- 管理 Memory
- 管理 RAG
- 管理多 Agent
‼️ 完整 Agent 架构图
User
↓
API Server
↓
Agent Controller
↓
┌───────────────┐
│ Context │
└───────────────┘
↓
LLM
↓
是否需要 Tool?
↓
Tool Executor
↓
Observation
↓
更新 Context
↓
循环
1.2 核心概念
1.2.1 Function Call
本质
模型输出一个 JSON 结构
例如:
{
"name": "get_weather",
"arguments": { "city": "北京" }
}
模型不是执行函数。
它只是“建议你执行”。
1.2.2 Tool
Tool = 你暴露给模型的函数能力。
需要:
- name
- description
- parameters schema
模型根据 description 决定是否调用。
1.2.3 Context(上下文)
在 LLM / Agent 系统中:
Context = 模型决策所依赖的全部信息
包括:
- 用户输入(User Query)
- 系统指令(System Prompt)
- 历史对话(Conversation History)
- 外部工具返回的信息(Observation / Tool Result)
- 检索到的文档 / 知识(RAG Result)
- 其他环境信息(日期、状态、用户偏好)
也就是说:
Context = 让模型“知道当前情况”的所有信息
‼️ Context 的作用
1️⃣ 让模型理解问题背景
- 没有 context,模型无法分辨前后逻辑
- 例如多轮对话中,如果没有历史消息,模型会忘记用户之前问过什么
2️⃣ 引导模型行为
- System Prompt 是 Context 的一部分
- 可以告诉模型“你是助手/客服/法律顾问”
3️⃣ 辅助工具调用
- ReAct / Function Call / RAG 都需要 context
- 例如模型决定调用哪个工具,需要知道用户意图 + 当前信息
4️⃣ 保持多轮一致性
- 用 Memory 或向量数据库管理 context
- 可以让 Agent 保持长期状态
‼️ Context 的组成结构
可以抽象成三层:
| 层级 | 内容 | 来源 | 示例 |
|---|---|---|---|
| System Context | 系统指令 / 风格 | 开发者 | “你是智能客服,请礼貌回答” |
| User Context | 当前用户请求 | 用户 | “帮我查北京天气” |
| Agent Context | 内部状态、历史消息、工具结果 | Agent / Memory / Tool | Thought、Observation、RAG 文档 |
‼️ Context 的类型
1️⃣ 短期上下文(Short-term Context)
- 最近几轮消息
- ReAct 循环中使用的实时上下文
- 保存在 Agent 内存中或 session messages
2️⃣ 长期上下文(Long-term Context / Memory)
- 历史记录 / 用户偏好 / 企业知识
- 通常存入向量数据库或知识库
- 可通过 RAG 检索注入
3️⃣ 环境上下文(External Context)
- 时间、位置、系统状态、API 数据
- 可以作为模型的额外输入
- 例如天气 API 返回结果
‼️ Context 的管理方式
1️⃣ Message Stack(消息堆栈)
- 最简单方式
- 每次对话把消息全部发送给模型
缺点:
- 上下文窗口有限
- 长对话可能超 token
2️⃣ Sliding Window(滑动窗口)
- 只保留最近 N 轮消息
- 对旧消息进行摘要压缩或丢弃
3️⃣ Vector Memory(向量记忆)
- 把长期 context 转成 embedding
- 检索 top-k 与当前 query 最相关的内容
- 和 RAG 紧密结合
4️⃣ Structured Memory(结构化记忆)
- 将 context 结构化存储(如 JSON / 数据表 / key-value)
- 方便 Agent 读取、修改、推理
- 常用于复杂 Agent 或多 Agent 系统
‼️ Context 的工程问题
1️⃣ 上下文超长
- Token 窗口有限,超长会被截断
- 解决:摘要、截断、分块、分轮管理
2️⃣ 上下文污染 / 冲突
- 多工具或 RAG 返回信息矛盾
- 解决:标记来源、加优先级、去重、摘要
3️⃣ 信息遗忘
- 模型无法记住长期信息
- 解决:Memory + RAG 检索长期上下文
4️⃣ 隐私问题
- 用户数据可能被泄露
- 解决:context 隔离、加密、敏感信息脱敏
5️⃣ 性能问题
- context 太大 → token 消耗大 → 响应慢
- 解决:缓存、向量检索、分步加载
‼️ Context 的优化策略
1️⃣摘要压缩
- 对旧消息或文档做摘要,减少 token
- 例:
今天用户提了关于支付的问题→ 代替原始对话
2️⃣分块注入
- RAG 文档分块只注入最相关的部分
- 避免噪声信息干扰模型
3️⃣优先级管理
- 最新用户请求 > 工具返回 > 历史消息
- 防止模型被旧信息误导
4️⃣Context + ReAct
- Thought、Observation 都要加入 context
- 下一轮决策才完整
‼️ Context 与 Memory 的关系
| 概念 | 定义 | 作用 |
|---|---|---|
| Context | 当前决策可见信息 | 决策和推理基础 |
| Memory | 历史信息存储 | 为 context 提供补充,长期保留 |
| RAG | 检索知识 | 将 memory 注入 context,用于增强回答 |
总结:Memory + RAG = context 的动态补充 context = 决策的“即时全局视图”
‼️ Context 的抽象公式
可以这样形式化:
contextₜ = system_prompt + user_inputₜ + memory_contextₜ + observationₜ
模型输出依赖 contextₜ:
outputₜ = LLM(contextₜ)
ReAct 循环中,每轮 contextₜ 更新:
contextₜ₊₁ = contextₜ + Thoughtₜ + Actionₜ + Observationₜ
1.2.4 Memory
Memory 是:
上下文的长期管理策略
分两种:
短期记忆(Short Term)
直接 append 到 messages。
长期记忆(Long Term)
通常用:
Vector DB
通过 RAG 检索后插入 context。
1.2.5 RAG(检索增强生成)
RAG所解决的核心问题:
大模型不知道你的私有数据
模型训练数据是:
- 公网数据
- 公开知识
- 截止到某个时间点
但现实场景需要:
- 公司内部文档
- 实时数据库数据
- 用户个人数据
- 法律合同
- 产品说明书
如果你直接问模型:
公司 2025 Q1 营收多少?
它会:
- 瞎编
- 或回答不知道
所以我们要:
先找资料
再让模型回答
这就是 RAG。
‼️ RAG 的核心思想
在模型回答前,先从知识库检索相关内容,并注入上下文。
流程:
用户问题
↓
向量化
↓
向量数据库检索
↓
取出最相关文档
↓
拼接到 prompt
↓
模型生成回答
‼️ RAG 系统完整结构
第一层:数据准备(Indexing 阶段)
这是一个离线过程。
1️⃣ 文档收集
- Markdown
- Notion
- 数据库
- API
2️⃣ 文本切分(Chunking)
不能整本书直接丢进去。
要:
按 300~1000 token 切块
为什么?
因为:
- 向量搜索粒度更精确
- 上下文窗口有限
- 大块会浪费 token
3️⃣ 生成向量(Embedding)
把文本转成向量。
例如:
使用 OpenAI 的 embedding 模型。
"北京今天晴天"
→ [0.123, -0.982, ...]
4️⃣ 存入向量数据库
例如:
- Pinecone
- Weaviate
- Milvus
- Qdrant
本质存储:
vector + 原文
第二层:查询阶段(在线过程)
1️⃣ 用户提问
公司 2025 Q1 营收多少?
2️⃣ 向量化问题
同样生成 embedding。
3️⃣ 相似度搜索
计算:
cosine similarity
找出最接近的几个文档块。
4️⃣ 拼接 prompt
已知资料:
[文档1]
[文档2]
[文档3]
请根据资料回答:
公司 2025 Q1 营收多少?
5️⃣ 模型生成
模型“基于资料”回答。
‼️ 向量到底是什么?
这是很多人真正模糊的地方。Embedding 是:
把“语义”映射到高维空间
例如:
猫
狗
动物
它们在向量空间里距离很近。
而:
猫
火箭
距离远。
所以:
向量距离 ≈ 语义相似度
‼️ RAG 的局限
RAG 不是万能的,它不适合:
- 数学计算
- 复杂逻辑推理
- 长链式决策
那是 Agent 的领域。
1.2.6 MCP(Model Context Protocol)
MCP 是:
一个标准化的 Tool 通信协议
它的目标是:
让“模型如何调用外部能力”变成一个标准,而不是每家公司各写一套。
‼️ MCP解决的问题
在 MCP 之前,大家是怎么做的?
例如用 OpenAI 的 function call:
{
"name": "get_weather",
"arguments": { "city": "北京" }
}
然后:
- 你自己解析
- 自己执行
- 自己拼接结果
- 自己做权限控制
每个公司:
- schema 不一样
- tool 描述方式不一样
- 权限系统不一样
- context 注入方式不一样
这在企业环境里会产生:
- 安全风险
- 接口混乱
- 无法统一管理
‼️ MCP 解决的核心问题
可以总结为四个字:
标准化 + 安全化
它主要解决:
1️⃣ 工具描述标准化
统一 tool 的定义格式。
而不是每个框架一套。
2️⃣ 工具调用协议化
工具调用变成:
模型 <—> MCP Server <—> 外部系统
而不是模型直接“随便调用”。
3️⃣ 权限控制
MCP 强调:
模型不应该拥有无限权限
例如:
- 是否允许访问文件?
- 是否允许访问数据库?
- 是否允许发 HTTP 请求?
都需要声明。
4️⃣ 上下文管理规范
MCP 规范:
- 哪些信息可以注入模型
- 哪些信息不能暴露
- 如何限制 context
‼️ MCP 的核心架构
抽象结构如下:
User
↓
LLM
↓
MCP Client
↓
MCP Server
↓
Tool / Database / Filesystem
‼️ MCP 和 Function Call 的区别
很多人以为 MCP = function call。
其实不一样。
| 对比 | Function Call | MCP |
|---|---|---|
| 属于 | 模型能力 | 系统协议 |
| 控制层 | 应用层 | 基础设施层 |
| 是否标准化 | 各家不同 | 统一规范 |
| 是否强调权限 | 不强制 | 强调安全模型 |
更直观理解:
Function Call 是:
模型输出一个 JSON
MCP 是:
一个完整的通信标准
一句话:
MCP 是 AI 时代的“操作系统接口规范”。
就像:
- HTTP 统一了 Web 通信
- SQL 统一了数据库访问
MCP 试图统一:
模型访问世界的方式
1.2.7 ReAct
ReAct = Reason + Act
核心思想:
让模型一边“思考”,一边“行动”,并根据行动结果继续思考。
在它之前,大模型基本只有:
- 直接回答
- Chain of Thought(只思考,不行动)
ReAct 做了一个关键突破:
思考 → 行动 → 观察 → 再思考 → 再行动
这就是现代 Agent 的原型。
‼️ ReAct 解决什么问题?
假设用户问:
2024 年奥运会冠军是谁?
模型如果不知道,会:
- 猜
- 或胡编
但如果允许它:
- 调用搜索
- 再根据搜索结果回答
准确率就大幅提升。
ReAct 提出:
不要一次性思考完 让模型可以中途行动
‼️ ReAct 的核心结构
ReAct Prompt 通常长这样:
Question: xxx
Thought: 我需要先查一下
Action: Search[xxx]
Observation: 搜索结果
Thought: 根据结果我可以回答
Final Answer: ...
关键三步:
Thought
Action
Observation
这三步构成一个循环。
‼️ ReAct 的循环本质
本质上是一个状态机:
while (not finished) {
Thought = LLM(context)
if (需要行动) {
Observation = Tool(Action)
context += Observation
} else {
输出答案
break
}
}
你之前写的 mini-agent,本质就是 ReAct。
‼️ReAct 和 Function Call 的关系
ReAct 是“思想”
Function Call 是“实现手段”
早期 ReAct:
- 模型输出纯文本
- 开发者用正则解析 Action
现代实现:
- 用 function call 结构化输出
- 不再需要解析字符串
所以现在:
Function Call 是 ReAct 的工程实现方式
‼️ ReAct vs Chain-of-Thought
| 对比 | Chain-of-Thought | ReAct |
|---|---|---|
| 是否调用工具 | ❌ | ✅ |
| 是否有 Observation | ❌ | ✅ |
| 是否可交互 | ❌ | ✅ |
| 是否适合 Agent | ❌ | ✅ |
Chain-of-Thought 只是:
想清楚再回答
ReAct 是:
想一部分 → 查一部分 → 再想
1.2.8 Embedding
Embedding = 将对象(通常是文本、图片或其他数据)映射到一个高维向量空间,用数字向量表示其语义特征
特点:
- 固定长度:无论文本多长,embedding 通常是固定维度(例如 1536 维)
- 语义相似性:相似语义 → 向量距离近,差异语义 → 距离远
- 可计算相似度:通常用 cosine similarity 或 L2 距离
例子:
"北京天气" → [0.12, -0.34, 0.56, ...]
"天气预报" → [0.11, -0.35, 0.55, ...]
距离很近 → 语义相关
‼️ Embedding 的作用
1️⃣ 语义检索(Semantic Search)
- 通过 embedding 比较向量距离,找出语义最相关的信息
- 例如 RAG 中检索文档
2️⃣ 长期记忆(Memory)管理
- 长期 context 太大不能直接丢给模型
- embedding 存入向量数据库 → 查询最相关上下文注入 prompt
3️⃣ 工具选择 / 决策
- 根据 query embedding 找最合适的工具或任务
4️⃣多模态表示
- 图片、文本、音频都可以转为 embedding,便于统一处理
‼️ Embedding 的生成流程
假设你要把一段长期 context 转成 embedding:
"用户上周购买了智能手表,偏好夜间模式。"
生成流程:
1️⃣文本切分(Chunking)
- 大文本切成小块,方便检索
- 例如 100~200 字
2️⃣调用 Embedding 模型
- 例如 OpenAI
text-embedding-3-large - 输出固定维度向量(如 1536 维)
import OpenAI from "openai";
const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const embeddingRes = await client.embeddings.create({
model: "text-embedding-3-large",
input: "用户上周购买了智能手表,偏好夜间模式。"
});
const vector = embeddingRes.data[0].embedding;
3️⃣存储向量
- 向量数据库(Pinecone、Weaviate、Milvus、pgvector)
- 可以加 metadata,例如原文、时间、来源
‼️ 长期 context 如何利用 embedding
当用户提问新问题:
- 将 query 转 embedding
- 向向量数据库检索 top-k 相似向量
- 取对应原文/文档,注入当前 context → 供 LLM 使用
User query: "上次我买的手表电量怎么样?"
Embedding 检索: "用户上周购买了智能手表,偏好夜间模式。"
注入 context → 模型回答
这样就实现了长期记忆 + 动态 context
‼️ 向量在 Agent/RAG/Memory 中的作用
| 场景 | 作用 |
|---|---|
| RAG | 检索相关文档 → 注入 prompt |
| Memory | 管理长期用户信息或对话历史 |
| Tool Selection | 根据 query embedding 找最匹配的工具 |
| Multi-Agent Coordination | 找到相关任务或状态 |
‼️ 工程实践问题
1️⃣ 向量存储
- 选择数据库和索引类型(HNSW、IVF、PQ)
2️⃣ 更新/删除
- 用户长期 context 变化,需要更新 embedding
- 删除敏感信息
3️⃣ 检索效率
- 高维向量检索慢 → 用近似最近邻(ANN)算法
4️⃣ embedding drift
- 模型更新后 embedding 可能语义偏移 → 定期重建
‼️ 长期 context → embedding 总结流程
1. 收集长期 context → 文本/文档/对话
2. 文本切分(chunking)
3. 调用 embedding 模型生成向量
4. 存入向量数据库,带 metadata
5. 用户新 query → 生成 query embedding
6. 向量检索 top-k 相似内容
7. 将检索结果注入当前 context
本质:embedding 是长期 context 的可检索语义表示
‼️ 知识结构树
Agent
│
├── LLM 能力
│ ├── Text Generation
│ ├── Function Call
│ ├── Structured Output
│
├── Context
│ ├── System Prompt
│ ├── History
│ ├── Tool Result
│ ├── RAG
│
├── Tools
│ ├── API
│ ├── DB
│ ├── Search
│
├── Memory
│ ├── Short Term
│ ├── Long Term
│
├── Decision Loop
│ ├── ReAct
│ ├── Planner
│
└── Orchestration Framework
├── LangChain
├── LlamaIndex
├── Semantic Kernel
2. 工作流程
假设用户问:
“帮我查一下北京的天气,并告诉我今天是否适合跑步。”
1️⃣ 用户输入
User Input: "帮我查一下北京的天气,并告诉我今天是否适合跑步。"
这个输入会被加入 Context,连同系统提示(System Prompt)和历史对话。
2️⃣ 模型生成输出
模型根据 Context 做两件事:
- 思考(Thought)
- “我需要查天气,才能判断是否适合跑步”
- 决定行动(Action / Function Call)
- 输出一个 JSON,表示想调用的工具和参数
示例 Function Call 输出:
{
"name": "getWeather",
"arguments": {
"city": "北京"
}
}
注意:这里模型只是“说我要干什么”,它并没有自己去查天气。
3️⃣ 系统执行工具
Agent / 框架拿到 JSON:
- 解析
name和arguments - 调用实际函数 / API
const args = JSON.parse(funcCall.arguments);
const result = await getWeather(args.city);
工具返回结果,例如:
{
"temperature": "18°C",
"weather": "晴",
"suitable_for_running": true
}
4️⃣ Observation 注入 Context
工具返回的结果加入 Context:
Observation: { "temperature": "18°C", "weather": "晴", "suitable_for_running": true }
模型下一轮可以参考这个 Observation 继续推理或回答。
5️⃣ 生成最终回答
模型根据 Context + Observation 输出最终回答:
"今天北京天气晴,温度 18°C,非常适合跑步。"
| 概念 | 作用 |
|---|---|
| User Input | 当前 query,是 Context 的一部分 |
| Context | 让模型知道历史和环境信息 |
| Thought (ReAct) | 模型判断下一步动作 |
| Function Call | 模型输出的结构化行动指令 |
| Tool | 实际执行功能(API / 函数) |
| Observation | 工具返回结果 → 更新 Context |
| MCP(可选) | 管理权限和安全,确保模型调用工具安全可靠 |
| Embedding(长期 context) | 检索历史信息注入当前 Context,使模型有长期记忆 |
‼️ 关键点总结
- 模型不会自己执行函数
- 它只会生成 Function Call 或行动指令
- Agent 执行 Function Call
- 系统根据 JSON 输出调用对应工具
- Observation 注入 Context
- 下一轮决策参考工具结果
- 循环执行(ReAct)
- 如果需要进一步行动,模型可以继续生成 Function Call
- 长期记忆 / RAG
- 通过 embedding 检索历史 context,补充给模型
同时给出一个以OpenAI为例的简易Demo
// tools.ts
export async function getWeather(city: string) {
return `北京今天晴天,25度`;
}
// agent.ts
import OpenAI from "openai";
import { getWeather } from "./tools";
const client = new OpenAI({
apiKey: process.env.OPENAI_API_KEY!,
});
type Message = {
role: "system" | "user" | "assistant" | "tool";
content: string | null;
tool_call_id?: string;
};
async function runAgent(userInput: string) {
const messages: Message[] = [
{
role: "system",
content: "你是一个智能助手,可以调用工具解决问题。",
},
{
role: "user",
content: userInput,
},
];
while (true) {
const response = await client.chat.completions.create({
model: "gpt-4o-mini",
messages,
tools: [
{
type: "function",
function: {
name: "get_weather",
description: "获取某个城市的天气",
parameters: {
type: "object",
properties: {
city: {
type: "string",
description: "城市名称",
},
},
required: ["city"],
},
},
},
],
});
const message = response.choices[0].message;
// 如果模型想调用工具
if (message.tool_calls && message.tool_calls.length > 0) {
const toolCall = message.tool_calls[0];
const args = JSON.parse(toolCall.function.arguments);
const result = await getWeather(args.city);
// 把 assistant 的 tool call 记录下来
messages.push(message);
// 把工具结果塞回去
messages.push({
role: "tool",
tool_call_id: toolCall.id,
content: result,
});
continue; // 继续循环
}
// 否则就是最终答案
console.log("Final Answer:", message.content);
break;
}
}
runAgent("帮我查一下北京天气");
3. 实际场景
3.1 模型能力相关问题
1️⃣ Function Call 输出不准确 / 无法解析
- 原因:
- 模型可能输出不符合 schema 的 JSON
- 工程上对 JSON 解析依赖严格格式
- 场景:
- 用户问“查北京天气”,模型输出多余文字或者格式错误
- 解决思路:
- 对输出进行验证(JSON Schema 验证)
- 加 prompt 指令强制输出标准 JSON
- 失败重试 + fallback
2️⃣ 幻觉(Hallucination)
- 原因:
- 模型本身在知识不足或上下文不完整时会胡编
- 场景:
- Agent 调用 RAG,但检索结果不充分
- 解决思路:
- 强制引用来源
- 提高 RAG 精度
- 使用外部工具验证(calculator, database)
3️⃣ 生成延迟 / 速度慢
- 原因:
- 模型调用时间长
- 多轮 ReAct 循环增加 token
- 解决思路:
- 流式输出 (streaming)
- 限制循环次数
- 缓存历史回答
3.2 上下文与 Memory 问题
1️⃣ Context Window 超限
- 原因:
- 长上下文 + 多轮 ReAct + RAG
- 场景:
- Agent 连续调用工具 5 次,messages 过长
- 解决思路:
- 压缩 Memory(summary)
- 截断不重要历史
- 向量数据库管理长期记忆
2️⃣ Memory 冲突 / 信息重复
- 原因:
- 不同工具返回的信息重复或矛盾
- 解决思路:
- 文本去重
- 加入上下文来源标记
- 确定优先级规则
3.3 工具调用相关问题(Tools / MCP)
1️⃣ 工具调用失败
- 原因:
- API 超时
- 权限不足
- Tool 内部异常
- 解决思路:
- 异常捕获
- 超时重试
- fallback 工具(例如备用 API)
2️⃣ 安全与权限问题
- 原因:
- Agent 有能力访问敏感资源(文件、数据库)
- 解决思路:
- 使用 MCP 或自定义安全网关
- 限制工具权限
- 审计日志
3️⃣ 工具接口变化
- 原因:
- 后端 API 改动
- 解决思路:
- version 控制
- 接口抽象层
3.4 RAG / 知识增强相关问题
1️⃣ 检索结果噪声大
- 原因:
- 向量检索精度不足
- 文档切块过大或过小
- 解决思路:
- 使用 rerank
- hybrid search(关键词 + 向量)
- 调整 chunk size
2️⃣ 上下文注入冲突
- 原因:
- 多个检索结果同时放入 prompt
- 模型忽略或者冲突
- 解决思路:
- 精简或摘要文档
- 分步问答(multi-turn RAG)
3️⃣ 实时数据难以覆盖
- 原因:
- 向量数据库不是实时更新
- 解决思路:
- 实时索引
- hybrid retrieval(结合数据库查询 + RAG)
3.5 ReAct 循环 / Agent 决策问题
1️⃣ 循环次数不可控 / 无限循环
- 原因:
- Agent 判断“是否需要工具”逻辑不完善
- 解决思路:
- 最大循环步数
- 条件触发退出
- 设置 fallback 策略
2️⃣ 工具调用顺序错乱
- 原因:
- ReAct 思考和行动顺序复杂
- 多工具依赖关系
- 解决思路:
- Planner + Executor 拆分
- DAG 任务管理
3️⃣ 多 Agent 协作复杂
- 原因:
- 多 Agent 间通信、共享 Memory、同步状态困难
- 解决思路:
- 统一共享 context
- 使用消息队列或事件总线
- step-by-step 调度
3.6 工程和成本问题
1️⃣ Token 成本高
- ReAct + RAG 循环次数多 → token 大量消耗 → 成本高
- 解决:
- 压缩 context
- 缓存回答
- 优化 RAG top-k
2️⃣ 可观测性差
- Agent 运行过程难以追踪
- 解决:
- 日志记录每轮 Thought / Action / Observation
- token 统计、响应时间监控
- tool 调用审计
3️⃣ 可扩展性 / 部署问题
- 高并发场景下多 Agent 调度复杂
- 解决:
- 分布式 Agent 架构
- 使用队列 / 微服务
- 异步执行
3.7 总结 — 实际开发痛点矩阵
| 分类 | 问题 | 工程解决思路 |
|---|---|---|
| 模型 | 输出不规范 | JSON 验证 / prompt 强化 |
| 模型 | 幻觉 | 强引用 / RAG / 验证工具 |
| Context | 超长 | summary / 截断 / vector memory |
| Context | 冲突 | 标记来源 / 去重 |
| Tool | 调用失败 | 异常捕获 / 重试 / fallback |
| Tool | 安全风险 | MCP / 权限控制 / 审计 |
| RAG | 噪声大 | rerank / hybrid search / chunk 调整 |
| ReAct | 循环无限 | max step / fallback / Planner |
| 成本 | token 高 | 压缩 context / cache / top-k |
| 运维 | 可观测性差 | 日志 / tracing / metric |
总结一句话:
Agent 开发的痛点集中在 循环管理、上下文管理、工具调用安全、RAG 精度,以及成本控制和可观测性。
这些问题解决好了,你的 Agent 才能从实验室走向生产环境。