引言
MicroAgent 是 OpenHands 系统中的一个重要模块,旨在通过模块化的方式提供特定的知识、任务和仓库相关的功能支持。本文将从 MicroAgent 的分类、作用、协作方式、源码实现以及测试覆盖等多个维度,全面解析其设计理念和技术实现。
1. MicroAgent 的分类与作用
MicroAgent 分为三大类,每一类都有其特定的功能和应用场景:
(1) KnowledgeMicroAgent
- 作用:提供特定领域的知识支持,例如编程语言的最佳实践、框架指南、常见模式和工具使用等。
- 触发机制:通过关键词触发。例如,当用户输入包含特定关键词的消息时,KnowledgeMicroAgent 会被激活。
- 典型场景:
- 用户询问某个框架的最佳实践。
- 提供工具的使用指南。
(2) RepoMicroAgent
- 作用:专注于仓库(Repository)相关的知识和指导,例如团队的代码规范、项目特定的工作流和文档引用。
- 加载方式:从
.openhands/microagents/repo.md
文件中加载,或者从遗留的.openhands_instructions
文件中加载。 - 典型场景:
- 提供项目特定的开发规范。
- 自动加载与当前仓库相关的文档和说明。
(3) TaskMicroAgent
- 作用:专注于任务驱动的操作,例如执行特定的任务或工作流。
- 典型场景:
- 自动化执行某些重复性任务。
- 提供任务的分步指导。
2. MicroAgent 的协作方式
MicroAgent 的协作方式体现在以下几个方面:
(1) 模块化设计
每个 MicroAgent 都是一个独立的模块,具有自己的元数据(Metadata)和内容(Content)。这种模块化设计使得 MicroAgent 可以独立开发、测试和部署。
(2) 统一加载与管理
通过 load_microagents_from_dir
函数,系统可以从指定目录加载所有类型的 MicroAgent,并将它们分类存储为字典(repo_agents
、knowledge_agents
、task_agents
)。这确保了 MicroAgent 的统一管理和高效加载。
(3) 动态触发与执行
- 触发机制:例如,KnowledgeMicroAgent 会根据用户输入的关键词动态触发。
- 执行机制:TaskMicroAgent 可以根据任务需求执行特定的操作。
(4) 与 CodeAct Agent 的集成
MicroAgent 是 CodeAct Agent 的重要组成部分。CodeAct Agent 可以调用 MicroAgent 提供的知识或任务支持,从而增强其功能。
3. 源码解析
以下是对 MicroAgent 核心源码的解析:
(1) MicroAgent 的基类
BaseMicroAgent
是所有 MicroAgent 的基类,定义了 MicroAgent 的基本结构和加载逻辑。
class BaseMicroAgent(BaseModel):
name: str
content: str
metadata: MicroAgentMetadata
source: str # 文件路径
type: MicroAgentType
@classmethod
def load(cls, path: Union[str, Path], file_content: str | None = None) -> 'BaseMicroAgent':
# 从文件加载 MicroAgent
...
核心字段:
name
:MicroAgent 的名称。content
:MicroAgent 的内容。metadata
:MicroAgent 的元数据,包括类型、触发器等。type
:MicroAgent 的类型(Knowledge、Repo 或 Task)。
加载逻辑:
- 从文件中读取内容。
- 根据元数据的类型动态创建对应的子类(
KnowledgeMicroAgent
、RepoMicroAgent
或TaskMicroAgent
)。
(2) KnowledgeMicroAgent
KnowledgeMicroAgent
提供了关键词触发的功能。
class KnowledgeMicroAgent(BaseMicroAgent):
def match_trigger(self, message: str) -> str | None:
# 匹配消息中的触发器
message = message.lower()
for trigger in self.triggers:
if trigger.lower() in message:
return trigger
return None
@property
def triggers(self) -> list[str]:
return self.metadata.triggers
- 关键词匹配:通过
match_trigger
方法,判断用户输入是否包含触发关键词。 - 触发器列表:从元数据中提取触发器。
(3) RepoMicroAgent
RepoMicroAgent
专注于仓库相关的知识。
class RepoMicroAgent(BaseMicroAgent):
...
- 加载方式:从
.openhands/microagents/repo.md
或.openhands_instructions
文件中加载。 - 应用场景:提供项目特定的开发规范和文档。
(4) TaskMicroAgent
TaskMicroAgent
专注于任务驱动的操作。
class TaskMicroAgent(BaseMicroAgent):
...
- 应用场景:执行特定的任务或工作流。
(5) MicroAgent 的加载函数
load_microagents_from_dir
函数用于从指定目录加载所有 MicroAgent。
def load_microagents_from_dir(microagent_dir: Union[str, Path]) -> tuple[...]:
repo_agents = {}
knowledge_agents = {}
task_agents = {}
for file in microagent_dir.rglob('*.md'):
agent = BaseMicroAgent.load(file)
if isinstance(agent, RepoMicroAgent):
repo_agents[agent.name] = agent
elif isinstance(agent, KnowledgeMicroAgent):
knowledge_agents[agent.name] = agent
elif isinstance(agent, TaskMicroAgent):
task_agents[agent.name] = agent
return repo_agents, knowledge_agents, task_agents
- 功能:从目录中递归加载所有
.md
文件,并根据类型分类存储。 - 返回值:包含
repo_agents
、knowledge_agents
和task_agents
的字典。
4. 测试覆盖
MicroAgent 的测试覆盖包括以下几个方面:
(1) 基本功能测试
- 测试 MicroAgent 的加载功能。
- 验证不同类型的 MicroAgent 是否正确分类。
(2) 特殊场景测试
- 测试嵌套目录中的 MicroAgent 加载。
- 测试带有遗留文件(
.openhands_instructions
)的加载。
(3) 异常处理测试
- 测试无效类型的 MicroAgent 是否抛出异常。
- 测试缺失文件的场景。
5. MicroAgent 的关系与协作
MicroAgent 之间的关系是松耦合的,每个 MicroAgent 独立提供特定的功能。它们通过以下方式协作:
- 统一管理:通过
load_microagents_from_dir
函数统一加载和管理。 - 动态调用:CodeAct Agent 根据需求动态调用不同类型的 MicroAgent。
- 功能互补:KnowledgeMicroAgent 提供知识支持,RepoMicroAgent 提供项目规范,TaskMicroAgent 执行具体任务。
总结
MicroAgent 是 OpenHands 系统中一个强大且灵活的模块,通过模块化设计和动态加载机制,为系统提供了知识支持、任务执行和仓库管理等多种功能。其与 CodeAct Agent 的深度集成,使得 OpenHands 能够更高效地满足用户的多样化需求。