Agent原理及实践
本文主体是宋志学老师和锦恢老师在datawhale的宣讲。辅以一些本人的看法,希望各位大佬一起交流指正。
本文主体是宋志学老师在datawhale的宣讲。
辅以一些本人的看法,希望各位大佬一起交流指正。
https://github.com/ceilf6/Lab/tree/main/agent/ReAct-starter
一. Agent
1. 原理
Agent = 大模型 + 记忆 + 主动规划 + 工具使用
像人一样会去对环境做出反应的同时,利用工具解决当前任务
当前主流框架
- ReAct 推理 + 行动
思考、行动 → 观察、反馈 → 再思考…如此循环往复
将思考和行动融合在每个步骤中
适合需要实时响应的动态任务
- Plan-and-Solve 规划-求解
先规划再执行的解耦式架构
就像 claude code 在执行前会生成 todo lists
全程会确保目标一致性,适合需要追求高精度的关键任务
- Reflection 反思优化
执行 → 反思 → 优化
像是前两者的补充
实现高质量优化
反射(如果有机会拿到新的外部信息的话,可以提高输出效果)
ReAct
是当前最简洁有效的Agent架构
观察环境 -> 思考推理 -> 采取行动 -> 观察结果 -> 循环

注意设置边界迭代上线,否则一直觉得没有好的结果就会一直递归,浪费Token

LangChain
基于链式调用的Agent框架
支持多种提示模版
丰富生态、适合复杂工作流
LangGraph
把已有能力按图结构组织起来,让 Agent 更可控地行动
类似于 Agent 行为的交通调度系统,像传统Agent
while (true) {
response = llm(state)
if (需要工具) callTool()
if (结束条件) break
}
行为路径不可控,容易死循环,中间状态难以追踪(追踪中间状态、及时分析,很有利于优化你的Agent),不适合复杂多Agent协作
核心思想
Agent = 节点
决策 = 边
状态 = 显式State
并不是自由对话,而是在一张图里走状态迁移
| 状态机 | Graph State |
|---|---|
| if / switch | Conditional Edge |
| 任务流 | Graph traversal |
| 回退 / 重试 | Loop / Edge |
| 日志 / traceId | State 可追踪 |
| 可观测性 | LangSmith 集成 |
AutoGPT
完全自主的目标追求
记忆系统长期
自我提示生成
适合开放任务
MetaGPT
多智能体的Agent框架
模拟真实软件团队角色分工,扮演了产品经理、架构师、工程师等角色
适合自动化软件开发任务
CAMELAI
也是角色扮演、多智能体的框架
(感觉比MetaGPT更好用)
强调通信协议,适合创意写作、教育培训等
2. 实现React Agent
sequenceDiagram
participant User
participant Agent
participant LLM
participant Tools
User->>Agent: 输入查询
Agent->>Agent: 构建提示词
Agent->>LLM: 发送提示
LLM->>Agent: 返回思考+行动
alt 需要工具
Agent->>Tools: 调用指定工具
Tools->>Agent: 返回执行结果
Agent->>Agent: 更新历史记录
Agent->>LLM: 再次思考
LLM->>Agent: 返回最终答案
else 无需工具
Agent->>User: 直接返回答案
end
Agent->>User: 最终结果

User输入后Agent构建提示词,然后决定下一步要调的API ( LLM 或者 工具库 ),拿到结果后存储到记忆的同时判断是否需要进一步还是返回
1. 构造大模型
思考模型工具调用可能不准确,实践的时候最好用 instant
class BaseModel:
def __init__(self, api_key: str = '') -> None:
self.api_key = api_key
def chat(self, prompt: str, history: List[Dict[str, str]], system_prompt: str = "") -> Tuple[str, List[Dict[str, str]]]:
"""
基础聊天接口
Args:
prompt: 用户输入
history: 对话历史
system_prompt: 系统提示
Returns:
(模型响应, 更新后的对话历史)
"""
pass
首先在 BaseModal 里面管理一下 ApiKey ,
接着写个 chat 方法
- 用户输入
- 对话历史
- 系统提示
class Siliconflow(BaseModel):
def __init__(self, api_key: str):
self.api_key = api_key
self.client = OpenAI(api_key=self.api_key, base_url="https://api.siliconflow.cn/v1")
def chat(self, prompt: str, history: List[Dict[str, str]] = [], system_prompt: str = "") -> Tuple[str, List[Dict[str, str]]]:
"""
与 Siliconflow API 进行聊天
Args:
prompt: 用户输入
history: 对话历史
system_prompt: 系统提示
Returns:
(模型响应, 更新后的对话历史)
"""
# 构建消息列表
messages = [
{"role": "system", "content": system_prompt or "You are a helpful assistant."}
]
# 添加历史消息
if history:
messages.extend(history)
# 添加当前用户消息
messages.append({"role": "user", "content": prompt})
# 调用 API
response = self.client.chat.completions.create(
model="Qwen/Qwen3-30B-A3B-Instruct-2507",
messages=messages,
temperature=0.6,
max_tokens=2000,
)
model_response = response.choices[0].message.content
# 更新对话历史
updated_history = messages.copy()
updated_history.append({"role": "assistant", "content": model_response})
return model_response, updated_history
继承自基准模型类,实现chat方法
硅基流动平台提供了很多开源模型的 api 服务方便调试和开发
注意将 Endpoint 模型接口修改为硅基的
历史消息 - 记忆
temperature 模型的创意程度
2. 构造工具
tools.py 中实现 Tools 类
告诉LLM可以调用的工具
class ReactTools:
"""
React Agent 工具类
为 ReAct Agent 提供标准化的工具接口
"""
def __init__(self) -> None:
self.toolConfig = self._build_tool_config()
def _build_tool_config(self) -> List[Dict[str, Any]]:
"""构建工具配置信息"""
return [
{
'name_for_human': '谷歌搜索',
'name_for_model': 'google_search',
'description_for_model': '谷歌搜索是一个通用搜索引擎,可用于访问互联网、查询百科知识、了解时事新闻等。',
'parameters': [
{
'name': 'search_query',
'description': '搜索关键词或短语',
'required': True,
'schema': {'type': 'string'},
}
],
}
]
def google_search(self, search_query: str) -> str:
"""执行谷歌搜索
可在 https://serper.dev/dashboard 申请 api key
Args:
search_query: 搜索关键词
Returns:
格式化的搜索结果字符串
"""
url = "https://google.serper.dev/search"
payload = json.dumps({"q": search_query})
headers = {
'X-API-KEY': 'your serper api key',
'Content-Type': 'application/json'
}
pass
def get_available_tools(self) -> List[str]:
pass
def get_tool_description(self, tool_name: str) -> str:
pass
需要使用 Google 搜索功能得去申请 然后填 ApiKey
https://serper.dev/dashboard
3. React Agent
分层方便维护
- 接口层:对外暴露简单的
run()方法 - 协调层:管理思考-行动-观察的循环
- 解析层:从模型输出中提取结构化信息 - JSON
- 执行层:调用具体工具完成任务
class ReactAgent:
def __init__(self, api_key: str = '') -> None:
"""初始化 React Agent"""
self.api_key = api_key
self.tools = Tools() # 工具管理
self.model = Siliconflow(api_key) # LLM 客户端
self.system_prompt = self._build_system_prompt()
def _build_system_prompt(self) -> str:
"""构建 ReAct 系统提示"""
# 组合工具描述和 ReAct 模式指导
return prompt_template
def _parse_action(self, text: str) -> tuple[str, dict]:
"""解析模型输出中的行动和参数"""
# 使用正则表达式提取行动和参数
action_pattern = r"行动[::]\s*(\w+)"
action_input_pattern = r"行动输入[::]\s*({.*?}|[^\n]*)"
return action, action_input_dict
def _execute_action(self, action: str, action_input: dict) -> str:
"""执行指定的工具行动"""
# 调用对应工具并返回结果
def run(self, query: str, max_iterations: int = 3, verbose: bool = True) -> str:
"""运行 ReAct Agent 主循环"""
# 实现思考-行动-观察循环
verbose - 是否显示中间执行过程(推荐打开,方便优化)
系统提示
决定了 Agent 的行为模式
一个好的ReAct系统提示词应该包含
- 时间信息:让 Agent 知道当前时间,避免过时信息
- 工具清单:明确告诉 Agent 有哪些工具可用
- 行为模式:详细的 ReAct 流程指导
- 输出格式:规范化的思考-行动-观察格式
通过 py 的 f-string 动态格式
prompt = f"""现在时间是 {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}。
你是一位智能助手,可以使用以下工具来回答问题:
{tool_descriptions}
请遵循以下 ReAct 模式:
思考:分析问题和需要使用的工具
行动:选择工具 [google_search] 中的一个
行动输入:提供工具的参数
观察:工具返回的结果
你可以重复以上循环,直到获得足够的信息来回答问题。
最终答案:基于所有信息给出最终答案
开始!"""
注意
- 中文提示:更符合国内用户习惯
- 具体工具名:明确告诉模型可用工具
- 循环指导:说明可以多次使用工具
- 最终答案:明确结束条件
行动解析
复杂是为了规范大模型的输出格式
- 中英文混合的冒号
- JSON格式不规范
- 参数缺失或格式错误
- 多余的空格或换行
因此我们需要一个鲁棒的解析机制。
解析思路:
- 多层匹配:先用正则提取,再用JSON解析
- 容错设计:解析失败时提供降级方案
- 格式兼容:支持JSON字符串和纯文本参数
解析流程
模型输出:
思考:用户询问特朗普生日,需要搜索
行动:google_search
行动输入:{"search_query": "特朗普生日"}
解析步骤:
1. 正则提取行动 → google_search
2. 正则提取参数 → {"search_query": "特朗普生日"}
3. JSON解析 → {'search_query': '特朗普生日'}
4. 返回结构化数据 → ('google_search', {'search_query': '特朗普生日'})
ReAct 主循环
ReAct 循环是 Agent 的"心跳",它让 Agent 能够:
- 持续思考:基于新信息不断调整策略
- 工具调用:在需要时主动获取外部信息
- 结果整合:将工具结果与已有知识结合
循环的四个阶段:
- 思考阶段(Thought):模型分析问题,决定是否需要工具
- 行动阶段(Action):选择合适的工具并提供参数
- 观察阶段(Observation):执行工具并获取结果
- 整合阶段(Integration):将新信息整合到上下文中
为什么需要 max_iterations?
- 防止无限循环:避免模型陷入死循环
- 控制成本:限制 API 调用次数
- 用户体验:避免过长的响应时间
注意每次都需要
- 保持上下文:将观察结果加入对话历史
- 更新输入:为下一轮循环准备新的提示
- 历史记录:确保模型知道之前做了什么
QA
-
Q: Agent框架、强化学习、优化算法这三者是什么关系?
A: Agent是和LLM相关的;强化学习分为两种,一种是用于矫正大模型回答,另一种是做Agent的强化学习,让模型更好的思考、工具调用
-
Q: 开发框架怎么说
A: 使用层面各个框架都好,如果想学习底层原理,可以看OpenAI的swam框架
-
langgraph 的稳定性更好
-
Q: 什么场景下需要自己搭建实现Agent而不是用框架?
A: 需要在领域特定化修改
-
Q: 理解Agent原理对Agent应用开发有哪些帮助?
A: 上限更高
-
Q: 怎么管理长期记忆?
-
记忆的持久化保存一般用什么方法
太长的记忆处理方法(超过最大输入尺寸)可以做前文总结,一般会保存为本地文件以RAG支持大模型;还有一种方法是通过正则匹配去搜索你输入的内容进行召回
-
Agent如何高效且准确地应用记忆
向量数据库或者直接搜索
-
-
Q: 调用工具失败,有反思纠错逻辑吗?
A: 换个模型
-
Q: codex 和 cc 里的 agent 设计有什么区别?
A: 并不开源,得去拦截才能分析
-
框架选一个即可
-
Q: 工程中的优化点
A: 得先明确目标,明确使用Agent想要解决的问题
-
推荐 agentscope 和 MSA
-
ReAct Agent 这种循环基本是现在框架基石
更多推荐


所有评论(0)