上一篇我们搭建了基础的 AI Agent,这篇文章将带你进阶:让 Agent 拥有记忆,支持多工具协作,变得更加智能。
🎯 你将学到什么
- 如何给 Agent 添加短期和长期记忆
- 如何实现多工具协作
- 如何处理复杂的多步骤任务
- 如何优化 Agent 的决策能力
- 实战案例:智能项目管理助手
前置知识: 需要先阅读第 1 篇基础教程
一、为什么需要记忆?
1.1 没有记忆的 Agent
# 第一次对话
用户: "帮我查看今天的邮件"
Agent: "好的,你有 3 封邮件..."
# 第二次对话
用户: "帮我回复第一封"
Agent: "抱歉,我不知道你说的是哪封邮件" ❌
问题: Agent 不记得之前的对话,每次都是全新开始。
1.2 有记忆的 Agent
# 第一次对话
用户: "帮我查看今天的邮件"
Agent: "好的,你有 3 封邮件..."
[记忆:用户查看了邮件列表]
# 第二次对话
用户: "帮我回复第一封"
Agent: "好的,我记得第一封是关于项目进度的..." ✅
[记忆:用户要回复第一封邮件]
优势: Agent 能记住上下文,支持连续对话。
二、记忆系统设计
2.1 记忆类型
| 记忆类型 | 存储时长 | 用途 | 实现方式 |
|---|---|---|---|
| 短期记忆 | 当前会话 | 上下文理解 | ConversationBufferMemory |
| 工作记忆 | 最近 N 轮 | 任务执行 | ConversationBufferWindowMemory |
| 长期记忆 | 永久 | 知识积累 | VectorStore + Embeddings |
| 实体记忆 | 永久 | 人物/事件 | EntityMemory |
2.2 记忆架构
┌─────────────────────────────────────┐
│ 用户输入 │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 短期记忆(当前对话) │
│ - 最近 5 轮对话 │
│ - 快速访问 │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 工作记忆(任务上下文) │
│ - 当前任务相关信息 │
│ - 中等容量 │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 长期记忆(知识库) │
│ - 向量数据库 │
│ - 语义检索 │
└─────────────────────────────────────┘
三、实现短期记忆
3.1 基础对话记忆
from langchain.memory import ConversationBufferMemory
from langchain_openai import ChatOpenAI
from langchain.chains import ConversationChain
# 创建记忆
memory = ConversationBufferMemory()
# 创建对话链
llm = ChatOpenAI(model="gpt-4-turbo-preview")
conversation = ConversationChain(
llm=llm,
memory=memory,
verbose=True
)
# 对话示例
print(conversation.predict(input="我叫张三"))
# 输出: "你好张三!很高兴认识你。"
print(conversation.predict(input="我叫什么名字?"))
# 输出: "你叫张三。"
3.2 滑动窗口记忆
from langchain.memory import ConversationBufferWindowMemory
# 只保留最近 5 轮对话
memory = ConversationBufferWindowMemory(k=5)
conversation = ConversationChain(
llm=llm,
memory=memory
)
# 超过 5 轮后,旧的对话会被自动丢弃
3.3 摘要记忆
from langchain.memory import ConversationSummaryMemory
# 自动总结历史对话
memory = ConversationSummaryMemory(llm=llm)
conversation = ConversationChain(
llm=llm,
memory=memory
)
# Agent 会自动总结之前的对话,节省 token
四、实现长期记忆
4.1 向量数据库
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
class LongTermMemory:
def __init__(self, persist_directory="./memory_db"):
self.embeddings = OpenAIEmbeddings()
self.vectorstore = Chroma(
embedding_function=self.embeddings,
persist_directory=persist_directory
)
self.text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
def remember(self, content: str, metadata: dict = None):
"""保存到长期记忆"""
chunks = self.text_splitter.split_text(content)
self.vectorstore.add_texts(
texts=chunks,
metadatas=[metadata] * len(chunks) if metadata else None
)
self.vectorstore.persist()
def recall(self, query: str, k: int = 3):
"""从长期记忆中检索"""
docs = self.vectorstore.similarity_search(query, k=k)
return [doc.page_content for doc in docs]
def forget(self, query: str):
"""删除相关记忆"""
# Chroma 不直接支持删除,需要重建索引
pass
4.2 实体记忆
from langchain.memory import ConversationEntityMemory
# 自动提取和记住实体(人名、地名、事件)
entity_memory = ConversationEntityMemory(llm=llm)
conversation = ConversationChain(
llm=llm,
memory=entity_memory
)
# 示例
conversation.predict(input="我的老板叫李四,他很严格")
# Agent 会记住:李四 = 老板,性格严格
conversation.predict(input="李四怎么样?")
# Agent 会回忆:李四是你的老板,性格严格
五、多工具协作
5.1 工具定义
from langchain.tools import tool
from typing import List, Dict
import json
@tool
def search_emails(keywords: str, folder: str = "inbox") -> List[Dict]:
"""
搜索邮件
Args:
keywords: 搜索关键词
folder: 邮箱文件夹
Returns:
匹配的邮件列表
"""
# 模拟搜索
return [
{"id": "001", "subject": f"包含 {keywords} 的邮件"}
]
@tool
def read_calendar(date: str) -> List[Dict]:
"""
读取日历
Args:
date: 日期(YYYY-MM-DD)
Returns:
当天的日程列表
"""
return [
{"time": "10:00", "event": "团队会议"},
{"time": "14:00", "event": "客户演示n
@tool
def create_task(title: str, description: str, deadline: str) -> str:
"""
创建任务
Args:
title: 任务标题
description: 任务描述
deadline: 截止日期
Returns:
任务 ID
"""
task_id = "TASK-001"
print(f"✅ 任务已创建: {title}")
return task_id
@tool
def search_documents(query: str, doc_type: str = "all") -> List[Dict]:
"""
搜索文档
Args:
query: 搜索关键词
doc_type: 文档类型(pdf, docx, all)
Returns:
匹配的文档列表
"""
return [
{"name": 案.pdf", "path": "/docs/project.pdf"}
]
# 工具列表
tools = [
search_emails,
read_calendar,
create_task,
search_documents
]
5.2 工具协作示例
from langchain.agents import AgentExecutor, create_openai_functions_agent
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
# 定义 Prompt
prompt = ChatPromptTemplate.from_messages([
("system", """你是一个智能项目管理助手。
你可以:
1. 搜索邮件(search_emails)
2. 查看日历(read_calendar)
3. 创建任务(create_task)
4. 搜索文档(search_documents)
工作流程:
1. 理解用户需求
2. 选择合适的工具
3. 按顺序执行多个工具
4. 整合结果反馈给用户
示例:
用户: "帮我n你应该:
1. 调用 read_calendar 查看今天的日程
2. 调用 search_emails 查看今天的邮件
3. 整合信息,给出今日工作清单
"""),
MessagesPlaceholder(variable_name="chat_history"),
("human", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
])
# 创建 Agent
llm = ChatOpenAI(model="gpt-4-turbo-preview", temperature=0)
agent = create_openai_functions_agent(llm=llm, tools=tools, prompt=prompt)
# 创建 Executor
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True,
max_iterations=10
)
# 测试
result = agent_executor.invoke({
"input": "帮我整理今天的工作,并创建一个任务提醒我下午的会议"
})
执行过程:
> Entering new AgentExecutor chain...
Invoking: `recalendar` with `{'date': '2026-02-22'}`
[{'time': '10:00', 'event': '团队会议'}, {'time': '14:00', 'event': '客户演示'}]
Invoking: `search_emails` with `{'keywords': '今天', 'folder': 'inbox'}`
[{'id': '001', 'subject': '包含 今天 的邮件'}]
Invoking: `create_task` with `{'title': '下午客户演示提醒', 'description': '14:00 客户演示', 'deadline': '2026-02-22 13:30'}`
✅ 任务已创建: 下午客户演示提醒
今天的工作安排:
📅 日程:
- 10:00 团队会议
- 14:00 客户演示
📧 邮件:
- 1 封待处理邮件
✅ 已创建任务提醒:下午客户演示(13:30 提醒)
六、复杂任务处理
6.1 任务分解
from langchain.chains import LLMChainfrom langchain.prompts import PromptTemplate
class TaskDecom:
def __init__(self, llm):
self.llm = llm
self.prompt = PromptTemplate(
input_variables=["task"],
template="""将以下任务分解为具体的步骤:
任务:{task}
请按照以下格式输出:
1. [步骤1]
2. [步骤2]
3. [步骤3]
...
每个步骤应该:
- 具体可执行
- 有明确的输入输出
- 按逻辑顺序排列
"""
)
self.chain = LLMChain(llm=self.llm, prompt=self.prompt)
def decompose(self, task: str) -> List[str]:
"""分解任务"""
result = self.chain.run(task=task)
steps = [line.strip() for line in result.split('\n') if line.strip()]
return steps
# 使用示例
decomposer = TaskDecomposer(llm)
steps = decomposer.decompose("准备下周的项目演示")
# 输出:
# 1. 查看项目当前进度
# 2. 整理项目成果和数据
# 3. 制作演示 PPT
# 4. 准备演示脚本
# 5. 预演练习
6.2 任务执行器
class TaskExecutor:
def __init__(self, agent_executor, memory):
self.agent = agent_executor
self.memory = memory
def execute_steps(self, steps: List[str]) -> Dict:
"""按步骤执行任务"""
results = []
for i, step in enumerate(steps, 1):
print(f"\n📍 执行步骤 {i}/{len(steps)}: {step}")
try:
result = self.agent.invoke({"input": step})
results.append({
"step": step,
"status": "success",
"output": result["output"]
})
# 保存到记忆
self.memory.remember(
f"步骤 {i}: {step}\n结果: {result['output']}",
metadata={"type": "task_step", "step_number": i}
)
except Exception as e:
results.append({
"step": step,
"status": "failed",
"error": str(e)
})
print(f"❌ 步骤失败: {e}")
break
return {
"total_steps": len(steps),
"completed": len([r for r in results if r["status"] == "success"]),
"results": results
}
# 使用示例
executor = TaskExecutor(agent_executor, long_term_memory)
results = executor.execute_steps(steps)
七、完整示例:智能项目管理助手
7.1 系统架构
from langchain.memory import ConversationBufferMemory
from langchain.agents import AgentExecutor, create_openai_functions_agent
from langchain_openai import ChatOpenAI
class ProjectManagementAgent:
def __init__(self):
# 初始化 LLM
self.llm = ChatOpenAI(
model="gpt-4-turbo-preview",
temperature=0.7
)
# 短期记忆
self.short_term_memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True
)
# 长期记忆
self.long_term_memory = LongTermMemory()
# 任务分解器
self.task_decomposer = TaskDecomposer(self.llm)
# 创建 Agent
self.agent = self._create_agent()
# 任务执行器
self.task_executor = TaskExecutor(
self.agent,
self.long_term_memory
)
def _create_agent(self):
"""创建 Agent"""
prompt = ChatPromptTemplate.from_messages([
("system", """你是一个智能项目管理助手。
核心能力:
1. 任务管理(创建、查询、更新)
2. 日程管理(查看、安排)
3. 邮件处理(搜索、回复)
4. 文档管理(搜索、整理)
工作原则:
- 主动思考,提供建议
- 记住用户的偏好和习惯
- 复杂任务自动分解
- 定期总结和提醒
"""),
MessagesPlaceholder(variable_name="chat_history"),
("human", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
])
agent = create_openai_functions_agent(
llm=self.llm,
tools=tools,
prompt=prompt
)
return AgentExecutor(
agent=agent,
tools=tools,
memory=self.short_term_memory,
verbose=True
)
def run(self, user_input: str) -> str:
"""执行用户请求"""
# 检查是否是复杂任务
if self._is_complex_task(user_input):
# 分解任务
steps = self.task_decomposer.decompose(user_input)
print(f"\n📋 任务已分解为 {len(steps)} 个步骤")
# 执行任务
results = self.task_executor.execute_steps(steps)
# 生成总结
summary = self._generate_summary(results)
return summary
else:
# 直接执行
result = self.agent.invoke({"input": user_input})
return result["output"]
def _is_complex_task(self, task: str) -> bool:
"""判断是否是复杂任务"""
complex_keywords = ["准备", "整理", "完成", "项目", "报告"]
return any(ked in task for keyword in complex_keywords)
def _generate_summary(self, results: Dict) -> str:
"""生成任务总结"""
completed = results["completed"]
total = results["total_steps"]
summary = f"\n✅ 任务完成情况:{completed}/{total}\n\n"
for i, result in enumerate(results["results"], 1):
status_icon = "✅" if result["status"] == "success" else "❌"
summary += f"{status_icon} 步骤 {i}: {result['step']}\n"
if result["status"] == "success":
summary += f" 结果: {result['output'][:100]}...\n"
else:
summary += f" 错误: {result['error']}\n"
return summary
7.2 使用示例
# 创建助手
assistant = ProjectManagementAgent()
# 简单任务
print(assistant.run("帮我查看今天的日程"))
# 复杂任务
print(assistant.run("帮我准备下周一的项目汇报"))
# 输出:
# 📋 任务已分解为 5 个步骤
#
# 📍 执行步骤 1/5: 查看项目当前进度
# ✅ 完成
#
# 📍 执行步骤 2/5: 整理项目成果和数据
# ✅ 完成
#
# ...
#
# ✅ 任务完成情况:5/5
八、性能优化
8.1 记忆压缩
from langchain.memory import ConversationSummaryBufferMemory
# 自动压缩历史对话
memory = ConversationSummaryBufferMemory(
llm=llm,
max_token_limit=2000 # 超过 2000 tokens 自动总结
)
8.2 缓存机制
from langchain.cache import InMemoryCache
from langchain.globals import set_llm_cache
import hashlib
# 启用缓存
set_llm_cache(InMemoryCache())
class CachedLongTermMemory(LongTermMemory):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.cache = {}
def recall(self, query: str, k: int = 3):
"""带缓存的检索"""
cache_key = hashlib.md5(f"{query}_{k}".encode()).hexdigest()
if cache_key in self.cache:
print("📦 使用缓存")
return self.cache[cache_key]
results = super().recall(query, k)
self.cache[cache_key] = results
return results
8.3 异步处理
import asyncio
class AsyncProjectManagementAgent(ProjectManagementAgent):
async def arun(self, user_input: str) -> str:
"""异步执行"""
if self._is_complex_task(user_input):
steps = self.task_decomposer.decompose(user_input)
# 并行执行独立的步骤
tasks = [
self._execute_step_async(step)
for step in steps
]
results = await asyncio.gather(*tasks)
return self._generate_summary({"results": results})
else:
result = await self.agent.ainvoke({"input": user_input})
return result["output"]
async def _execute_step_async(self, step: str):
"""异步执行单个步骤"""
try:
result = await self.agent.ainvoke({"input": step})
return {
"step": step,
"status": "n "output": result["output"]
}
except Exception as e:
return {
"step": step,
"status": "failed",
"error": str(e)
}
九、最佳实践
9.1 记忆管理
DO ✅:
- 定期清理短期记忆
- 重要信息保存到长期记忆
- 使用元数据标记记忆类型
- 实现记忆过期机制
DON'T ❌:
- 不要无限制保存所有对话
- 不要在短期记忆中存储敏感信息
- 不要忽略记忆检索的性能
9.2 工具设计
DO ✅:
- 工具功能单一明确
- 提供详细的文档字符串
- 实现错误处理
- 返回结构化数据
DON'T ❌:
- 不要让一个工具做太多事情
- 不要返回非结构化的文本
- 不要忽略异常情况
9.3 任务分解
DO ✅:
- 步骤具体可执行
- 考虑的依赖
- 提供失败重试机制
- 记录执行过程
DON'T ❌:
- 不要分解得过于细碎
- 不要忽略步骤之间的关联
- 不要在失败后继续执行
十、总结
10.1 关键要点
-
记忆是 Agent 智能的基础
- 短期记忆:上下文理解
- 长期记忆:知识积累
- 实体记忆:关系管理
-
多工具协作提升能力
- 工具设计要单一职责
- Agent 自动选择和组合工具
- 实现工具之间的数据传递
-
复杂任务需要分解
- 自动分解为可执行步骤
- 按顺序或并行执行
- 记录和总结执行结果
10.2 下一步
- 🚀 第 3 篇:生产环境部署 — 如何部署到真实环境
- 📊 第 4 篇:性能优化和成本控制 — 如何降低成本提高性能
关注我,不错过后续更新! 🚀
如果觉得有帮助,欢迎点赞、收藏、转发! ❤️