框架开发实战
为什么需要框架?
- 提升代码复用和开发效率
- 实现核心组件的解耦与可扩展性
- 模型层:负责与LLM交互,可以轻松切换不同的大模型
- 工具层:提供标准化的工具定义、注册和执行接口
- 记忆层:处理短期和长期记忆
- 标准化复杂的状态管理
比如Memory类,需要处理上下文窗口限制、历史信息持久化、多轮对话状态跟踪。开发者就不需要每次重新处理这些复杂的状态管理
- 简化可观测性与调试过程
主流框架
- AutoGen
通过对话实现协作。它将多智能体系统抽象为由多个可对话智能体组成的群聊。任务在这些智能体之间自动化消息传递,不断对话、协作、迭代来解决问题。
- AgentScope
AgentScope 是一个专为多智能体应用设计的、功能全面的开发平台。它的核心特点是易用性和工程化。它提供了一套非常友好的编程接口,让开发者可以轻松定义智能体、构建通信网络,并管理整个应用的生命周期。其内置的消息传递机制和对分布式部署的支持,使其非常适合构建和运维复杂、大规模的多智能体系统。
- CAMEL
CAMEL 提供了一种新颖的、名为角色扮演 (Role-Playing) 的协作方法。其核心理念是,我们只需要为两个智能体(例如,AI研究员 和 Python程序员)设定好各自的角色和共同的任务目标,它们就能在"初始提示 (Inception Prompting) "的引导下,自主地进行多轮对话,相互启发、相互配合,共同完成任务。它极大地降低了设计多智能体对话流程的复杂度
- LangGraph
作为 LangChain 生态的扩展,LangGraph 另辟蹊径,将智能体的执行流程建模为F图 (Graph)。在传统的链式结构中,信息只能单向流动。而 LangGraph 将每一步操作(如调用LLM、执行工具)定义为图中的一个节点 (Node),并用边 (Edge) 来定义节点之间的跳转逻辑。这种设计天然支持循环 (Cycles),使得实现如 Reflection 这样的迭代、修正、自我反思的复杂工作流变得异常简单和直观。
构建智能体框架
市面上的框架需要初学者学习大量概念才能完成任务,API接口变更频繁。
构建自己的智能体框架可以深度理解智能体的工作原理,获得完整的控制权,培养系统设计能力。
支持多供应商
python
class MyLLM(HelloAgentsLLM):
def __init__(
self,
model: Optional[str] = None,
api_key: Optional[str] = None,
base_url: Optional[str] = None,
provider: Optional[str] = "auto",
**kwargs
):
# 检查provider是否为我们想处理的'modelscope'
if provider == "modelscope":
print("正在使用自定义的 ModelScope Provider")
self.provider = "modelscope"
# 解析 ModelScope 的凭证
self.api_key = api_key or os.getenv("MODELSCOPE_API_KEY")
self.base_url = base_url or "https://api-inference.modelscope.cn/v1/"
# 验证凭证是否存在
if not self.api_key:
raise ValueError("ModelScope API key not found. Please set MODELSCOPE_API_KEY environment variable.")
# 设置默认模型和其他参数
self.model = model or os.getenv("LLM_MODEL_ID") or "Qwen/Qwen2.5-VL-72B-Instruct"
self.temperature = kwargs.get('temperature', 0.7)
self.max_tokens = kwargs.get('max_tokens')
self.timeout = kwargs.get('timeout', 60)
# 使用获取的参数创建OpenAI客户端实例
self._client = OpenAI(api_key=self.api_key, base_url=self.base_url, timeout=self.timeout)
else:
# 如果不是 modelscope, 则完全使用父类的原始逻辑来处理
super().__init__(model=model, api_key=api_key, base_url=base_url, provider=provider, **kwargs)
三个核心文件:
message.py: 定义了框架内统一的消息格式,确保了智能体与模型之间信息传递的标准化。config.py: 提供了一个中心化的配置管理方案,使框架的行为易于调整和扩展。agent.py: 定义了所有智能体的抽象基类(Agent),为后续实现不同类型的智能体提供了统一的接口和规范。
1. Message 类
python
"""消息系统"""
from typing import Optional, Dict, Any, Literal
from datetime import datetime
from pydantic import BaseModel
# 定义消息角色的类型,限制其取值
MessageRole = Literal["user", "assistant", "system", "tool"]
class Message(BaseModel):
"""消息类"""
content: str
role: MessageRole
timestamp: datetime = None
metadata: Optional[Dict[str, Any]] = None
def __init__(self, content: str, role: MessageRole, **kwargs):
super().__init__(
content=content,
role=role,
timestamp=kwargs.get('timestamp', datetime.now()),
metadata=kwargs.get('metadata', {})
)
def to_dict(self) -> Dict[str, Any]:
"""转换为字典格式(OpenAI API格式)"""
return {
"role": self.role,
"content": self.content
}
def __str__(self) -> str:
return f"[{self.role}] {self.content}"
2. Config类
python
"""配置管理"""
import os
from typing import Optional, Dict, Any
from pydantic import BaseModel
class Config(BaseModel):
"""HelloAgents配置类"""
# LLM配置
default_model: str = "gpt-3.5-turbo"
default_provider: str = "openai"
temperature: float = 0.7
max_tokens: Optional[int] = None
# 系统配置
debug: bool = False
log_level: str = "INFO"
# 其他配置
max_history_length: int = 100
@classmethod
def from_env(cls) -> "Config":
"""从环境变量创建配置"""
return cls(
debug=os.getenv("DEBUG", "false").lower() == "true",
log_level=os.getenv("LOG_LEVEL", "INFO"),
temperature=float(os.getenv("TEMPERATURE", "0.7")),
max_tokens=int(os.getenv("MAX_TOKENS")) if os.getenv("MAX_TOKENS") else None,
)
def to_dict(self) -> Dict[str, Any]:
"""转换为字典"""
return self.dict()
3. Agent基类
python
"""Agent基类"""
from abc import ABC, abstractmethod
from typing import Optional, Any
from .message import Message
from .llm import HelloAgentsLLM
from .config import Config
class Agent(ABC):
"""Agent基类"""
def __init__(
self,
name: str,
llm: HelloAgentsLLM,
system_prompt: Optional[str] = None,
config: Optional[Config] = None
):
self.name = name
self.llm = llm
self.system_prompt = system_prompt
self.config = config or Config()
self._history: list[Message] = []
@abstractmethod
def run(self, input_text: str, **kwargs) -> str:
"""运行Agent"""
pass
def add_message(self, message: Message):
"""添加消息到历史记录"""
self._history.append(message)
def clear_history(self):
"""清空历史记录"""
self._history.clear()
def get_history(self) -> list[Message]:
"""获取历史记录"""
return self._history.copy()
def __str__(self) -> str:
return f"Agent(name={self.name}, provider={self.llm.provider})"