AI自主Agent与Manus完全教程
适用读者:AI开发者、产品经理、技术架构师、对AI Agent感兴趣的工程师 预计阅读时间:30-35分钟 最后更新:2026年6月
目录
- 自主Agent概述与发展历程
- Agent核心架构:感知-规划-执行-反思
- ReAct与Plan-and-Execute模式
- 工具使用与API编排
- 长期记忆与知识管理
- 多Agent系统协作
- Manus Agent架构解析
- Computer Use与浏览器自动化
- 自主Agent安全与对齐
- 开源Agent框架对比
- 企业级Agent部署方案
1. 自主Agent概述与发展历程
1.1 什么是自主Agent
自主Agent(Autonomous Agent)是指能够独立感知环境、制定计划、执行行动并从结果中学习的AI系统。与传统的"问答式"AI不同,自主Agent具备以下核心特征:
- 自主性(Autonomy):不需要人类逐步指令,能够自主决定下一步行动
- 目标驱动(Goal-directed):围绕高层目标工作,能将复杂目标分解为可执行的子任务
- 环境交互(Environment interaction):能够使用工具、调用API、操作文件系统等
- 适应性(Adaptability):根据执行结果调整策略,从错误中恢复
- 持续性(Persistence):能够在较长时间内维持工作状态,处理多步骤任务
1.2 发展历程
2023年3月 - AutoGPT引爆Agent热潮
AutoGPT的发布让公众首次看到"AI自主完成任务"的可能性。虽然实际效果有限,但它开创了LLM作为Agent核心控制器的范式。
2023年下半年 - 框架百花齐放
LangChain Agents、BabyAGI、MetaGPT等框架相继出现。研究者开始探索不同的Agent架构:单Agent、多Agent、层级Agent等。
2024年 - 工具使用能力成熟
Claude的Computer Use、GPT-4的Function Calling等能力使Agent真正能够"操作"外部世界。MCP(Model Context Protocol)等标准协议的出现,使Agent的工具生态开始标准化。
2025年 - Manus与企业级Agent
Manus Agent的发布标志着Agent从"Demo级"走向"生产级"。它展示了Agent在复杂真实任务中的可靠性:自主浏览网页、操作软件、处理文档、编写代码。
2026年(当前) - Agent基础设施成熟
Agent的基础设施逐步完善:标准化的工具协议、可靠的记忆系统、成熟的监控和审计框架。企业开始大规模部署Agent处理业务流程。
1.3 Agent与传统AI的区别
| 维度 | 传统AI助手 | 自主Agent |
|---|---|---|
| 交互模式 | 一问一答 | 自主执行多步任务 |
| 工具使用 | 有限或无 | 广泛的工具调用能力 |
| 上下文 | 单轮或短期 | 长期记忆和状态管理 |
| 错误处理 | 返回错误信息 | 自主诊断和恢复 |
| 任务复杂度 | 单步任务 | 复杂多步骤工作流 |
| 人类参与 | 每步都需要 | 仅在关键决策点介入 |
2. Agent核心架构:感知-规划-执行-反思
2.1 四阶段循环
几乎所有Agent系统都遵循一个核心循环:感知(Perceive)→ 规划(Plan)→ 执行(Act)→ 反思(Reflect)。
┌─────────────────────────────────────────────┐
│ 目标(Goal) │
│ ↓ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 感知 │ → │ 规划 │ → │ 执行 │ │
│ │ Perceive │ │ Plan │ │ Act │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ ↑ ↓ │
│ └────────── 反思 Reflect ────┘ │
│ ↓ │
│ 更新记忆与状态 │
└─────────────────────────────────────────────┘
2.2 感知(Perceive)
感知阶段是Agent收集环境信息的过程。Agent需要理解:
- 当前状态:我在哪里?当前任务的进展如何?
- 可用资源:我有哪些工具?可以访问哪些数据?
- 约束条件:时间限制、权限限制、格式要求等
class PerceptionModule:
"""Agent的感知模块"""
def __init__(self):
self.observations = []
self.tools = []
self.constraints = {}
def observe(self, environment: dict) -> dict:
"""从环境中收集信息"""
observation = {
'timestamp': time.time(),
'environment_state': environment.get('state'),
'available_actions': environment.get('actions', []),
'recent_results': environment.get('results', []),
}
self.observations.append(observation)
return observation
def get_context(self, max_history: int = 10) -> str:
"""将感知历史组装为上下文"""
recent = self.observations[-max_history:]
context_parts = []
for obs in recent:
context_parts.append(
f"[{obs['timestamp']}] 状态: {obs['environment_state']}\n"
f"可用操作: {obs['available_actions']}\n"
f"最近结果: {obs['recent_results']}"
)
return "\n---\n".join(context_parts)
2.3 规划(Plan)
规划阶段是Agent的核心推理过程。Agent需要:
- 目标分解:将高层目标拆解为可执行的子任务
- 策略选择:确定完成每个子任务的方法
- 资源分配:决定使用哪些工具和API
- 风险评估:预判可能的失败点和应对方案
from dataclasses import dataclass, field
from enum import Enum
class TaskStatus(Enum):
PENDING = "pending"
IN_PROGRESS = "in_progress"
COMPLETED = "completed"
FAILED = "failed"
@dataclass
class SubTask:
id: str
description: str
dependencies: list[str] = field(default_factory=list)
status: TaskStatus = TaskStatus.PENDING
result: any = None
retry_count: int = 0
max_retries: int = 3
class PlanningModule:
"""Agent的规划模块"""
def __init__(self, llm):
self.llm = llm
self.plan: list[SubTask] = []
async def create_plan(self, goal: str, context: str) -> list[SubTask]:
"""基于目标和上下文创建执行计划"""
prompt = f"""你是一个任务规划专家。根据以下目标和上下文,创建一个详细的执行计划。
目标:{goal}
当前上下文:
{context}
要求:
1. 将目标分解为可执行的子任务
2. 标明子任务之间的依赖关系
3. 为每个子任务指定预期使用的工具
4. 考虑可能的失败点
输出JSON格式的计划。"""
response = await self.llm.generate(prompt)
self.plan = self._parse_plan(response)
return self.plan
def get_next_task(self) -> SubTask | None:
"""获取下一个可执行的任务(依赖已满足)"""
for task in self.plan:
if task.status != TaskStatus.PENDING:
continue
# 检查依赖是否都已完成
deps_met = all(
self._get_task(dep_id).status == TaskStatus.COMPLETED
for dep_id in task.dependencies
)
if deps_met:
return task
return None
def update_task_status(self, task_id: str, status: TaskStatus, result=None):
"""更新任务状态"""
task = self._get_task(task_id)
if task:
task.status = status
task.result = result
2.4 执行(Act)
执行阶段是Agent实际操作环境的过程。关键设计原则:
class ExecutionModule:
"""Agent的执行模块"""
def __init__(self, tools: dict):
self.tools = tools # {"tool_name": tool_instance}
self.execution_log = []
async def execute_task(self, task: SubTask, plan_context: dict) -> dict:
"""执行单个子任务"""
# 1. 选择工具
tool_name = self._select_tool(task, plan_context)
tool = self.tools.get(tool_name)
if not tool:
return {'success': False, 'error': f'工具 {tool_name} 不可用'}
# 2. 准备参数
params = self._prepare_params(task, plan_context)
# 3. 执行(带超时和重试)
for attempt in range(task.max_retries):
try:
result = await asyncio.wait_for(
tool.execute(**params),
timeout=60
)
# 4. 验证结果
if self._validate_result(result, task):
self.execution_log.append({
'task_id': task.id,
'tool': tool_name,
'success': True,
'attempt': attempt + 1,
})
return {'success': True, 'result': result}
else:
self.execution_log.append({
'task_id': task.id,
'tool': tool_name,
'success': False,
'reason': '结果验证失败',
'attempt': attempt + 1,
})
except asyncio.TimeoutError:
self.execution_log.append({
'task_id': task.id,
'tool': tool_name,
'success': False,
'reason': '执行超时',
'attempt': attempt + 1,
})
except Exception as e:
self.execution_log.append({
'task_id': task.id,
'tool': tool_name,
'success': False,
'reason': str(e),
'attempt': attempt + 1,
})
return {'success': False, 'error': '所有重试均失败'}
def _select_tool(self, task: SubTask, context: dict) -> str:
"""根据任务描述选择最合适的工具"""
# 简化实现:基于关键词匹配
for tool_name, tool in self.tools.items():
if tool.can_handle(task.description):
return tool_name
return list(self.tools.keys())[0] if self.tools else None
2.5 反思(Reflect)
反思是Agent从执行结果中学习的关键环节:
class ReflectionModule:
"""Agent的反思模块"""
def __init__(self, llm, memory):
self.llm = llm
self.memory = memory
async def reflect_on_result(
self,
task: SubTask,
result: dict,
plan_context: dict
) -> dict:
"""对执行结果进行反思"""
prompt = f"""分析以下任务执行结果,提供反思和改进建议。
任务:{task.description}
执行结果:{result}
计划上下文:{plan_context}
请分析:
1. 任务是否成功完成?为什么?
2. 如果失败,根本原因是什么?
3. 有什么改进建议?
4. 是否需要调整后续计划?
输出JSON格式的反思结果。"""
reflection = await self.llm.generate(prompt)
parsed = self._parse_reflection(reflection)
# 将反思结果存入记忆
await self.memory.store_reflection(
task_id=task.id,
reflection=parsed,
timestamp=time.time()
)
return parsed
async def adjust_plan(
self,
plan: list[SubTask],
reflection: dict
) -> list[SubTask]:
"""根据反思结果调整计划"""
if reflection.get('needs_plan_adjustment'):
# 使用LLM重新规划
prompt = f"""根据以下反思结果,调整执行计划。
当前计划:{[t.__dict__ for t in plan]}
反思结果:{reflection}
请输出调整后的计划。"""
adjusted = await self.llm.generate(prompt)
return self._parse_plan(adjusted)
return plan
3. ReAct与Plan-and-Execute模式
3.1 ReAct模式
ReAct(Reasoning + Acting)是最基础的Agent模式,由Yao等人在2022年提出。核心思想是让LLM交替进行推理和行动。
循环:
Thought: 我需要查找用户的信息...
Action: search_users(query="张三")
Observation: 找到3个匹配结果...
Thought: 第一个结果看起来最匹配...
Action: get_user_details(user_id="u001")
Observation: 用户信息: {name: "张三", ...}
Thought: 现在我有了用户信息,可以完成任务了
Action: send_notification(user_id="u001", message="...")
实现示例:
class ReActAgent:
"""基于ReAct模式的Agent"""
def __init__(self, llm, tools: list, max_steps: int = 15):
self.llm = llm
self.tools = {tool.name: tool for tool in tools}
self.max_steps = max_steps
async def run(self, task: str) -> str:
"""执行任务"""
# 初始化上下文
context = f"任务: {task}\n\n"
for step in range(self.max_steps):
# 1. 让LLM决定下一步(Thought + Action)
prompt = f"""{context}
可用工具: {list(self.tools.keys())}
请按以下格式思考和行动:
Thought: [你的推理过程]
Action: [工具名称]([参数])
如果任务已完成,请使用:
Thought: [总结]
Answer: [最终答案]"""
response = await self.llm.generate(prompt)
# 2. 解析响应
thought, action = self._parse_response(response)
context += f"Step {step + 1}:\n{response}\n\n"
# 3. 检查是否完成
if action and action.get('type') == 'answer':
return action['content']
# 4. 执行行动
if action:
tool = self.tools.get(action['tool'])
if tool:
result = await tool.execute(**action['params'])
context += f"Observation: {result}\n\n"
else:
context += f"Observation: 错误 - 工具 {action['tool']} 不存在\n\n"
return "达到最大步数限制,任务未完成"
3.2 Plan-and-Execute模式
Plan-and-Execute模式将"规划"和"执行"分离为两个独立阶段。先制定完整计划,再逐步执行。
class PlanAndExecuteAgent:
"""基于Plan-and-Execute模式的Agent"""
def __init__(self, planner_llm, executor_llm, tools: list):
self.planner = planner_llm
self.executor = executor_llm
self.tools = {tool.name: tool for tool in tools}
async def run(self, task: str) -> str:
"""执行任务"""
# 阶段1:规划
plan = await self._create_plan(task)
# 阶段2:逐步执行
results = {}
for i, step in enumerate(plan['steps']):
# 使用执行器LLM完成每个步骤
step_result = await self._execute_step(
step,
task,
results
)
results[step['id']] = step_result
# 检查是否需要重新规划
if step_result.get('needs_replan'):
remaining_steps = plan['steps'][i+1:]
new_plan = await self._replan(task, results, remaining_steps)
plan['steps'] = plan['steps'][:i+1] + new_plan['steps']
# 阶段3:总结
return await self._summarize(task, results)
async def _create_plan(self, task: str) -> dict:
"""创建执行计划"""
prompt = f"""你是一个任务规划专家。为以下任务创建一个详细的执行计划。
任务:{task}
可用工具:{list(self.tools.keys())}
要求:
1. 将任务分解为3-8个具体步骤
2. 每个步骤应该是一个可独立执行的原子操作
3. 标明每个步骤需要使用的工具
4. 考虑步骤之间的依赖关系
输出JSON格式:
{{
"steps": [
{{"id": "step_1", "description": "...", "tool": "...", "depends_on": []}},
...
]
}}"""
response = await self.planner.generate(prompt)
return json.loads(response)
async def _execute_step(self, step: dict, task: str, previous_results: dict) -> dict:
"""执行单个步骤"""
prompt = f"""执行以下步骤:
总任务:{task}
当前步骤:{step['description']}
使用工具:{step.get('tool', '无')}
之前步骤的结果:{previous_results}
请决定具体的执行方式并调用工具。"""
response = await self.executor.generate(prompt)
# 解析并执行工具调用
tool_call = self._parse_tool_call(response)
if tool_call:
tool = self.tools.get(tool_call['tool'])
if tool:
result = await tool.execute(**tool_call['params'])
return {'success': True, 'result': result}
return {'success': False, 'error': '无法解析工具调用'}
3.3 两种模式的适用场景
| 维度 | ReAct | Plan-and-Execute |
|---|---|---|
| 适用场景 | 简单任务、探索性任务 | 复杂任务、有明确流程的任务 |
| 灵活性 | 高(每步可调整) | 中(计划可调整但较重) |
| 效率 | 中等(推理开销大) | 高(规划后执行快) |
| 可靠性 | 较低(可能偏离目标) | 较高(有明确计划) |
| Token消耗 | 高(每步都需推理) | 中(规划一次,执行多次) |
4. 工具使用与API编排
4.1 工具抽象层
Agent的工具使用能力是其与环境交互的基础。设计良好的工具抽象层至关重要:
from abc import ABC, abstractmethod
from typing import Any
from pydantic import BaseModel, Field
class ToolParameter(BaseModel):
name: str
type: str
description: str
required: bool = True
default: Any = None
class ToolDefinition(BaseModel):
name: str
description: str
parameters: list[ToolParameter]
return_type: str
examples: list[dict] = Field(default_factory=list)
class BaseTool(ABC):
"""工具基类"""
@abstractmethod
def definition(self) -> ToolDefinition:
"""返回工具定义,用于LLM理解工具能力"""
pass
@abstractmethod
async def execute(self, **kwargs) -> Any:
"""执行工具"""
pass
def can_handle(self, task_description: str) -> bool:
"""判断该工具是否能处理给定任务"""
# 默认基于描述关键词匹配
defn = self.definition()
return any(
keyword in task_description.lower()
for keyword in defn.name.lower().split('_')
)
# 实现一个具体的工具
class WebSearchTool(BaseTool):
"""网页搜索工具"""
def __init__(self, api_key: str):
self.api_key = api_key
def definition(self) -> ToolDefinition:
return ToolDefinition(
name="web_search",
description="在互联网上搜索信息,返回相关网页的标题、URL和摘要",
parameters=[
ToolParameter(
name="query",
type="string",
description="搜索查询词"
),
ToolParameter(
name="max_results",
type="integer",
description="最大返回结果数",
required=False,
default=5
),
],
return_type="list[dict]",
examples=[
{"query": "Python异步编程最佳实践", "max_results": 3}
]
)
async def execute(self, query: str, max_results: int = 5) -> list[dict]:
# 实际实现会调用搜索API
# 这里是示例结构
results = []
# ... 调用搜索API ...
return results
4.2 工具编排
复杂的任务往往需要多个工具协同工作。工具编排引擎负责管理工具之间的调用关系:
class ToolOrchestrator:
"""工具编排引擎"""
def __init__(self, tools: dict[str, BaseTool]):
self.tools = tools
self.call_stack = []
self.max_depth = 5 # 防止递归调用
async def orchestrate(
self,
task: str,
llm,
context: dict = None
) -> dict:
"""编排工具调用完成任务"""
context = context or {}
results = []
for step in range(10): # 最多10步
# 让LLM决定下一步
available_tools_desc = "\n".join([
f"- {name}: {tool.definition().description}"
for name, tool in self.tools.items()
])
prompt = f"""任务: {task}
可用工具:
{available_tools_desc}
之前的执行结果: {results}
当前上下文: {context}
请决定下一步操作。如果任务已完成,输出 DONE。
否则输出要调用的工具和参数(JSON格式)。"""
decision = await llm.generate(prompt)
if "DONE" in decision:
break
# 解析并执行工具调用
tool_call = self._parse_decision(decision)
if tool_call and tool_call['tool'] in self.tools:
tool = self.tools[tool_call['tool']]
result = await tool.execute(**tool_call['params'])
results.append({
'step': step,
'tool': tool_call['tool'],
'params': tool_call['params'],
'result': result,
})
# 将结果添加到上下文
context[f'step_{step}_result'] = result
return {
'task': task,
'steps': results,
'final_result': results[-1]['result'] if results else None,
}
4.3 MCP协议
MCP(Model Context Protocol)是Anthropic推出的标准化协议,用于连接AI模型与外部工具。它定义了:
- 工具发现:模型可以动态发现可用工具
- 工具调用:标准化的调用和响应格式
- 上下文管理:工具可以向模型提供上下文信息
# MCP服务器示例
from mcp import Server, Tool
server = Server("my-tools")
@server.tool()
async def get_weather(city: str) -> dict:
"""获取指定城市的天气信息"""
# 调用天气API
weather_data = await fetch_weather_api(city)
return {
"city": city,
"temperature": weather_data["temp"],
"condition": weather_data["condition"],
"humidity": weather_data["humidity"],
}
@server.tool()
async def send_email(to: str, subject: str, body: str) -> dict:
"""发送电子邮件"""
# 调用邮件API
result = await send_email_api(to, subject, body)
return {"status": "sent", "message_id": result["id"]}
# 启动服务器
server.run()
5. 长期记忆与知识管理
5.1 记忆系统架构
Agent的记忆系统是其持续工作的基础。一个完整的记忆系统包含三个层次:
from datetime import datetime
from typing import Optional
import json
import hashlib
class MemorySystem:
"""Agent的三层记忆系统"""
def __init__(self, embedding_model=None):
# 第一层:工作记忆(短期)
self.working_memory = WorkingMemory(max_items=20)
# 第二层:情景记忆(中期)
self.episodic_memory = EpisodicMemory()
# 第三层:语义记忆(长期)
self.semantic_memory = SemanticMemory(embedding_model)
async def store(self, content: str, memory_type: str = "auto", metadata: dict = None):
"""存储记忆"""
if memory_type == "auto":
memory_type = self._classify_memory(content)
if memory_type == "working":
self.working_memory.add(content, metadata)
elif memory_type == "episodic":
await self.episodic_memory.store(content, metadata)
elif memory_type == "semantic":
await self.semantic_memory.store(content, metadata)
async def recall(self, query: str, top_k: int = 5) -> list[dict]:
"""根据查询回忆相关记忆"""
results = []
# 从工作记忆中查找
working_results = self.working_memory.search(query)
results.extend(working_results)
# 从情景记忆中查找
episodic_results = await self.episodic_memory.search(query, top_k)
results.extend(episodic_results)
# 从语义记忆中查找
semantic_results = await self.semantic_memory.search(query, top_k)
results.extend(semantic_results)
# 按相关性排序
results.sort(key=lambda x: x.get('relevance', 0), reverse=True)
return results[:top_k]
class WorkingMemory:
"""工作记忆 - 最近的上下文"""
def __init__(self, max_items: int = 20):
self.items = []
self.max_items = max_items
def add(self, content: str, metadata: dict = None):
self.items.append({
'content': content,
'metadata': metadata or {},
'timestamp': datetime.now().isoformat(),
})
# 超出容量时移除最旧的
if len(self.items) > self.max_items:
self.items.pop(0)
def search(self, query: str) -> list[dict]:
# 简单的关键词匹配
results = []
for item in self.items:
if query.lower() in item['content'].lower():
results.append({**item, 'relevance': 0.8})
return results
class EpisodicMemory:
"""情景记忆 - 具体的事件和经历"""
def __init__(self, storage_path: str = "memory/episodic.jsonl"):
self.storage_path = storage_path
self.index = {}
async def store(self, content: str, metadata: dict = None):
episode = {
'id': self._generate_id(content),
'content': content,
'metadata': metadata or {},
'timestamp': datetime.now().isoformat(),
}
# 追加到文件
with open(self.storage_path, 'a') as f:
f.write(json.dumps(episode, ensure_ascii=False) + '\n')
# 更新索引
self.index[episode['id']] = episode
async def search(self, query: str, top_k: int = 5) -> list[dict]:
# 实际实现应使用向量搜索
results = []
for ep in self.index.values():
if query.lower() in ep['content'].lower():
results.append({**ep, 'relevance': 0.7})
return results[:top_k]
class SemanticMemory:
"""语义记忆 - 抽象的知识和概念"""
def __init__(self, embedding_model=None):
self.embedding_model = embedding_model
self.knowledge_base = {} # 实际应使用向量数据库
async def store(self, content: str, metadata: dict = None):
if self.embedding_model:
embedding = await self.embedding_model.embed(content)
else:
embedding = None
knowledge = {
'content': content,
'embedding': embedding,
'metadata': metadata or {},
'timestamp': datetime.now().isoformat(),
}
key = hashlib.md5(content.encode()).hexdigest()
self.knowledge_base[key] = knowledge
async def search(self, query: str, top_k: int = 5) -> list[dict]:
# 实际实现应使用向量相似度搜索
results = []
for kb in self.knowledge_base.values():
if query.lower() in kb['content'].lower():
results.append({**kb, 'relevance': 0.6})
return results[:top_k]
5.2 记忆压缩与摘要
长时间运行的Agent会产生大量记忆。压缩和摘要是管理记忆的关键策略:
class MemoryCompressor:
"""记忆压缩器"""
def __init__(self, llm):
self.llm = llm
async def compress_episodes(self, episodes: list[dict]) -> dict:
"""将多个情景记忆压缩为一条摘要"""
content = "\n".join([ep['content'] for ep in episodes])
prompt = f"""请将以下经历总结为一条简洁的摘要,保留关键信息:
{content}
要求:
1. 保留重要的决策和结果
2. 去除冗余细节
3. 突出关键学习和经验
4. 长度不超过200字"""
summary = await self.llm.generate(prompt)
return {
'type': 'compressed_summary',
'content': summary,
'source_count': len(episodes),
'compressed_at': datetime.now().isoformat(),
}
async def extract_knowledge(self, episodes: list[dict]) -> list[dict]:
"""从情景记忆中提取可复用的知识"""
content = "\n".join([ep['content'] for ep in episodes])
prompt = f"""从以下经历中提取可复用的知识和经验:
{content}
输出格式:
- 知识点1:[具体内容]
- 知识点2:[具体内容]
..."""
knowledge_text = await self.llm.generate(prompt)
# 解析为知识条目
knowledge_items = self._parse_knowledge(knowledge_text)
return knowledge_items
6. 多Agent系统协作
6.1 多Agent架构模式
多Agent系统中,Agent之间的协作模式主要有三种:
模式1:层级式(Hierarchical)
┌─────────────┐
│ 主控Agent │
│ (Orchestrator)│
└──────┬──────┘
│
┌────────┼────────┐
↓ ↓ ↓
┌──────┐ ┌──────┐ ┌──────┐
│Agent A│ │Agent B│ │Agent C│
│(研究) │ │(编码) │ │(测试) │
└──────┘ └──────┘ └──────┘
模式2:平等式(Peer-to-Peer)
┌──────┐ ┌──────┐ ┌──────┐
│Agent A│ ←→ │Agent B│ ←→ │Agent C│
└──────┘ └──────┘ └──────┘
模式3:流水线式(Pipeline)
┌──────┐ ┌──────┐ ┌──────┐
│Agent A│ → │Agent B│ → │Agent C│
│(输入) │ │(处理) │ │(输出) │
└──────┘ └──────┘ └──────┘
6.2 实现一个多Agent系统
class MultiAgentSystem:
"""多Agent协作系统"""
def __init__(self):
self.agents: dict[str, Agent] = {}
self.message_queue = asyncio.Queue()
self.shared_memory = SharedMemory()
def register_agent(self, name: str, agent: Agent):
"""注册Agent"""
self.agents[name] = agent
agent.set_message_queue(self.message_queue)
agent.set_shared_memory(self.shared_memory)
async def run_task(self, task: str, coordinator: str) -> str:
"""使用多Agent协作完成任务"""
# 由协调者Agent分配任务
coordinator_agent = self.agents[coordinator]
plan = await coordinator_agent.create_plan(task)
results = {}
for step in plan['steps']:
assigned_agent = self.agents.get(step['agent'])
if assigned_agent:
result = await assigned_agent.execute(
step['task'],
context={
'shared_memory': self.shared_memory,
'previous_results': results,
}
)
results[step['id']] = result
# 更新共享记忆
await self.shared_memory.update(
key=f"step_{step['id']}_result",
value=result
)
# 协调者总结结果
return await coordinator_agent.summarize(task, results)
class Agent:
"""Agent基类"""
def __init__(self, name: str, llm, tools: list):
self.name = name
self.llm = llm
self.tools = {tool.name: tool for tool in tools}
self.message_queue = None
self.shared_memory = None
def set_message_queue(self, queue: asyncio.Queue):
self.message_queue = queue
def set_shared_memory(self, memory: SharedMemory):
self.shared_memory = memory
async def execute(self, task: str, context: dict = None) -> dict:
"""执行任务"""
prompt = f"""你是 {self.name} Agent。
任务:{task}
可用工具:{list(self.tools.keys())}
上下文:{context or '无'}
请完成任务。"""
response = await self.llm.generate(prompt)
# 解析并执行工具调用
return await self._process_response(response)
async def send_message(self, to: str, content: str):
"""向其他Agent发送消息"""
if self.message_queue:
await self.message_queue.put({
'from': self.name,
'to': to,
'content': content,
'timestamp': datetime.now().isoformat(),
})
6.3 Agent间通信协议
class AgentMessage(BaseModel):
"""Agent间通信消息"""
id: str
sender: str
receiver: str
content: str
message_type: str # "request", "response", "notification"
timestamp: datetime
metadata: dict = Field(default_factory=dict)
class CommunicationProtocol:
"""Agent通信协议"""
def __init__(self):
self.channels: dict[str, asyncio.Queue] = {}
self.message_history: list[AgentMessage] = []
def create_channel(self, agent_name: str):
"""为Agent创建通信频道"""
self.channels[agent_name] = asyncio.Queue()
async def send(self, message: AgentMessage):
"""发送消息"""
self.message_history.append(message)
if message.receiver in self.channels:
await self.channels[message.receiver].put(message)
async def receive(self, agent_name: str, timeout: float = 30) -> AgentMessage:
"""接收消息"""
if agent_name in self.channels:
try:
return await asyncio.wait_for(
self.channels[agent_name].get(),
timeout=timeout
)
except asyncio.TimeoutError:
return None
return None
7. Manus Agent架构解析
7.1 Manus概述
Manus是一个通用型AI Agent,能够自主完成复杂的现实世界任务。它的核心设计理念是:让AI像人类一样使用计算机——通过操作浏览器、文件系统、终端等工具来完成任务。
7.2 核心架构
Manus的架构可以分为四个核心层:
┌─────────────────────────────────────────────┐
│ 用户接口层 │
│ (自然语言输入 / 任务描述 / 目标定义) │
├─────────────────────────────────────────────┤
│ 规划引擎层 │
│ (目标分解 / 步骤规划 / 策略选择 / 反思调整) │
├─────────────────────────────────────────────┤
│ 执行引擎层 │
│ (工具调用 / 浏览器操作 / 代码执行 / 文件IO) │
├─────────────────────────────────────────────┤
│ 基础设施层 │
│ (沙箱环境 / 安全隔离 / 监控审计 / 记忆管理) │
└─────────────────────────────────────────────┘
7.3 任务执行流程
Manus执行一个典型任务的流程如下:
class ManusAgent:
"""Manus Agent核心实现"""
def __init__(self):
self.planner = PlannerModule()
self.executor = ExecutorModule()
self.sandbox = SandboxEnvironment()
self.memory = MemorySystem()
self.monitoring = MonitoringSystem()
async def execute_task(self, task_description: str) -> dict:
"""执行用户任务"""
# 1. 任务理解与澄清
task = await self._understand_task(task_description)
# 2. 创建执行计划
plan = await self.planner.create_plan(
goal=task['goal'],
constraints=task.get('constraints', []),
available_tools=self.executor.get_available_tools(),
)
# 3. 在沙箱中执行
results = []
for step in plan['steps']:
# 记录执行开始
self.monitoring.log_step_start(step)
# 在沙箱中执行步骤
try:
result = await self.sandbox.execute(
tool=step['tool'],
params=step['params'],
timeout=step.get('timeout', 60),
)
# 验证结果
if await self._validate_result(step, result):
results.append({
'step': step['id'],
'success': True,
'result': result,
})
else:
# 结果验证失败,触发反思和重新规划
reflection = await self._reflect_on_failure(step, result)
if reflection.get('should_replan'):
plan = await self.planner.adjust_plan(
plan, reflection, step
)
results.append({
'step': step['id'],
'success': False,
'error': '结果验证失败',
'reflection': reflection,
})
except TimeoutError:
results.append({
'step': step['id'],
'success': False,
'error': '执行超时',
})
except Exception as e:
results.append({
'step': step['id'],
'success': False,
'error': str(e),
})
# 记录执行结束
self.monitoring.log_step_end(step, results[-1])
# 4. 生成最终报告
return await self._generate_report(task, plan, results)
7.4 Manus的关键创新
1. 沙箱执行环境
Manus在隔离的沙箱中执行所有操作,确保安全性:
class SandboxEnvironment:
"""沙箱执行环境"""
def __init__(self):
self.container = None # Docker容器
self.browser = None # 隔离的浏览器实例
self.filesystem = VirtualFilesystem()
async def setup(self):
"""初始化沙箱环境"""
# 创建隔离的Docker容器
self.container = await self._create_container(
image="manus-sandbox:latest",
memory_limit="4g",
cpu_limit="2.0",
network_mode="bridge", # 受限网络
)
# 启动隔离的浏览器
self.browser = await self._launch_browser(
headless=True,
sandbox=True,
)
async def execute(self, tool: str, params: dict, timeout: float = 60):
"""在沙箱中执行操作"""
if tool == "browser":
return await self._execute_browser_action(params, timeout)
elif tool == "shell":
return await self._execute_shell_command(params, timeout)
elif tool == "file":
return await self._execute_file_operation(params, timeout)
else:
raise ValueError(f"未知工具: {tool}")
async def cleanup(self):
"""清理沙箱环境"""
if self.container:
await self.container.stop()
await self.container.remove()
if self.browser:
await self.browser.close()
2. 计划的动态调整
Manus不是僵化地执行计划,而是在每一步执行后评估结果,必要时调整后续计划。
3. 多模态理解
Manus能够理解屏幕截图、网页内容、文档等多种模态的信息,这使它能够"看到"操作结果并做出判断。
8. Computer Use与浏览器自动化
8.1 Computer Use概述
Computer Use是Claude的一项能力,允许AI模型直接操作计算机界面——移动鼠标、点击按钮、输入文字、截取屏幕。这使Agent能够使用任何人类可以使用的软件。
8.2 浏览器自动化架构
class BrowserAutomation:
"""浏览器自动化模块"""
def __init__(self, headless: bool = True):
self.headless = headless
self.page = None
self.browser = None
self.context = None
async def setup(self):
"""初始化浏览器"""
from playwright.async_api import async_playwright
self.playwright = await async_playwright().start()
self.browser = await self.playwright.chromium.launch(
headless=self.headless,
args=['--no-sandbox']
)
self.context = await self.browser.new_context(
viewport={'width': 1280, 'height': 720}
)
self.page = await self.context.new_page()
async def navigate(self, url: str) -> dict:
"""导航到指定URL"""
try:
response = await self.page.goto(url, wait_until='networkidle')
return {
'success': True,
'url': self.page.url,
'title': await self.page.title(),
'status': response.status if response else None,
}
except Exception as e:
return {'success': False, 'error': str(e)}
async def click(self, selector: str) -> dict:
"""点击页面元素"""
try:
element = await self.page.wait_for_selector(selector, timeout=5000)
await element.click()
return {'success': True}
except Exception as e:
return {'success': False, 'error': str(e)}
async def type_text(self, selector: str, text: str) -> dict:
"""在指定元素中输入文字"""
try:
element = await self.page.wait_for_selector(selector, timeout=5000)
await element.fill(text)
return {'success': True}
except Exception as e:
return {'success': False, 'error': str(e)}
async def screenshot(self) -> str:
"""截取当前页面截图"""
screenshot_bytes = await self.page.screenshot()
# 转换为base64
import base64
return base64.b64encode(screenshot_bytes).decode()
async def get_page_content(self) -> dict:
"""获取页面内容"""
title = await self.page.title()
url = self.page.url
# 获取主要文本内容
content = await self.page.evaluate('''() => {
const main = document.querySelector('main') || document.body;
return main.innerText;
}''')
# 获取所有链接
links = await self.page.evaluate('''() => {
return Array.from(document.querySelectorAll('a')).map(a => ({
text: a.innerText,
href: a.href,
}));
}''')
return {
'title': title,
'url': url,
'content': content[:5000], # 限制长度
'links': links[:50],
}
async def cleanup(self):
"""清理资源"""
if self.context:
await self.context.close()
if self.browser:
await self.browser.close()
if self.playwright:
await self.playwright.stop()
8.3 视觉理解驱动的操作
Computer Use的核心创新在于,Agent可以通过"看"屏幕来决定下一步操作:
class VisionDrivenAgent:
"""基于视觉理解的Agent"""
def __init__(self, vision_model, action_model):
self.vision = vision_model
self.action = action_model
self.browser = BrowserAutomation()
async def perform_task(self, task: str):
"""通过视觉理解执行任务"""
await self.browser.setup()
for step in range(20):
# 1. 截取屏幕
screenshot = await self.browser.screenshot()
# 2. 让视觉模型理解当前状态
understanding = await self.vision.analyze(
image=screenshot,
prompt=f"任务: {task}\n\n请描述当前屏幕的内容,特别关注与任务相关的元素。"
)
# 3. 让行动模型决定下一步
next_action = await self.action.decide(
task=task,
current_state=understanding,
step_number=step,
)
# 4. 执行动作
if next_action['type'] == 'click':
await self.browser.click(next_action['selector'])
elif next_action['type'] == 'type':
await self.browser.type_text(
next_action['selector'],
next_action['text']
)
elif next_action['type'] == 'navigate':
await self.browser.navigate(next_action['url'])
elif next_action['type'] == 'done':
return next_action['result']
return {"status": "max_steps_reached"}
9. 自主Agent安全与对齐
9.1 安全风险分类
自主Agent面临的安全风险可以分为以下几类:
1. 目标偏移(Goal Drift)
Agent在执行过程中偏离原始目标。例如,用户要求"搜索竞品价格",Agent却开始浏览无关网页。
2. 过度执行(Over-execution)
Agent执行了超出任务范围的操作。例如,用户要求"整理文件",Agent却删除了重要文件。
3. 信息泄露(Information Leakage)
Agent在执行任务时意外泄露敏感信息。例如,在自动化邮件中包含了内部数据。
4. 权限越界(Privilege Escalation)
Agent尝试访问超出其权限的资源或执行超出其权限的操作。
9.2 安全防护机制
class SafetyFramework:
"""Agent安全框架"""
def __init__(self):
self.policies = []
self.audit_log = []
self.approval_queue = asyncio.Queue()
def add_policy(self, policy: 'SafetyPolicy'):
"""添加安全策略"""
self.policies.append(policy)
async def check_action(self, action: dict) -> dict:
"""检查操作是否符合安全策略"""
for policy in self.policies:
result = await policy.evaluate(action)
if result['blocked']:
self.audit_log.append({
'action': action,
'policy': policy.name,
'result': 'blocked',
'reason': result['reason'],
'timestamp': datetime.now().isoformat(),
})
return {
'allowed': False,
'reason': result['reason'],
'requires_approval': result.get('requires_approval', False),
}
self.audit_log.append({
'action': action,
'result': 'allowed',
'timestamp': datetime.now().isoformat(),
})
return {'allowed': True}
async def request_human_approval(self, action: dict, reason: str) -> bool:
"""请求人类审批"""
approval_request = {
'action': action,
'reason': reason,
'timestamp': datetime.now().isoformat(),
}
await self.approval_queue.put(approval_request)
# 等待人类审批
# 实际实现中,这会触发UI通知
approved = await self._wait_for_approval(approval_request)
return approved
class SafetyPolicy:
"""安全策略基类"""
def __init__(self, name: str):
self.name = name
async def evaluate(self, action: dict) -> dict:
raise NotImplementedError
class FileDeletionPolicy(SafetyPolicy):
"""文件删除安全策略"""
def __init__(self):
super().__init__("file_deletion_policy")
self.protected_paths = [
'/etc/', '/usr/', '/bin/', '/sbin/',
'~/.ssh/', '~/.gnupg/',
]
async def evaluate(self, action: dict) -> dict:
if action.get('type') != 'file_delete':
return {'blocked': False}
path = action.get('path', '')
for protected in self.protected_paths:
if path.startswith(protected):
return {
'blocked': True,
'reason': f'尝试删除受保护路径: {protected}',
'requires_approval': True,
}
return {'blocked': False}
class NetworkPolicy(SafetyPolicy):
"""网络安全策略"""
def __init__(self):
super().__init__("network_policy")
self.allowed_domains = set()
self.blocked_ports = {22, 23, 3389} # SSH, Telnet, RDP
async def evaluate(self, action: dict) -> dict:
if action.get('type') != 'network_request':
return {'blocked': False}
url = action.get('url', '')
# 检查是否是允许的域名
# ...
return {'blocked': False}
9.3 人类在环(Human-in-the-Loop)
关键操作必须经过人类确认:
class HumanInTheLoop:
"""人类在环控制"""
def __init__(self):
self.risk_thresholds = {
'low': 0.3, # 低风险:自动执行
'medium': 0.6, # 中风险:通知但继续
'high': 0.8, # 高风险:暂停等待确认
'critical': 1.0, # 关键风险:必须人工审批
}
async def evaluate_and_decide(self, action: dict, risk_score: float) -> dict:
"""根据风险评分决定是否需要人类介入"""
if risk_score >= self.risk_thresholds['critical']:
return {
'decision': 'require_approval',
'message': '此操作风险极高,需要人工审批',
}
elif risk_score >= self.risk_thresholds['high']:
return {
'decision': 'pause_and_notify',
'message': '此操作风险较高,已暂停并通知用户',
}
elif risk_score >= self.risk_thresholds['medium']:
return {
'decision': 'notify_and_continue',
'message': '此操作有一定风险,已通知用户',
}
else:
return {
'decision': 'auto_execute',
'message': '低风险操作,自动执行',
}
10. 开源Agent框架对比
10.1 AutoGPT
概述:最早引起广泛关注的自主Agent框架(2023年3月发布)
核心特点:
- 完全自主的目标驱动执行
- 内置记忆管理(短期/长期)
- 支持网页浏览、文件操作、代码执行
- 插件系统扩展能力
架构:
用户目标 → 任务队列 → 执行循环 → 结果
↑ ↓
└── 记忆系统 ←┘
优势:
- 社区庞大,插件丰富
- 概念简单易懂
- 持续更新维护
局限:
- 复杂任务可靠性不足
- Token消耗高
- 容易陷入循环
10.2 BabyAGI
概述:一个极简的任务管理系统(2023年4月发布)
核心特点:
- 任务创建 → 任务优先级排序 → 任务执行的循环
- 极简设计,代码量小
- 专注于任务管理而非工具使用
架构:
┌─────────────┐
│ 任务创建Agent │ ← 新任务
└──────┬──────┘
↓
┌─────────────┐
│ 优先级排序Agent│
└──────┬──────┘
↓
┌─────────────┐
│ 任务执行Agent │ → 结果 → 新任务
└─────────────┘
优势:
- 设计优雅,易于理解
- 适合学习Agent概念
- 可扩展性强
局限:
- 功能相对简单
- 缺少工具使用能力
- 更适合研究而非生产
10.3 MetaGPT
概述:模拟软件公司的多Agent协作框架(2023年8月发布)
核心特点:
- 多角色协作(产品经理、架构师、工程师、QA)
- 标准化输出(PRD、设计文档、代码、测试)
- 基于SOP(标准操作流程)的工作方式
架构:
用户需求
↓
产品经理Agent → PRD文档
↓
架构师Agent → 技术设计
↓
工程师Agent → 代码实现
↓
QA Agent → 测试报告
↓
最终交付物
优势:
- 多Agent协作模式成熟
- 输出质量相对较高
- 适合软件开发场景
局限:
- 主要针对软件开发场景
- 配置和调优较复杂
- 运行成本较高
10.4 LangChain Agents
概述:LangChain框架中的Agent模块
核心特点:
- 丰富的工具集成
- 灵活的Agent类型(ReAct、Plan-and-Execute等)
- 与LangChain生态深度集成
- 支持多种LLM
优势:
- 工具生态最丰富
- 社区活跃,文档完善
- 灵活性高
局限:
- 学习曲线较陡
- 抽象层次多,调试困难
- 版本更新频繁,API不稳定
10.5 框架选型建议
| 场景 | 推荐框架 | 理由 |
|---|---|---|
| 学习Agent概念 | BabyAGI | 代码简洁,易于理解 |
| 通用自主Agent | AutoGPT | 功能全面,社区支持好 |
| 软件开发任务 | MetaGPT | 多角色协作,输出质量高 |
| 工具集成需求 | LangChain Agents | 工具生态最丰富 |
| 生产级部署 | 自研或基于LangChain | 需要更多控制和定制 |
11. 企业级Agent部署方案
11.1 部署架构
企业级Agent部署需要考虑可靠性、安全性、可扩展性和可观测性:
┌─────────────────────────────────────────────────────┐
│ 负载均衡器 │
│ (Nginx / ALB) │
├─────────────────────────────────────────────────────┤
│ API网关层 │
│ (认证 / 限流 / 路由 / 日志) │
├─────────────────────────────────────────────────────┤
│ Agent服务层 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Agent-1 │ │ Agent-2 │ │ Agent-N │ │
│ │ (Pod) │ │ (Pod) │ │ (Pod) │ │
│ └──────────┘ └──────────┘ └──────────┘ │
├─────────────────────────────────────────────────────┤
│ 基础设施层 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐│
│ │ 消息队列 │ │ 向量数据库│ │ 对象存储 │ │ 监控 ││
│ │ (Redis) │ │(Qdrant) │ │ (MinIO) │ │(Grafana)││
│ └──────────┘ └──────────┘ └──────────┘ └────────┘│
└─────────────────────────────────────────────────────┘
11.2 可靠性设计
class ReliableAgentService:
"""企业级可靠的Agent服务"""
def __init__(self):
self.circuit_breaker = CircuitBreaker(
failure_threshold=5,
recovery_timeout=60,
)
self.retry_policy = RetryPolicy(
max_retries=3,
backoff_base=2,
backoff_max=30,
)
self.rate_limiter = RateLimiter(
max_requests=100,
time_window=60,
)
async def execute_task(self, task: dict) -> dict:
"""执行任务(带可靠性保障)"""
# 1. 限流检查
if not await self.rate_limiter.allow(task.get('user_id')):
return {
'status': 'rate_limited',
'message': '请求过于频繁,请稍后重试',
}
# 2. 断路器检查
if self.circuit_breaker.is_open():
return {
'status': 'service_unavailable',
'message': '服务暂时不可用,请稍后重试',
}
# 3. 带重试的执行
for attempt in range(self.retry_policy.max_retries):
try:
result = await self._execute_with_timeout(task, timeout=120)
self.circuit_breaker.record_success()
return result
except TimeoutError:
if attempt < self.retry_policy.max_retries - 1:
wait_time = self.retry_policy.get_wait_time(attempt)
await asyncio.sleep(wait_time)
else:
self.circuit_breaker.record_failure()
return {
'status': 'timeout',
'message': '任务执行超时',
}
except Exception as e:
self.circuit_breaker.record_failure()
if attempt < self.retry_policy.max_retries - 1:
wait_time = self.retry_policy.get_wait_time(attempt)
await asyncio.sleep(wait_time)
else:
return {
'status': 'error',
'message': f'任务执行失败: {str(e)}',
}
return {'status': 'error', 'message': '所有重试均失败'}
class CircuitBreaker:
"""断路器"""
def __init__(self, failure_threshold: int, recovery_timeout: int):
self.failure_threshold = failure_threshold
self.recovery_timeout = recovery_timeout
self.failure_count = 0
self.last_failure_time = None
self.state = "closed" # closed, open, half-open
def is_open(self) -> bool:
if self.state == "open":
# 检查是否到了恢复时间
if time.time() - self.last_failure_time > self.recovery_timeout:
self.state = "half-open"
return False
return True
return False
def record_success(self):
self.failure_count = 0
self.state = "closed"
def record_failure(self):
self.failure_count += 1
self.last_failure_time = time.time()
if self.failure_count >= self.failure_threshold:
self.state = "open"
11.3 监控与可观测性
class AgentMonitoring:
"""Agent监控系统"""
def __init__(self):
self.metrics = {
'tasks_total': 0,
'tasks_success': 0,
'tasks_failed': 0,
'avg_execution_time': 0,
'active_agents': 0,
}
self.traces = []
def record_task_start(self, task_id: str, task_type: str):
"""记录任务开始"""
self.metrics['tasks_total'] += 1
self.traces.append({
'task_id': task_id,
'task_type': task_type,
'start_time': time.time(),
'steps': [],
})
def record_step(self, task_id: str, step: dict):
"""记录执行步骤"""
trace = self._get_trace(task_id)
if trace:
trace['steps'].append({
'step': step,
'timestamp': time.time(),
})
def record_task_end(self, task_id: str, success: bool):
"""记录任务结束"""
trace = self._get_trace(task_id)
if trace:
trace['end_time'] = time.time()
trace['duration'] = trace['end_time'] - trace['start_time']
trace['success'] = success
if success:
self.metrics['tasks_success'] += 1
else:
self.metrics['tasks_failed'] += 1
# 更新平均执行时间
self._update_avg_execution_time()
def get_health_status(self) -> dict:
"""获取健康状态"""
total = self.metrics['tasks_total']
success = self.metrics['tasks_success']
return {
'status': 'healthy' if total == 0 or success / total > 0.8 else 'degraded',
'success_rate': success / total if total > 0 else 1.0,
'avg_execution_time': self.metrics['avg_execution_time'],
'active_agents': self.metrics['active_agents'],
}
11.4 部署检查清单
## 企业级Agent部署检查清单
### 基础设施
- [ ] 容器化部署(Docker / Kubernetes)
- [ ] 负载均衡和自动扩缩容
- [ ] 数据持久化(向量数据库、对象存储)
- [ ] 网络隔离和安全组配置
### 安全
- [ ] API认证和授权(OAuth2 / API Key)
- [ ] 数据加密(传输中 + 静态)
- [ ] 敏感信息管理(Vault / Secrets Manager)
- [ ] 沙箱执行环境
- [ ] 操作审计日志
### 可靠性
- [ ] 断路器和重试机制
- [ ] 超时控制
- [ ] 健康检查和自愈
- [ ] 灾难恢复方案
### 可观测性
- [ ] 分布式追踪(OpenTelemetry)
- [ ] 指标收集(Prometheus)
- [ ] 日志聚合(ELK / Loki)
- [ ] 告警规则(PagerDuty / 钉钉)
### 合规
- [ ] 数据保留策略
- [ ] 用户同意机制
- [ ] GDPR / 隐私合规
- [ ] 行业特定合规要求
总结
AI自主Agent正在从实验室走向生产环境。关键要点:
- 理解核心架构:感知-规划-执行-反思循环是所有Agent的基础
- 选择合适的模式:ReAct适合简单任务,Plan-and-Execute适合复杂任务
- 工具是关键:Agent的能力边界由其可用工具决定
- 安全第一:人类在环、沙箱隔离、审计日志是企业部署的必备条件
- 持续迭代:Agent的可靠性需要通过实际部署不断改进
自主Agent代表了AI应用的下一个范式转变——从"AI回答问题"到"AI完成工作"。随着模型能力的提升和基础设施的成熟,Agent将在更多场景中发挥价值。但同时,安全性和可靠性仍然是需要持续关注的核心问题。
本教程持续更新,欢迎反馈和建议。