# PR #6718 完整报告

- 仓库：`verl-project/verl`
- 标题：[fully_async] fix: check audio forwarding contract in agent loop
- 合并时间：2026-06-13 09:18
- 原文链接：http://prhub.com.cn/verl-project/verl/pull/6718

---

# 执行摘要

- 一句话：修复全异步音频转发契约测试目标文件
- 推荐动作：建议合并。该 PR 修正了测试中的断言位置，使其与实际的转发实现一致，提高了测试的有效性和可靠性。值得关注的是，开发者在描述中已主动搜索了相似 PR 并确认无重复，体现了良好的协作习惯。

# 功能与动机

PR body 指出之前的断言错误地查找 `audio_data=audio_data` 在 `fully_async_rollouter.py` 中，但该文件仅将客户端接入代理循环管理器，实际转发发生在 `single_turn_agent_loop.py` 和 `tool_agent_loop.py` 中。

# 实现拆解

1. **修改测试文件路径常量**：在 `tests/experimental/agent_loop/test_audio_server_contract_on_cpu.py` 中，将 `FULLY_ASYNC_ROLLOUTER_SOURCE` 替换为 `SINGLE_TURN_AGENT_LOOP_SOURCE` 和 `TOOL_AGENT_LOOP_SOURCE`，分别指向 `verl/experimental/agent_loop/single_turn_agent_loop.py` 和 `tool_agent_loop.py`。
2. **更新断言逻辑**：在测试函数 `test_fully_async_server_manager_generate_forwards_audio_and_mm_kwargs` 中，分别读取两个代理循环文件的内容，并断言其中包含正确的音频和多模态处理器参数字符串。单次代理循环期望 `audio_data=audios` 和 `mm_processor_kwargs=mm_processor_kwargs`；工具代理循环期望 `audio_data=agent_data.audio_data` 和 `mm_processor_kwargs=agent_data.mm_processor_kwargs`。
3. **移除无效断言**：删除了针对 `fully_async_rollouter.py` 的旧断言，确保测试真正覆盖了参数传递的实际代码路径。

关键文件：
- `tests/experimental/agent_loop/test_audio_server_contract_on_cpu.py`（模块 测试；类别 test；类型 test-coverage）: 唯一变更文件，修正了全异步音频转发契约测试的断言目标，确保测试覆盖实际的代理循环转发逻辑。

关键符号：未识别

## 关键源码片段

### `tests/experimental/agent_loop/test_audio_server_contract_on_cpu.py`

唯一变更文件，修正了全异步音频转发契约测试的断言目标，确保测试覆盖实际的代理循环转发逻辑。

```python
# 此文件为 CPU 单元测试，验证全异步模式下音频和多模态参数的转发契约

REPO_ROOT = Path(__file__).resolve().parents[3]
LLM_SERVER_SOURCE = REPO_ROOT / "verl/workers/rollout/llm_server.py"
# 原指向 fully_async_rollouter.py，现在分别指向实际发生转发的两个代理循环文件
SINGLE_TURN_AGENT_LOOP_SOURCE = REPO_ROOT / "verl/experimental/agent_loop/single_turn_agent_loop.py"
TOOL_AGENT_LOOP_SOURCE = REPO_ROOT / "verl/experimental/agent_loop/tool_agent_loop.py"
VLLM_SERVER_SOURCE = REPO_ROOT / "verl/workers/rollout/vllm_rollout/vllm_async_server.py"


def test_fully_async_server_manager_generate_forwards_audio_and_mm_kwargs() -> None:
    """断言全异步模式下音频和多模态参数被正确转发到 LLM 客户端"""
    # 检查单次代理循环：参数名为 audios
    single_turn_source = SINGLE_TURN_AGENT_LOOP_SOURCE.read_text(encoding="utf-8")
    assert "audio_data=audios" in single_turn_source
    assert "mm_processor_kwargs=mm_processor_kwargs" in single_turn_source

    # 检查工具代理循环：参数通过 agent_data 获取
    tool_source = TOOL_AGENT_LOOP_SOURCE.read_text(encoding="utf-8")
    assert "audio_data=agent_data.audio_data" in tool_source
    assert "mm_processor_kwargs=agent_data.mm_processor_kwargs" in tool_source

    # 旧版本错误地检查了 fully_async_rollouter.py，该文件不包含实际的转发调用

```

# 评论区精华

无实质讨论。Gemini Code Assist 自动评论仅声明无反馈，wuxibin89 直接审批通过。

- gemini-code-assist 自动评论 (other): 无异议。
- wuxibin89 审批 (other): 同意合并。

# 风险与影响

- 风险：风险极低。该 PR 仅修改了测试文件中的断言目标，未涉及生产代码逻辑变更。只要测试通过（PR body 确认 4 项全部通过），即可保证测试正确反映了实际代码的接口契约。
- 影响：影响范围仅限于测试文件本身，对用户无影响，对系统无影响。团队可确保全异步音频转发契约的持续集成测试能正确验证预期行为。
- 风险标记：暂无

# 关联脉络

- PR #6716 [trainer] fix: use FullyAsyncLLMServerClient for async trainer: 与 PR #6716 均涉及 `FullyAsyncLLMServerClient` 的调用优化，本 PR 修正了相关测试的断言目标，确保其与实际接口一致。