当前位置: 首页 > news >正文

Agent 人机协作回路:审阅-修正-重试的工程化闭环

Agent 人机协作回路:审阅-修正-重试的工程化闭环

一、Agent 的输出不能直接上线

让 Agent 生成一段代码就自动提交到生产环境?这是灾难的配方。Agent 的幻觉率大约在 3-15% 之间(取决于任务复杂度和模型),这意味着每 10 次输出就有 1 次可能有问题。

解决思路不是让 Agent 做得更完美——这在可预见的未来不现实。而是构建一个人机协作闭环:Agent 生成 → 人类审阅 → Agent 修正 → 重新提交,循环往复直到质量过关。

这个闭环的设计难点在于:如何最小化人类的参与时间?如果每轮审阅都要 5 分钟,那还不如人直接写。目标是把人类从"执行者"变成"审批者"——只看差异、只点"通过/驳回",一轮审阅不超过 30 秒。

sequenceDiagram participant H as 人类审阅者 participant C as 协作控制器 participant A as Agent participant G as Git 仓库 H->>C: 提交任务指令 C->>A: 分配任务 + 上下文 A->>A: 规划 + 执行工具链 A->>C: 提交产出 (PR/MR) C->>H: 通知审阅(仅展示 diff) alt 通过 H->>C: 批准 C->>G: Merge + 标记完成 else 驳回(附修改意见) H->>C: 驳回 + 修正指令 C->>A: 传递修正指令 + diff 上下文 A->>A: 针对性修正 A->>C: 更新 PR(force-push) C->>H: 通知重新审阅 end Note over A,C: 最多重试 3 轮,超过则转人工处理

二、闭环的四个核心组件

1. 任务分配与上下文注入

不能直接把用户的自然语言丢给 Agent。需要做任务拆解(Task Decomposition)和上下文注入(Context Injection)。拆解的目的是把大任务分解为 Agent 能稳定执行的小步骤;注入的目的是让 Agent 知道当前项目的技术栈、代码规范、已有代码库。

2. 差异审查界面

人类的审阅成本集中在"理解 Agent 做了什么"。一个 good diff 应该:

  • 只展示变更部分,不展示上下文无关代码
  • 高亮可能有问题的地方(由静态分析工具标记)
  • 附带 Agent 的变更理由说明

3. 修正闭环

驳回时,修正指令必须精确 + 可执行。不能写"这里写得不对",要写"第三个参数应该传入 timeout 而不是 retries,参考 utils/timeout.go:42"。

4. 重试上限

设置 3 轮重试上限。超过 3 轮修正仍未通过,自动转入人工处理队列。防止 Agent 和人类在低质量任务上互相消耗。

三、协作控制器实现

import asyncio import hashlib import json from dataclasses import dataclass, field from datetime import datetime, timedelta from enum import Enum from typing import Optional class ReviewStatus(Enum): PENDING = "pending" APPROVED = "approved" CHANGES_REQUESTED = "changes_requested" class TaskStatus(Enum): IN_PROGRESS = "in_progress" AWAITING_REVIEW = "awaiting_review" REVISION_NEEDED = "revision_needed" COMPLETED = "completed" FAILED = "failed" # 超过重试上限 @dataclass class ReviewFeedback: """审阅反馈。 设计决策: - 包含 diff 上下文便于 Agent 定位 - 修正指令必须是可操作的 - 严重性标记用于优先级排序 """ file_path: str line_range: tuple[int, int] instruction: str # 可执行的修正指令 severity: str = "normal" # critical / normal / suggestion diff_snippet: str = "" # 原始 diff 片段供 Agent 上下文感知 @dataclass class CollaborationTask: task_id: str description: str status: TaskStatus = TaskStatus.IN_PROGRESS retry_count: int = 0 max_retries: int = 3 agent_output: Optional[str] = None review_feedback: list[ReviewFeedback] = field(default_factory=list) created_at: datetime = field(default_factory=datetime.now) updated_at: datetime = field(default_factory=datetime.now) class CollaborationController: """人机协作闭环控制器。 架构决策: - 状态机驱动:IN_PROGRESS → AWAITING_REVIEW → (APPROVED|REVISION_NEEDED) - 超时保护:审阅超过 2 小时自动提醒,超过 24 小时自动转人工 - 重试上限:3 轮,第四轮自动 FAILED """ def __init__(self, agent, git_repo, notifier): self._agent = agent self._git = git_repo self._notifier = notifier self._tasks: dict[str, CollaborationTask] = {} # 审阅超时锁——防止任务长时间无人审阅 self._review_deadlines: dict[str, datetime] = {} async def submit_task(self, description: str) -> CollaborationTask: """提交任务:Agent 生成初稿 → 创建 PR → 通知审阅""" task_id = self._generate_task_id(description) task = CollaborationTask(task_id=task_id, description=description) self._tasks[task_id] = task # Agent 执行任务 try: output = await asyncio.wait_for( self._agent.execute(description), timeout=300.0, # 5 分钟超时 ) except asyncio.TimeoutError: task.status = TaskStatus.FAILED return task task.agent_output = output branch_name = f"agent/task-{task_id[:8]}" # 创建分支 + 提交 + PR await self._git.create_branch(branch_name) await self._git.commit_and_push(branch_name, output) pr_url = await self._git.create_pr(branch_name, description) task.status = TaskStatus.AWAITING_REVIEW task.updated_at = datetime.now() self._review_deadlines[task_id] = datetime.now() + timedelta(hours=2) await self._notifier.send_review_request(task_id, pr_url) return task async def submit_review( self, task_id: str, status: ReviewStatus, feedback: Optional[list[ReviewFeedback]] = None ) -> CollaborationTask: """提交审阅意见""" task = self._tasks.get(task_id) if not task: raise ValueError(f"Task {task_id} not found") if status == ReviewStatus.APPROVED: task.status = TaskStatus.COMPLETED await self._git.merge_pr(task_id) return task if status == ReviewStatus.CHANGES_REQUESTED: task.retry_count += 1 if task.retry_count > task.max_retries: task.status = TaskStatus.FAILED await self._notifier.send_failure_alert(task_id, "exceeded max retries") return task task.review_feedback = feedback or [] task.status = TaskStatus.REVISION_NEEDED task.updated_at = datetime.now() # 异步触发 Agent 修正,不阻塞审阅者 asyncio.create_task(self._agent_revise(task)) return task return task async def _agent_revise(self, task: CollaborationTask) -> None: """Agent 根据审阅反馈修正代码。 关键:让 Agent 在一轮内处理所有反馈,而非逐条逐轮 ——减少审阅轮次是关键 """ revision_prompt = self._build_revision_prompt(task) try: revised_output = await self._agent.execute(revision_prompt) except Exception as e: task.status = TaskStatus.FAILED return task.agent_output = revised_output task.status = TaskStatus.AWAITING_REVIEW task.updated_at = datetime.now() await self._notifier.send_review_request( task.task_id, f"Updated PR for task {task.task_id[:8]}" ) def _build_revision_prompt(self, task: CollaborationTask) -> str: """构建修正提示。 把多条反馈合并成一个 prompt,减少 Agent 推理轮次。 按严重性排序——critical 的改对了再说 suggestion。 """ critical_feedbacks = [f for f in task.review_feedback if f.severity == "critical"] normal_feedbacks = [f for f in task.review_feedback if f.severity != "critical"] prompt_parts = ["请根据以下审阅意见修正代码:\n"] for fb in critical_feedbacks + normal_feedbacks: prompt_parts.append( f"- {fb.file_path}:{fb.line_range[0]}-{fb.line_range[1]}\n" f" 修正方向: {fb.instruction}" ) return "\n".join(prompt_parts) def _generate_task_id(self, description: str) -> str: ts = datetime.now().strftime("%Y%m%d%H%M%S") desc_hash = hashlib.sha256(description.encode()).hexdigest()[:8] return f"task-{ts}-{desc_hash}"

四、边界与工程代价

审阅疲劳的问题

人类审阅者一天最多审 20-30 个 Agent PR。超过这个数,注意力衰减,审批质量下降。需要引入自动化前置检查(lint、test、type-check)先过滤掉明显有问题的产出,减少人类审阅量。

修正收敛性

Agent 不一定能根据反馈正确修正。最坏的情况是:每轮修正引入新的问题,导致重试循环。这就是为什么需要 3 轮上限——保护人类时间。

不适合的场景

  • 需要深度架构判断的任务(Agent 无法理解系统级的耦合关系)
  • 安全关键代码(认证、加密、支付)
  • 一次性脚本/临时任务(人机协作回路的设置成本 > 直接手写)

五、总结

人机协作回路的本质是把人类从"写代码"角色升级为"审代码"角色。这要求闭环设计上做到:Agent 的产出可审查(干净 diff)、人类的反馈可执行(精确指令)、修正的循环可收敛(重试上限)。三个条件缺了任何一个,闭环都会变成负担而非增效。

http://www.jsqmd.com/news/1148419/

相关文章:

  • 免费开源建站工具推荐,零基础新手搭建网站必备,你用过几个?
  • TigerVNC国产化部署实战:ARM架构深度适配与信创环境性能优化指南
  • PyTorch 2.0 特征图可视化:3种Hook方法对比与ResNet-18逐层激活分析
  • 英雄联盟Akari助手:如何用开源工具将游戏效率提升300%
  • DBSCAN 密度聚类算法实战:Python 实现与 3 个核心参数调优指南
  • AI创业的技术债全景图:模型依赖、数据管道和Prompt腐化的系统性治理
  • 数字电路信号上拉与下拉配置及PIC24FJ128GA310实现
  • openEuler Jenkins YAML配置检查:自动化包管理配置文件验证
  • CK2DLL双字节补丁:让《十字军之王II》完美显示中文的终极方案
  • 如何在Windows上轻松解密网易云音乐NCM格式文件
  • 迷你HTML本地测试小工具
  • WayCa鲲鹏故障处理进阶教程:高级RAS特性与自动化诊断方案
  • Vue Vben Admin 5.0:现代化企业级管理后台框架的完整解决方案
  • 如何快速配置游戏汉化:终极CK2DLL双字节字符渲染解决方案
  • 第十二章:常用命令速查与实战技巧
  • Photoshop快速填充前景色
  • 在 48KB SRAM 里挤出每一字节:TFLite Micro MemoryPlanner 的 Greedy 与 Linear 分配策略深度解读与取舍分析
  • OpenSCOW快速上手指南:3个步骤掌握计算中心管理核心功能
  • Adobe Illustrator 2025 正版安装与AI工作流实战指南
  • IQC 部门组织、岗位职责与体系文件审核
  • 基于TM4C123与压电蜂鸣器的嵌入式音频系统设计
  • 如何用ncmdump解锁网易云音乐加密文件?三步实现NCM文件解密
  • 终极FModel使用指南:轻松探索虚幻引擎游戏资源
  • 工业负载控制:TPD2017FN与PIC18F45K80的智能驱动方案
  • 堆排序工程化适配:从题目代码到生产级优先队列的改造
  • ACOLITE开源卫星图像大气校正完整指南:从零到精通
  • 后端Agent框架选型:LangChain、Spring AI与自研方案的工程对比
  • C-NCAP 2024版ADAS测试规程解读:AEB/LKA/ELK等10项新增场景与评分变化
  • Windows更新终极修复指南:一键重置更新组件,彻底解决卡顿失败问题
  • OpenDesign核心组件详解:如何快速掌握Button组件的设计与实现原理