跳转至

interaction_registry.py — verl/interactions/utils/interaction_registry.py

文件路径

verl/interactions/utils/interaction_registry.py

文件概述

interaction_registry.py 是交互系统的注册中心,负责从配置文件中读取交互定义,动态加载对应的交互类,并创建交互实例。它与 tool_registry.py 的设计思路一致,但更加简洁(不需要处理 MCP 协议)。

关键代码讲解

1. 动态加载交互类

def get_interaction_class(cls_name):
    """Dynamically import and return the interaction class."""
    module_name, class_name = cls_name.rsplit(".", 1)
    if module_name not in sys.modules:
        spec = importlib.util.find_spec(module_name)
        module = importlib.util.module_from_spec(spec)
        sys.modules[module_name] = module
        spec.loader.exec_module(module)
    else:
        module = sys.modules[module_name]
    interaction_cls = getattr(module, class_name)
    return interaction_cls

与 tool_registry.py 的 get_tool_class 完全相同的实现——通过完全限定类名动态导入类对象。

2. 从配置文件初始化交互(核心函数)

def initialize_interactions_from_config(interaction_config_file):
    interaction_config = OmegaConf.load(interaction_config_file)
    interaction_map = {}

    for interaction_item in interaction_config.interaction:
        cls_name = interaction_item.class_name
        interaction_cls = get_interaction_class(cls_name)

        config = OmegaConf.to_container(interaction_item.config, resolve=True)

        # 获取交互名称
        name = interaction_item.get("name", None)
        if name is None:
            class_simple_name = cls_name.split(".")[-1]
            if class_simple_name.endswith("Interaction"):
                name = class_simple_name[:-11].lower()  # 移除 "Interaction" 后缀
            else:
                name = class_simple_name.lower()

        # 检查重复名称
        if name in interaction_map:
            raise ValueError(f"Duplicate interaction name '{name}' found.")

        config["name"] = name
        interaction = interaction_cls(config=config)
        interaction_map[name] = interaction

    return interaction_map

与 tool_registry.py 的区别: 1. 返回字典(而非列表):interaction_map 将交互名称映射到交互实例,方便按名查找。 2. 自动命名:如果配置文件没有指定名称,自动从类名推导(如 Gsm8kInteraction -> "gsm8k")。 3. 重复检测:防止两个交互使用相同的名称。 4. 不需要 MCP 支持:比工具注册器简单,不需要处理异步初始化。

配置文件示例

interaction:
  - class_name: verl.interactions.gsm8k_interaction.Gsm8kInteraction
    name: gsm8k  # 可选,不指定则自动推导
    config:
      some_option: value

  - class_name: verl.interactions.weather_interaction.WeatherInteraction
    config:
      some_option: value

核心类/函数列表

函数 作用
get_interaction_class 动态加载交互类
initialize_interactions_from_config 从配置文件初始化所有交互(核心入口)

与其他模块的关系

  • 加载所有交互类:通过动态导入加载 Gsm8kInteraction、WeatherInteraction 等。
  • 使用 OmegaConf 解析 YAML 配置文件。
  • 被 rollout 系统调用:训练开始时调用 initialize_interactions_from_config 加载所有交互环境。
  • 设计模式与 tool_registry.py 一致。

小结

interaction_registry.py 是交互系统的启动入口。它通过声明式配置实现了交互环境的灵活组合,用户只需编写 YAML 文件就能添加新的交互环境,无需修改代码。