Action类解析
概述
Action类是MetaGPT框架中的核心组件,用于定义可执行动作,集成了LLM调用、上下文管理和动作节点执行功能,作为所有具体动作类的基类。
继承关系
- SerializationMixin: 提供序列化能力,支持对象的持久化与传输
- ContextMixin: 提供上下文管理功能,维护动作执行过程中的状态信息
- BaseModel: 基于Pydantic的模型基类,提供数据验证和配置管理
核心配置
- model_config : 使用
ConfigDict(arbitrary_types_allowed=True)
允许任意类型属性,适应复杂上下文场景
核心属性
属性名 | 类型 | 描述 |
---|---|---|
name | str | 动作名称,默认为类名(通过模型验证器自动设置) |
i_context | Union[dict, CodingContext, str, None] | 输入上下文,支持多种类型以适应不同动作场景(编码、测试、代码总结等) |
prefix | str | LLM调用的系统提示前缀,通过set_prefix 方法更新 |
desc | str | 动作描述,用于技能管理器识别和分类 |
node | ActionNode | 动作节点实例,定义具体执行逻辑和LLM交互模板 |
llm_name_or_type | Optional[str] | LLM模型名称或类型,对应config2.yaml 中的模型配置 |
关键属性方法
- prompt_schema: 获取配置中的提示词模板结构
- project_name: 获取/设置当前项目名称(关联配置上下文)
- project_path: 获取当前项目路径(关联配置上下文)
主要方法
方法名 | 说明 |
---|---|
run(*args, **kwargs) | 动作执行入口方法,若存在node 则调用_run_action_node ,否则需子类实现 |
_aask(prompt, system_msgs) | 异步调用LLM,自动附加prefix 作为系统提示 |
_run_action_node(*args, **kwargs) | 处理历史消息上下文,调用ActionNode.fill() 执行节点逻辑 |
set_prefix(prefix) | 更新前缀并同步至LLM系统提示,若存在node 则同步节点的LLM实例 |
override_context() | 将private_context 与context 统一为同一对象,确保上下文一致性 |
str /repr | 返回类名作为字符串表示,便于日志和调试 |
模型验证器逻辑
- set_name_if_empty (前置验证):若未提供
name
,自动将类名设为动作名称 - _init_with_instruction (前置验证):若传入
instruction
参数,自动创建ActionNode
实例并赋值给node
- _update_private_llm (后置验证):根据
llm_name_or_type
从配置中加载LLM实例,继承成本管理器(cost_manager)
ActionNode集成
- 通过
node
属性关联ActionNode
,实现基于模板的LLM交互 _run_action_node
方法会将历史消息格式化为上下文,调用node.fill()
完成具体内容生成set_prefix
方法同步更新LLM系统提示时,会同时更新node
的LLM实例
使用示例
示例1:代码生成动作(WriteCode)
python
class WriteCode(Action):
name: str = "WriteCode"
i_context: Document = Field(default_factory=Document)
repo: Optional[ProjectRepo] = Field(default=None, exclude=True)
input_args: Optional[BaseModel] = Field(default=None, exclude=True)
async def run(self, *args, **kwargs) -> CodingContext:
# 1. 加载上下文(设计文档、任务描述、历史代码等)
coding_context = CodingContext.loads(self.i_context.content)
# 2. 构建LLM提示词
prompt = PROMPT_TEMPLATE.format(
design=coding_context.design_doc.content,
task=coding_context.task_doc.content,
code=code_context,
filename=self.i_context.filename
)
# 3. 调用LLM生成代码
code = await self.write_code(prompt)
# 4. 更新上下文并返回
coding_context.code_doc.content = code
return coding_context
关键实现点:
- 重写
run
方法实现代码生成逻辑 - 使用
CodingContext
管理编码相关上下文信息 - 通过模板构建提示词,调用
_aask
方法与LLM交互 - 支持增量开发和调试日志集成
示例2:需求分析动作(AnalyzeRequirementsRestrictions)
python
class AnalyzeRequirementsRestrictions(Action):
name: str = "AnalyzeRequirementsRestrictions"
async def run(self, requirements, isinstance=INSTRUCTIONS, output_format=OUTPUT_FORMAT):
# 1. 构建提示词(包含示例、需求和输出格式)
prompt = ANALYZE_REQUIREMENTS.format(
examples=EXAMPLES,
requirements=requirements,
instructions=isinstance,
output_format=output_format
)
# 2. 调用LLM分析需求
rsp = await self.llm.aask(prompt)
return rsp
关键实现点:
- 轻量级实现,专注于需求分析单一职责
- 通过格式化字符串构建复杂提示词
- 直接使用
llm.aask
方法进行LLM调用 - 返回原始LLM响应结果
使用场景
- 作为所有具体动作(如
WriteCode
、AnalyzeRequirements
)的基类 - 标准化LLM调用流程,统一上下文管理和消息处理机制
- 通过
ActionNode
实现可配置的动作逻辑,支持不同场景下的提示词模板复用