笔记5:代理系统架构概述
一、引言
AI代理系统是一种能够自主执行任务的智能软件架构,OpenHands作为AI驱动的软件开发代理平台,拥有完整的代理系统架构设计。本笔记将探讨AI代理架构的基本原理,并通过分析OpenHands核心架构,实现一个简化版的代理框架。
二、AI代理架构设计原则
2.1 AI代理系统的核心组件
- 感知模块(Perception): 接收和处理外部输入
- 认知模块(Cognition): 分析信息并进行决策
- 执行模块(Action): 实施决策并与环境交互
- 记忆模块(Memory): 存储历史信息和经验
- 工具模块(Tools): 扩展代理能力的功能集合
2.2 代理系统设计原则
- 自主性原则: 代理应能在有限监督下自主完成任务
- 可观察性原则: 代理的状态和决策过程应当透明可见
- 安全性原则: 代理应有明确的操作边界和安全保障
- 适应性原则: 代理应能根据反馈调整行为
- 模块化原则: 系统应由解耦合的组件构成,便于扩展
- 可靠性原则: 代理应能处理异常情况,避免灾难性失败
2.3 AI代理架构模式
- 反应式代理(Reactive Agent): 基于简单规则响应环境
- 基于目标的代理(Goal-Based Agent): 根据目标规划行动
- 基于效用的代理(Utility-Based Agent): 优化行动的预期效用
- 学习型代理(Learning Agent): 通过经验优化自身行为
- 混合架构(Hybrid Architecture): 结合多种架构模式的优势
三、OpenHands代理架构分析
从README_CN.md中,我们可以推断OpenHands采用了复杂的混合代理架构,具有以下特点:
3.1 OpenHands核心架构组件
- LLM决策引擎: 由Claude Sonnet 4等大型语言模型提供核心智能
- 工具集成系统: 允许代理使用各种开发工具
- 沙箱执行环境: 安全隔离的代码执行环境
- 对话式界面: 用户与代理交互的主要接口
- 上下文管理系统: 维护代理的工作状态和历史
- 权限与安全控制: 管理代理的操作权限和安全边界
3.2 OpenHands架构特性
- 容器化设计: 使用Docker实现环境隔离和可移植性
- 多模态交互: 支持文本、代码和命令行交互
- 无头模式支持: 可在无GUI环境下以编程方式使用
- 云原生架构: 支持云端部署和本地运行
- 可扩展设计: 支持添加新工具和自定义功能
3.3 OpenHands架构图(推断)
┌─────────────────────────────────────────┐
│ OpenHands系统架构 │
└─────────────────────────────────────────┘
│
┌───────────┼───────────┐
│ │ │
┌───────▼───────┐ ┌─▼─┐ ┌───────▼───────┐
│ 用户界面层 │ │ │ │ 安全层 │
│ (Web/CLI/API) │ │ │ │(权限/隔离/审计)│
└───────┬───────┘ │ │ └───────┬───────┘
│ │ │ │
┌───────▼───────┐ │核 │ ┌───────▼───────┐
│ 对话管理层 │ │心 │ │ 工具集成层 │
│(上下文/历史) │ │控 │ │(工具定义/调用)│
└───────┬───────┘ │制 │ └───────┬───────┘
│ │层 │ │
┌───────▼───────┐ │ │ ┌───────▼───────┐
│ LLM决策层 │ │ │ │ 执行环境层 │
│(思维/规划/推理)│ │ │ │(沙箱/运行时) │
└───────┬───────┘ └─┬─┘ └───────┬───────┘
│ │ │
└───────────┼───────────┘
│
┌───────────▼───────────┐
│ 持久化存储层 │
│ (配置/历史/工作区) │
└───────────────────────┘
四、实践项目:实现简化版代理框架
4.1 代理系统核心结构设计
// agent-core.js
const EventEmitter = require('events');
const LLMClient = require('./llm-client'); // 前一笔记中的LLM客户端
const PromptManager = require('./prompt-manager'); // 前一笔记中的提示管理器
class AgentCore extends EventEmitter {
constructor(config = {}) {
super();
this.config = {
llmProvider: config.llmProvider || 'claude',
apiKey: config.apiKey,
systemPrompt: config.systemPrompt || 'You are a helpful AI assistant.',
maxIterations: config.maxIterations || 10,
...config
};
this.llmClient = null;
this.promptManager = new PromptManager();
this.memory = {
shortTerm: [], // 当前会话记忆
workingMemory: {}, // 工作记忆(变量、状态等)
longTerm: [] // 长期记忆(可选,用于跨会话)
};
this.tools = {}; // 可用工具映射
this.state = 'idle'; // 代理状态:idle, thinking, executing, waiting
}
// 初始化代理系统
async initialize() {
try {
// 初始化提示管理器
await this.promptManager.initialize();
// 初始化LLM客户端
if (!this.config.apiKey) {
throw new Error('API key is required');
}
this.llmClient = new LLMClient({
apiKey: this.config.apiKey,
model: this.config.model,
baseURL: this.config.baseURL
});
// 加载默认工具
await this._registerDefaultTools();
this.emit('initialized');
return true;
} catch (error) {
this.emit('error', error);
throw error;
}
}
// 注册默认工具
async _registerDefaultTools() {
// 这里可以注册默认工具
// 例如文件操作、命令执行等
const defaultTools = [
{
name: 'search_web',
description: '搜索互联网获取信息',
handler: async (query) => {
// 简化的web搜索实现
return { results: [`模拟搜索结果: ${query}`] };
}
},
{
name: 'execute_command',
description: '执行shell命令',
handler: async (command) => {
// 在实际实现中,这里应该有安全检查
// 简化的命令执行实现
return { output: `模拟命令执行: ${command}` };
}
}
];
defaultTools.forEach(tool => {
this.registerTool(tool.name, tool.description, tool.handler);
});
}
// 注册工具
registerTool(name, description, handler) {
if (this.tools[name]) {
throw new Error(`Tool ${name} already exists`);
}
this.tools[name] = {
name,
description,
handler
};
this.emit('tool_registered', name);
return this;
}
// 获取工具信息
getTools() {
return Object.values(this.tools).map(tool => ({
name: tool.name,
description: tool.description
}));
}
// 处理用户输入
async processInput(userInput, options = {}) {
try {
this.state = 'thinking';
this.emit('state_change', this.state);
// 记录用户输入到短期记忆
this._addToMemory('user', userInput);
// 构建系统提示
const systemPrompt = this._buildSystemPrompt();
// 准备提示上下文
const context = this._prepareContext();
// 使用提示管理器增强用户输入
const enhancedInput = this.promptManager.enhanceUserPrompt(userInput, context);
// 调用LLM获取响应
const response = await this.llmClient.complete(enhancedInput, systemPrompt, options);
// 解析响应
const parsedResponse = this._parseResponse(response);
// 记录助手响应到短期记忆
this._addToMemory('assistant', parsedResponse.content);
// 处理工具调用
if (parsedResponse.toolCalls && parsedResponse.toolCalls.length > 0) {
this.state = 'executing';
this.emit('state_change', this.state);
// 执行工具调用
const toolResults = await this._executeToolCalls(parsedResponse.toolCalls);
// 记录工具调用结果到短期记忆
toolResults.forEach(result => {
this._addToMemory('tool_result', result);
});
// 如果需要继续对话,递归处理
if (parsedResponse.needsFollowUp && this.memory.shortTerm.length < this.config.maxIterations * 2) {
return this.processInput(`请处理以下工具调用结果并继续任务: ${JSON.stringify(toolResults)}`, options);
}
}
this.state = 'idle';
this.emit('state_change', this.state);
return parsedResponse;
} catch (error) {
this.state = 'error';
this.emit('error', error);
throw error;
}
}
// 构建系统提示
_buildSystemPrompt() {
// 获取所有工具的描述
const tools = this.getTools();
// 使用提示管理器生成系统提示
return this.promptManager.generateSystemPrompt(null, tools, {
AGENT_CAPABILITIES: "You can search the web, execute commands, and more."
});
}
// 准备上下文
_prepareContext() {
return {
memory: this.memory.shortTerm.slice(-10), // 最近10条记忆
workingMemory: this.memory.workingMemory,
tools: Object.keys(this.tools)
};
}
// 解析LLM响应
_parseResponse(response) {
// 简化的响应解析
// 在实际实现中,需要根据具体LLM API响应格式进行解析
const content = response.content?.[0]?.text || '';
// 简单的工具调用解析
const toolCallRegex = /\[\[TOOL:(\w+)\]\[(.*?)\]\]/g;
const toolCalls = [];
let match;
while ((match = toolCallRegex.exec(content)) !== null) {
toolCalls.push({
tool: match[1],
args: JSON.parse(match[2])
});
}
return {
content: content.replace(toolCallRegex, '').trim(),
toolCalls,
needsFollowUp: toolCalls.length > 0
};
}
// 执行工具调用
async _executeToolCalls(toolCalls) {
const results = [];
for (const call of toolCalls) {
const tool = this.tools[call.tool];
if (!tool) {
results.push({
tool: call.tool,
status: 'error',
error: `Tool not found: ${call.tool}`
});
continue;
}
try {
const result = await tool.handler(call.args);
results.push({
tool: call.tool,
status: 'success',
result
});
} catch (error) {
results.push({
tool: call.tool,
status: 'error',
error: error.message
});
}
}
return results;
}
// 添加到记忆
_addToMemory(role, content) {
this.memory.shortTerm.push({
role,
content,
timestamp: Date.now()
});
this.emit('memory_updated', role, content);
}
// 设置工作记忆
setWorkingMemory(key, value) {
this.memory.workingMemory[key] = value;
this.emit('working_memory_updated', key, value);
}
// 获取工作记忆
getWorkingMemory(key) {
return this.memory.workingMemory[key];
}
// 清除短期记忆
clearShortTermMemory() {
this.memory.shortTerm = [];
this.emit('memory_cleared', 'shortTerm');
}
// 保存代理状态
async saveState(filePath) {
// 简化的状态保存
const state = {
memory: this.memory,
timestamp: Date.now()
};
// 在实际实现中,这里应该写入文件
return state;
}
// 加载代理状态
async loadState(filePath) {
// 简化的状态加载
// 在实际实现中,这里应该读取文件
// 假设已经加载了状态
this.emit('state_loaded');
}
}
module.exports = AgentCore;
4.2 实现工具管理系统
// tool-manager.js
const EventEmitter = require('events');
const fs = require('fs').promises;
const path = require('path');
class ToolManager extends EventEmitter {
constructor(config = {}) {
super();
this.toolsDir = config.toolsDir || path.join(process.cwd(), 'tools');
this.tools = {};
this.toolSchemas = {}; // 用于存储工具的JSON Schema
this.toolCategories = {
'file': [],
'command': [],
'web': [],
'code': [],
'other': []
};
}
// 初始化工具管理器
async initialize() {
try {
// 创建工具目录(如果不存在)
await fs.mkdir(this.toolsDir, { recursive: true });
// 尝试加载工具
const files = await fs.readdir(this.toolsDir);
for (const file of files) {
if (file.endsWith('.js') || file.endsWith('.json')) {
try {
await this.loadToolFromFile(path.join(this.toolsDir, file));
} catch (error) {
console.warn(`Failed to load tool from ${file}:`, error.message);
}
}
}
console.log(`Loaded ${Object.keys(this.tools).length} tools`);
} catch (error) {
console.warn('Error initializing tool manager:', error.message);
}
}
// 从文件加载工具
async loadToolFromFile(filePath) {
try {
let tool;
if (filePath.endsWith('.js')) {
// 加载JavaScript工具模块
const toolModule = require(filePath);
tool = toolModule.tool || toolModule.default || toolModule;
} else if (filePath.endsWith('.json')) {
// 加载JSON工具定义
const content = await fs.readFile(filePath, 'utf8');
const toolDef = JSON.parse(content);
if (!toolDef.name || !toolDef.handler) {
throw new Error('Invalid tool definition: missing name or handler');
}
// 创建动态处理函数
const handlerFn = new Function('args', `return ${toolDef.handler}`);
tool = {
name: toolDef.name,
description: toolDef.description || '',
category: toolDef.category || 'other',
handler: async (args) => handlerFn(args),
schema: toolDef.schema || {}
};
}
if (tool && tool.name) {
this.registerTool(tool);
}
} catch (error) {
throw new Error(`Failed to load tool from ${filePath}: ${error.message}`);
}
}
// 注册工具
registerTool(tool) {
if (!tool.name || typeof tool.handler !== 'function') {
throw new Error('Invalid tool: must have name and handler function');
}
if (this.tools[tool.name]) {
throw new Error(`Tool ${tool.name} already exists`);
}
this.tools[tool.name] = tool;
// 存储工具schema
if (tool.schema) {
this.toolSchemas[tool.name] = tool.schema;
}
// 分类工具
const category = tool.category || 'other';
if (this.toolCategories[category]) {
this.toolCategories[category].push(tool.name);
} else {
this.toolCategories[category] = [tool.name];
}
this.emit('tool_registered', tool.name);
return this;
}
// 执行工具
async executeTool(name, args = {}) {
const tool = this.tools[name];
if (!tool) {
throw new Error(`Tool not found: ${name}`);
}
try {
this.emit('tool_execution_start', name, args);
const result = await tool.handler(args);
this.emit('tool_execution_complete', name, args, result);
return result;
} catch (error) {
this.emit('tool_execution_error', name, args, error);
throw error;
}
}
// 获取工具列表
getTools(category = null) {
if (category && this.toolCategories[category]) {
return this.toolCategories[category].map(name => ({
name,
description: this.tools[name].description,
category
}));
}
return Object.values(this.tools).map(tool => ({
name: tool.name,
description: tool.description,
category: tool.category || 'other'
}));
}
// 获取工具描述
getToolDescription(name) {
const tool = this.tools[name];
return tool ? {
name: tool.name,
description: tool.description,
category: tool.category || 'other',
schema: tool.schema
} : null;
}
// 获取所有工具的JSON Schemas
getToolSchemas() {
return this.toolSchemas;
}
// 创建并保存新工具
async createTool(toolDef) {
if (!toolDef.name || !toolDef.handler) {
throw new Error('Invalid tool definition: missing name or handler');
}
// 生成工具文件名
const fileName = `${toolDef.name.toLowerCase().replace(/\s+/g, '_')}.json`;
const filePath = path.join(this.toolsDir, fileName);
// 保存工具定义
await fs.writeFile(
filePath,
JSON.stringify(toolDef, null, 2),
'utf8'
);
// 加载工具
await this.loadToolFromFile(filePath);
return toolDef.name;
}
}
module.exports = ToolManager;
4.3 实现代理执行引擎
// agent-executor.js
const EventEmitter = require('events');
const AgentCore = require('./agent-core');
const ToolManager = require('./tool-manager');
class AgentExecutor extends EventEmitter {
constructor(config = {}) {
super();
this.config = config;
this.agentCore = new AgentCore(config);
this.toolManager = new ToolManager(config);
this.isRunning = false;
this.taskQueue = []; // 任务队列
this.currentTask = null; // 当前正在执行的任务
}
// 初始化执行引擎
async initialize() {
try {
// 初始化工具管理器
await this.toolManager.initialize();
// 将工具管理器中的工具注册到代理核心
const tools = this.toolManager.getTools();
for (const tool of tools) {
this.agentCore.registerTool(tool.name, tool.description,
async (args) => this.toolManager.executeTool(tool.name, args)
);
}
// 初始化代理核心
await this.agentCore.initialize();
// 连接事件处理
this._connectEvents();
this.emit('initialized');
return true;
} catch (error) {
this.emit('error', error);
throw error;
}
}
// 连接事件处理
_connectEvents() {
// 监听代理核心事件
this.agentCore.on('error', (error) => {
this.emit('error', error);
});
this.agentCore.on('state_change', (state) => {
this.emit('state_change', state);
});
// 监听工具管理器事件
this.toolManager.on('tool_execution_start', (name, args) => {
this.emit('tool_execution_start', name, args);
});
this.toolManager.on('tool_execution_complete', (name, args, result) => {
this.emit('tool_execution_complete', name, args, result);
});
this.toolManager.on('tool_execution_error', (name, args, error) => {
this.emit('tool_execution_error', name, args, error);
});
}
// 添加任务到队列
addTask(task) {
if (!task.input) {
throw new Error('Task must have input');
}
const taskWithId = {
id: `task_${Date.now()}_${Math.floor(Math.random() * 1000)}`,
input: task.input,
options: task.options || {},
status: 'queued',
createdAt: Date.now(),
...task
};
this.taskQueue.push(taskWithId);
this.emit('task_queued', taskWithId);
// 如果没有正在执行的任务,启动执行
if (!this.isRunning) {
this._processNextTask();
}
return taskWithId.id;
}
// 处理下一个任务
async _processNextTask() {
if (this.taskQueue.length === 0) {
this.isRunning = false;
this.emit('queue_empty');
return;
}
this.isRunning = true;
this.currentTask = this.taskQueue.shift();
this.currentTask.status = 'running';
this.currentTask.startedAt = Date.now();
this.emit('task_started', this.currentTask);
try {
// 执行任务
const result = await this.agentCore.processInput(
this.currentTask.input,
this.currentTask.options
);
this.currentTask.status = 'completed';
this.currentTask.completedAt = Date.now();
this.currentTask.result = result;
this.emit('task_completed', this.currentTask);
} catch (error) {
this.currentTask.status = 'failed';
this.currentTask.error = error.message;
this.currentTask.completedAt = Date.now();
this.emit('task_failed', this.currentTask, error);
}
// 处理下一个任务
this._processNextTask();
}
// 执行单个任务
async executeTask(task) {
const taskId = this.addTask(task);
return new Promise((resolve, reject) => {
const onCompleted = (completedTask) => {
if (completedTask.id === taskId) {
this.removeListener('task_completed', onCompleted);
this.removeListener('task_failed', onFailed);
resolve(completedTask.result);
}
};
const onFailed = (failedTask, error) => {
if (failedTask.id === taskId) {
this.removeListener('task_completed', onCompleted);
this.removeListener('task_failed', onFailed);
reject(error);
}
};
this.on('task_completed', onCompleted);
this.on('task_failed', onFailed);
});
}
// 取消任务
cancelTask(taskId) {
// 从队列中移除任务
const index = this.taskQueue.findIndex(task => task.id === taskId);
if (index !== -1) {
const canceledTask = this.taskQueue.splice(index, 1)[0];
canceledTask.status = 'canceled';
this.emit('task_canceled', canceledTask);
return true;
}
// 如果是当前任务,无法取消(简化版)
if (this.currentTask && this.currentTask.id === taskId) {
return false;
}
return false;
}
// 获取当前状态
getStatus() {
return {
isRunning: this.isRunning,
queueLength: this.taskQueue.length,
currentTask: this.currentTask
};
}
// 清空任务队列
clearTaskQueue() {
const canceledTasks = [...this.taskQueue];
this.taskQueue = [];
canceledTasks.forEach(task => {
task.status = 'canceled';
this.emit('task_canceled', task);
});
return canceledTasks.length;
}
}
module.exports = AgentExecutor;
4.4 创建简单的代理应用框架
// agent-app.js
const express = require('express');
const bodyParser = require('body-parser');
const AgentExecutor = require('./agent-executor');
class AgentApp {
constructor(config = {}) {
this.config = {
port: config.port || 3000,
apiKey: config.apiKey,
llmProvider: config.llmProvider || 'claude',
...config
};
this.app = express();
this.agentExecutor = new AgentExecutor({
apiKey: this.config.apiKey,
llmProvider: this.config.llmProvider
});
}
// 初始化应用
async initialize() {
// 配置Express
this.app.use(bodyParser.json());
// 初始化代理执行器
await this.agentExecutor.initialize();
// 设置路由
this._setupRoutes();
return this;
}
// 设置API路由
_setupRoutes() {
// 健康检查
this.app.get('/health', (req, res) => {
res.json({ status: 'ok' });
});
// 获取工具列表
this.app.get('/api/tools', (req, res) => {
const tools = this.agentExecutor.toolManager.getTools(req.query.category);
res.json({ tools });
});
// 执行任务
this.app.post('/api/tasks', async (req, res) => {
try {
const { input, options } = req.body;
if (!input) {
return res.status(400).json({ error: 'Input is required' });
}
const taskId = this.agentExecutor.addTask({ input, options });
res.status(202).json({ taskId });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// 获取任务状态
this.app.get('/api/tasks/:taskId', (req, res) => {
// 简化版:实际实现需要任务存储
const { currentTask } = this.agentExecutor.getStatus();
if (currentTask && currentTask.id === req.params.taskId) {
res.json(currentTask);
} else {
res.status(404).json({ error: 'Task not found' });
}
});
// 取消任务
this.app.delete('/api/tasks/:taskId', (req, res) => {
const success = this.agentExecutor.cancelTask(req.params.taskId);
if (success) {
res.status(204).send();
} else {
res.status(404).json({ error: 'Task not found or cannot be canceled' });
}
});
// 对话接口
this.app.post('/api/chat', async (req, res) => {
try {
const { message, options } = req.body;
if (!message) {
return res.status(400).json({ error: 'Message is required' });
}
const response = await this.agentExecutor.executeTask({
input: message,
options
});
res.json(response);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
}
// 启动应用
async start() {
return new Promise((resolve) => {
this.server = this.app.listen(this.config.port, () => {
console.log(`Agent app running on port ${this.config.port}`);
resolve(this.server);
});
});
}
// 停止应用
async stop() {
if (this.server) {
return new Promise((resolve) => {
this.server.close(() => {
console.log('Agent app stopped');
resolve();
});
});
}
}
}
module.exports = AgentApp;
4.5 使用示例
// index.js
require('dotenv').config(); // 加载环境变量
const AgentApp = require('./agent-app');
async function main() {
try {
const agentApp = new AgentApp({
port: process.env.PORT || 3000,
apiKey: process.env.API_KEY,
llmProvider: process.env.LLM_PROVIDER || 'claude'
});
await agentApp.initialize();
await agentApp.start();
console.log('Agent app started successfully');
} catch (error) {
console.error('Failed to start agent app:', error);
process.exit(1);
}
}
main();
五、总结与思考
-
AI代理架构的关键组成:
- 决策引擎(LLM)是核心智能来源
- 工具系统扩展代理能力边界
- 记忆系统维持连贯性和上下文
- 执行引擎协调各组件工作
- 安全层确保操作在可控范围内
-
OpenHands的架构特点:
- 容器化隔离执行环境
- 强大的工具集成能力
- 灵活的部署模式(云端/本地)
- 多模态交互界面
- 安全性与功能性平衡
-
代理系统设计考量:
- 如何平衡自主性与控制
- 如何处理复杂任务分解
- 如何维护长期上下文
- 如何确保执行安全
- 如何优化性能和资源使用
六、下一步学习方向
- 探索更复杂的工具集成机制
- 研究多代理协作系统
- 实现更高级的记忆和规划机制
- 开发更完善的安全防护措施
- 优化资源使用和性能表现