Agent开发与框架
一、Agent基础概念
Q1: 什么是Agent?LLM为什么需要Agent?
Agent(智能体) = LLM(大脑) + 工具使用能力 + 记忆 + 规划能力
Agent能自主理解目标、规划步骤、调用工具、从结果中学习,是LLM从"纯文本生成"到"执行任务"的关键升级。
LLM vs Agent:
| 能力 | 纯LLM | Agent |
|---|---|---|
| 回答问题 | ✅(基于训练知识) | ✅(可调用工具获取实时信息) |
| 编写代码 | ✅ | ✅(可以执行代码并修复bug) |
| 数据查询 | ❌(训练数据内的知识) | ✅(连接数据库实时查询) |
| 网络搜索 | ❌ | ✅(调用搜索引擎API) |
| 复杂任务规划 | ❌(单步推理) | ✅(多步规划+执行+反思) |
| 与外部系统交互 | ❌ | ✅(API调用、文件操作) |
Agent的意义: 把LLM从"只能说话"的聊天助手变成"可以做事"的智能助理。
Q2: Agent的核心组件
┌──────────────────────────────────────────────────────────────┐
│ Agent 核心架构 │
├──────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────┐ 目标/任务 │
│ │ Planner(规划器) │◄────────────────────────── │
│ │ · 任务拆解 │ │
│ │ · 选择工具 │──┐ │
│ │ · 反思优化 │ │ │
│ └──────────────────────┘ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ LLM 推理引擎 │ │
│ │ 接收输入 → 选择行动 → 调用工具 → 整合结果 → 判断是否完成│ │
│ └───────────────────────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────┼──────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Memory │ │ Tools │ │ Execution │ │
│ │ 记忆模块 │ │ 工具集 │ │ 执行器 │ │
│ │ ·短期记忆 │ │ ·搜索 │ │ ·API调用 │ │
│ │ ·长期记忆 │ │ ·代码执行 │ │ ·文件操作 │ │
│ │ ·知识库 │ │ ·数据库 │ │ ·命令执行 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────┐ │
│ │ 最终输出 │ │
│ └────────────┘ │
│ │
└──────────────────────────────────────────────────────────────┘Q3: ReAct模式详解(Agent的核心工作流程)
ReAct = Reasoning(推理) + Acting(行动)
示例:用户问"2024年最火的AI开源项目有哪些?按Star数排序"
ReAct完整流程:
🔵 思考1 (Thought):
用户需要最新的开源项目数据,这是实时变化的信息,
我的训练数据不包含2024年的最新排名。我需要先
搜索获取最新数据。
🟢 行动1 (Action):
调用工具 Search["2024 trending AI open source projects GitHub stars"]
🟡 观察1 (Observation):
搜索返回多个列表,包含Claude API、LangChain等,
但数据来源不一致,排名有差异。
🔵 思考2 (Thought):
搜索结果有差异,我需要直接查GitHub的官方数据,
用GitHub API获取准确的Star数。
🟢 行动2 (Action):
调用工具 GitHubAPI["search", "topic:ai", "sort:stars", "per_page:10"]
🟡 观察2 (Observation):
返回Top-10项目列表,包含项目名、Star数、描述:
1. llama.cpp - 52K stars - C++本地推理
2. langchain - 85K stars - Agent框架
...
🔵 思考3 (Thought):
已获取准确数据,可以整理成表格回答用户。
🟢 最终答案 (Answer):
根据2024年GitHub最新数据,最火的AI开源项目Top-5是:
1. LangChain (85K⭐) - LLM应用开发框架
2. ...Q4: 常见的Agent模式
| 模式 | 特点 | 适用场景 |
|---|---|---|
| ReAct Agent | 推理+行动交替执行 | 通用问答、研究任务 |
| Plan-and-Execute | 先做完整规划,再按步骤执行 | 复杂多步任务(如写报告) |
| Router Agent | 先判断任务类型,路由到专门处理模块 | 多领域混合任务 |
| Multi-Agent | 多个Agent协作,每个Agent专精一个领域 | 大型复杂项目(如软件开发) |
| Autonomous Agent | 自主设定目标、长期执行(如AutoGPT) | 探索性任务、研究 |
二、Function Calling(工具调用)
Q5: 什么是Function Calling?
Function Calling是OpenAI等模型提供的能力:让LLM不是输出文本,而是输出一个JSON格式的函数调用请求,包含函数名和参数。开发者收到这个请求后,在自己的代码中执行对应函数,再把结果返回给LLM。
┌──────────────────────────────────────────────────────────────┐
│ Function Calling 流程 │
├──────────────────────────────────────────────────────────────┤
│ │
│ ① 用户发送问题 │
│ "帮我查询北京到上海最近的3个航班" │
│ ↓ │
│ ② LLM判断需要工具,返回函数调用 │
│ { │
│ "name": "search_flight", │
│ "arguments": { │
│ "from": "北京", │
│ "to": "上海", │
│ "limit": 3 │
│ } │
│ } │
│ ↓ │
│ ③ 开发者代码执行函数(如调用航旅纵横API) │
│ result = search_flight(from="北京", to="上海", limit=3)│
│ ↓ │
│ ④ 把函数结果返回给LLM │
│ [{"航班号": "CA1234", "时间": "08:30"}, ...] │
│ ↓ │
│ ⑤ LLM根据结果生成自然语言回答 │
│ "最近的3个航班是:CA1234 08:30起飞..." │
│ │
└──────────────────────────────────────────────────────────────┘Q6: 如何定义一个函数工具?
OpenAI Function Calling 定义格式:
javascript
const tools = [
{
type: "function",
function: {
name: "search_flight", // 函数名(英文,有意义)
description: "查询航班信息", // 给LLM看的函数描述
parameters: {
type: "object",
properties: {
from: {
type: "string",
description: "出发城市,如:北京、上海"
},
to: {
type: "string",
description: "到达城市"
},
date: {
type: "string",
description: "日期,格式:YYYY-MM-DD"
}
},
required: ["from", "to"] // 必填参数
}
}
},
// ... 更多工具
];设计工具的关键原则:
- 函数描述要清晰:让LLM理解这个工具是做什么的、什么时候该用
- 参数Schema要详细:每个参数都要有description
- 参数用enum限制:可能的取值尽量列出来,减少LLM选错
- 工具要正交:每个工具做一件事,不要多功能混合
- 返回结构化数据:函数返回值要便于LLM理解
Q7: 常用工具示例
| 工具类型 | 示例 | 用途 |
|---|---|---|
| 网络搜索 | Bing Search API, SerpAPI | 获取最新信息 |
| 代码执行 | Python REPL, Sandbox | 计算、数据处理 |
| 数据库 | SQL查询工具 | 业务数据查询 |
| API调用 | 通用HTTP请求 | 连接外部服务 |
| 文件操作 | 读取/写入文件 | 文档处理 |
| 知识库检索 | RAG向量搜索 | 企业内部知识问答 |
三、记忆管理(Memory)
Q8: Agent的记忆类型
┌──────────────────────────────────────────────────────────────┐
│ Agent 记忆系统 │
├──────────────────────────────────────────────────────────────┤
│ │
│ 🧠 短期记忆(Short-term / Episodic Memory) │
│ └─ 本次对话的所有消息历史 │
│ └─ 存在内存中,对话结束即消失 │
│ └─ 大小受Context Window限制 │
│ │
│ 📚 长期记忆(Long-term / Semantic Memory) │
│ └─ 存储在向量数据库 │
│ └─ 过往的知识、经验、偏好 │
│ └─ 需要时通过相似度搜索召回 │
│ │
│ ⚙️ 程序记忆(Procedural Memory) │
│ └─ 完成任务的流程/模式 │
│ └─ "当用户问X时,先调用工具Y再做Z" │
│ │
└──────────────────────────────────────────────────────────────┘Q9: 记忆设计的常见模式
模式1: ConversationSummaryMemory(对话摘要)
当对话超过N个token后:
↓
让LLM把前面的对话摘要成一段文字
↓
保留摘要 + 最近K个消息(节省空间的同时保留上下文)模式2: EntityMemory(实体记忆)
从对话中提取关键实体(人、公司、项目等)
↓
存储到知识图谱或结构化存储
↓
需要时可以查询:"之前提到的XX产品负责人是谁?"模式3: VectorStore-backed Memory(向量记忆)
把每条重要的用户消息和助手回复
↓
向量化后存入向量数据库
↓
新的问题到来时,先从向量库检索历史相关内容
↓
注入当前对话的上下文中四、LangChain Agent实战
Q10: LangChain Agent的快速上手
python
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain_openai import ChatOpenAI
from langchain.tools import tool
# Step 1: 定义工具
@tool
def get_weather(city: str) -> str:
"""查询指定城市的天气信息"""
# 实际项目中调用天气API
return f"{city}今天天气晴朗,温度25度"
@tool
def search_web(query: str) -> str:
"""搜索互联网信息"""
# 实际项目中调用搜索API
return f"搜索结果:{query}的相关信息..."
# Step 2: 初始化LLM
llm = ChatOpenAI(model="gpt-4-turbo", temperature=0)
# Step 3: 创建Agent
tools = [get_weather, search_web]
agent = create_openai_tools_agent(llm, tools, prompt)
# Step 4: 执行Agent
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True, # 打印每步的思考过程
max_iterations=5 # 防止无限循环
)
result = agent_executor.invoke({"input": "北京明天天气如何?"})
print(result["output"])Q11: Agent的执行流程(从源码角度)
1. 构建Prompt(包含系统消息、工具描述、对话历史、用户输入)
↓
2. LLM推理,决定执行哪个工具或直接回答
↓
3. 如果需要工具:
a. 解析函数名和参数
b. 调用对应Python函数
c. 把结果加入对话历史
d. 返回步骤2(让LLM判断下一步)
↓
4. 如果不需要工具:
- 直接返回答案(Final Answer)
↓
5. 结束Q12: 如何防止Agent"无限循环"?
防御机制:
- max_iterations: 限制最大迭代次数(如5-10次)
- max_execution_time: 超时截断
- early_stopping_method: "force": 到上限时强制返回答案
- 循环检测: 检测到相同的Tool调用多次则强制停止
python
AgentExecutor(
max_iterations=10,
max_execution_time=60, # 60秒超时
early_stopping_method="force",
handle_parsing_errors=True, # 自动修复格式错误
)五、Multi-Agent协作
Q13: 什么时候需要多Agent?
| 场景 | 为什么需要多Agent |
|---|---|
| 复杂软件项目 | 需要专门的架构Agent、前端Agent、后端Agent、测试Agent |
| 研究报告撰写 | 资料收集Agent、数据分析Agent、写作Agent、校对Agent |
| 大型企业客服 | 产品咨询Agent、技术支持Agent、售后服务Agent + 路由Agent |
| 数据分析流程 | 数据清洗Agent、分析Agent、可视化Agent、报告Agent |
Q14: Multi-Agent的设计模式
模式1: 分层协作(Hierarchical)
🎯 协调者Agent (Coordinator)
│ │ │ │
▼ ▼ ▼ ▼
🔍 📝 💻 📊
研究 写作 代码 数据
Agent Agent Agent Agent- 协调者:理解任务,分配给子Agent,汇总结果
- 子Agent:专注自己领域的任务
模式2: 顺序协作(Pipeline)
用户需求 → 分析Agent → 设计Agent → 实现Agent → 测试Agent → 最终输出- 像流水线一样,每个Agent只做一个环节
- 适合有明确步骤的任务
模式3: 辩论模式(Debate)
AgentA(支持观点) <--> AgentB(反对观点)
↓
Judge Agent(评判并给出最终结论)- 用于关键决策场景,让Agent互相挑战
六、Agent开发的最佳实践
Q15: 设计Agent的常见陷阱
| 陷阱 | 问题描述 | 解决方法 |
|---|---|---|
| 🔄 工具循环 | 反复调用同一工具,无进展 | 增加循环检测、限制工具调用次数 |
| 📏 工具选择错误 | 选错工具或工具参数解析错 | 提供更好的工具描述、加入示例、简化工具接口 |
| 🎭 "幻觉"工具 | 调用不存在的工具 | 严格校验工具名、用Function Calling原生支持 |
| 💾 记忆丢失 | 对话过程中忘记之前的关键信息 | 实体记忆、关键信息摘要、向量记忆 |
| ⏰ 超时 | 任务太复杂,执行太久 | 分阶段、设置硬超时、任务拆解 |
| 🔒 安全风险 | 不当的工具调用可能泄露数据或破坏系统 | 沙箱执行、权限最小化、人工审核关键操作 |
Q16: Agent的Prompt设计要点
高质量Agent Prompt必须包含:
1. 角色定义
"你是一个XX领域的专家助手,擅长..."
2. 工具列表(由框架自动注入)
可用工具:工具A(用途), 工具B(用途)...
3. 行为规范
"当你不确定时,请先搜索而不是猜测"
"对于事实性问题,必须引用来源"
4. 思考模板
"先思考:我需要什么信息?→ 如何获取?→ 如何组织答案?"
5. 输出格式约定
"最终答案必须包含:1.结论 2.关键依据 3.引用来源"
6. 边界定义
"如果无法完成任务,请明确说明原因并建议下一步"Q17: Agent性能优化建议
┌────────────────────────────────────────────────────────────┐
│ Agent 性能优化清单 │
├────────────────────────────────────────────────────────────┤
│ │
│ 🔧 工具层 │
│ · 用异步方式并行调用工具(asyncio) │
│ · 工具结果缓存(相同输入不重复执行) │
│ · 工具超时设置 │
│ │
│ 🤖 LLM层 │
│ · 简单任务用gpt-3.5,复杂任务切到gpt-4 │
│ · 压缩历史对话(只保留关键信息) │
│ · Streaming模式,让用户感知更快 │
│ │
│ 📚 记忆层 │
│ · 短期记忆用LRU缓存,避免无限增长 │
│ · 长期记忆用向量数据库,设置TTL │
│ │
│ 🔍 调试 │
│ · verbose=True查看每步决策 │
│ · 记录每步的决策日志,便于事后分析 │
│ · A/B测试不同的Prompt策略 │
│ │
└────────────────────────────────────────────────────────────┘七、Agent vs RAG的定位
Q18: Agent与RAG的关系?
RAG是"检索+生成"的特定模式,Agent是更通用的"规划+执行"框架。Agent可以包含RAG作为其中一个工具。
RAG:
Query → Retrieve → Generate → Answer
(专用:文档问答)
Agent:
Query → 规划 → 工具1 → 工具2 → ... → 汇总 → Answer
(检索是众多工具中的一个)
实际项目:
Agent = 包含搜索工具 + RAG知识库工具 + 代码执行工具 + ...
↑
RAG作为Agent的一个子工具存在Agent高频问题速查
| 问题 | 一句话解决方案 |
|---|---|
| Agent选错工具 | 完善工具描述、给Few-shot示例、简化工具接口 |
| 无限循环 | 设置max_iterations、检测重复调用、强制停止 |
| 忘记上下文 | 加入实体记忆、VectorStore记忆、摘要记忆 |
| 工具参数解析失败 | 用原生Function Calling、提供Schema示例、简化参数 |
| 输出格式不对 | Prompt中明确格式要求、加"请只输出JSON"指令 |
| 执行太慢 | 并行工具调用、Stream输出、用轻量LLM做简单任务 |
| 安全风险 | 工具沙箱化、权限最小化、敏感操作需二次确认 |