ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

面向对象智能体:用Python类构建可维护的AI智能体系统

面向对象智能体:用Python类构建可维护的AI智能体系统 这次我们来看一个来自 NVIDIA 的技术概念面向对象的智能体Object-Oriented Agents。它的核心思想非常直接——一个智能体Agent就是一个 Python 类Class。这并非一个具体的软件包或模型而是一种构建和设计智能体系统的编程范式与架构理念。对于正在探索如何将大语言模型LLM能力工程化、模块化的开发者来说理解这个范式至关重要。简单来说它解决了智能体开发中的混乱问题。传统的智能体脚本往往混杂着提示词工程、工具调用、状态管理和流程控制代码难以维护和复用。而“智能体即类”的理念将智能体封装成具有清晰生命周期初始化、运行、销毁和内部状态的对象使得智能体像乐高积木一样可以被组合、继承和扩展。本文将深入拆解这一理念并展示如何从零构建一个符合该范式的智能体涵盖环境搭建、类结构设计、工具集成、记忆管理以及实际效果验证。如果你关心如何用更工程化、更 Pythonic 的方式开发稳定可靠的 AI 智能体希望代码结构清晰、易于调试和团队协作那么这篇文章值得你仔细阅读并动手实践。1. 核心能力速览首先我们通过一个表格快速了解“面向对象智能体”范式的核心特征与价值这有助于判断它是否适合你的项目。能力项说明核心理念将智能体抽象为一个 Python 类封装其状态、工具和能力。核心优势高内聚、低耦合状态、逻辑、工具封装在类内部。易复用与扩展通过类继承和多态轻松创建新智能体。生命周期清晰__init__,run,reset等方法定义明确阶段。易于测试与调试可以实例化智能体并对其方法进行单元测试。硬件/环境门槛无特殊要求。主要依赖 Python 环境及所选 LLM 的接入方式本地或 API。本地部署大模型则需要相应 GPU 资源。启动/运行方式通过 Python 脚本实例化智能体类并调用其方法如agent.run(task)。主要功能1.对话交互处理多轮对话维护上下文。2.工具调用动态选择并执行外部工具搜索、计算、API等。3.状态管理内部维护对话历史、执行状态等。4.任务规划与执行将复杂任务分解为可执行的步骤序列。是否支持 API是。智能体类本身可作为后端服务的核心逻辑单元通过 Web 框架如 FastAPI暴露为 REST API。是否支持批量/异步任务是。可以轻松实现多智能体实例并行处理任务或利用异步编程处理高并发请求。适合场景需要长期运行、状态复杂的对话系统如客服机器人、游戏 NPC需要组合多种工具的自动化工作流团队协作的中大型智能体项目。2. 适用场景与使用边界“智能体即类”的范式并非银弹理解其适用边界能帮助你做出更好的技术选型。它非常适合以下场景复杂任务自动化例如一个需要先搜索信息、再进行分析、最后生成报告的工作流。每个步骤可以作为智能体的一个工具方法状态在类实例中流转。可维护的对话系统当你的聊天机器人需要记住用户偏好、管理多轮对话上下文、并可能调用不同插件时用类来封装这些逻辑比散落各处的全局变量和函数要清晰得多。研究与原型快速迭代你可以定义一个BaseAgent基类然后通过继承快速创建具有不同能力如“具有网络搜索能力的Agent”、“具有代码执行能力的Agent”的变体方便对比实验。团队协作开发清晰的类接口公有方法、私有方法和属性定义让团队成员更容易理解智能体的功能边界减少代码冲突。它可能不是最佳选择的情况一次性脚本或简单提示词调用如果你的需求只是向 LLM 发送一个提示词并获取回复直接使用requests调用 API 或langchain的简单链可能更快捷。对极致轻量有要求类的抽象会带来轻微的开销。如果是在资源极度受限的边缘设备上运行一个极其简单的智能体或许更直接的函数式编程更合适。概念验证PoC阶段在最初验证想法时可能快速写一个线性的脚本更有效率。但当 PoC 通过需要走向工程化时就是引入该范式的好时机。合规与安全边界工具调用安全智能体类中集成的工具如执行代码、访问数据库、调用网络API必须经过严格的安全审查和权限控制防止越权操作。数据隐私智能体内部维护的对话历史等状态可能包含敏感信息。需确保数据存储、传输和处理符合隐私法规并在不再需要时及时清理。内容合规智能体生成的内容需设置审查机制避免产生有害、偏见或侵权信息。3. 环境准备与前置条件开始构建我们的面向对象智能体之前需要准备好开发环境。以下是一个通用的环境清单你可以根据实际使用的 LLM 后端进行调整。基础环境操作系统Windows 10/11, macOS, 或 Linux (如 Ubuntu 20.04)。本文示例将在通用 Python 环境下运行。Python 版本推荐 Python 3.9 或 3.10这是多数 AI 库兼容性较好的版本。包管理工具使用pip或conda管理依赖。核心依赖我们将使用openai库兼容 OpenAI API 及 Azure OpenAI作为 LLM 的调用客户端。你也可以替换为litellm,anthropic等库以支持其他模型。# 创建并激活虚拟环境推荐 python -m venv venv # Windows: venv\Scripts\activate # Linux/macOS: source venv/bin/activate # 安装核心依赖 pip install openai python-dotenvLLM 配置你需要一个可用的 LLM API 密钥。这里以 OpenAI 为例访问 OpenAI 平台创建 API Key。在项目根目录创建.env文件并添加你的密钥OPENAI_API_KEYyour_api_key_here OPENAI_BASE_URLhttps://api.openai.com/v1 # 如果使用其他兼容API修改此处使用python-dotenv在代码中加载配置。可选工具依赖为了演示工具调用我们可能会用到一些工具库例如进行网络搜索或计算。可以按需安装pip install duckduckgo-search # 用于网络搜索 pip install wolframalpha # 用于计算和知识查询需API Key4. 从零构建设计智能体基类让我们从最核心的部分开始设计一个智能体基类BaseAgent。这个类将定义所有智能体共有的属性和行为。4.1 定义基类结构与初始化首先我们设计BaseAgent的__init__方法。它需要初始化 LLM 客户端、工具列表、记忆系统等核心组件。import os from abc import ABC, abstractmethod from typing import List, Dict, Any, Optional from openai import OpenAI from dotenv import load_dotenv # 加载环境变量 load_dotenv() class BaseAgent(ABC): 智能体基类。 所有具体智能体都应继承自此基类并实现 run 方法。 def __init__(self, name: str BaseAgent, model: str gpt-3.5-turbo, system_prompt: Optional[str] None, temperature: float 0.7): 初始化智能体。 Args: name: 智能体名称。 model: 使用的LLM模型名称。 system_prompt: 系统提示词用于设定智能体角色和行为。 temperature: LLM生成温度控制随机性。 self.name name self.model model self.system_prompt system_prompt or You are a helpful AI assistant. self.temperature temperature # 初始化LLM客户端 self.client OpenAI( api_keyos.getenv(OPENAI_API_KEY), base_urlos.getenv(OPENAI_BASE_URL, https://api.openai.com/v1) ) # 工具列表每个工具是一个字典包含名称、描述和函数引用 self.tools: List[Dict[str, Any]] [] # 对话记忆存储多轮对话历史 self.memory: List[Dict[str, str]] [] if self.system_prompt: self.memory.append({role: system, content: self.system_prompt}) # 内部状态可用于存储任务进度、用户偏好等 self.internal_state: Dict[str, Any] {} # 注册基础工具可选 self._register_default_tools() def _register_default_tools(self): 注册一些默认工具。子类可以重写此方法。 # 例如一个简单的回显工具 self.add_tool( nameecho, descriptionEcho back the input text., funclambda text: fEcho: {text} ) def add_tool(self, name: str, description: str, func: callable): 向智能体添加一个工具。 Args: name: 工具名称。 description: 工具描述用于提示LLM理解工具用途。 func: 工具对应的可调用函数。 self.tools.append({ name: name, description: description, func: func }) print(f[{self.name}] Tool added: {name})4.2 实现核心run方法与对话逻辑run方法是智能体的主入口。这里我们实现一个简单的循环接收用户输入调用LLM并处理可能的工具调用。class BaseAgent(ABC): # ... 接上面的 __init__ 等方法 ... abstractmethod def run(self, initial_input: Optional[str] None): 运行智能体的主循环。这是一个抽象方法子类必须实现。 基类提供一个基础的交互式实现。 print(f[{self.name}] Agent started. Type exit to quit.) if initial_input: self._process_user_input(initial_input) while True: try: user_input input(\nYou: ) if user_input.lower() in [exit, quit]: print(f[{self.name}] Goodbye!) break response self._process_user_input(user_input) print(f\n{self.name}: {response}) except KeyboardInterrupt: print(f\n[{self.name}] Interrupted.) break except Exception as e: print(f\n[{self.name}] Error: {e}) def _process_user_input(self, user_input: str) - str: 处理单轮用户输入的核心逻辑。 1. 将用户输入加入记忆。 2. 构造包含工具信息的消息。 3. 调用LLM。 4. 解析LLM回复检查是否需要调用工具。 5. 执行工具调用并将结果返回给LLM进行总结。 6. 将最终回复加入记忆并返回。 # 1. 更新记忆 self.memory.append({role: user, content: user_input}) # 2. 准备发送给LLM的消息包含工具定义 messages_for_llm self._prepare_messages_with_tools() # 3. 调用LLM llm_response self._call_llm(messages_for_llm) # 4. 解析回复检查工具调用 final_response self._handle_llm_response(llm_response) # 5. 将助手的最终回复加入记忆 self.memory.append({role: assistant, content: final_response}) return final_response def _prepare_messages_with_tools(self) - List[Dict[str, Any]]: 准备发送给LLM的消息列表。如果工具体不为空则在系统提示中附加工具描述。 messages self.memory.copy() if self.tools: # 构建工具描述文本 tools_text You have access to the following tools:\n for tool in self.tools: tools_text f- {tool[name]}: {tool[description]}\n tools_text \nIf you need to use a tool, respond with: TOOL_CALL:tool_name:arguments. After the tool returns, I will give you the result. # 将工具描述插入到第一条系统消息之后或作为新的系统消息 if messages[0][role] system: messages[0][content] messages[0][content] \n\n tools_text else: messages.insert(0, {role: system, content: tools_text}) return messages def _call_llm(self, messages: List[Dict[str, Any]]) - str: 调用LLM API并返回纯文本回复。 try: response self.client.chat.completions.create( modelself.model, messagesmessages, temperatureself.temperature, streamFalse ) return response.choices[0].message.content except Exception as e: return fError calling LLM: {e} def _handle_llm_response(self, llm_response: str) - str: 处理LLM的回复。 如果回复中包含 TOOL_CALL 指令则执行工具并递归处理。 否则直接返回回复。 # 一个简单的工具调用解析实际应用应使用更鲁棒的方式如JSON if llm_response.startswith(TOOL_CALL:): try: # 解析格式: TOOL_CALL:tool_name:argument _, tool_call_str llm_response.split(TOOL_CALL:, 1) tool_name, argument tool_call_str.split(:, 1) tool_name tool_name.strip() argument argument.strip() # 查找并执行工具 tool_func None for tool in self.tools: if tool[name] tool_name: tool_func tool[func] break if tool_func: print(f[{self.name}] Executing tool: {tool_name} with arg: {argument}) tool_result tool_func(argument) print(f[{self.name}] Tool result: {tool_result}) # 将工具执行结果作为新的用户输入继续对话 follow_up_response self._process_user_input(fTool {tool_name} returned: {tool_result}) return follow_up_response else: return fError: Tool {tool_name} not found. except Exception as e: return fError parsing or executing tool call: {e} else: # 没有工具调用直接返回LLM回复 return llm_response def reset(self): 重置智能体的记忆和状态保留工具和系统提示。 self.memory [] if self.system_prompt: self.memory.append({role: system, content: self.system_prompt}) self.internal_state {} print(f[{self.name}] Memory and state reset.)5. 功能测试与效果验证创建具体智能体现在我们基于BaseAgent创建两个具体的智能体来验证其功能一个简单的对话助手和一个具备计算能力的助手。5.1 测试一基础对话智能体这个智能体继承BaseAgent使用其默认的交互式run方法。class ConversationAgent(BaseAgent): 一个简单的对话智能体。 def __init__(self, nameConvoBot): super().__init__( namename, modelgpt-3.5-turbo, system_promptYou are a friendly and helpful conversation assistant. Keep your responses concise., temperature0.8 ) # 测试运行 if __name__ __main__: print( Testing ConversationAgent ) agent ConversationAgent() # 运行一次交互循环 agent.run(Hello, introduce yourself.)预期结果与验证启动控制台打印[ConvoBot] Agent started.。初始输入处理智能体接收 “Hello, introduce yourself.”调用 LLM生成并打印一段自我介绍。交互循环进入You:提示符等待用户输入。输入 “Whats the weather like?” 等观察其回复。记忆测试在对话中问 “What did I just ask?”智能体应能基于self.memory回忆起之前的对话。退出输入exit智能体退出循环。5.2 测试二具备工具调用能力的计算智能体这个智能体将集成一个真正的计算工具例如利用wolframalpha或一个本地函数。import math import requests from datetime import datetime class CalculatorAgent(BaseAgent): 一个具备计算和查询能力的智能体。 def __init__(self, nameCalcBot): super().__init__( namename, system_promptYou are a precise calculation and information assistant. Use tools whenever needed., temperature0.2 # 计算任务需要低随机性 ) self._register_calculator_tools() def _register_calculator_tools(self): 注册计算和查询工具。 # 工具1: 简单数学计算 (使用Python eval生产环境需更安全的方式) def safe_calculate(expression: str) - str: try: # 警告实际生产环境应对表达式进行严格的安全过滤 # 这里仅作演示使用受限的eval。 allowed_names {abs: abs, round: round, pow: pow, min: min, max: max} code compile(expression, string, eval) for name in code.co_names: if name not in allowed_names and not name.isdigit(): raise NameError(fUse of {name} not allowed) result eval(expression, {__builtins__: {}}, {**allowed_names, math: math}) return str(result) except Exception as e: return fCalculation error: {e} self.add_tool( namecalculate, descriptionPerform a basic arithmetic or math calculation. Input should be a string like 3 5 * 2 or sqrt(16)., funcsafe_calculate ) # 工具2: 获取当前时间 def get_current_time(_) - str: return datetime.now().strftime(%Y-%m-%d %H:%M:%S) self.add_tool( nameget_time, descriptionGet the current date and time., funcget_current_time ) # 工具3: 网络搜索 (示例使用 duckduckgo) def web_search(query: str) - str: try: from duckduckgo_search import DDGS with DDGS() as ddgs: results list(ddgs.text(query, max_results3)) if results: summary \n.join([f{r[title]}: {r[body][:150]}... for r in results]) return fSearch results for {query}:\n{summary} else: return No results found. except ImportError: return Error: duckduckgo-search package not installed. except Exception as e: return fSearch error: {e} self.add_tool( namesearch_web, descriptionSearch the web for information. Input is a search query string., funcweb_search ) def run(self, task: str): 重写run方法以任务模式运行而非交互式。 接收一个任务字符串处理并返回结果。 print(f[{self.name}] Task received: {task}) response self._process_user_input(task) print(f[{self.name}] Final response: {response}) return response # 测试运行 if __name__ __main__: print(\n Testing CalculatorAgent ) calc_agent CalculatorAgent() # 测试1: 纯计算 print(\nTest 1: Calculation) calc_agent.run(What is 15 * (3 7)?) # 测试2: 需要工具链的任务 print(\nTest 2: Task requiring tool chain) calc_agent.run(Search for the latest news about NVIDIA AI, then tell me the current time.) # 测试3: 重置状态 print(\nTest 3: Resetting agent) calc_agent.reset() calc_agent.run(What was our previous conversation about?) # 应该不记得预期结果与验证工具调用识别当用户提问涉及计算或查询时LLM 应能根据系统提示中的工具描述生成TOOL_CALL:calculate:15*(37)格式的回复。工具执行智能体解析该指令调用对应的safe_calculate函数得到结果 “150”。结果整合智能体将工具执行结果Tool calculate returned: 150作为新的用户输入再次调用 LLM。LLM 应生成包含计算结果的友好回复如 “15 * (3 7) equals 150.”工具链对于复杂任务 “Search... then tell me the time”LLM 可能先调用search_web获取结果后再调用get_time最终整合信息回复。状态隔离调用reset()后新的对话不应包含之前的历史。判断成功的标准智能体能正确解析并执行工具调用指令。多轮工具调用链式能顺利进行。对话历史被正确维护在self.memory中。reset()方法能有效清空记忆。6. 接口 API 与批量任务集成将智能体类封装成 Web API 或用于处理批量任务是工程化的关键一步。6.1 将智能体封装为 FastAPI 服务我们可以轻松地将CalculatorAgent包装成一个 REST API 服务。# agent_api.py from fastapi import FastAPI, HTTPException from pydantic import BaseModel from typing import Optional import uvicorn # 假设 CalculatorAgent 定义在同一个文件或已导入 from your_agent_module import CalculatorAgent app FastAPI(titleObject-Oriented Agent API) # 全局智能体实例简单示例生产环境需考虑并发和状态隔离 agent CalculatorAgent(nameAPIAgent) class AgentRequest(BaseModel): task: str session_id: Optional[str] None # 用于区分不同会话 reset_session: bool False class AgentResponse(BaseModel): response: str session_id: str status: str # 简单的会话内存生产环境应使用数据库或Redis sessions {} app.post(/chat, response_modelAgentResponse) async def chat_with_agent(request: AgentRequest): 与智能体对话的端点。 session_id request.session_id or default # 获取或创建会话特定的智能体实例 if request.reset_session or session_id not in sessions: sessions[session_id] CalculatorAgent(namefAgent-{session_id}) current_agent sessions[session_id] if request.reset_session: current_agent.reset() else: current_agent sessions[session_id] try: # 运行智能体处理任务 response_text current_agent.run(request.task) return AgentResponse( responseresponse_text, session_idsession_id, statussuccess ) except Exception as e: raise HTTPException(status_code500, detailfAgent execution failed: {e}) app.get(/health) async def health_check(): return {status: healthy, agent: agent.name} if __name__ __main__: # 启动服务 uvicorn.run(app, host0.0.0.0, port8000)启动与测试 API安装依赖pip install fastapi uvicorn启动服务运行python agent_api.py。调用测试使用curl或 Pythonrequests。curl -X POST http://127.0.0.1:8000/chat \ -H Content-Type: application/json \ -d {task: Calculate 2 to the power of 10, session_id: user123}会话保持使用相同的session_id发送后续请求智能体会保持对话记忆。6.2 批量任务处理对于需要处理任务列表的场景可以设计一个BatchProcessor类来管理多个智能体实例或重复调用。import threading import queue import json from typing import List from your_agent_module import BaseAgent # 或你的具体Agent类 class AgentBatchProcessor: 使用智能体批量处理任务的处理器。 def __init__(self, agent_class, agent_init_argsNone, num_workers2): Args: agent_class: 智能体类如 CalculatorAgent。 agent_init_args: 初始化智能体的参数字典。 num_workers: 并发工作线程数。 self.agent_class agent_class self.agent_init_args agent_init_args or {} self.num_workers num_workers self.task_queue queue.Queue() self.results [] self.lock threading.Lock() def add_task(self, task_input: str, task_id: str None): 向队列添加一个任务。 self.task_queue.put({input: task_input, id: task_id or str(len(self.results))}) def _worker(self): 工作线程函数从队列取任务并执行。 # 每个线程有自己的智能体实例避免状态冲突 local_agent self.agent_class(**self.agent_init_args) while True: try: task self.task_queue.get(timeout1) # 超时1秒后退出 except queue.Empty: break try: # 处理任务 result local_agent.run(task[input]) with self.lock: self.results.append({ task_id: task[id], input: task[input], output: result, status: success }) except Exception as e: with self.lock: self.results.append({ task_id: task[id], input: task[input], output: str(e), status: failed }) finally: self.task_queue.task_done() def process(self) - List[dict]: 启动工作线程处理所有任务并返回结果列表。 threads [] for _ in range(self.num_workers): t threading.Thread(targetself._worker) t.start() threads.append(t) # 等待所有任务完成 self.task_queue.join() # 通知工作线程退出 for _ in range(self.num_workers): self.task_queue.put(None) # 发送结束信号 for t in threads: t.join() return self.results # 使用示例 if __name__ __main__: from your_agent_module import CalculatorAgent processor AgentBatchProcessor( agent_classCalculatorAgent, agent_init_args{name: BatchCalcBot}, num_workers3 ) # 添加批量任务 tasks [ What is 99 1?, Calculate the area of a circle with radius 5., What time is it now?, Search for the capital of France. ] for i, task in enumerate(tasks): processor.add_task(task, ftask_{i}) # 处理并获取结果 all_results processor.process() print(json.dumps(all_results, indent2))7. 资源占用与性能观察面向对象智能体范式本身不直接消耗大量硬件资源资源消耗主要来自集成的 LLM 和工具。内存占用智能体对象本身占用内存很小主要是 Python 对象开销、对话历史列表和内部状态字典。对话历史过长是主要增长点需定期清理或使用摘要技术。LLM 客户端OpenAI等客户端是轻量级的。如果使用本地大模型如通过transformers加载则模型权重会占用主要内存GPU 显存。CPU/GPU 使用智能体类的逻辑处理字符串解析、状态管理是 CPU 密集型但计算量通常很小。主要性能瓶颈在 LLM 调用如果使用云端 API性能受网络延迟和 API 速率限制影响。如果使用本地模型则受 GPU 算力和显存影响。性能优化建议对话历史管理实现memory的滚动窗口或摘要功能避免无限增长。工具调用优化对耗时工具如网络请求进行异步调用避免阻塞主线程。批量处理如AgentBatchProcessor所示利用多线程/异步处理多个独立任务。LLM 调用缓存对重复或相似的查询结果进行缓存减少不必要的 API 调用或模型推理。连接池如果高频调用 API使用 HTTP 连接池如requests.Session提升效率。观察方法使用系统监控工具如htop,nvidia-smi观察进程的 CPU/内存/GPU 使用情况。在智能体类中添加性能日志记录每个_call_llm和工具调用的耗时。对于 Web API 服务使用 APM 工具如 Prometheus, Grafana监控接口响应时间和 QPS。8. 常见问题与排查方法在开发和运行面向对象智能体时你可能会遇到以下问题。问题现象可能原因排查方式解决方案LLM 不调用工具1. 系统提示词中工具描述不清晰。2. LLM 温度 (temperature) 过高导致输出不稳定。3. 工具描述与用户问题不匹配。1. 打印发送给 LLM 的最终消息 (messages_for_llm)检查工具描述是否完整。2. 尝试降低temperature(如设为 0.1)。3. 简化工具描述确保 LLM 能理解。1. 优化系统提示词明确指令格式如TOOL_CALL:name:arg。2. 使用更强大的模型如gpt-4进行工具调用决策。3. 考虑使用 OpenAI 的 Function Calling 或 ReAct 等更规范的框架。工具调用解析失败1. LLM 输出的工具调用格式与解析逻辑不匹配。2. 参数中包含特殊字符导致分割错误。1. 打印llm_response原始内容检查其格式。2. 使用更鲁棒的解析器如正则表达式或尝试解析 JSON。1. 改用结构化输出如要求 LLM 输出 JSON。2. 使用现成的 Agent 框架如 LangChain, AutoGen的工具调用机制。智能体状态混乱1. 多个请求共享了同一个智能体实例导致记忆串扰。2.reset()方法未正确清空所有状态。1. 检查是否在 Web 服务或批量处理中错误地复用了实例。2. 检查reset()方法是否重置了memory和internal_state。1. 为每个用户会话创建独立的智能体实例如 API 示例中的sessions字典。2. 确保reset()方法覆盖所有需要清理的属性。API 调用或工具执行超时1. 网络问题。2. 工具函数执行时间过长如复杂计算、慢速网络请求。3. LLM API 响应慢。1. 添加超时设置和重试机制。2. 记录每个步骤的耗时。3. 监控网络连接。1. 为requests或openai调用设置合理的timeout参数。2. 将耗时工具异步化。3. 实现熔断机制避免一个失败工具拖垮整个系统。内存泄漏1. 对话历史memory列表无限增长。2. 工具函数或第三方库存在内存泄漏。1. 监控进程内存使用量随时间的变化。2. 使用内存分析工具如tracemalloc。1. 为memory设置最大长度限制或定期将旧消息摘要化。2. 确保工具函数释放了它申请的资源如关闭文件、网络连接。9. 最佳实践与使用建议基于上述实践总结出以下工程化建议帮助你构建更健壮的智能体系统。设计清晰的类层次结构BaseAgent负责最通用的对话循环、记忆管理和工具调用框架。派生出DomainSpecificAgent如CustomerServiceAgent,DataAnalysisAgent添加领域特定的系统提示词和工具集。进一步派生出ConcreteAgent用于具体部署可以固化某些配置。工具管理的安全性永远不要直接eval用户输入。上面的safe_calculate仅作演示生产环境必须使用安全的表达式求值库如asteval或沙箱。为每个工具函数实现严格的输入验证和权限检查。考虑为工具调用添加审批流程或确认机制特别是对于具有写操作或外部影响的工具。状态持久化将会话记忆 (memory) 和内部状态 (internal_state) 定期保存到数据库如 SQLite, Redis。实现save_session(session_id)和load_session(session_id)方法支持智能体状态的暂停与恢复。测试驱动开发为BaseAgent的关键方法如_handle_llm_response,add_tool编写单元测试。为具体的智能体创建集成测试模拟用户对话并验证工具调用链的正确性。使用 mocking 来模拟 LLM 的响应和工具的执行使测试不依赖外部服务。与成熟框架结合LangChain可以将你的BaseAgent与 LangChain 的AgentExecutor,Tools结合利用其更强大的工具调用、记忆和链式能力。AutoGen微软的 AutoGen 框架本身就是基于多智能体对话的你的智能体类可以包装成 AutoGen 的AssistantAgent。Semantic Kernel适用于与微软技术栈深度集成。监控与可观测性在_call_llm和每个工具函数中记录耗时、输入和输出注意脱敏。记录智能体的关键决策点便于后期分析和调试复杂对话流。为 Web API 添加健康检查、性能指标和请求日志。“智能体即 Python 类”的范式其最大价值在于将 AI 能力的复杂性封装进熟悉的面向对象编程模型里。它让智能体不再是黑盒脚本而是拥有明确状态、行为和接口的软件组件。从今天构建的BaseAgent出发你可以通过继承来创造专注于客服、编程、数据分析等领域的专业智能体通过组合工具来扩展其能力边界并通过封装为 API 或批量处理器来融入现有的生产系统。最先应该验证的是工具调用流程是否畅通这是智能体超越简单聊天机器的关键。最容易踩的坑是状态管理特别是在多用户、高并发的 Web 服务场景下务必确保会话隔离。下一步你可以探索更复杂的记忆机制如向量数据库长期记忆、更可靠的工具调用协议如 OpenAI Function Calling以及将多个智能体组合起来完成更宏大任务的架构模式。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进