AI Agent 是 LLM 驱动的自主系统,能够感知环境、做出决策并执行动作。
2.1 Agent 架构解析
AI Agent 的核心架构由 Lilian Weng(OpenAI)提出:
┌─────────────────────────────────────────────────────────┐
│ Agent 架构 │
├─────────────────────────────────────────────────────────┤
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Profile │ │ Memory │ │Planning │ │ Action │ │
│ │ 角色 │ │ 记忆 │ │ 规划 │ │ 行动 │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
│ │ │ │ │ │
│ └────────────┴────────────┴────────────┘ │
│ │ │
│ ┌─────▼─────┐ │
│ │ LLM │ │
│ │ (大脑) │ │
│ └───────────┘ │
└─────────────────────────────────────────────────────────┘
核心组件详解
| 组件 | 功能 | 实现方式 |
|---|---|---|
| Profile | 定义 Agent 角色与目标 | System Prompt |
| Memory | 短期/长期记忆存储 | Vector DB / Redis |
| Planning | 任务分解与规划 | CoT / ReAct / Plan-and-Solve |
| Action | 工具调用与执行 | Function Calling |
2.2 Agent 类型对比
2.2.1 ReAct Agent
最经典的 Agent 模式,结合推理(Reasoning)与行动(Acting):
Thought: 用户想知道今天的天气,我需要先获取位置信息
Action: get_user_location
Observation: 北京
Thought: 现在我知道了用户在北京,需要查询北京天气
Action: get_weather("北京")
Observation: 晴天,25°C
Answer: 北京今天天气晴朗,气温25°C
ReAct 执行流程:
┌───────────────────────────────────────────────────┐
│ ReAct 循环 │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Thought │───▶│ Action │───▶│Observation│ │
│ │ 思考 │ │ 行动 │ │ 观察 │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ ▲ │ │
│ └───────────────────────────────┘ │
│ (循环直到完成) │
└───────────────────────────────────────────────────┘
2.2.2 Plan-and-Execute Agent
适用于复杂任务,先规划后执行:
# 规划阶段
plan = """
1. 收集用户需求文档
2. 分析技术可行性
3. 生成项目架构设计
4. 编写代码框架
5. 编写测试用例
"""
# 执行阶段
for step in plan.steps:
result = execute_step(step)
if result.needs_revision:
revise_plan(result.feedback)
架构图:
用户输入 ──▶ 规划器 ──▶ 任务列表 ──▶ 执行器 ──▶ 结果
│
▼
反馈循环
2.2.3 Multi-Agent System
多 Agent 协作,模拟团队工作:
┌──────────────────────────────────────────────────┐
│ Multi-Agent 系统 │
├──────────────────────────────────────────────────┤
│ │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ Leader │───▶│Analyst │ │ Coder │ │
│ │ Agent │ │ Agent │ │ Agent │ │
│ └────────┘ └────────┘ └────────┘ │
│ │ │ │ │
│ └─────────────┴─────────────┘ │
│ │ │
│ ┌───────▼───────┐ │
│ │ Shared Memory │ │
│ └───────────────┘ │
└──────────────────────────────────────────────────┘
协作模式:
| 模式 | 描述 | 适用场景 |
|---|---|---|
| 层级式 | Leader 分配任务给下属 Agent | 项目管理、软件开发 |
| 对等式 | Agent 之间平等协作 | 研究讨论、头脑风暴 |
| 混合式 | 根据任务动态调整协作方式 | 复杂业务流程 |
2.3 实战案例:构建自动化研究 Agent
场景描述
构建一个研究 Agent,能够:
- 自动搜索相关论文
- 总结关键发现
- 生成研究报告
项目结构
research-agent/
├── src/
│ ├── agent/
│ │ ├── __init__.py
│ │ ├── planner.py # 规划器
│ │ ├── executor.py # 执行器
│ │ └── memory.py # 记忆管理
│ ├── tools/
│ │ ├── arxiv.py # arXiv 搜索
│ │ ├── scholar.py # Google Scholar
│ │ └── summarizer.py # 论文总结
│ └── main.py
├── requirements.txt
└── README.md
核心实现
# src/agent/planner.py
import json
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
class ResearchPlanner:
def __init__(self, model: str = "gpt-4"):
self.llm = ChatOpenAI(model=model)
self.prompt = ChatPromptTemplate.from_messages([
("system", """你是一个研究规划专家。给定一个研究主题,你需要:
1. 分解研究任务
2. 确定需要搜索的关键词
3. 规划研究步骤
输出格式为 JSON:
{
"tasks": [...],
"keywords": [...],
"steps": [...]
}"""),
("user", "{topic}")
])
async def plan(self, topic: str) -> dict:
chain = self.prompt | self.llm
result = await chain.ainvoke({"topic": topic})
return json.loads(result.content)
# src/agent/executor.py
from typing import List, Dict
from .memory import AgentMemory
class ResearchExecutor:
def __init__(self, tools: List, memory: AgentMemory):
self.tools = {tool.name: tool for tool in tools}
self.memory = memory
async def execute(self, plan: dict) -> Dict:
results = {}
for step in plan["steps"]:
# 记录执行状态
self.memory.add_message("system", f"执行步骤: {step['description']}")
# 执行工具调用
if step["tool"] in self.tools:
tool = self.tools[step["tool"]]
result = await tool.arun(**step.get("params", {}))
results[step["id"]] = result
# 存储结果到记忆
self.memory.add_message("tool", result)
return results
# src/agent/memory.py
from typing import List, Dict
from dataclasses import dataclass, field
from datetime import datetime
@dataclass
class Message:
role: str
content: str
timestamp: datetime = field(default_factory=datetime.now)
class AgentMemory:
def __init__(self, max_short_term: int = 10):
self.short_term: List[Message] = []
self.long_term: List[Dict] = [] # 可接入向量数据库
self.max_short_term = max_short_term
def add_message(self, role: str, content: str):
message = Message(role=role, content=content)
self.short_term.append(message)
# 超过限制时,压缩历史
if len(self.short_term) > self.max_short_term:
self._compress_history()
def get_context(self) -> str:
"""获取上下文用于 LLM 输入"""
return "\n".join([
f"{m.role}: {m.content}"
for m in self.short_term
])
def _compress_history(self):
"""压缩历史记忆"""
# 简单实现:保留最近的消息
compressed = self.short_term[:-self.max_short_term]
self.long_term.extend([{
"role": m.role,
"content": m.content,
"timestamp": m.timestamp.isoformat()
} for m in compressed])
self.short_term = self.short_term[-self.max_short_term:]
# src/tools/arxiv.py
from langchain.tools import BaseTool
from pydantic import BaseModel, Field
import arxiv
class ArxivSearchInput(BaseModel):
query: str = Field(description="搜索关键词")
max_results: int = Field(default=5, description="最大结果数")
class ArxivSearchTool(BaseTool):
name: str = "arxiv_search"
description: str = "在 arXiv 上搜索学术论文"
args_schema: type[BaseModel] = ArxivSearchInput
def _run(self, query: str, max_results: int = 5) -> str:
search = arxiv.Search(
query=query,
max_results=max_results,
sort_by=arxiv.SortCriterion.relevance
)
results = []
for paper in search.results():
results.append({
"title": paper.title,
"authors": [a.name for a in paper.authors],
"summary": paper.summary,
"url": paper.pdf_url
})
return str(results)
async def _arun(self, query: str, max_results: int = 5) -> str:
return self._run(query, max_results)
# src/main.py
import asyncio
from agent.planner import ResearchPlanner
from agent.executor import ResearchExecutor
from agent.memory import AgentMemory
from tools.arxiv import ArxivSearchTool
from tools.scholar import ScholarSearchTool
from tools.summarizer import PaperSummarizer
async def main():
# 初始化组件
planner = ResearchPlanner()
memory = AgentMemory()
tools = [
ArxivSearchTool(),
ScholarSearchTool(),
PaperSummarizer()
]
executor = ResearchExecutor(tools, memory)
# 执行研究任务
topic = "大语言模型在代码生成领域的最新进展"
# 1. 规划
print("正在规划研究任务...")
plan = await planner.plan(topic)
print(f"研究计划: {plan}")
# 2. 执行
print("正在执行研究...")
results = await executor.execute(plan)
# 3. 生成报告
report = await generate_report(results, memory)
print(report)
async def generate_report(results: dict, memory: AgentMemory) -> str:
"""生成研究报告"""
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
llm = ChatOpenAI(model="gpt-4")
prompt = ChatPromptTemplate.from_template("""
基于以下研究结果,生成一份研究报告:
研究结果:
{results}
对话历史:
{history}
请生成结构化的报告,包含:
1. 研究概述
2. 主要发现
3. 关键论文推荐
4. 未来研究方向
""")
chain = prompt | llm
return await chain.ainvoke({
"results": str(results),
"history": memory.get_context()
})
if __name__ == "__main__":
asyncio.run(main())
2.4 Agent 框架对比与选型
主流框架概览
| 框架 | 特点 | 适用场景 | GitHub Stars |
|---|---|---|---|
| LangChain | 生态最完善,模块化设计 | 企业级应用 | 100k+ |
| LangGraph | 状态化工作流,可视化 | 复杂任务流 | 40k+ |
| CrewAI | 多 Agent 协作,角色驱动 | 团队协作场景 | 50k+ |
| AutoGen (微软) | 对话式多 Agent,代码生成 | 编程辅助 | 40k+ |
| AutoGPT | 自主决策,目标驱动 | 个人助手 | 170k+ |
| MetaGPT | 模拟企业角色,软件生成 | MVP 原型开发 | 60k+ |
详细对比
┌─────────────────────────────────────────────────────────────────┐
│ Agent 框架能力雷达图 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 生态完整性 │
│ ▲ │
│ LangChain ●│● LangGraph │
│ │ │
│ 易用性 ◄───────┼───────► 扩展性 │
│ CrewAI ● │ ● AutoGen │
│ │ │
│ AutoGPT ●│● MetaGPT │
│ ▼ │
│ 自主性 │
│ │
└─────────────────────────────────────────────────────────────────┘
选型决策树
┌─────────────────────────────────────────────────────────┐
│ Agent 框架选型指南 │
├─────────────────────────────────────────────────────────┤
│ │
│ 需要企业级稳定性和丰富生态? │
│ │ │
│ ├── 是 ──▶ LangChain + LangGraph │
│ │ │
│ └── 否 ──▶ 需要多 Agent 协作? │
│ │ │
│ ├── 是 ──▶ CrewAI 或 AutoGen │
│ │ │
│ └── 否 ──▶ 需要完全自主? │
│ │ │
│ ├── 是 ──▶ AutoGPT │
│ │ │
│ └── 否 ──▶ 纯 Python │
└─────────────────────────────────────────────────────────┘
框架特点详解
LangChain + LangGraph
# LangGraph 示例:状态化工作流
from langgraph.graph import StateGraph, END
def research_node(state):
# 研究节点
return {"research_done": True}
def write_node(state):
# 写作节点
return {"article": "..."}
workflow = StateGraph(State)
workflow.add_node("research", research_node)
workflow.add_node("write", write_node)
workflow.add_edge("research", "write")
workflow.add_edge("write", END)
app = workflow.compile()
CrewAI
# CrewAI 示例:多 Agent 协作
from crewai import Agent, Task, Crew
researcher = Agent(
role="研究员",
goal="收集相关信息",
backstory="资深研究专家",
allow_delegation=False
)
writer = Agent(
role="作家",
goal="撰写高质量文章",
backstory="专业内容创作者",
allow_delegation=True
)
task1 = Task(description="研究 AI 趋势", agent=researcher)
task2 = Task(description="撰写报告", agent=writer)
crew = Crew(agents=[researcher, writer], tasks=[task1, task2])
result = crew.kickoff()
AutoGen
# AutoGen 示例:对话式多 Agent
from autogen import AssistantAgent, UserProxyAgent
assistant = AssistantAgent(
name="assistant",
llm_config={"model": "gpt-4"}
)
user_proxy = UserProxyAgent(
name="user_proxy",
human_input_mode="NEVER",
code_execution_config={"work_dir": "coding"}
)
user_proxy.initiate_chat(
assistant,
message="帮我写一个 Python 爬虫"
)
2.5 GitHub 项目推荐
| 项目 | 描述 | 链接 |
|---|---|---|
| AutoGPT | 自主 AI Agent 先驱 | github.com/Significant… |
| CrewAI | 多 Agent 协作框架 | github.com/joaomdmoura… |
| AutoGen | 微软多 Agent 框架 | github.com/microsoft/a… |
| MetaGPT | 软件 Agent 团队 | github.com/geekan/Meta… |
| AgentGPT | Web 端 Agent 部署 | github.com/reworkd/Age… |
| GPT Researcher | 研究 Agent | github.com/assafelovic… |
| Open Interpreter | 代码执行 Agent | github.com/OpenInterpr… |
2.6 最佳实践
1. 清晰的角色定义
# 好的角色定义
agent = Agent(
role="数据分析专家",
goal="从数据中提取有价值的洞察",
backstory="""
你是一位拥有10年经验的数据科学家,
擅长数据清洗、统计分析和可视化。
你总是以数据为依据,提供客观的分析结果。
""",
tools=[pandas_tool, matplotlib_tool]
)
2. 合理的工具选择
# 工具应该是必要且有边界的
tools = [
Tool(
name="search_web",
description="搜索互联网获取最新信息",
func=search_web,
# 设置边界
return_direct=False # 不直接返回,允许 Agent 继续处理
)
]
3. 记忆管理策略
class SmartMemory:
def __init__(self):
self.working_memory = [] # 工作记忆(当前任务)
self.episodic_memory = [] # 情景记忆(历史交互)
self.semantic_memory = {} # 语义记忆(知识库)
def get_relevant_context(self, query: str) -> str:
"""智能检索相关上下文"""
# 1. 从工作记忆获取最近信息
recent = self.working_memory[-5:]
# 2. 从语义记忆检索相关知识
relevant_knowledge = self.semantic_memory.search(query)
return self._merge_context(recent, relevant_knowledge)
欢迎关注的我的公众号《码上未来》,一起交流AI前沿技术!
扫码二维码加我微信进群聊AI