7.3框架接口实现

在上节中,我们构建了 HelloAgentsLLM 这一核心组件,解决了与大语言模型通信的关键问题。不过它还需要一系列配套的接口和组件来处理数据流、管理配置、应对异常,并为上层应用的构建提供一个清晰、统一的结构。本节将讲述以下三个核心文件:

  • message.py: 定义了框架内统一的消息格式,确保了智能体与模型之间信息传递的标准化。
  • config.py: 提供了一个中心化的配置管理方案,使框架的行为易于调整和扩展。
  • agent.py: 定义了所有智能体的抽象基类(Agent),为后续实现不同类型的智能体提供了统一的接口和规范。

7.3.1Message类

在智能体与大语言模型的交互中,对话历史是至关重要的上下文。为了规范地管理这些信息,我们设计了一个简易 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}"复制到剪贴板错误已复制

该类的设计有几个关键点。首先,我们通过 typing.Literal 将 role 字段的取值严格限制为 "user", "assistant", "system", "tool" 四种,这直接对应 OpenAI API 的规范,保证了类型安全。除了 content 和 role 这两个核心字段外,我们还增加了 timestamp 和 metadata,为日志记录和未来功能扩展预留了空间。最后,to_dict() 方法是其核心功能之一,负责将内部使用的 Message 对象转换为与 OpenAI API 兼容的字典格式,体现了"对内丰富,对外兼容"的设计原则。

7.3.2Config类

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()复制到剪贴板错误已复制

首先,我们将配置项按逻辑划分为 LLM配置、系统配置 等,使结构一目了然。其次,每个配置项都设有合理的默认值,保证了框架在零配置下也能工作。最核心的是 from_env() 类方法,它允许用户通过设置环境变量来覆盖默认配置,无需修改代码,这在部署到不同环境时尤其有用。

7.3.3Agent抽血基类

Agent 类是整个框架的顶层抽象。它定义了一个智能体应该具备的通用行为和属性,但并不关心具体的实现方式。我们通过 Python 的 abc (Abstract Base Classes) 模块来实现它,这强制所有具体的智能体实现(如后续章节的 SimpleAgent, ReActAgent 等)都必须遵循同一个"接口"。

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})"复制到剪贴板错误已复制

该类的设计体现了面向对象中的抽象原则。首先,它通过继承 ABC 被定义为一个不能直接实例化的抽象类。其构造函数 __init__ 清晰地定义了 Agent 的核心依赖:名称、LLM 实例、系统提示词和配置。最重要的部分是使用 @abstractmethod 装饰的 run 方法,它强制所有子类必须实现此方法,从而保证了所有智能体都有统一的执行入口。此外,基类还提供了通用的历史记录管理方法,这些方法与 Message 类协同工作,体现了组件间的联系。

至此,我们已经完成了 HelloAgents 框架核心基础组件的设计与实现。

相关推荐
用户976104399211 小时前
7.2HelloAgentsLLM扩展
agent
许雪里3 小时前
XXL-AI|AI应用开发平台(Agent编排、多供应商、「MCP + SKILL + RAG」扩展、工程化底座)
人工智能·agent·ai编程
10年前端老司机3 小时前
Next.js+LangGraph.js+ 简历工具AI Agent完整落地
前端·langchain·agent
Csvn8 小时前
第 28 章 案例四 多智能体协作系统
人工智能·aigc·agent
SFLYQ8 小时前
你的数字员工正在苏醒中。。。
agent·ai编程
吴佳浩8 小时前
Agent 怎么做自动化评测?构建端到端的 Agent Evaluation 体系
人工智能·agent·ai编程
Csvn8 小时前
第 27 章 案例三 自动化工作流 Agent
人工智能·aigc·agent
BreezeJiang8 小时前
从 LangChain 到 LangGraph:多 Agent 不是玄学,是 token 账本和干扰问题
langchain·agent