ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

CopilotKit Sub-Agents 演示 QA 全流程验证指南:CrewAI 监督者多智能体委派的测试要点与源码解析

CopilotKit Sub-Agents 演示 QA 全流程验证指南:CrewAI 监督者多智能体委派的测试要点与源码解析 CopilotKit Sub-Agents 演示 QA 全流程验证指南CrewAI 监督者多智能体委派的测试要点与源码解析【免费下载链接】CopilotKitThe Frontend Stack for Agents Generative UI. React, Angular, Mobile, Slack, and more. Makers of the AG-UI Protocol项目地址: https://gitcode.com/GitHub_Trending/co/CopilotKit本文以 CopilotKit 开源仓库中showcase/integrations/crewai-conversational-flows的 Sub-Agents 演示及其 QA 文档qa/subagents.md为主线完整梳理监督者SupervisorLLM 三个 CrewAI 子 Crew多智能体委派场景的手工验收步骤、预期结果并结合 subagents.py 的 Flow 实现、delegation-log.tsx 的前端渲染与 subagents.spec.ts 的 e2e 测试说明如何从功能、实时状态转换、错误处理三个维度验证并理解这套子智能体即工具sub-agents-as-tools的架构。读完本文你可以直接复现整套手工测试步骤并据此为其他多智能体演示编写同类 QA 用例。一、测试前置条件在开始任何测试之前QA 文档要求环境满足以下三点缺一不可演示页面已部署且可访问Sub-Agents 演示运行在 dashboard 主机的/demos/subagents路由下。对应前端源码位于 src/app/demos/subagents/page.tsx。Agent 后端健康/api/health返回正常OPENAI_API_KEY环境变量已配置后端通过 litellm 驱动监督者 LLM 与三个子 Crew默认模型为gpt-5.4见 subagents.py。Flow 端点已挂载FastAPI Agent 服务器必须在/subagents路径挂载该 Flow。后端通过add_crewai_flow_fastapi_endpoint(...)把每个 Flow 类型注册为独立端点见 agent_server.py而conversational_flows.py中的注册表把subagents映射到SubagentsFlow见 conversational_flows.py。前端侧src/app/api/copilotkit/route.ts 通过createAgent(/subagents)建立 AG-UI 连接。前置条件对应的两条命令式检查可以归纳为检查项命令 / 位置期望结果后端健康GET /api/health返回 200 与健康状态Flow 挂载GET /subagentsAG-UI 握手端点可达且能完成会话协商模型凭证服务器环境变量OPENAI_API_KEY已设置且能通过 litellm 发起acompletion二、页面布局与基本功能验证Test Steps 1打开/demos/subagents后QA 文档要求依次核对如下内容每一项都可以用浏览器 DevTools 或 Playwright 直接断言3 秒内完成渲染页面包含左侧委派日志面板delegation log与右侧CopilotChat聊天窗格。日志面板结构data-testiddelegation-log可见标题为 Sub-agent delegations顶部data-testiddelegation-count在发送任何任务前显示0 calls。空状态文案显示 Ask the supervisor to complete a task. Every sub-crew it kicks off will appear here.输入框占位符Give the supervisor a task...三个建议 pill 可见Write a blog post、Explain a topic、Summarize a topic。这三个建议 pill 由 suggestions.ts 通过useConfigureSuggestions声明点击后会发送完整的多步骤提示词例如 Write a blog post 实际发送的是Produce a short blog post about the benefits of cold exposure training. Research first, then write, then critique.从源码实现看日志面板的每个 DOM 钩子都有明确出处delegation-log.tsx 中delegation-log、delegation-count、supervisor-running、delegation-entry、subagent-indicator-*等data-testid与 QA 文档一一对应说明这份 QA 清单与前端实现是同源设计的——这也是该演示能被 e2e 可靠自动化的前提。三、功能特性检查监督者向子 Crew 委派Test Steps 2.1QA 文档的核心场景是点击 Write a blog post触发一条完整的 research → write → critique 委派链。验收要点运行中徽标点击后约 3 秒内头部应出现data-testidsupervisor-running的 Supervisor running 脉冲徽标animate-pulse见 delegation-log.tsx表示 Flow 正在执行。三条委派记录按序出现60 秒内第 1 条 Research紫色 data-testiddelegation-status为completed结果体为 3~5 条以-开头的要点第 2 条 Writing绿色 ✍️状态completed结果为单段文字第 3 条 Critique橙色 状态completed结果为 2~3 条批判性要点。计数更新data-testiddelegation-count结束时应显示3 calls或与委派数一致的数字。监督者收尾聊天中监督者最终助手消息应当简短并声明工作已完成——因为系统提示词明确要求它Keep your own messages short见 subagents.py。这些预期与后端实现严格对应。三个子 Crew 分别定义在 subagents.py 的_build_research_crew/_build_writing_crew/_build_critique_crew中每个都是真实的单 Agent CrewAI Crew自带role/goal/backstory挂一个Task并设置allow_delegationFalse禁止二级委派。三个 Crew 的产出格式要点、单段、批判要点由各自 Task 的description与expected_output约束因此 QA 才能对结果体格式做确定性断言。值得注意的架构选择为什么不用 CrewAI 自带的 hierarchical Process 直接编排子 Agent源码注释明确解释了原因——CrewAI 的层级/顺序 Process 在内部编排子 Agent通过 AG-UI 桥对外只暴露最终 Crew 输出每一次中间子任务/委派对客户端完全不透明。而本演示的需求是每次委派都要向 state 追加 Delegation 记录、UI 渲染实时委派日志因此最干净的做法是每个子 Agent 都是真实 CrewAI Crew保留 CrewAI 原生语义监督者是 litellm 驱动的 LLM把三个 Crew 作为工具暴露给它外层 Flow 在每次委派后发射状态快照copilotkit_emit_state。底层调用链从工具调用到 Crew 执行监督者每轮循环supervise方法见 subagents.py执行如下流程组装消息系统提示词 历史消息与工具列表前端注册 actions 三个委派工具DELEGATION_TOOLS。调用litellm.acompletion获取带tool_calls的流式响应通过copilotkit_stream转发给前端。若无工具调用说明监督者已给出最终回复本轮结束否则逐条处理工具调用解析task参数为空则写入一条 tool 错误消息让模型下一轮自我修正先追加一条statusrunning的Delegation并发射状态快照此时 UI 显示 Sub-agent running...通过_kickoff_crew在 asyncio 工作线程中同步执行Crew.kickoff(inputs{task: task})asyncio.to_thread避免阻塞事件循环见 subagents.py将同一条记录更新为completed或异常时failed异常信息仅保留类名以规避敏感信息泄漏并再次发射状态快照把子 Crew 的原始输出作为tool消息回填给监督者供下一轮推理使用。这条链正好解释了两个 QA 观察点每条记录都会先出现running再变为completed是因为 Flow 在kickoff前后各发射一次 STATE_SNAPSHOT委派日志能实时增长是因为Delegation被追加进继承自CopilotKitState的AgentState.delegationssubagents.py。委派工具本身是标准 OpenAI 兼容函数 schema_delegation_tool三个工具research_agent/writing_agent/critique_agent各自声明唯一的必填参数task描述字段引导监督者把上下文事实、草稿通过task传递给子 Agent见 subagents.py。前端如何感知正在运行除侧栏日志外聊天流内还会通过useRenderTool为每个子 Agent 渲染一张内联活动卡片subagent-activity-card.tsx状态机为inProgress → executing → complete。而当前是哪个子 Agent 在跑由 active-subagent.ts 的inferActiveSubAgent推断它遍历消息流找到最新一条尚无对应 tool 回复的子 Agent 工具调用作为活跃委派并对流式部分 JSON 参数做了容错解析先严格JSON.parse失败再正则嗅探task: ...。四、实时状态转换验证Test Steps 2.2点击 Explain a topic 建议QA 关注的是状态转换的可见性委派记录应先以running出现结果体显示 Sub-agent running...随后在子 Crewkickoff返回后转为completed。这直接验证了 Flow 在每个Crew.kickoff(...)调用之前和之后各发射一次 STATE_SNAPSHOT 的行为对应 subagents.py 与 subagents.py 两处copilotkit_emit_state。运行结束后data-testidsupervisor-running徽标应消失由agent.isRunning驱动见 page.tsx。前端订阅方式在 page.tsx 中可见useAgent({ agentId: subagents, updates: [UseAgentUpdate.OnStateChanged, UseAgentUpdate.OnRunStatusChanged] })同时监听状态变更与运行状态变更两类更新这是日志能实时增长、徽标能及时亮灭的前端前提。五、单会话多任务验证Test Steps 2.3QA 文档还要求验证跨轮次行为第一轮运行结束后发送 Now do the same for solar power adoption.委派列表应在新的一轮开始时重置Flow 的supervise()在每轮顶部清空state.delegations随后随着新子 Agent 被调用再次增长。每个子 Agent 的结果体非空且格式与角色对应research 为要点、writing 为段落、critique 为要点。需要留意一点在 subagents.py 中supervise开头实际上先copilotkit_emit_state(self.state)保留历史委派注释说明跨轮次累积以匹配 langgraph-python、mastra 等其余后端的语义。QA 文档描述的每轮重置与其实现中self.state.delegations.clear()的确切位置可能存在版本差异——实践中请以当前仓库实现为准无论累积还是清空验收的本质是新轮次的委派记录要与上一轮区分开、并随新子 Agent 调用继续增长。测试时应以运行时实际行为核对若实现为累积日志则应调整断言为新记录追加而非旧记录被覆盖。六、错误处理验证Test Steps 3QA 文档定义了三个错误/边界场景空消息发送空消息应是无操作no-op——不产生用户气泡、不触发监督者调用。歧义消息发送类似 Hi 的模糊消息监督者允许两种行为直接回复而不委派委派计数保持 0或至多启动一个子 Crew。 两种都算通过但聊天必须产生最终的 assistant 消息且运行结束后不允许有任何记录卡在running状态。控制台无未捕获错误以上所有操作期间DevTools Console 不应出现未捕获异常。后端对异常路径的兜底设计值得关注若子 Crew 内部抛错LLM 错误、kickoff异常等Flow 会把委派记录标记为failed并以sub-agent call failed: ExceptionClass (see server logs for details)的形式把错误作为工具消息返回给监督者让它尝试换一种方式完成任务subagents.py。刻意只暴露异常类名是为了避免repr(exc)泄漏 URL、请求 ID 或部分凭证。这是记录永不卡死与监督者可自愈两个验收标准背后的实现保障。另外_MAX_DELEGATION_ROUNDS 6硬上限subagents.py防止 LLM 反复重新委派造成无界循环正常 research → write → critique 加最终总结恰好 3 轮左右6 轮留有充足余量。七、预期结果汇总Expected ResultsQA 文档给出的整体验收标准如下也是每次手工回归的通过定义页面在 3 秒内加载完成一次典型的 research → write → critique 运行在约 60 秒内完成产生 3 条委派记录且全部为completed每条委派记录经历running → completed子 Crew 出错时为failed监督者结束后绝不允许卡在running委派日志在每个新用户回合开始时重置或按实现语义正确追加无 UI 布局错乱、无未捕获控制台错误。八、与 e2e 自动化测试的对应关系这份手工 QA 文档的绝大多数断言都被自动化落地到 tests/e2e/subagents.spec.ts可以作为手工验证 → 自动化的对照范例手工 QA 检查对应 e2e 断言页面渲染、3 个 pill、3 个指示器page loads with composer, 3 pills, and 3 subagent indicators用例断言 composer、三条建议、subagent-indicator-{researcher,writer,critic}可见三个 pill 各产生 3 张非样板结果卡片三个独立用例分别点击 blog / explain / summarizewaitForAllCardsDone等待所有卡片data-statuscomplete并断言结果非空、不得包含Hi there! Im your showcase assistant 等展示样板文案防止此前 Writer/Critic 卡片泄漏聊天欢迎语的回归运行不卡死Summarize a topic用例注释记录了历史 bugdelegations状态键缺少 reducer 时返回 HTTP 400INVALID_CONCURRENT_GRAPH_UPDATE能到达done即证明 reducer 已就位Critique 只跑一次、状态稳定Critic runs exactly once per pill click and stays done (no loop)用例断言恰好 1 张 critic 卡片等待 5 秒后数量仍为 1、状态仍为complete防监督者重复进入 critique 的死循环其中卡片计数与角色映射依赖subagent-card-{researcher,writer,critic}测试钩子该钩子在 subagent-activity-card.tsx 中定义把后端工具名research_agent等映射为短角色名。九、把这份 QA 方法论复用到其他多智能体演示从subagents.md可以提炼出一套可复用的多智能体演示 QA 模板前置条件清单化页面路由、后端健康、模型凭证、Flow 挂载四件事必须显式列出并逐项检查。用稳定的 DOM 钩子做断言所有关键 UI 元素日志、计数、运行徽标、委派条目、状态徽标都应具备data-testidQA 文档与组件源码同源维护。状态机三态验证running → completed/failed的每次跃迁都要能观测到并且运行结束后不得滞留 running是通用铁律。结果体格式校验子 Agent 的输出格式要点/段落/条数由 Task 的expected_output约束QA 应据此做确定性校验。边界与错误场景单列空输入、歧义输入、异常回退failed 监督者自愈必须单独成节。给循环兜底验证后端是否存在类似_MAX_DELEGATION_ROUNDS的防死循环上限并专门加一条同轮不重复委派的回归用例。结合本文引用的源码路径subagents.py、delegation-log.tsx、subagents.spec.ts你既能照单执行手工验收也能把同一套断言迁移到自己的多智能体应用中实现手工 QA 与 e2e 双轨同构。【免费下载链接】CopilotKitThe Frontend Stack for Agents Generative UI. React, Angular, Mobile, Slack, and more. Makers of the AG-UI Protocol项目地址: https://gitcode.com/GitHub_Trending/co/CopilotKit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进