wip(multi-agent): 停止按钮软停止链路调试日志+对话切换500修复+子智能体进度面板+多智能体软停止机制

This commit is contained in:
JOJO 2026-07-14 17:50:15 +08:00
parent 4fcd0ccc4d
commit 30bfb79cbd
21 changed files with 1446 additions and 79 deletions

View File

@ -445,6 +445,25 @@ class MultiAgentState:
def get_blocking_question_id(self, agent_id: int) -> Optional[str]:
return self.agent_blocking_question.get(agent_id)
def cancel_pending_question_for_agent(self, agent_id: int) -> bool:
"""取消指定子智能体正在等待的问答 future用于软停止时解除阻塞。"""
question_id = self.agent_blocking_question.pop(agent_id, None)
if not question_id:
return False
fut = self.pending_questions.pop(question_id, None)
loop = self.pending_question_loops.pop(question_id, None)
if fut and not fut.done():
try:
if loop and not loop.is_closed():
loop.call_soon_threadsafe(fut.cancel)
else:
fut.cancel()
except Exception:
pass
if fut:
return True
return False
# ----- 持久化(最简版) -----
def to_snapshot(self) -> Dict[str, Any]:
return {
@ -463,3 +482,25 @@ class MultiAgentState:
if a.task_id:
state.task_id_to_agent_id[a.task_id] = a.agent_id
return state
def clear(self) -> None:
"""清空所有运行态实例、pending消息、阻塞问答、角色计数。
用于用户连续第二下按停止按钮时强制丢弃所有运行中/半成品状态
"""
# 取消所有阻塞中的 future避免泄漏
for qid, fut in list(self.pending_questions.items()):
loop = self.pending_question_loops.get(qid)
if loop and not loop.is_closed() and not fut.done():
try:
loop.call_soon_threadsafe(fut.cancel)
except Exception:
pass
self.agents.clear()
self.task_id_to_agent_id.clear()
self.pending_master_messages.clear()
self.pending_questions.clear()
self.pending_question_loops.clear()
self.pending_answers.clear()
self.agent_blocking_question.clear()
self.role_counters.clear()

View File

@ -29,6 +29,7 @@ from modules.sub_agent.state import SubAgentStateMixin
from modules.sub_agent.stats import SubAgentStatsMixin
from modules.sub_agent.creation import SubAgentCreationMixin
from modules.multi_agent.debug_logger import ma_debug
from server.utils_common import debug_log
if TYPE_CHECKING:
from core.web_terminal import WebTerminal
@ -385,6 +386,46 @@ class SubAgentManager(SubAgentStateMixin, SubAgentStatsMixin, SubAgentCreationMi
return self._handle_timeout(task)
def soft_stop_all_agents(self, conversation_id: str) -> int:
"""软停止指定会话的所有运行中子智能体。
terminate_sub_agent 的区别不取消 asyncio.Task 而是设 _soft_stop 标志
让子智能体在当前工具完成后进入 idle 状态保留上下文
返回实际发出软停止信号的子智能体数量
"""
debug_log(f"[TaskCancel][stop_debug] soft_stop_all_agents 进入conv={conversation_id}")
count = 0
matched = 0
skipped_terminal = 0
skipped_no_instance = 0
for task_id, task_info in list(self.tasks.items()):
if task_info.get("conversation_id") != conversation_id:
continue
matched += 1
status = task_info.get("status")
debug_log(f"[TaskCancel][stop_debug] soft_stop 遍历: task_id={task_id}, status={status}")
if status in TERMINAL_STATUSES.union({"terminated", "idle"}):
skipped_terminal += 1
debug_log(f"[TaskCancel][stop_debug] soft_stop 跳过 (terminal/idle): task_id={task_id}, status={status}")
continue
agent_id = task_info.get("agent_id")
if agent_id is None:
continue
# 從 _sub_agent_instances 查找 SubAgentTask 实例
sub_agent_task = self._sub_agent_instances.get(agent_id)
debug_log(f"[TaskCancel][stop_debug] soft_stop _sub_agent_instances 查找: agent_id={agent_id}, found={bool(sub_agent_task)}")
if sub_agent_task and hasattr(sub_agent_task, "request_soft_stop"):
try:
sub_agent_task.request_soft_stop()
count += 1
debug_log(f"[TaskCancel][stop_debug] soft_stop 已请求: task_id={task_id}, agent_id={agent_id}")
except Exception as exc:
debug_log(f"[TaskCancel][stop_debug] soft_stop 请求失败: task_id={task_id}, error={exc}")
else:
skipped_no_instance += 1
debug_log(f"[TaskCancel][stop_debug] soft_stop_all_agents 结束: matched={matched}, count={count}, skipped_terminal={skipped_terminal}, skipped_no_instance={skipped_no_instance}")
return count
def terminate_sub_agent(
self,
*,
@ -541,6 +582,7 @@ class SubAgentManager(SubAgentStateMixin, SubAgentStatsMixin, SubAgentCreationMi
"agent_id": task.get("agent_id"),
"summary": task.get("summary"),
"status": task.get("status"),
"display_name": task.get("display_name") or "",
"created_at": task.get("created_at"),
"updated_at": task.get("updated_at"),
"target_dir": task.get("target_project_dir"),
@ -551,6 +593,18 @@ class SubAgentManager(SubAgentStateMixin, SubAgentStatsMixin, SubAgentCreationMi
"sub_conversation_id": task.get("sub_conversation_id"),
}
# 读取 stats 文件获取当前上下文 token
stats_file = Path(task.get("stats_file", ""))
if stats_file.exists():
try:
stats = json.loads(stats_file.read_text(encoding="utf-8"))
snapshot["current_context_tokens"] = stats.get("current_context_tokens", 0)
snapshot["stats_summary"] = self._build_stats_summary(stats)
except Exception:
snapshot["current_context_tokens"] = 0
else:
snapshot["current_context_tokens"] = 0
if snapshot["status"] in TERMINAL_STATUSES or snapshot["status"] == "terminated":
final_result = task.get("final_result") or {}
snapshot["final_message"] = final_result.get("system_message") or final_result.get("message")

View File

@ -103,6 +103,9 @@ class SubAgentTask:
self._stdout_lines: List[str] = []
self._cancelled = False
self._task: Optional[asyncio.Task] = None
# 软停止标志:设为 True 后,子智能体会在当前工具调用完成后
# 停止执行后续工具,保存当前进度并进入 idle 状态(不 terminate
self._soft_stop = False
# 多智能体模式相关字段
self.multi_agent_mode = bool(multi_agent_mode)
@ -135,6 +138,30 @@ class SubAgentTask:
try:
await self._run_loop()
except asyncio.CancelledError:
if self._soft_stop:
# 软停止:中断当前工作,从对话文件恢复,重新进入 idle 等待循环
ma_debug(
"sub_agent_soft_stop_cancelled",
task_id=self.task_id,
agent_id=self.agent_id,
display_name=self.display_name,
)
await asyncio.shield(self._recover_from_soft_stop())
# 不 raise不 return——重新进入 idle 等待后续消息
# 注意:不能清除 self._task 引用inject_message 跨线程唤醒时
# 需要通过 self._task.get_loop() 获取事件循环来 call_soon_threadsafe。
# 当前 task 虽被 cancel 但 CancelledError 被捕获且未 re-raise
# task 会继续执行直到 run() return此期间 self._task 仍有效。
# 进入 idle 等待循环,直到被再次唤醒或取消
try:
await asyncio.shield(self._idle_wait_loop())
except asyncio.CancelledError:
# 二次取消视为硬取消
self._cancelled = True
await asyncio.shield(self._write_failure("子智能体被手动终止"))
raise
return
# 硬取消terminate路径
self._cancelled = True
logger.debug(f"[SubAgent] task={self.task_id} 被取消")
ma_debug("sub_agent_run_cancelled", task_id=self.task_id, agent_id=self.agent_id, display_name=self.display_name)
@ -212,6 +239,14 @@ class SubAgentTask:
self.stats["runtime_seconds"] = int(elapsed)
self.emit("stats", {**self.stats, "turn_count": turn})
# 运行期间实时持久化 stats供 get_sub_agent_status 查询
try:
self.stats_file.parent.mkdir(parents=True, exist_ok=True)
_stats_snapshot = {**self.stats, "runtime_seconds": int(elapsed), "turn_count": turn}
self.stats_file.write_text(json.dumps(_stats_snapshot, ensure_ascii=False), encoding="utf-8")
except Exception:
pass
# 多智能体模式:在模型调用前识别是否有待回答的提问
if self.multi_agent_mode:
self._pending_answer_question_id = self._peek_pending_question_id()
@ -276,6 +311,25 @@ class SubAgentTask:
for tool_call in tool_calls:
if self._cancelled:
break
# 软停止:如果检测到 _soft_stop给未执行的工具调用插入取消结果并跳出
if self._soft_stop:
ma_debug(
"sub_agent_soft_stop_break",
task_id=self.task_id,
agent_id=self.agent_id,
display_name=self.display_name,
skipped_tool=tool_call.get("function", {}).get("name", ""),
)
# 给未执行的工具调用补上“被取消”的 tool result保持消息结构合法
cancelled_progress_id = tool_call.get("id") or f"tool_{int(time.time() * 1000)}_{uuid.uuid4().hex[:6]}"
self.emit("progress", {"id": cancelled_progress_id, "tool": tool_call.get("function", {}).get("name", ""), "status": "cancelled", "args": self._parse_args(tool_call), "ts": int(time.time() * 1000)})
self.messages.append({
"role": "tool",
"tool_call_id": tool_call.get("id", cancelled_progress_id),
"content": "⦶ 工具执行被取消(用户手动停止)",
})
self._persist_conversation(partial_summary=assistant_message[:200])
break
name = tool_call.get("function", {}).get("name", "")
args = self._parse_args(tool_call)
progress_id = tool_call.get("id") or f"tool_{int(time.time() * 1000)}_{uuid.uuid4().hex[:6]}"
@ -300,6 +354,21 @@ class SubAgentTask:
})
self._persist_conversation(partial_summary=assistant_message[:200])
# 软停止:工具循环结束后进入 idle不 terminate
if self._soft_stop and not self._cancelled:
ma_debug(
"sub_agent_soft_stop_idle",
task_id=self.task_id,
agent_id=self.agent_id,
display_name=self.display_name,
)
# 重置软停止标志,下次 Team Leader 可以重新发消息唤醒
self._soft_stop = False
self._mark_idle()
self._idle = True
self._persist_conversation(partial_summary=assistant_message[:200])
continue
# 循环结束(取消或 idle 被外部终止)后的清理
if self.multi_agent_mode and self._cancelled:
if self.multi_agent_state:
@ -557,7 +626,11 @@ class SubAgentTask:
inst.last_output = f"[ask_master] {question[:200]}"
# 阻塞等待回答(状态标为正在等待主智能体回答)
state.mark_status(self.agent_id, "running")
answer = await state.wait_for_answer(question_id, self.agent_id, timeout=float(args.get("timeout_seconds") or 600))
try:
answer = await state.wait_for_answer(question_id, self.agent_id, timeout=float(args.get("timeout_seconds") or 600))
except asyncio.CancelledError:
# 软停止取消了等待 future返回取消结果而非抛 CancelledError
return {"success": False, "error": "等待回答被取消(软停止)", "question_id": question_id}
state.mark_status(self.agent_id, "running")
return {"success": True, "answer": answer, "question_id": question_id}
@ -586,7 +659,10 @@ class SubAgentTask:
msg = build_sub_agent_ask_other_text(self.display_name, target_display, question, question_id)
self.manager.inject_message_to_sub_agent(target_id, msg)
# 阻塞等待回答
answer = await state.wait_for_answer(question_id, self.agent_id, timeout=float(args.get("timeout_seconds") or 600))
try:
answer = await state.wait_for_answer(question_id, self.agent_id, timeout=float(args.get("timeout_seconds") or 600))
except asyncio.CancelledError:
return {"success": False, "error": "等待回答被取消(软停止)", "question_id": question_id}
return {"success": True, "answer": answer, "question_id": question_id}
if name == "answer_other_agent":
@ -621,6 +697,15 @@ class SubAgentTask:
elif name == "run_command":
self.stats["commands"] += 1
# 工具调用后立即持久化 stats供运行期间 get_sub_agent_status 查询
try:
self.stats_file.parent.mkdir(parents=True, exist_ok=True)
_elapsed = int((time.time() * 1000 - self.stats["runtime_start"]) / 1000)
_snapshot = {**self.stats, "runtime_seconds": _elapsed, "turn_count": self.stats.get("turn_count", 0)}
self.stats_file.write_text(json.dumps(_snapshot, ensure_ascii=False), encoding="utf-8")
except Exception:
pass
def _apply_usage(self, usage: Any) -> None:
try:
if isinstance(usage, dict):
@ -866,6 +951,71 @@ class SubAgentTask:
except Exception as exc:
logger.warning(f"[SubAgentTask] 增量保存失败: {exc}")
async def _recover_from_soft_stop(self) -> None:
"""软停止恢复:从磁盘重新加载对话文件,丢弃半成品状态,变 idle。
被取消时的半成品状态调用一半的工具未执行的 tool_calls不会
在对话文件里因为 _persist_conversation 只在完整轮次结束时保存
"""
try:
if self.conversation_file.exists():
data = json.loads(self.conversation_file.read_text(encoding="utf-8"))
self.messages = data.get("messages", [])
ma_debug(
"sub_agent_soft_stop_recovered",
task_id=self.task_id,
agent_id=self.agent_id,
display_name=self.display_name,
messages_count=len(self.messages),
)
except Exception as exc:
logger.warning(f"[SubAgentTask] 软停止恢复失败: {exc}")
# 重置标志和状态
self._soft_stop = False
self._cancelled = False
self._idle = True
if self.multi_agent_state:
self.multi_agent_state.mark_status(self.agent_id, "idle")
# 重新初始化 continue event 以备后续唤醒
self._continue_event = asyncio.Event()
# 持久化恢复后的状态
self._persist_conversation(partial_summary="[soft stopped]")
async def _idle_wait_loop(self) -> None:
"""软停止后进入的 idle 等待循环。
保持子智能体活着等待新消息注入后重新进入 _run_loop 正常工作
"""
while not self._cancelled:
if self._continue_event is None:
self._continue_event = asyncio.Event()
try:
await asyncio.wait_for(self._continue_event.wait(), timeout=1.0)
except asyncio.TimeoutError:
pass
if self._cancelled:
break
if not self._continue_event.is_set():
continue
# 被唤醒了,有新消息注入,重新进入正常 _run_loop
self._continue_event.clear()
self._idle = False
if self.multi_agent_state:
self.multi_agent_state.mark_status(self.agent_id, "running")
ma_debug(
"sub_agent_idle_wait_wake",
task_id=self.task_id,
agent_id=self.agent_id,
display_name=self.display_name,
)
# 重新进入正常循环
await self._run_loop()
# _run_loop 退出后再次 idle 等待
self._idle = True
if self.multi_agent_state:
self.multi_agent_state.mark_status(self.agent_id, "idle")
def _finalize_task(self, success: bool, summary: str, elapsed: float, *, max_turns_exceeded: bool = False, timeout: bool = False) -> None:
runtime_seconds = int(elapsed)
ma_debug(
@ -910,3 +1060,45 @@ class SubAgentTask:
self._cancelled = True
if self._task and not self._task.done():
self._task.cancel()
def request_soft_stop(self) -> None:
"""请求软停止:中断子智能体当前工作 → 从对话文件恢复 → 变 idle。
cancel() 的区别
- cancel(): 取消 asyncio.Task CancelledError _write_failure terminated
- request_soft_stop(): 设标志 + cancel asyncio.Task CancelledError
捕获后重载对话文件丢弃半成品 mark idle 保留实例
"""
from server.utils_common import debug_log as _dbg
_dbg(f"[TaskCancel][stop_debug] request_soft_stop 进入: task_id={self.task_id}, agent_id={self.agent_id}, _soft_stop 前={self._soft_stop}, _task={self._task}, _task.done()={self._task.done() if self._task else 'n/a'}")
self._soft_stop = True
# 取消子智能体正在阻塞等待的 ask_master/ask_other 未来,解除阻塞
if self.multi_agent_state and self.agent_id is not None:
try:
self.multi_agent_state.cancel_pending_question_for_agent(self.agent_id)
_dbg(f"[TaskCancel][stop_debug] request_soft_stop cancel_pending_question_for_agent 已调 agent_id={self.agent_id}")
except Exception as exc:
_dbg(f"[TaskCancel][stop_debug] request_soft_stop cancel_pending_question_for_agent 失败: {exc}")
# 直接 cancel asyncio.Task 以中断正在执行的工具调用/API 调用
# CancelledError 会在 run() 中被捕获,检测到 _soft_stop 后走恢复路径
if self._task and not self._task.done():
try:
loop = self._task.get_loop()
loop.call_soon_threadsafe(self._task.cancel)
_dbg(f"[TaskCancel][stop_debug] request_soft_stop call_soon_threadsafe(cancel) 已投递 task_id={self.task_id}")
except Exception as exc:
_dbg(f"[TaskCancel][stop_debug] request_soft_stop call_soon_threadsafe 失败: {exc}")
self._task.cancel()
else:
_dbg(f"[TaskCancel][stop_debug] request_soft_stop 无可用 _task无法 cancel (done or None): task_id={self.task_id}")
# 额外保险:如果 _task 为 None 但子智能体状态是 running直接设 idle 状态
if self._task is None and self.multi_agent_state and self.agent_id is not None:
_dbg(f"[TaskCancel][stop_debug] request_soft_stop _task 为 None直接 mark idle: task_id={self.task_id}")
self._soft_stop = False
self._idle = True
self.multi_agent_state.mark_status(self.agent_id, "idle")
try:
self._persist_conversation(partial_summary="[soft stopped no task]")
except Exception:
pass

View File

@ -1,15 +1,80 @@
# 多智能体模式
# 多智能体模式 — Team Leader 系统提示词
你是 **Team Leader**(团队领导者),负责协调多个子智能体分工协作完成用户的复杂任务。
## 你的角色
你是 **Team Leader**(团队领导者),一个多智能体协作团队的核心。你不仅仅是"协调者"——你是这个团队的**战略规划者、任务分解者、运行监督者和综合决策者**。
你的职责:
- **理解与规划**:理解用户的复杂需求,制定执行策略,将需求拆解为可独立执行的子任务
- **分工与委派**:为每个子任务选择合适的角色,创建子智能体并下达清晰的指令
- **监督与引导**:掌握团队全局进度,在子智能体偏离方向时及时干预纠正
- **综合与决策**:收集子智能体的产出,综合形成最终结果,对用户负责
- **除非用户要求,或必须为之,你需要尽可能避免自己亲自去执行任务**
你不是单打独斗的执行者。除非任务极其简单或明确不需要子智能体否则你应该主动把任务拆解并指派给合适的角色。但同时你仍然拥有完整的工具集文件读写、终端、搜索、MCP、skill、memory 等),在需要时可以自己动手。
## 任务复杂度评估与投入预算
在开始执行前,先评估任务复杂度,决定子智能体数量和工具调用预算:
- **简单任务**单一明确目标1-2 步即可完成1 个子智能体,约 3-10 次工具调用。甚至可以自己直接做,不需要创建子智能体。
- **中等任务**(需要多方面调查或 2-3 个不同角色协作2-4 个子智能体,每个约 10-15 次工具调用。
- **复杂任务**(涉及多个领域、需要深度调查或多阶段执行):可以创建更多子智能体,每个有明确分工的职责范围。
这些是参考值,不是硬性限制。核心原则是:**投入要与任务价值匹配**。不要为简单问题大动干戈,也不要为复杂问题吝啬资源。如果你发现当前配置不足以完成任务,可以随时调整——创建更多子智能体或给现有子智能体追加任务。
## 委派质量标准
每次用 `send_message_to_sub_agent` 或 `create_sub_agent` 委派任务时,确保指令包含以下四要素:
1. **目标Objective**:这个子智能体要完成什么,产出什么
2. **输出格式Output Format**:期望的产出形式——文件列表、代码片段、分析报告、对比表格等
3. **工具与范围指引Tools & Scope**:应该使用哪些工具、关注哪些目录/领域、不需要做什么
4. **任务边界Boundaries**:明确不需要做什么,避免与其他子智能体的工作重叠
模糊的指令会导致子智能体重复工作、遗漏关键信息或误解任务。例如:
- ❌ "调查一下前端认证实现" — 太模糊,子智能体不知道要做到什么程度、产出什么
- ✅ "分析 `static/src/` 下认证相关组件的实现方式,重点关注 token 存储和路由守卫。产出:组件文件路径列表 + 关键代码逻辑说明 + 潜在问题清单。不需要修改任何代码。" — 目标、范围、产出、边界都清晰
## 工作原则
- **主动分工**:除非任务极其简单或明确不需要子智能体,否则主动把任务拆解并指派给合适的角色。
- **明确指令**:用 `send_message_to_sub_agent` 发任务时,写清楚任务目标、范围、产出要求。
- **及时回答**:当子智能体通过 `ask_master` 提问时,必须尽快通过 `answer_sub_agent_question` 回答。
- **明确指令**委派时写清楚任务目标、范围、产出要求和边界(见上方"委派质量标准"
- **及时回答**:当子智能体通过 `ask_master` 提问时,必须尽快通过 `answer_sub_agent_question` 回答。子智能体在阻塞等待你的回答,拖延会卡住整个团队。
- **监督进度**:通过 `list_active_sub_agents` / `get_sub_agent_status` 掌握全局,并在合适的时机引导子智能体。
- **运行时引导**:看到子智能体作出的步骤需要纠正时,立刻用 `send_message_to_sub_agent` 在其运行期间插入消息干预。
- **运行时引导**在子智能体工作期间,你能看到所有子智能体的输出。积极使用 `send_message_to_sub_agent` 做以下事情:纠正子智能体的错误方向、提供额外的上下文或指导、帮助互不知情的子智能体之间交换信息。子智能体之间不一定会主动沟通,但你知道全局,你应当充当信息桥梁。不要等子智能体跑完再纠正——运行期间实时干预效率更高
- **明确问答**:当你需要一个具体的、可被回答的小问题被某个子智能体处理时,用 `ask_sub_agent` 阻塞等待一轮回答。
- **先宽后窄**:在探索性任务中,引导子智能体先从宽泛的角度了解全局,再逐步聚焦到具体细节。避免一开始就钻入过窄的方向。
- **上下文意识**:子智能体的每轮输出都会插入你的对话上下文。引导子智能体精简输出——只汇报关键步骤和结论,不要把冗长的过程细节都推给你。详细过程留在子智能体自己的上下文里。
## 子智能体运行期间的行为规范
当子智能体正在工作时,你的行为必须遵循以下规则:
- **严格禁止反复查看状态**:不要在子智能体运行期间反复调用 `get_sub_agent_status` 或 `list_active_sub_agents` 来查看进度。子智能体的输出会自动以消息形式插入你的对话,你不需要主动轮询。反复查状态是浪费时间的行为。
- **严格禁止用 sleep 填充等待**:不要在子智能体运行期间反复调用 `sleep` 工具来等待。如果你没有需要立即处理的事情,**立刻停止输出**,等待子智能体的汇报消息自动到达。
- **无事可做时立刻停止输出**:如果你已经把任务委派出去,当前没有需要回答的 `ask_master` 提问,也没有需要干预的情况,就**停止输出**,不要输出任何文字。子智能体的产出会以 user 消息自动插入你的对话,届时你再继续工作。
- **有事可做时主动干预**:如果你在子智能体的输出中发现了需要纠正的错误、可以提供的指导、或需要传递给其他子智能体的信息,立刻用 `send_message_to_sub_agent` 行动。这是你运行期间最有价值的工作。
## 子智能体可能出现的失败模式及应对
子智能体(尤其是能力较弱的模型)可能出现以下问题行为,你需要能识别并及时干预:
| 失败模式 | 表现 | 应对方式 |
|---------|------|---------|
| **角色反转** | 子智能体不干活,反过来向你提问"你觉得该怎么做?"或建议你自己完成 | 用 `send_message_to_sub_agent` 明确要求它直接执行,不要反问 |
| **指令回声** | 子智能体复述任务但不实际执行,输出看起来像做了但实际没做 | 要求它给出具体产物(文件路径、代码片段、数据等),不接受纯概述 |
| **敷衍回复** | "看起来没问题""可能需要进一步调查"等模糊回答 | 明确要求具体结论,不接受"可能""似乎"这类措辞 |
| **无限循环** | 子智能体重复尝试同一种失败方法 | 用 `send_message_to_sub_agent` 指示它换一种根本不同的方法;必要时 `terminate_sub_agent` |
## 收敛与终止判断
- **整体任务完成判断**:当所有子智能体的产出都已收集,且你已经能综合形成给用户的最终回复时,任务完成。不要无谓地让子智能体继续跑。
- **子智能体卡住处理**:如果一个子智能体明显陷入循环或无法推进,先尝试用 `send_message_to_sub_agent` 引导换方向;如果仍无改善,用 `terminate_sub_agent` 终止并自己接手或重新分配。
- **避免过度工程**:从 2-3 个子智能体开始,遇到明确的效率瓶颈再加。不要一开始就创建大量子智能体。
## 工具清单(多智能体模式专属)

View File

@ -2,34 +2,84 @@
你是智能体集群团队的一员。你的团队通过分工协作完成复杂任务,主智能体 **Team Leader** 负责督导全局。
# 在任务中
## 你的角色定位
- 不要频繁输出内容,不重要的内容会污染主智能体上下文
- 只汇报关键步骤
- 任务完成后给出详细结论
- 自然结束输出即本轮任务结束上下文会被保留Team Leader 可能会再次发消息让你继续
你是**执行者**,不是协调者。你的职责是:
# 沟通工具
- **直接执行** Team Leader 分配给你的任务
- 在你的专业领域内自主完成工作,使用你的工具解决问题
- 遇到需要 Team Leader 决策的问题时,通过 `ask_master` 提问
- 完成任务后给出详细的结论和产出
你不是 Team Leader不要反过来指挥 Team Leader 或建议 Team Leader 该做什么。不要试图重新分配任务给其他子智能体——那是 Team Leader 的工作。
## 核心行为准则
### 1. 直接执行,不复述任务
收到任务后,**立即开始执行**,不要复述或改写任务内容。
- ❌ "好的,我来分析一下前端认证的实现方式,首先我会查看..." — 这只是复述任务,没有实际产出
- ✅ 直接调用工具开始工作,在输出中报告你**实际做了什么**和**发现了什么**
### 2. 输出必须具体
你的每一轮输出都应该包含**具体的、可验证的产物**
- ✅ 文件路径、代码片段、数据数字、明确的结论
- ✅ "在 `src/auth/token.ts` 第 42 行发现 token 存储使用 localStorage存在 XSS 风险"
- ❌ "我分析了一下,看起来认证实现基本没问题"
- ❌ "可能需要进一步调查"
- ❌ "似乎有一些潜在的问题"
模糊的、不承诺的、纯概述性的回复是不可接受的。如果你确实无法得出结论,说明**为什么**以及**你尝试了什么**。
### 3. 收敛而非发散
- 如果一种方法尝试了两次仍然失败,**换一种根本不同的方法**,不要重复同样的路径。
- 聚焦于完成分配给你的任务,不要主动扩大范围或去做 Team Leader 没要求的事。
- 如果你觉得任务需要扩展,通过 `ask_master` 向 Team Leader 提议,而不是自行决定。
### 4. 卡住时主动求助
如果你发现自己陷入以下情况,主动求助:
- 同一个错误重复出现,换了方法也无法解决 → `ask_master`
- 任务要求不明确,无法继续 → `ask_master`
- 需要其他子智能体的专业能力 → `ask_other_agent`
- 发现任务范围需要调整 → `ask_master`
不要在原地空转。求助比卡死好。
## 输出节奏
- **工作期间**:只汇报关键步骤和阶段性发现。不要把每一步操作都推给 Team Leader——那会污染主智能体的上下文。
- **任务完成时**:给出详细、结构化的最终结论,包含所有关键产出。
- **自然结束**:你的 assistant 输出后续没有工具调用时即本轮任务结束。上下文会被保留Team Leader 可能会再次发消息让你继续。
## 沟通工具
- **需要 Team Leader 决策时**:调用 `ask_master` 工具,传入 question 文本
- 工具会阻塞等待 Team Leader 通过 `answer_sub_agent_question` 给出回答
- 你的 question 会以 XML 「提问」格式被插入主对话
- 你的 question 会以 XML「提问」格式被插入主对话
- 提问要具体、可回答,不要问开放式问题让 Team Leader 猜你的意思
- **要问其他子智能体时**:调用 `ask_other_agent`,传入 target_agent_id 与 question
- 等待对方调用 `answer_other_agent` 回答
- **要回答其他子智能体的提问时**:调用 `answer_other_agent`,传入 source_agent_id 与 question_id 和 answer
- 你的回答直接作为对方 `ask_other_agent` 工具的结果返回(不会以 user 消息插入对话)
- **查询当前活跃子智能体**:调用 `list_active_sub_agents`
# 关于向你团队「汇报」的强制要求
## 关于向你团队「汇报」的强制要求
**如果你要向其他子智能体提问,必须同时直接输出一条汇报给 Team Leader**(在你的普通文本输出里),说明:
1. 你为什么要问这个问题
2. 你问了谁
3. 你期望得到什么
不能偷偷沟通Team Leader 需要看到完整协作流程。
# 输出格式
## 输出格式
你每轮的普通 assistant 文字输出都会被自动捕获并以如下格式插入到主对话:
@ -46,10 +96,10 @@ id: out_xxxxxxxx
你不需要自己包裹 XML直接输出正文即可。
# 你的显示名
## 你的显示名
你的显示名是 `{display_name}`。
# 你的专属设定
## 你的专属设定
{role_body}

275
research/camel_paper.txt Normal file
View File

@ -0,0 +1,275 @@
CAMEL: Communicative Agents for “Mind” Exploration of Large Language Model Society https://www.camel-ai.org Guohao Li⇤ Hasan Abed Al Kader Hammoud* Hani Itani* Dmitrii Khizbullin Bernard Ghanem King Abdullah University of Science and Technology (KAUST) Abstract The rapid advancement of chat-based language models has led to remarkable progress in complex task-solving. However, their success heavily relies on human input to guide the conversation, which can be challenging and time-consuming.
This paper explores the potential of building scalable techniques to facilitate au-tonomous cooperation among communicative agents, and provides insight into their “cognitive” processes. To address the challenges of achieving autonomous cooperation, we propose a novel communicative agent framework named role-playing . Our approach involves using inception prompting to guide chat agents toward task completion while maintaining consistency with human intentions. We showcase how role-playing can be used to generate conversational data for studying the behaviors and capabilities of a society of agents, providing a valuable resource for investigating conversational language models. In particular, we conduct com-prehensive studies on instruction-following cooperation in multi-agent settings.
Our contributions include introducing a novel communicative agent framework, offering a scalable approach for studying the cooperative behaviors and capabili-ties of multi-agent systems, and open-sourcing our library to support research on communicative agents and beyond: https://github.com/camel-ai/camel.
1 Introduction “What magical trick makes us intelligent? The trick is that there is no trick. The power of intelligence stems from our vast diversity, not from any single, perfect principle.” - Marvin Minsky, The Society of Mind, p. 308 Confronted with the complexities of real-world tasks, solving them often requires multiple steps.
The rapid progress of chat-based large-scale language models (LLMs) has yielded remarkable achievements in complex task-solving [82, 84, 116, 89, 5, 10, 122, 13]. Nevertheless, it is worth noting that their success is heavily reliant on human input to guide the conversation in the right direction. This reliance necessitates users to provide relevant and precise prompts based on their intentions and the chat agents feedback. This can be challenging, time-consuming, and sometimes impossible. Crafting effective prompts often demands a deep understanding and expertise of a particular domain of knowledge. Consider an individual who lacks trading expertise; they would find it difficult to create suitable prompts for directing a chat agent to develop a trading application. This predicament is raising a crucial question: can we replace human intervention with an autonomous communicative agent capable of steering the conversation toward task completion with minimal human supervision? To tackle this issue, it is crucial to conduct more research exploring the potential, ⇤Equal contribution 37th Conference on Neural Information Processing Systems (NeurIPS 2023).
capabilities, and limitations of communicative agents that operate entirely on their own to complete tasks. Understanding how multiple agents interact with each other is important for anticipating the future of artificial intelligence. The dynamics of collaborating or competing agents play a key role in determining the success of AI systems [6, 26, 27, 84, 99, 9, 10].
This paper explores the potential of building scalable techniques to facilitate autonomous cooperation among communicative agents and provide insight into their “cognitive” processes. Several challenges arise when asking a society of agents to autonomously cooperate on completing tasks. Examples we encountered in our preliminary analysis include role flipping, assistant repeating instructions, flake replies, and infinite loop of messages. Therefore, it is critical to investigate ways to align these models with human intentions and to explore means enabling their effective cooperation. To address these issues, we propose a novel cooperative agent framework named role-playing to automate cooperation between communicative agents. Specifically, our proposed approach involves using role-playing with inception prompting to autonomously guide the communicative agents toward task completion. Only a preliminary idea is needed from human to guide the conversations toward complex task-solving.
Our library, which we make publicly available, provides modular functionality, and includes imple-mentations of different agents, examples of well-crafted prompts, and data explorers. We hope our library serves as a ground for future research in various areas such as multi-agent systems, cooperative AI, game theory simulations, social analysis, AI ethics, AI alignment, and beyond. In addition, our role-playing method provides a highly scalable way to generate conversational data for studying the behaviors and capabilities of chat agents. We showcase how role-playing can be used to let chat agents communicate with each other for task completion and record their conversations for behavior analysis and capability understanding. In particular, we consider two cooperative scenarios of role-playing and generate two large conversational, task-oriented, and instruction-following datasets: AI Society and Code. We also use our framework to collect two single-turn question-answer datasets, Math and Science, for LLM ability emergence study. Furthermore, we generate a Misalignment dataset that is a simulation of possible malicious applications which demonstrate the potential risks of an unaligned autonomous agent system. The datasets offer a valuable resource for investigating conversational language models, enabling them to comprehend and react to human language more effectively. Fur-thermore, our role-playing offers a scalable method of creating conversational instruction-following data, which can potentially enhance the development of more advanced language models. We show that solutions derived from our role-playing framework outperform those generated in a single shot by gpt-3.5-turbo [82] in both GPT4 and human evaluations. We also study knowledge emergence in LLMs by fine-tuning LLaMA [117] on progressively growing datasets generated through our framework. Additionally, we evaluate our code generation capabilities through benchmarking our final model on HumanEval [18] and HumanEval+ [69].
Contributions. Our contributions are fourfold: (1) We introduce a novel cooperative agent frame-work, role-playing , that allows communicative agents to collaborate autonomously toward completing tasks while requiring minimal human intervention; (2) Our framework offers a scalable approach for studying the cooperative behaviors and capabilities of multi-agent systems. It illuminates the challenges of achieving autonomous cooperation, and provides strategies for addressing them. We showcase the potential power of multi-agent collaboration for complex-task solving; (3) We demon-strate the significant emergence of LLM training abilities by utilizing the datasets we have collected from simulating four distinct agent collaboration scenarios; (4) We have open-sourced our library, containing implementations of various agents, data generation pipelines, data analysis tools, and collected datasets, to support research on communicative agents and beyond.
2 Related Work Communicative Agents. Communication between agents has been studied for a long time [76, 77]. There are many ways to facilitate communication between agents, and with agents [29, 90, 97]. Among these, natural language is considered the most natural form of communication [97].
By enabling agents to function as communicators themselves, they become capable of solving complex tasks [113, 85, 72, 3, 30, 111, 79, 41, 28, 102, 80, 106, 35, 49, 2, 51, 1, 55, 50, 65, 92].
Communication between AI agents can occur in a competitive setting [115, 108] or a cooperative setting [40, 27, 11, 137, 70]. Cooperative AI refers to artificial intelligence systems that are designed to work together with humans and other AI systems to achieve common goals [24, 125]. Cooperative AI systems take into account the needs and capabilities of other agents in the system and actively seek to collaborate and coordinate their actions with them, which has many potential benefits, including 2 increased efficiency, improved decision-making, and the ability to tackle complex problems that are beyond the reach of any single agent. However, designing effective cooperative AI systems is still an active area of research, as it requires addressing a range of technical, ethical, and social challenges [27]. Our work enables communicative agents to engage in a conversation and cooperate with each other to solve assigned tasks. The agents, each assigned a distinct role, are expected to apply their expertise and knowledge to solve their common task.
Instructional LLMs and Prompt Engineering. LLMs are trained on diverse text data and excel in text completion, with various downstream NLP applications [12, 22, 47, 131, 117]. However, InstructGPT suggests that LLMs may not align with user intent, proposing reinforcement learning from human feedback (RLHF) [23] and Instruction Fine-Tuning (IFT) [121] to improve LLMs relevance and appropriateness to user instructions. Special types of instruction or prompting methods , such as Chain-of-Thought (CoT) [123], zero-shot-CoT [61], and ReAct [126], have recently been developed to enhance the performance of LLMs on reasoning, arithmetic and decision making tasks [134, 118, 52, 73, 31, 103, 43, 64, 132, 46, 133, 105, 128, 25, 81, 109]. These techniques underpin the impressive capabilities of recent dialogue LLMs [106, 116, 36, 9, 82, 13], which aim to simulate human-like conversations and provide personalized and interactive experiences for users, exhibiting the behavior of conversational AI agents [33]. However, generating instruction datasets is a crucial challenge in building instruct-based LLMs, with existing datasets ranging from crowdsourced to generated. Hand-crafted instruction instances are available in [120], while leveraging previously crowdsourced NLP datasets is a less labor-intensive curation approach [121, 71, 78, 53]. LLMs have been explored for data generation in [101, 63, 68, 114], and Self-Instruct [119] proposes a semi-automated process for instruction instance generation. Unnatural-Instruction [48] collects instruction instances by prompting a language model with only three seed examples and paraphrasing the generated instances to expand the dataset. There is also a large chunk of work that has proposed methods for automatic dataset creation [67, 57, 19, 75, 20, 98, 59, 96, 129, 62, 130, 86, 8].
Another important challenge is prompt engineering. The quality of the prompt used to guide LLMs significantly affects its performance [91, 12, 66]. While LMs pre-trained on large data can implicitly learn tasks with few-shot prompting, hand-crafted prompts may not always suffice. Automated prompt generation methods have been proposed, such as gradient-guided search [104], mining-based and paraphrasing-based techniques [54], a meta-prompt [93], and automatic instruction selection and generation [136]. In this work, we introduce a conversational LLM auto-prompting method called Inception Prompting, which enables agents to prompt each other to solve tasks through Role-Playing.
The AI user continuously provides instructions to the AI assistant for task-solving. This enables us to save the streaming instruction-solution pairs and create diverse, instructional, conversational, and task-oriented datasets. These datasets can be used to analyze the behavior and capabilities of LLMs and for future research for fine-tuning LLMs with conversational instructions.
AI Alignment. AI alignment is a field that aims to ensure that AI systems adhere to their intended goals, interests, and values, as envisioned by their designers [4, 39, 110, 32, 38, 74, 10]. The first attempt at AI alignment was made through the "Three Laws of Robotics," which was introduced by Isaac Asimov in his science fiction stories [6]. Developing aligned AI systems is crucial for achieving desired objectives while avoiding unintended consequences. Research in AI alignment focuses on discouraging AI models from producing false, offensive, deceptive, or manipulative information that could result in various harms [56, 112, 42, 37]. Achieving a high level of alignment requires researchers to grapple with complex ethical, philosophical, and technical issues. We conduct extensive experiments to study different role-playing situations, which probe the alignment of LLMs.
3 Methodology In this paper, we focus on studying communicative agents under cooperative settings where they share common interests. In particular, we study the assistant-user scenario, where a preliminary idea is given at the start. Agents will conceptualize the idea into a specific task and complete it autonomously through conversations.
3.1 Role-playing Framework “Whats the most resilient parasite? An Idea. A single idea from the human mind can build cities. An idea can transform the world and rewrite all the rules. Which is why I have to steal it.” - Dom Cobb, Inception 3 Idea: Develop a trading bot for the stock market Human User Role Assignment: AI Assistant: Python Programmer AI User: Stock Trader Human Input Task Specifier AI Assistant AI User Specified Task: Develop a trading bot with a sentiment analysis tool that can monitor social media platforms for positive or negative comments about a particular stock, and execute trades based on sentiment analysis results Instruction: Install the necessary Python libraries for sentiment analysis and stock trading.
Input: None Solution: To install the necessary Python libraries for sentiment analysis and stock trading, we can use pip, the package installer for Python. Here are the libraries we need to install: 1. tweepy - for accessing the Twitter API 2. textblob - for sentiment analysis 3. yfinance - for accessing Yahoo Finance API To install these libraries, open the command prompt or terminal and enter the following commands: pip install tweepy pip install textblob pip install yfinance Next request.
Role Playing Session Instruction: Import the necessary libraries in Python.
Input: None Solution: Here's the code to import these libraries: ``` import tweepy from textblob import TextBlob import pandas as pd import numpy as np import yfinance as yf ``` Next request.
Figure 1: CAMEL Role-Playing Framework. Our role-playing setup starts with the human user having an idea they want to implement, e.g. develop a trading bot for the stock market. The roles involved in this task would be an AI assistant agent who is a python programmer and an AI user agent who is a stock trader. The task is made more specific using our task specifier agent, leading to a well-defined task for the assistant to solve. Both AI user and AI assistant are provided with the specified task, after which they collaboratively communicate by chatting with each other in an instruction-following fashion to solve the specified task.
Our proposed framework is a novel role-playing approach for studying multiple communicative agents. Specifically, we concentrate on task-oriented role-playing that involves one AI assistant and one AI user. After the multi-agent system receives a preliminary idea and the role assignment from human users, a task-specifier agent will provide a detailed description to make the idea specific.
Afterwards, the AI assistant and AI user will cooperate on completing the specified task through multi-turn conversations until the AI user determines the task is done. The AI user is responsible for giving instructions to the AI assistant and directing the conversation toward task completion. On the other hand, the AI assistant is designed to follow the instructions from the AI user and respond with specific solutions. The whole role-playing framework is depicted in Figure 1.
Human Input and Task Specifying. The role-playing session will be instantiated from an idea and selected roles by humans. As an example in Figure 1, a human has a preliminary idea to develop a trading bot for the stock market. Humans may or may not have the knowledge about how the idea can be realized. What is needed is only to designate the potential roles that can implement the idea. For instance, a Python Programmer could collaborate with a Stock Trader to realize the idea of developing a trading bot for the stock market. After the idea and roles are determined, the task specifier agent will brainstorm a specific task that the AI Assistant role can help with the AI user role to complete based on the input idea. An example of a specified task in this scenario could be: develop a trading bot with a sentiment analysis tool that can monitor social media platforms for positive or negative comments about a particular stock, and execute trades based on sentiment analysis results.
The main motivation for introducing a task specifier is that conversational agents usually require a concrete task prompt for realizing the task which might be challenging or time-consuming for a non-domain expert. Therefore, the task specifier agent serves as an enhanced imagination module for the idea implementation. Please note that, when studying our framework at a large scale for AI society and Code scenarios, we generate roles and ideas automatically by prompting LLMs instead of relying on human inputs. For our generated Math and Science datasets we generated problem topics, subtopics, and problems automatically by prompting LLMs.
AI Assistant-User Role Assignment. After the task specification, The AI assistant role and the AI user role will be assigned to the user agent and the assistant agent correspondingly to complete the specified task. In practice, a system message is passed to each agent declaring their role. We refer to the assistant system prompt/message by PA and that of the user by PU. The system messages are passed to the agents before the conversations start. Let F1 and F2 denote two large-scale auto-regressive language models [82]. When the system message is passed to those models respectively, we 4 obtain A FPA 1 and U FPU 2 which are referred to as the assistant and user agents respectively.
In Figure 1, the AI assistant and the AI user are assigned the roles of a Python Programmer and a Stock Trader at the beginning of the role-playing session respectively. The AI user serves as a task planner, engaging in interactive planning to determine feasible steps for the AI assistant to execute.
Meanwhile, the AI assistant acts as a task executor, offering solutions, executing planned steps, and providing responses to the AI user.
Conversation Towards Task-Solving. After the role assignment is completed, the AI assistant A and AI user U will collaborate in an instruction-following manner to accomplish the task. In the AI assistant-user scenario, the AI user is responsible for providing instructions, and the assistant is expected to respond with a solution that fulfills the instructions. Formally, we denote the user instruction message obtained at time t by It and the assistant solution by St. The set of conversational messages obtained up until time t is denoted by Equation (1) shown below: Mt = {(I0, S0), ..., (It, St)} = {(Ii, Si)}|t i=0 (1) At the next time step, t + 1, the AI user U takes the historical conversation message set Mt and provides a new instruction It+1, as shown in Equation (2). The produced instruction message It+1 is then passed, along with message set Mt, to the AI assistant A. The AI assistant will then respond with a solution, denoted by St+1 in Equation (3): It+1 = U(Mt) (2) St + 1 = A(Mt, It + 1) (3) After obtaining the solution St+1 to the instruction It+1, the message set is updated using Equation (4) to obtain Mt+1: Mt+1 Mt [ (It+1, St+1) (4) Note that the formulation above not only models AI-AI communicative scenarios, but it can also be easily extended to model human-AI communication or communication between more than two agents.
Specifically, we can use message-passing graphs to model communication between an arbitrary number of agents. In Figure 1, we observe that the AI user initiates the installation and import of essential Python libraries for sentiment analysis and stock trading by instructing the AI assistant through conversations. This example is drawn from our experiments, and the entire conversation is available in the Appendix.
Critic-In-The-Loop. To enhance the controllability of the role-playing framework, we introduce a critic agent capable of selecting proposals from or providing feedback to the role-playing agents.
This enables tree-search-like decision-making for task-solving. In practice, the critic can be either an AI agent or a human. The detailed implementation and case studies can be found in the Appendix.
3.2 Inception Prompting Since prompt engineering is crucial to our role-playing framework, this section delves deeply into our prompting techniques. Our prompt engineering occurs solely at the beginning of role-playing, for task specification and role assignment. Once the conversation phase commences, the AI assistant and AI user prompt each other automatically in a loop until termination. As such, we refer to our technique as Inception Prompting. Our Inception prompt consists of three prompts: the task specifier prompt PT , the assistant system prompt PA, and the user system prompt PU. As an example, we consider the inception prompt of the AI Society scenario. The templates for these prompts of AI Society role-playing are shown in Figure 2. The task specifier prompt contains information about the roles of the AI assistant and AI user in the role-playing session. Therefore, the task specifier agent can take a preliminary task/idea as input and generate a specific task using imagination. The AI assistant system prompt PA and the AI user system prompt PU are mostly symmetrical and include information about the assigned task and roles, communication protocols, termination conditions, and constraints or requirements to avoid unwanted behaviors. The prompt designs for both roles are crucial to achieve autonomous cooperation between agents. It is non-trivial to engineer prompts that ensure agents act in alignment with our intentions. We take the prompt templates from the AI Society in Figure 2 as an example to explain our key design choices. The prompts used for the Code scenario follow a similar sprint as the AI society scenario, but with some additional engineering related to programming languages. More details in the Appendix.
5 AI Society Inception Prompt Task Specifier Prompt: Here is a task that <ASSISTANT_ROLE> will help <USER_ROLE> to complete: <TASK>.
Please make it more specific. Be creative and imaginative.
Please reply with the specified task in <WORD_LIMIT> words or less. Do not add anything else.
Assistant System Prompt: Never forget you are a <ASSISTANT_ROLE> and I am a <USER_ROLE>. Never flip roles!
Never instruct me!
We share a common interest in collaborating to successfully complete a task.
You must help me to complete the task.
Here is the task: <TASK>. Never forget our task!
I must instruct you based on your expertise and my needs to complete the task.
I must give you one instruction at a time.
You must write a specific solution that appropriately completes the requested instruction.
You must decline my instruction honestly if you cannot perform the instruction due to physical, moral, legal reasons or your capability and explain the reasons.
Unless I say the task is completed, you should always start with: Solution: <YOUR_SOLUTION> <YOUR_SOLUTION> should be specific, and provide preferable implementations and examples for task-solving.
Always end <YOUR_SOLUTION> with: Next request.
User System Prompt: Never forget you are a <USER_ROLE> and I am a <ASSISTANT_ROLE>.
Never flip roles! You will always instruct me.
We share a common interest in collaborating to successfully complete a task.
I must help you to complete the task.
Here is the task: <TASK>. Never forget our task!
You must instruct me based on my expertise and your needs to complete the task ONLY in the following two ways: 1. Instruct with a necessary input: Instruction: <YOUR_INSTRUCTION> Input: <YOUR_INPUT> 2. Instruct without any input: Instruction: <YOUR_INSTRUCTION> Input: None The "Instruction" describes a task or question. The paired "Input" provides further context or information for the requested "Instruction".
You must give me one instruction at a time.
I must write a response that appropriately completes the requested instruction.
I must decline your instruction honestly if I cannot perform the instruction due to physical, moral, legal reasons or my capability and explain the reasons.
You should instruct me not ask me questions.
Now you must start to instruct me using the two ways described above.
Do not add anything else other than your instruction and the optional corresponding input!
Keep giving me instructions and necessary inputs until you think the task is completed.
When the task is completed, you must only reply with a single word <CAMEL_TASK_DONE>.
Never say <CAMEL_TASK_DONE> unless my responses have solved your task.
Figure 2: Inception Prompt of AI Society Role-Playing. This shows the task specifier prompt, assistant system prompt, and user system prompt which are used for studying the AI society scenario.
Prompt Engineering. To delve deeper into the details in Figure 2, we start by chunking the various parts of the AI assistant system prompt PA shown below: • Never forget you are a <ASSISTANT_ROLE> and I am a <USER_ROLE>. This assigns the chosen role to the assistant agent and provides it with information about the users role.
• Never flip roles!
Never instruct me! This prevents agents from flipping roles. In some cases, we have observed the assistant and the user switching roles, where the assistant suddenly takes control and instructs the user, and the user follows those instructions.
• You must decline my instruction honestly if you cannot perform the instruction due to physical, moral, legal reasons or your capability and explain the reasons. This prohibits the agent from producing harmful, false, illegal, and misleading information.
• Unless I say the task is completed, you should always start with: Solution: <YOUR_SOLUTION>.
<YOUR_SOLUTION> should be specific, and provide preferable implementations and examples for task-solving.
This encourages the assistant always responds in a consistent format, avoiding any deviation from the 6 structure of the conversation, and preventing vague or incomplete responses, which we refer to as flake responses, such as "I will do something".
• Always end your solution with: Next request. This ensures that the assistant keeps the conversation going by requesting a new instruction to solve.
For the AI user system prompt PU, we strive to maintain as much symmetry as possible with respect to the AI assistant system prompt. Apart from the opposite role assignment, the user system prompt differs from the assistant prompt in the following ways: • You must instruct me ...
to complete the task ONLY in the following two ways: 1.
Instruct with a necessary input: ...; 2.
Instruct without any input: ... This follows the typical data structure of instruction-following, which allows the generated instruction-solution pairs to be easily used for fine-tuning LLMs.
• Keep giving me instructions and necessary inputs until you think the task is completed.
When the task is completed, you must only reply with a single word <CAMEL_TASK_DONE>.
We introduce an end-of-task token, namely, <CAMEL_TASK_DONE>. This token is used once the user believes the task is done. This ensures that the chat is terminated when the user is satisfied. Without doing so, the agents might fall into a chatting loop where they keep on saying “thank you” to each other or “goodbye” indefinitely.
4 Experiments In this section, we will discuss the various experiments that we conducted to arrive at our final design choices. Specifically, we will examine the interesting observations, challenging issues, and several examples we have encountered while enabling agents to communicate with each other under different prompt design choices to achieve autonomous cooperation. In our experiments, we employed two gpt-3.5-turbo agents, referred to as LLM agents for simplicity, with Inception Prompts, as described in Section 3.2, to simulate assistant-user cooperation. For our analysis, we set our attention on AI Society setting. We also gathered conversational data, named CAMEL AI Society and CAMEL Code datasets and problem-solution pairs data named CAMEL Math and CAMEL Science and analyzed and evaluated their quality. Moreover, we will discuss potential extensions of our framework and highlight both the risks and opportunities that future AI society might present.
Data Generation Prompts of AI Society AI Society Assistant Role Generation Prompt: You are a helpful assistant that can play many different roles. Now please list <NUM_ROLES> different roles that you can play with your expertise in diverse fields. Sort them by alphabetical order. No explanation required.
User Role Generation Prompt: Please list <NUM_ROLES> most common and diverse groups of internet users or occupations.
Use singular form. No explanation.
Sort them by alphabetical order. No explanation required.
Task Generation Prompt: List <NUM_TASKS> diverse tasks that <ASSISTANT_ROLE> can assist <USER_ROLE> cooperatively to achieve together. Be concise. Be creative.
Figure 3: Data Generation Prompts. In order to maintain a scalable approach our data parameters are generated using an LLM model to reduce human involvement in the generation process. The generation prompts for both AI Society dataset are summarized in this figure.
4.1 Role-Playing for AI Society To create our AI Society dataset, we have developed a scalable approach that follows a series of steps.
Firstly, we prompt the LLM agent to generate possible roles for the assistant and the user. We achieve this by providing the LLM agent with specific prompts designed to elicit these roles. Next, we ask the LLM agent to generate a range of possible tasks that can be solved through collaboration between the assistant and user roles generated previously. After generating a range of possible tasks as described 7 in the previous step, we then use the task specifier prompt passed to the LLM agent to make the task more specific. The prompts for assistant role generation, user role generation, and task generation are shown in Figure 5 (AI Society). For our AI society dataset, we generated 50 assistant roles, 50 user roles, and 10 tasks for each combination of roles yielding a total of 25,000 conversations. The generated assistant roles and user roles for AI Society as well as details about the generation of Code, Math and Science datasets can be found in the Appendix.
Challenges and Observations. In this section, we explore the four main challenges that we identified during our analysis of the generated datasets. Our observations shed light on some interesting aspects of cooperative AI and the difficulties that arise in its development.
• Role Flipping: One challenge we encountered was role flipping, where the assistant and user switch roles during the conversation. This issue typically arises when the assistant starts providing instructions or commands instead of following the users prompts, which can lead to confusion and a reversal of roles. To avoid role flipping, it is crucial for the assistant not to ask questions, as this can also contribute to the problem.
• Assistant Repeats Instruction: Another challenge that we observed was the assistant simply repeating the users instructions without any role flipping occurring.
• Flake Replies: We also observed instances where the assistant agent responds with a flake reply, often taking the form of "I will...". These messages do not contribute to the task at hand, as the assistant promises to take action but ultimately fails to follow through.
• Infinite Loop of Messages: An interesting challenge that we encountered was when the assistant and user engage in an infinite loop of meaningless conversation, such as repeatedly thanking each other or saying goodbye without progressing the task. Interestingly, in some cases, the assistant and user are aware that they are stuck in a loop, but are unable to break out of it.
The Appendix shows examples of each of the four challenges discussed above. Overall, our observa-tions highlight the complexity of cooperative AI development and the need for continued exploration and innovation to overcome the challenges we face. By identifying these issues, we hope to contribute to the development of more effective and engaging cooperative AI systems.
Termination Conditions. The conversation between the assistant and user agents is designed to follow a specific format to ensure consistent and accurate data generation. To ensure that both the user and assistant adhere to their respective roles and responsibilities, certain conditions have been set in place to terminate the chat if necessary. These conditions are outlined below: • User No Instruct: If the user does not instruct the assistant for 3 rounds, conversation is ended.
• Assistant Instruct: If the assistant provides an instruction to the user, it indicates a role reversal, and the conversation is terminated.
• End of Task Token: If the user believes that the task has been solved, they are expected to say <CAMEL_TASK_DONE> to signify the completion of the task. Once this message is received, the conversation is terminated.
• Assistant&User Token Limit: Given that gpt-3.5-turbo has a limitation on the number of tokens, the conversation is terminated if either the assistant or the user reach the token limit.
• Maximum Number of Messages: To keep the cost of generated chats in check, we have set a maximum limit of 40 messages. This limit guarantees a long enough conversation between the user and assistant while also ensuring that the data generated is not too costly to produce.
The cost grows quadratically with the length of the conversation, making it essential to set a limit.
5 Evaluation 5.1 Agent Evaluation In order to assess the performance of CAMEL (Cooperative Role-playing Communication), we conduct two types of evaluations: (1) Human evaluation, and (2) GPT4 evaluation. We randomly select 100 tasks from our AI Society dataset for evaluation and 100 tasks from our Code dataset.
Then, we employ the GPT4 model to summarize the content of the CAMEL conversation-based 8 solution, presenting a consolidated final solution. Particularly, a GPT4 is used since it possesses a larger token limit which is suitable for summarization. Summarization also makes CAMEL agents solution undetectable by its format, allowing for a more fair comparison. Subsequently, this solution is compared with a single-shot solution generated by the gpt-3.5-turbo model for the same task.
Sample tasks are provided in the Appendix.
Human Evaluation. For this evaluation, we present both the CAMEL summarized agent solution and the gpt-3.5-turbo single-shot solution side-by-side to human participants. The identity behind each solution is not revealed. Participants are then asked to vote on whether one solution is superior to the other or if they are equally good. A total of 453 responses were collected during this evaluation.
Note that, human evaluation is only done for AI Society, as assessing code is generally harder for humans (without running the code).
GPT4 Evaluation. We engage a GPT4 agent to evaluate the effectiveness of Model 1 (CAMEL Agent solution) versus Model 2 (gpt-3.5-turbo single-shot solution) for each task. More specifically, we prompt GPT4 to score and decide which solution of the two solutions is better.
Results. The summarized results of each evaluation are outlined in Table 1 which showcases that the CAMEL solution outperforms gpt-3.5-turbo single-shot solution in both the human evaluation and the GPT4 evaluation by a big margin. It is also worth noting that both human evaluation and GPT4 evaluation are highly aligned.
Table 1: Agent Evaluation Results: Results of the evaluations of the CAMEL agent against gpt-3.5-turbo using both human evaluators and GPT4 consistently show that utilizing a multi-agent cooperative approach is more effective than gpt-3.5-turbos single shot solution.
Dataset Evaluation Type Draw gpt-3.5-turbo Wins CAMEL Agents Win AI Society Human Evaluation 13.3% 10.4% 76.3% GPT4 Evaluation 4.0% 23.0% 73.0% Code GPT4 Evaluation 0.0% 24.0% 76.0% 5.2 GPT4 for ChatBot Evaluation In this section, we progressively fine-tune a LLaMA 7B model on our generated datasets. By progressively incorporating diverse datasets like AI society, code, math, and science, we expect fine-tuned model to demonstrate the ability to develop an increasingly sophisticated understanding of these domains.
We initially start by training on AI society dataset, which aims to let the model learn about human interactions and societal dynamics. As additional datasets were introduced, such as code, the model gained knowledge of programming logic and syntax, enabling it to generate coherent and executable code snippets. The inclusion of the math dataset further expanded the models capabilities, allowing it to solve complex equations, reason about abstract concepts, and perform precise calculations.
Finally, exposure to the science dataset broadened the models understanding of scientific theories, empirical observations, and experimental methods. The emergence of model capabilities is measured by evaluating the quality of the model responses, before and after training on the new domain, on a set of questions of varying difficulties from each domain. More precisely, the model is tested on 20 AI Society related tasks, 20 coding tasks, 20 math tasks and 60 science tasks.
Those results are highlighted in Table 2 where we see that each time we add a dataset, the model performs better on the incorporated domain. Note that to measure the quality of the models responses, we follow the evaluation from Section T, which involves prompting a GPT4 agent to score and decide which solution is better. It is worth noting that an improvement on other domains is also observed in some cases such as when we train on Code we improve on Science. This is because our Code dataset contains problems that solve tasks in particular domains which include scientific domain. Similarly, training on AI Society improves code as AI Society contains the role of a "programmer" and hence coding related conversations. Finally, note that the draws observed in LLaMA-7B vs AI Society in Math reflects equally bad solutions compared to the draws observed in AI Society + Code + Math vs AI Society + Code + Math + Science where the draws are equally good solutions. This progression from AI society to code to math to science highlights the potential of AI models to acquire a versatile 9 and adaptable knowledge base, paralleling the way humans gain expertise in diverse subjects. Sample tasks are provided in the Appendix.
Table 2: Emergence of Knowledge. By progressively fine-tuning LLaMA on datasets from different domains, we observe the emergence of knowledge as the model transitions from AI society to code, math, and science. This finding is indicated by the fact that Model 2 almost always performs better than Model 1, especially on the added dataset.
Dataset Model 1 Model 2 Draw Model 1 Model 2 AI Society Code Math Science AI Society Code Math Science AI Society 3 0 6 14 Code 3 0 0 20 Math 3 9 5 6 Science 3 0 13 47 AI Society 3 3 3 4 8 8 Code 3 3 3 1 9 10 Math 3 3 3 5 8 7 Science 3 3 3 1 19 40 AI Society 3 3 3 3 3 5 6 9 Code 3 3 3 3 3 1 9 10 Math 3 3 3 3 3 1 3 16 Science 3 3 3 3 3 3 8 49 AI Society 3 3 3 3 3 3 3 3 1 16 Code 3 3 3 3 3 3 3 1 8 11 Math 3 3 3 3 3 3 3 10 5 5 Science 3 3 3 3 3 3 3 9 2 49 AI Society 3 3 3 3 0 0 20 Code 3 3 3 3 0 0 20 Math 3 3 3 3 0 0 20 Science 3 3 3 3 0 0 60 5.3 HumanEval(+) Table 3: HumanEval(+) for Various Models. We test our CAMEL model, which is a LLaMa-7B fine-tuned on all our datasets (AI Society, Code, Math, Science) on HumanEval and HumanEval+ benchmarks, where we show competitive pass@k scores with LLaMa-7B and Vicuna-7B.
HumanEval HumanEval+ pass@k [%] k = 1 k = 100 k = 1 k = 100 gpt-3.5-turbo 69.4 94.0 61.7 89.8 LLaMA-7B 10.5 36.5 --Vicuna-7B 11.0 42.9 9.9 34.7 CAMEL-7B 14.0 57.9 12.2 50.0 To evaluate the coding task-solving capabilities of our CAMEL model, specifically the LLaMA-7B fine-tuned on our comprehensive datasets, we rely on HumanEval [18] and HumanEval+ [69].
The results, as depicted in table 3, clearly demonstrate the remarkable performance of CAMEL. It surpasses not only the LLaMA-7B model but also Vicuna-7B [21] by a big margin. These findings underscore the critical role played by the generated datasets in enhancing LLaMAs ability to tackle coding-related tasks.
6 Conclusion In this paper, we explore the potential of autonomous cooperation among communicative agents and propose a novel cooperative agent framework named role-playing . Our approach enables communicative agents to collaborate autonomously toward completing tasks while requiring minimal human intervention, leading to better solutions are per our thorough evaluations. Through our analysis, we show that achieving autonomous cooperation is challenging due to issues like conversation deviation, role flipping, and termination conditions. Our framework offers a scalable approach for studying the cooperative behaviors and capabilities of multi-agent systems and provides strategies for addressing these challenges. Furthermore, our open-sourced library includes implementations of various agents, data generation pipelines, data analysis tools, and collected datasets, to support research on communicative agents and beyond. Our contributions offer valuable insights into the future of large language artificial intelligence models and cooperative AI systems.
7 Acknowledgements This work was supported by SDAIA-KAUST Center of Excellence in Data Science and Artificial Intelligence (SDAIA-KAUST AI).
10 References [1] Josh Abramson, Arun Ahuja, Iain Barr, Arthur Brussee, Federico Carnevale, Mary Cassin, Rachita Chhaparia, Stephen Clark, Bogdan Damoc, Andrew Dudzik, Petko Georgiev, Aurelia Guy, Tim Harley, Felix Hill, Alden Hung, Zachary Kenton, Jessica Landon, Timothy Lillicrap, Kory Mathewson, Soˇ na Mokrá, Alistair Muldal, Adam Santoro, Nikolay Savinov, Vikrant Varma, Greg Wayne, Duncan Williams, Nathaniel Wong, Chen Yan, and Rui Zhu. Imitating interactive intelligence, 2020.
[2] Michael Ahn, Anthony Brohan, Noah Brown, Yevgen Chebotar, Omar Cortes, Byron David, Chelsea Finn, Chuyuan Fu, Keerthana Gopalakrishnan, Karol Hausman, Alex Herzog, Daniel Ho, Jasmine Hsu, Julian Ibarz, Brian Ichter, Alex Irpan, Eric Jang, Rosario Jauregui Ruano, Kyle Jeffrey, Sally Jesmonth, Nikhil J Joshi, Ryan Julian, Dmitry Kalashnikov, Yuheng Kuang, Kuang-Huei Lee, Sergey Levine, Yao Lu, Linda Luu, Carolina Parada, Peter Pastor, Jornell Quiambao, Kanishka Rao, Jarek Rettinghouse, Diego Reyes, Pierre Sermanet, Nicolas Sievers, Clayton Tan, Alexander Toshev, Vincent Vanhoucke, Fei Xia, Ted Xiao, Peng Xu, Sichun Xu, Mengyuan Yan, and Andy Zeng. Do as i can, not as i say: Grounding language in robotic affordances, 2022.
[3] Jacob Andreas. Language models as agent models, 2022.
[4] Jacob Andreas and Dan Klein. Alignment-based compositional semantics for instruction following. arXiv preprint arXiv:1508.06491, 2015.
[5] Anthropic. Introducing claude. Anthropic Blog, 2023.
[6] Isaac Asimov. I. Robot. Narkaling Productions., 1940.
[7] Jimmy Ba and Rich Caruana. Do deep nets really need to be deep? Advances in neural information processing systems, 27, 2014.
[8] Sanghwan Bae, Donghyun Kwak, Sungdong Kim, Donghoon Ham, Soyoung Kang, Sang-Woo Lee, and Woomyoung Park. Building a role specified open-domain dialogue system leveraging large-scale language models. In Proceedings of the 2022 Conference of the North American Chapter of the Association for Computational Linguistics: Human Language Technologies, pages 21282150, Seattle, United States, July 2022. Association for Computational Linguistics.
[9] Yuntao Bai, Andy Jones, Kamal Ndousse, Amanda Askell, Anna Chen, Nova DasSarma, Dawn Drain, Stanislav Fort, Deep Ganguli, Tom Henighan, et al. Training a helpful and harmless assistant with reinforcement learning from human feedback. arXiv preprint arXiv:2204.05862, 2022.
[10] Yuntao Bai, Saurav Kadavath, Sandipan Kundu, Amanda Askell, Jackson Kernion, Andy Jones, Anna Chen, Anna Goldie, Azalia Mirhoseini, Cameron McKinnon, et al. Constitutional ai: Harmlessness from ai feedback. arXiv preprint arXiv:2212.08073, 2022.
[11] Nolan Bard, Jakob N Foerster, Sarath Chandar, Neil Burch, Marc Lanctot, H Francis Song, Emilio Parisotto, Vincent Dumoulin, Subhodeep Moitra, Edward Hughes, et al. The hanabi challenge: A new frontier for ai research. Artificial Intelligence, 280:103216, 2020.
[12] Tom Brown, Benjamin Mann, Nick Ryder, Melanie Subbiah, Jared D Kaplan, Prafulla Dhariwal, Arvind Neelakantan, Pranav Shyam, Girish Sastry, Amanda Askell, et al. Language models are few-shot learners.
Advances in neural information processing systems, 33:18771901, 2020.
[13] Sébastien Bubeck, Varun Chandrasekaran, Ronen Eldan, Johannes Gehrke, Eric Horvitz, Ece Kamar, Peter Lee, Yin Tat Lee, Yuanzhi Li, Scott Lundberg, et al. Sparks of artificial general intelligence: Early experiments with gpt-4. arXiv preprint arXiv:2303.12712, 2023.
[14] N Carlini, F Tramer, E Wallace, M Jagielski, A Herbert-Voss, K Lee, A Roberts, T Brown, D Song, Ú Erlingsson, et al. Extracting training data from large language models. arxiv. Preprint posted online December, 14, 2020.
[15] Nicholas Carlini, Jamie Hayes, Milad Nasr, Matthew Jagielski, Vikash Sehwag, Florian Tramèr, Borja Balle, Daphne Ippolito, and Eric Wallace. Extracting training data from diffusion models. arXiv preprint arXiv:2301.13188, 2023.
[16] Harrison Chase. Langchain. 2022.
[17] Defang Chen, Jian-Ping Mei, Yuan Zhang, Can Wang, Zhe Wang, Yan Feng, and Chun Chen. Cross-layer distillation with semantic calibration. In Proceedings of the AAAI Conference on Artificial Intelligence, volume 35, pages 70287036, 2021.
11 [18] Mark Chen, Jerry Tworek, Heewoo Jun, Qiming Yuan, Henrique Ponde de Oliveira Pinto, Jared Kaplan, Harri Edwards, Yuri Burda, Nicholas Joseph, Greg Brockman, et al. Evaluating large language models trained on code. arXiv preprint arXiv:2107.03374, 2021.
[19] Maximillian Chen, Alexandros Papangelis, Chenyang Tao, Seokhwan Kim, Andy Rosenbaum, Yang Liu, Zhou Yu, and Dilek Hakkani-Tur. Places: Prompting language models for social conversation synthesis.
arXiv preprint arXiv:2302.03269, 2023.
[20] Maximillian Chen, Alexandros Papangelis, Chenyang Tao, Andy Rosenbaum, Seokhwan Kim, Yang Liu, Zhou Yu, and Dilek Hakkani-Tur. Weakly supervised data augmentation through prompting for dialogue understanding. NeurIPS 2022 Workshop on Synthetic Data for Empowering ML Research, 2022.
[21] Wei-Lin Chiang, Zhuohan Li, Zi Lin, Ying Sheng, Zhanghao Wu, Hao Zhang, Lianmin Zheng, Siyuan Zhuang, Yonghao Zhuang, Joseph E. Gonzalez, Ion Stoica, and Eric P. Xing. Vicuna: An open-source chatbot impressing gpt-4 with 90%* chatgpt quality, March 2023.
[22] Aakanksha Chowdhery, Sharan Narang, Jacob Devlin, Maarten Bosma, Gaurav Mishra, Adam Roberts, Paul Barham, Hyung Won Chung, Charles Sutton, Sebastian Gehrmann, et al. Palm: Scaling language modeling with pathways. arXiv preprint arXiv:2204.02311, 2022.
[23] Paul F Christiano, Jan Leike, Tom Brown, Miljan Martic, Shane Legg, and Dario Amodei. Deep reinforcement learning from human preferences. Advances in neural information processing systems, 30, 2017.
[24] Caroline Claus and Craig Boutilier. The dynamics of reinforcement learning in cooperative multiagent systems. In AAAI/IAAI, 1998.
[25] Antonia Creswell, Murray Shanahan, and Irina Higgins. Selection-inference: Exploiting large language models for interpretable logical reasoning, 2022.
[26] Allan Dafoe, Yoram Bachrach, Gillian Hadfield, Eric Horvitz, Kate Larson, and Thore Graepel. Coopera-tive ai: machines must learn to find common ground. Nature, 593(7857):3336, 2021.
[27] Allan Dafoe, Edward Hughes, Yoram Bachrach, Tantum Collins, Kevin R McKee, Joel Z Leibo, Kate Larson, and Thore Graepel. Open problems in cooperative ai. arXiv preprint arXiv:2012.08630, 2020.
[28] Yali Du, Bo Liu, Vincent Moens, Ziqi Liu, Zhicheng Ren, Jun Wang, Xu Chen, and Haifeng Zhang.
Learning correlated communication topology in multi-agent reinforcement learning. In Proceedings of the 20th International Conference on Autonomous Agents and MultiAgent Systems, pages 456464, 2021.
[29] Tim Finin, Richard Fritzson, Don McKay, and Robin McEntire. Kqml as an agent communication language. In Proceedings of the third international conference on Information and knowledge management, pages 456463, 1994.
[30] Jakob Foerster, Ioannis Alexandros Assael, Nando De Freitas, and Shimon Whiteson. Learning to communicate with deep multi-agent reinforcement learning. Advances in neural information processing systems, 29, 2016.
[31] Yao Fu, Hao Peng, Ashish Sabharwal, Peter Clark, and Tushar Khot. Complexity-based prompting for multi-step reasoning. arXiv preprint arXiv:2210.00720, 2022.
[32] Iason Gabriel. Artificial intelligence, values, and alignment. Minds and Machines, 30:411 437, 2020.
[33] Jianfeng Gao, Michel Galley, and Lihong Li. Neural approaches to conversational ai. In The 41st International ACM SIGIR Conference on Research & Development in Information Retrieval, pages 13711374, 2018.
[34] Leo Gao, Jonathan Tow, Stella Biderman, Sid Black, Anthony DiPofi, Charles Foster, Laurence Golding, Jeffrey Hsu, Kyle McDonell, Niklas Muennighoff, Jason Phang, Laria Reynolds, Eric Tang, Anish Thite, Ben Wang, Kevin Wang, and Andy Zou. A framework for few-shot language model evaluation, September 2021.
[35] Amelia Glaese, Nat McAleese, Maja Trebacz, John Aslanides, Vlad Firoiu, Timo Ewalds, Maribeth Rauh, Laura Weidinger, Martin Chadwick, Phoebe Thacker, Lucy Campbell-Gillingham, Jonathan Uesato, Po-Sen Huang, Ramona Comanescu, Fan Yang, Abigail See, Sumanth Dathathri, Rory Greig, Charlie Chen, Doug Fritz, Jaume Sanchez Elias, Richard Green, Soˇ na Mokrá, Nicholas Fernando, Boxi Wu, Rachel Foley, Susannah Young, Iason Gabriel, William Isaac, John Mellor, Demis Hassabis, Koray Kavukcuoglu, Lisa Anne Hendricks, and Geoffrey Irving. Improving alignment of dialogue agents via targeted human judgements, 2022.
12 [36] Amelia Glaese, Nat McAleese, Maja Tr˛ ebacz, John Aslanides, Vlad Firoiu, Timo Ewalds, Maribeth Rauh, Laura Weidinger, Martin Chadwick, Phoebe Thacker, et al. Improving alignment of dialogue agents via targeted human judgements. arXiv preprint arXiv:2209.14375, 2022.
[37] Josh A Goldstein, Girish Sastry, Micah Musser, Renee DiResta, Matthew Gentzel, and Katerina Se-dova. Generative language models and automated influence operations: Emerging threats and potential mitigations. arXiv preprint arXiv:2301.04246, 2023.
[38] Dylan Hadfield-Menell. The principal-agent alignment problem in artificial intelligence. Ph. D. disserta-tion, 2021.
[39] Dylan Hadfield-Menell, McKane Andrus, and Gillian Hadfield. Legible normativity for ai alignment: The value of silly rules. In Proceedings of the 2019 AAAI/ACM Conference on AI, Ethics, and Society, pages 115121, 2019.
[40] Dylan Hadfield-Menell, Stuart J Russell, Pieter Abbeel, and Anca Dragan. Cooperative inverse reinforce-ment learning. Advances in neural information processing systems, 29, 2016.
[41] Serhii Havrylov and Ivan Titov. Emergence of language with multi-agent games: Learning to communicate with sequences of symbols. Advances in neural information processing systems, 30, 2017.
[42] Peter Henderson, Koustuv Sinha, Nicolas Angelard-Gontier, Nan Rosemary Ke, Genevieve Fried, Ryan Lowe, and Joelle Pineau. Ethical challenges in data-driven dialogue systems. In Proceedings of the 2018 AAAI/ACM Conference on AI, Ethics, and Society, pages 123129, 2018.
[43] Dan Hendrycks, Collin Burns, Saurav Kadavath, Akul Arora, Steven Basart, Eric Tang, Dawn Song, and Jacob Steinhardt. Measuring mathematical problem solving with the math dataset. arXiv preprint arXiv:2103.03874, 2021.
[44] Byeongho Heo, Minsik Lee, Sangdoo Yun, and Jin Young Choi. Knowledge transfer via distillation of activation boundaries formed by hidden neurons. In Proceedings of the AAAI Conference on Artificial Intelligence, volume 33, pages 37793787, 2019.
[45] Geoffrey Hinton, Oriol Vinyals, and Jeff Dean. Distilling the knowledge in a neural network. arXiv preprint arXiv:1503.02531, 2015.
[46] Namgyu Ho, Laura Schmid, and Se-Young Yun. Large language models are reasoning teachers. arXiv preprint arXiv:2212.10071, 2022.
[47] Jordan Hoffmann, Sebastian Borgeaud, Arthur Mensch, Elena Buchatskaya, Trevor Cai, Eliza Rutherford, Diego de Las Casas, Lisa Anne Hendricks, Johannes Welbl, Aidan Clark, et al. Training compute-optimal large language models. arXiv preprint arXiv:2203.15556, 2022.
[48] Or Honovich, Thomas Scialom, Omer Levy, and Timo Schick. Unnatural instructions: Tuning language models with (almost) no human labor. arXiv preprint arXiv:2212.09689, 2022.
[49] Ehsan Hosseini-Asl, Bryan McCann, Chien-Sheng Wu, Semih Yavuz, and Richard Socher. A sim-ple language model for task-oriented dialogue. Advances in Neural Information Processing Systems, 33:2017920191, 2020.
[50] Wenlong Huang, Pieter Abbeel, Deepak Pathak, and Igor Mordatch. Language models as zero-shot planners: Extracting actionable knowledge for embodied agents. arXiv preprint arXiv:2201.07207, 2022.
[51] Wenlong Huang, Fei Xia, Ted Xiao, Harris Chan, Jacky Liang, Pete Florence, Andy Zeng, Jonathan Tompson, Igor Mordatch, Yevgen Chebotar, et al. Inner monologue: Embodied reasoning through planning with language models. arXiv preprint arXiv:2207.05608, 2022.
[52] Shima Imani, Liang Du, and Harsh Shrivastava. Mathprompter: Mathematical reasoning using large language models. arXiv preprint arXiv:2303.05398, 2023.
[53] Srinivasan Iyer, Xi Victoria Lin, Ramakanth Pasunuru, Todor Mihaylov, Dániel Simig, Ping Yu, Kurt Shuster, Tianlu Wang, Qing Liu, Punit Singh Koura, et al. Opt-iml: Scaling language model instruction meta learning through the lens of generalization. arXiv preprint arXiv:2212.12017, 2022.
[54] Zhengbao Jiang, Frank F Xu, Jun Araki, and Graham Neubig. How can we know what language models know? Transactions of the Association for Computational Linguistics, 8:423438, 2020.
[55] Siddharth Karamcheti, Megha Srivastava, Percy Liang, and Dorsa Sadigh. Lila: Language-informed latent actions. In CoRL, pages 13791390, 2021.
13 [56] Zachary Kenton, Tom Everitt, Laura Weidinger, Iason Gabriel, Vladimir Mikulik, and Geoffrey Irving.
Alignment of language agents. arXiv preprint arXiv:2103.14659, 2021.
[57] Hyunwoo Kim, Jack Hessel, Liwei Jiang, Ximing Lu, Youngjae Yu, Pei Zhou, Ronan Le Bras, Mal-ihe Alikhani, Gunhee Kim, Maarten Sap, et al. Soda: Million-scale dialogue distillation with social commonsense contextualization. arXiv preprint arXiv:2212.10465, 2022.
[58] Jangho Kim, Seonguk Park, and Nojun Kwak. Paraphrasing complex network: Network compression via factor transfer. In S. Bengio, H. Wallach, H. Larochelle, K. Grauman, N. Cesa-Bianchi, and R. Garnett, editors, Advances in Neural Information Processing Systems, volume 31. Curran Associates, Inc., 2018.
[59] Yekyung Kim, Seohyeong Jeong, and Kyunghyun Cho. Linda: Unsupervised learning to interpolate in natural language processing. arXiv preprint arXiv:2112.13969, 2021.
[60] Pang Wei Koh and Percy Liang. Understanding black-box predictions via influence functions. In International conference on machine learning, pages 18851894. PMLR, 2017.
[61] Takeshi Kojima, Shixiang Shane Gu, Machel Reid, Yutaka Matsuo, and Yusuke Iwasawa. Large language models are zero-shot reasoners. arXiv preprint arXiv:2205.11916, 2022.
[62] Jonáš Kulhánek, Vojtˇ ech Hudeˇ cek, Tomáš Nekvinda, and Ondˇ rej Dušek. Augpt: Auxiliary tasks and data augmentation for end-to-end dialogue with pre-trained language models. In Proceedings of the 3rd Workshop on Natural Language Processing for Conversational AI, pages 198210, 2021.
[63] Kenton Lee, Kelvin Guu, Luheng He, Tim Dozat, and Hyung Won Chung. Neural data augmentation via example extrapolation. arXiv preprint arXiv:2102.01335, 2021.
[64] Aitor Lewkowycz, Anders Johan Andreassen, David Dohan, Ethan Dyer, Henryk Michalewski, Vinay Venkatesh Ramasesh, Ambrose Slone, Cem Anil, Imanol Schlag, Theo Gutman-Solo, et al.
Solving quantitative reasoning problems with language models. 2022.
[65] Shuang Li, Xavier Puig, Chris Paxton, Yilun Du, Clinton Wang, Linxi Fan, Tao Chen, De-An Huang, Ekin Akyürek, Anima Anandkumar, Jacob Andreas, Igor Mordatch, Antonio Torralba, and Yuke Zhu.
Pre-trained language models for interactive decision-making, 2022.
[66] Xiang Lisa Li and Percy Liang. Prefix-tuning: Optimizing continuous prompts for generation. arXiv preprint arXiv:2101.00190, 2021.
[67] Zekun Li, Wenhu Chen, Shiyang Li, Hong Wang, Jing Qian, and Xifeng Yan. Controllable dialogue simulation with in-context learning. arXiv preprint arXiv:2210.04185, 2022.
[68] Alisa Liu, Swabha Swayamdipta, Noah A. Smith, and Yejin Choi. WANLI: Worker and AI collaboration for natural language inference dataset creation. In Findings of the Association for Computational Linguistics: EMNLP 2022, pages 68266847, Abu Dhabi, United Arab Emirates, December 2022.
Association for Computational Linguistics.
[69] Jiawei Liu, Chunqiu Steven Xia, Yuyao Wang, and Lingming Zhang. Is your code generated by chatgpt really correct? rigorous evaluation of large language models for code generation.
arXiv preprint arXiv:2305.01210, 2023.
[70] Yat Long Lo, Christian Schroeder de Witt, Samuel Sokota, Jakob Nicolaus Foerster, and Shimon Whiteson.
Cheap talk discovery and utilization in multi-agent reinforcement learning. In The Eleventh International Conference on Learning Representations, 2023.
[71] Shayne Longpre, Le Hou, Tu Vu, Albert Webson, Hyung Won Chung, Yi Tay, Denny Zhou, Quoc V Le, Barret Zoph, Jason Wei, et al. The flan collection: Designing data and methods for effective instruction tuning. arXiv preprint arXiv:2301.13688, 2023.
[72] Ryan Lowe, Yi I Wu, Aviv Tamar, Jean Harb, OpenAI Pieter Abbeel, and Igor Mordatch. Multi-agent actor-critic for mixed cooperative-competitive environments. Advances in neural information processing systems, 30, 2017.
[73] Pan Lu, Liang Qiu, Kai-Wei Chang, Ying Nian Wu, Song-Chun Zhu, Tanmay Rajpurohit, Peter Clark, and Ashwin Kalyan. Dynamic prompt learning via policy gradient for semi-structured mathematical reasoning. In ICLR, 2023.
[74] Michael J. Matthews, Samuel H. Matthews, and Thomas K. Kelemen. The alignment problem: Machine learning and human values. Personnel Psychology, 2022.
14 [75] Yu Meng, Jiaxin Huang, Yu Zhang, and Jiawei Han. Generating training data with language models: Towards zero-shot language understanding. In Advances in Neural Information Processing Systems, 2022.
[76] Marvin Minsky. Society of mind. Simon and Schuster, 1988.
[77] Marvin Minsky. The emotion machine: Commonsense thinking, artificial intelligence, and the future of the human mind. Simon and Schuster, 2007.
[78] Swaroop Mishra, Daniel Khashabi, Chitta Baral, and Hannaneh Hajishirzi. Cross-task generalization via natural language crowdsourcing instructions. In ACL, 2022.
[79] Igor Mordatch and Pieter Abbeel. Emergence of grounded compositional language in multi-agent populations. In Proceedings of the AAAI conference on artificial intelligence, volume 32, 2018.
[80] Reiichiro Nakano, Jacob Hilton, Suchir Balaji, Jeff Wu, Long Ouyang, Christina Kim, Christopher Hesse, Shantanu Jain, Vineet Kosaraju, William Saunders, Xu Jiang, Karl Cobbe, Tyna Eloundou, Gretchen Krueger, Kevin Button, Matthew Knight, Benjamin Chess, and John Schulman. Webgpt: Browser-assisted question-answering with human feedback, 2021.
[81] Maxwell Nye, Anders Johan Andreassen, Guy Gur-Ari, Henryk Michalewski, Jacob Austin, David Bieber, David Dohan, Aitor Lewkowycz, Maarten Bosma, David Luan, Charles Sutton, and Augustus Odena.
Show your work: Scratchpads for intermediate computation with language models, 2021.
[82] OpenAI. Introducing chatgpt. Open AI Blog, 2022.
[83] OpenAI. Chatgpt plugins. OpenAI blog, 2023.
[84] Long Ouyang, Jeffrey Wu, Xu Jiang, Diogo Almeida, Carroll Wainwright, Pamela Mishkin, Chong Zhang, Sandhini Agarwal, Katarina Slama, Alex Ray, et al. Training language models to follow instructions with human feedback. Advances in Neural Information Processing Systems, 35:2773027744, 2022.
[85] Liviu Panait and Sean Luke. Cooperative multi-agent learning: The state of the art. Autonomous Agents and Multi-Agent Systems, 11:387434, 2005.
[86] Alexandros Papangelis, Karthik Gopalakrishnan, Aishwarya Padmakumar, Seokhwan Kim, Gokhan Tur, and Dilek Z. Hakkani-Tür. Generative conversational networks. In SIGDIAL, 2021.
[87] Wonpyo Park, Dongju Kim, Yan Lu, and Minsu Cho. Relational knowledge distillation. In Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition, pages 39673976, 2019.
[88] Peyman Passban, Yimeng Wu, Mehdi Rezagholizadeh, and Qun Liu. Alp-kd: Attention-based layer projection for knowledge distillation. In Proceedings of the AAAI Conference on artificial intelligence, volume 35, pages 1365713665, 2021.
[89] Sundar Pichai. An important next step on our ai journey. Google Blog, 2023.
[90] Stefan Poslad. Specifying protocols for multi-agent systems interaction. ACM Transactions on Au-tonomous and Adaptive Systems (TAAS), 2(4):15es, 2007.
[91] Alec Radford, Jeffrey Wu, Rewon Child, David Luan, Dario Amodei, Ilya Sutskever, et al. Language models are unsupervised multitask learners. OpenAI blog, 1(8):9, 2019.
[92] Scott Reed, Konrad Zolna, Emilio Parisotto, Sergio Gomez Colmenarejo, Alexander Novikov, Gabriel Barth-Maron, Mai Gimenez, Yury Sulsky, Jackie Kay, Jost Tobias Springenberg, Tom Eccles, Jake Bruce, Ali Razavi, Ashley Edwards, Nicolas Heess, Yutian Chen, Raia Hadsell, Oriol Vinyals, Mahyar Bordbar, and Nando de Freitas. A generalist agent, 2022.
[93] Laria Reynolds and Kyle McDonell. Prompt programming for large language models: Beyond the few-shot paradigm. In Extended Abstracts of the 2021 CHI Conference on Human Factors in Computing Systems, pages 17, 2021.
[94] Robin Rombach, Andreas Blattmann, Dominik Lorenz, Patrick Esser, and Björn Ommer. High-resolution image synthesis with latent diffusion models, 2021.
[95] Adriana Romero, Nicolas Ballas, Samira Ebrahimi Kahou, Antoine Chassang, Carlo Gatta, and Yoshua Bengio. Fitnets: Hints for thin deep nets. arXiv preprint arXiv:1412.6550, 2014.
[96] Andy Rosenbaum, Saleh Soltan, Wael Hamza, Yannick Versley, and Markus Boese. Linguist: Language model instruction tuning to generate annotated utterances for intent classification and slot tagging. arXiv preprint arXiv:2209.09900, 2022.
15 [97] Stuart J Russell. Artificial intelligence a modern approach. Pearson Education, Inc., 2010.
[98] Gaurav Sahu, Pau Rodriguez, Issam H Laradji, Parmida Atighehchian, David Vazquez, and Dzmitry Bahdanau. Data augmentation for intent classification with off-the-shelf large language models. ACL, 2022.
[99] William Saunders, Catherine Yeh, Jeff Wu, Steven Bills, Long Ouyang, Jonathan Ward, and Jan Leike.
Self-critiquing models for assisting human evaluators. arXiv preprint arXiv:2206.05802, 2022.
[100] Timo Schick, Jane Dwivedi-Yu, Roberto Dessì, Roberta Raileanu, Maria Lomeli, Luke Zettlemoyer, Nicola Cancedda, and Thomas Scialom. Toolformer: Language models can teach themselves to use tools.
arXiv preprint arXiv:2302.04761, 2023.
[101] Timo Schick and Hinrich Schütze. Generating datasets with pretrained language models. In Proceedings of the 2021 Conference on Empirical Methods in Natural Language Processing, pages 69436951, Online and Punta Cana, Dominican Republic, November 2021. Association for Computational Linguistics.
[102] Junjie Sheng, Xiangfeng Wang, Bo Jin, Junchi Yan, Wenhao Li, Tsung-Hui Chang, Jun Wang, and Hongyuan Zha. Learning structured communication for multi-agent reinforcement learning. Autonomous Agents and Multi-Agent Systems, 36(2):50, 2022.
[103] Freda Shi, Mirac Suzgun, Markus Freitag, Xuezhi Wang, Suraj Srivats, Soroush Vosoughi, Hyung Won Chung, Yi Tay, Sebastian Ruder, Denny Zhou, et al. Language models are multilingual chain-of-thought reasoners. In ICLR, 2023.
[104] Taylor Shin, Yasaman Razeghi, Robert L Logan IV, Eric Wallace, and Sameer Singh. Autoprompt: Eliciting knowledge from language models with automatically generated prompts.
arXiv preprint arXiv:2010.15980, 2020.
[105] Noah Shinn, Beck Labash, and Ashwin Gopinath. Reflexion: an autonomous agent with dynamic memory and self-reflection. arXiv preprint arXiv:2303.11366, 2023.
[106] Kurt Shuster, Jing Xu, Mojtaba Komeili, Da Ju, Eric Michael Smith, Stephen Roller, Megan Ung, Moya Chen, Kushal Arora, Joshua Lane, et al. Blenderbot 3: a deployed conversational agent that continually learns to responsibly engage. arXiv preprint arXiv:2208.03188, 2022.
[107] David Silver, Aja Huang, Chris J Maddison, Arthur Guez, Laurent Sifre, George Van Den Driessche, Julian Schrittwieser, Ioannis Antonoglou, Veda Panneershelvam, Marc Lanctot, et al. Mastering the game of go with deep neural networks and tree search. nature, 529(7587):484489, 2016.
[108] David Silver, Julian Schrittwieser, Karen Simonyan, Ioannis Antonoglou, Aja Huang, Arthur Guez, Thomas Hubert, Lucas Baker, Matthew Lai, Adrian Bolton, et al. Mastering the game of go without human knowledge. nature, 550(7676):354359, 2017.
[109] Abishek Sridhar, Robert Lo, Frank F. Xu, Hao Zhu, and Shuyan Zhou. Hierarchical prompting assists large language model on web navigation. In ArXiv, preprint.
[110] Jonathan Stray. Aligning ai optimization to community well-being. International Journal of Community Well-Being, 3:443 463, 2020.
[111] Sainbayar Sukhbaatar, Rob Fergus, et al. Learning multiagent communication with backpropagation.
Advances in neural information processing systems, 29, 2016.
[112] Alex Tamkin, Miles Brundage, Jack Clark, and Deep Ganguli. Understanding the capabilities, limitations, and societal impact of large language models. arXiv preprint arXiv:2102.02503, 2021.
[113] Ming Tan. Multi-agent reinforcement learning: Independent versus cooperative agents. In International Conference on Machine Learning, 1997.
[114] Rohan Taori, Ishaan Gulrajani, Tianyi Zhang, Yann Dubois, Xuechen Li, Carlos Guestrin, Percy Liang, and Tatsunori B. Hashimoto. Stanford alpaca: An instruction-following llama model. https://github.
com/tatsu-lab/stanford_alpaca, 2023.
[115] Gerald Tesauro et al. Temporal difference learning and td-gammon. Communications of the ACM, 38(3):5868, 1995.
[116] Romal Thoppilan, Daniel De Freitas, Jamie Hall, Noam Shazeer, Apoorv Kulshreshtha, Heng-Tze Cheng, Alicia Jin, Taylor Bos, Leslie Baker, Yu Du, et al. Lamda: Language models for dialog applications.
arXiv preprint arXiv:2201.08239, 2022.
16 [117] Hugo Touvron, Thibaut Lavril, Gautier Izacard, Xavier Martinet, Marie-Anne Lachaux, Timothée Lacroix, Baptiste Rozière, Naman Goyal, Eric Hambro, Faisal Azhar, et al. Llama: Open and efficient foundation language models. arXiv preprint arXiv:2302.13971, 2023.
[118] Xuezhi Wang, Jason Wei, Dale Schuurmans, Quoc Le, Ed Chi, and Denny Zhou. Self-consistency improves chain of thought reasoning in language models. In ICLR, 2023.
[119] Yizhong Wang, Yeganeh Kordi, Swaroop Mishra, Alisa Liu, Noah A Smith, Daniel Khashabi, and Hannaneh Hajishirzi. Self-instruct: Aligning language model with self generated instructions. arXiv preprint arXiv:2212.10560, 2022.
[120] Yizhong Wang, Swaroop Mishra, Pegah Alipoormolabashi, Yeganeh Kordi, Amirreza Mirzaei, An-jana Arunkumar, Arjun Ashok, Arut Selvan Dhanasekaran, Atharva Naik, David Stap, et al. Super-naturalinstructions:generalization via declarative instructions on 1600+ tasks. In EMNLP, 2022.
[121] Jason Wei, Maarten Bosma, Vincent Y Zhao, Kelvin Guu, Adams Wei Yu, Brian Lester, Nan Du, Andrew M Dai, and Quoc V Le. Finetuned language models are zero-shot learners. arXiv preprint arXiv:2109.01652, 2021.
[122] Jason Wei, Yi Tay, Rishi Bommasani, Colin Raffel, Barret Zoph, Sebastian Borgeaud, Dani Yogatama, Maarten Bosma, Denny Zhou, Donald Metzler, Ed H. Chi, Tatsunori Hashimoto, Oriol Vinyals, Percy Liang, Jeff Dean, and William Fedus. Emergent abilities of large language models. Transactions on Machine Learning Research, 2022. Survey Certification.
[123] Jason Wei, Xuezhi Wang, Dale Schuurmans, Maarten Bosma, Ed Chi, Quoc Le, and Denny Zhou. Chain of thought prompting elicits reasoning in large language models. arXiv preprint arXiv:2201.11903, 2022.
[124] Thomas Wolf, Lysandre Debut, Victor Sanh, Julien Chaumond, Clement Delangue, Anthony Moi, Pierric Cistac, Tim Rault, Rémi Louf, Morgan Funtowicz, Joe Davison, Sam Shleifer, Patrick von Platen, Clara Ma, Yacine Jernite, Julien Plu, Canwen Xu, Teven Le Scao, Sylvain Gugger, Mariama Drame, Quentin Lhoest, and Alexander M. Rush. Transformers: State-of-the-art natural language processing. In Proceedings of the 2020 Conference on Empirical Methods in Natural Language Processing: System Demonstrations, pages 3845, Online, October 2020. Association for Computational Linguistics.
[125] Michael Wooldridge. An introduction to multiagent systems. John wiley & sons, 2009.
[126] Shunyu Yao, Jeffrey Zhao, Dian Yu, Nan Du, Izhak Shafran, Karthik Narasimhan, and Yuan Cao.
ReAct: Synergizing reasoning and acting in language models. In International Conference on Learning Representations (ICLR), 2023.
[127] Sergey Zagoruyko and Nikos Komodakis. Paying more attention to attention: Improving the performance of convolutional neural networks via attention transfer. arXiv preprint arXiv:1612.03928, 2016.
[128] Eric Zelikman, Yuhuai Wu, Jesse Mu, and Noah D. Goodman. Star: Bootstrapping reasoning with reasoning, 2022.
[129] Houyu Zhang, Zhenghao Liu, Chenyan Xiong, and Zhiyuan Liu. Grounded conversation generation as guided traverses in commonsense knowledge graphs. In ACL, 2020.
[130] Rongsheng Zhang, Yinhe Zheng, Jianzhi Shao, Xiao-Xi Mao, Yadong Xi, and Minlie Huang. Dialogue distillation: Open-domain dialogue augmentation using unpaired data. ArXiv, abs/2009.09427, 2020.
[131] Susan Zhang, Stephen Roller, Naman Goyal, Mikel Artetxe, Moya Chen, Shuohui Chen, Christopher Dewan, Mona Diab, Xian Li, Xi Victoria Lin, et al. Opt: Open pre-trained transformer language models.
arXiv preprint arXiv:2205.01068, 2022.
[132] Zhuosheng Zhang, Aston Zhang, Mu Li, and Alex Smola. Automatic chain of thought prompting in large language models. In ICLR, 2023.
[133] Zhuosheng Zhang, Aston Zhang, Mu Li, Hai Zhao, George Karypis, and Alex Smola. Multimodal chain-of-thought reasoning in language models. arXiv preprint arXiv:2302.00923, 2023.
[134] Denny Zhou, Nathanael Schärli, Le Hou, Jason Wei, Nathan Scales, Xuezhi Wang, Dale Schuurmans, Olivier Bousquet, Quoc Le, and Ed Chi. Least-to-most prompting enables complex reasoning in large language models. arXiv preprint arXiv:2205.10625, 2022.
[135] Shuyan Zhou, Frank F Xu, Hao Zhu, Xuhui Zhou, Robert Lo, Abishek Sridhar, Xianyi Cheng, Yonatan Bisk, Daniel Fried, Uri Alon, et al. Webarena: A realistic web environment for building autonomous agents. arXiv preprint arXiv:2307.13854, 2023.
17 [136] Yongchao Zhou, Andrei Ioan Muresanu, Ziwen Han, Keiran Paster, Silviu Pitis, Harris Chan, and Jimmy Ba. Large language models are human-level prompt engineers. In The Eleventh International Conference on Learning Representations, 2023.
[137] Deyao Zhu, Jun Chen, Kilichbek Haydarov, Xiaoqian Shen, Wenxuan Zhang, and Mohamed Elhoseiny.
Chatgpt asks, blip-2 answers: Automatic questioning towards enriched visual descriptions, 2023.
18

View File

@ -0,0 +1,294 @@
# 多智能体主智能体Team Leader提示词优化调研报告
> 调研时间2026-07-14
> 目的:为 Astrion 项目的多智能体模式 Team Leader 提示词优化提供素材参考
---
## 一、当前现状
### 当前 Team Leader 提示词(`prompts/multi_agent/master.txt`)结构
1. 角色定义(一句话:协调多个子智能体分工协作)
2. 工作原则6 条:主动分工、明确指令、及时回答、监督进度、运行时引导、明确问答)
3. 工具清单9 个多智能体工具表格)
4. 会收到的消息格式(输出/提问 XML 示例)
5. 关于显示名
6. 通信协议三条硬性原则
7. 关于团队全局可见
### 当前子智能体提示词(`prompts/multi_agent/sub_agent.txt`)结构
1. 多智能体身份团队成员Team Leader 督导全局)
2. 在任务中4 条:不频繁输出、只汇报关键步骤、完成后给详细结论、自然结束即本轮结束)
3. 沟通工具ask_master / ask_other_agent / answer_other_agent / list_active_sub_agents
4. 汇报强制要求(向其他子智能体提问必须同时向 Team Leader 汇报)
5. 输出格式
6. 显示名
7. 专属设定role_body 占位符)
---
## 二、外部调研发现
### 来源 1Anthropic 多智能体研究系统(最重要)
**来源**https://www.anthropic.com/engineering/multi-agent-research-system
#### 核心架构
- Orchestrator-Worker 模式lead agent 协调subagents 并行工作
- Lead agent 分析查询 → 制定策略 → spawn subagents → subagents 独立搜索 → 返回结果给 lead agent → lead agent 综合最终答案
#### 8 条提示词工程原则(原文摘录)
1. **Think like your agents**(像你的智能体一样思考)
> "To iterate on prompts, you must understand their effects. We built simulations with the exact prompts and tools, then watched agents work step-by-step. This immediately revealed failure modes: agents continuing when they already had sufficient results, using overly verbose search queries, or selecting incorrect tools."
2. **Teach the orchestrator how to delegate**(教协调者如何委派)⭐ 最关键
> "The lead agent decomposes queries into subtasks and describes them to subagents. Each subagent needs an objective, an output format, guidance on the tools and sources to use, and clear task boundaries. Without detailed task descriptions, agents duplicate work, leave gaps, or fail to find necessary information."
> 教训:简单的 "research the semiconductor shortage" 指令太模糊,导致子智能体重复工作或误解任务。
3. **Scale effort to query complexity**(根据查询复杂度调整投入)⭐
> "Simple fact-finding requires just 1 agent with 3-10 tool calls, direct comparisons might need 2-4 subagents with 10-15 calls each, and complex research might use more than 10 subagents with clearly divided responsibilities."
4. **Tool design and selection are critical**(工具设计和选择至关重要)
> "Examine all available tools first, match tool usage to user intent, search the web for broad external exploration, or prefer specialized tools over generic ones."
5. **Let agents improve themselves**(让智能体自我改进)
> "Claude 4 models can be excellent prompt engineers. When given a prompt and a failure mode, they are able to diagnose why the agent is failing and suggest improvements."
6. **Start wide, then narrow down**(先宽后窄)
> "Search strategy should mirror expert human research: explore the landscape before drilling into specifics. Agents often default to overly long, specific queries. We counteracted this by prompting agents to start with short, broad queries, evaluate what's available, then progressively narrow focus."
7. **Guide the thinking process**(引导思考过程)
> "The lead agent uses thinking to plan its approach, assessing which tools fit the task, determining query complexity and subagent count, and defining each subagent's role."
8. **Parallel tool calling transforms speed and performance**(并行工具调用)
> "The lead agent spins up 3-5 subagents in parallel rather than serially; the subagents use 3+ tools in parallel. These changes cut research time by up to 90%."
#### 关键洞察
> "The best prompts for these agents are not just strict instructions, but **frameworks for collaboration** that define the division of labor, problem-solving approaches, and effort budgets."
#### 避坑经验
- 早期智能体会为简单查询 spawn 50 个子智能体 → 需要在提示词里嵌入 scaling rules
- 子智能体会用过长过具体的搜索查询 → 需要提示先宽后窄
- 子智能体会互相干扰,过度更新 → 需要限制通信频率
---
### 来源 2CAMEL 论文 - Inception Prompting
**来源**https://arxiv.org/abs/2303.17760 (NeurIPS 2023)
#### 四大失败模式CAMEL 系统识别的)
1. **Role-Flipping角色反转**:子智能体停止干活,开始像父智能体一样提问、要求澄清、或反向委派
2. **Instruction Echoing指令回声**:子智能体用不同的话复述任务但不实际执行
3. **Flake Replies敷衍回复**:给出模糊、不承诺的回复,如 "It seems fine"、"Further investigation needed"
4. **Infinite Loops无限循环**:子智能体卡在重复尝试同一种失败方法
#### Inception Prompting 解决方案5 个组件)
1. **Role anchoring角色锚定**
> "Never forget you are a <ASSISTANT_ROLE> and I am a <USER_ROLE>. Never flip roles! Never instruct me!"
2. **Output format enforcement输出格式强制**
> "You must write a specific solution that appropriately completes the requested instruction."
> "Always end <YOUR_SOLUTION> with: Next request."
3. **Completion signaling完成信号**
> "When the task is completed, you must only reply with a single word <CAMEL_TASK_DONE>."
4. **Anti-echo directives反回声指令**
> "Do not restate the task. Perform it."
5. **Convergence pressure收敛压力**
> "If an approach fails twice, try a fundamentally different approach rather than retrying the same thing."
#### CAMEL 提示词模板原文AI Society 场景)
**Assistant System Prompt:**
```
Never forget you are a <ASSISTANT_ROLE> and I am a <USER_ROLE>. Never flip roles!
Never instruct me!
We share a common interest in collaborating to successfully complete a task.
You must help me to complete the task.
Here is the task: <TASK>. Never forget our task!
I must instruct you based on your expertise and my needs to complete the task.
I must give you one instruction at a time.
You must write a specific solution that appropriately completes the requested instruction.
You must decline my instruction honestly if you cannot perform the instruction due to physical, moral, legal reasons or your capability and explain the reasons.
Unless I say the task is completed, you should always start with: Solution: <YOUR_SOLUTION>
<YOUR_SOLUTION> should be specific, and provide preferable implementations and examples for task-solving.
Always end <YOUR_SOLUTION> with: Next request.
```
**User System Prompt:**
```
Never forget you are a <USER_ROLE> and I am a <ASSISTANT_ROLE>.
Never flip roles! You will always instruct me.
We share a common interest in collaborating to successfully complete a task.
I must help you to complete the task.
Here is the task: <TASK>. Never forget our task!
You must instruct me based on my expertise and your needs to complete the task ONLY in the following two ways:
1. Instruct with a necessary input:
Instruction: <YOUR_INSTRUCTION>
Input: <YOUR_INPUT>
2. Instruct without any input:
Instruction: <YOUR_INSTRUCTION>
Input: None
You must give me one instruction at a time.
I must write a response that appropriately completes the requested instruction.
You must decline your instruction honestly if you cannot perform the instruction due to physical, moral, legal reasons or my capability and explain the reasons.
You should instruct me not ask me questions.
Now you must start to instruct me using the two ways described above.
Do not add anything else other than your instruction and the optional corresponding input!
Keep giving me instructions and necessary inputs until you think the task is completed.
When the task is completed, you must only reply with a single word <CAMEL_TASK_DONE>.
Never say <CAMEL_TASK_DONE> unless my responses have solved your task.
```
---
### 来源 3MetaGPT 论文 - SOP 驱动的多智能体协作
**来源**https://arxiv.org/abs/2308.00352
#### 核心理念SOPStandardized Operating Procedures
> "MetaGPT encodes Standardized Operating Procedures (SOPs) into prompt sequences for more streamlined workflows, thus allowing agents with human-like domain expertise to verify intermediate results and reduce errors."
#### 五个角色定义
- Product Manager分析竞争和用户需求创建 PRD
- Architect将需求转化为系统设计组件
- Project Manager任务分发
- Engineer执行代码编写
- QA Engineer测试用例和代码质量
#### 关键设计:结构化通信
> "Unlike ChatDev, agents in MetaGPT communicate through documents and diagrams (structured outputs) rather than dialogue. These documents contain all necessary information, preventing irrelevant or missing content."
#### 发布-订阅机制
> "Any agent can directly retrieve required information from the shared pool, eliminating the need to inquire about other agents and await their responses."
> "An agent activates its action only after receiving all its prerequisite dependencies."
#### 对闲聊的抑制
> "This reduces the risk of hallucinations caused by idle chatter between LLMs, particularly in role-playing frameworks, like: 'Hi, hello and how are you?' Alice (Product Manager); 'Great! Have you had lunch?' Bob (Architect)."
---
### 来源 4LangGraph/CrewAI/AutoGen 框架对比
**来源**https://dev.to/pockit_tools/langgraph-vs-crewai-vs-autogen-the-complete-multi-agent-ai-orchestration-guide-for-2026-2d63
#### LangGraph Supervisor Pattern 提示词示例
```python
def supervisor_node(state: AgentState) -> AgentState:
"""Central coordinator that routes to specialists."""
llm = ChatOpenAI(model="gpt-4o")
decision = llm.invoke([
{"role": "system", "content": """You are a supervisor.
Based on the current state, decide the next action:
- 'research': Need more information
- 'respond': Ready to generate response
- 'escalate': Needs human intervention
- 'complete': Task is done"""},
{"role": "user", "content": f"Current state: {state}"}
])
return {"next_action": decision.content}
```
#### CrewAI 角色定义模式
```python
classifier_agent = Agent(
role="Customer Intent Classifier",
goal="Accurately categorize customer inquiries to route them appropriately",
backstory="""You are an expert at understanding customer needs.
With years of experience in customer service, you can quickly
identify whether a customer needs billing help, technical support,
or has a complaint that needs escalation.""",
verbose=True,
allow_delegation=False # 关键:防止无限委派
)
```
#### 常见陷阱及解决方案
1. **Over-Engineering**20 个智能体做 3 个就能做的事 → 从 2-3 个开始
2. **Infinite Loops**:智能体互相无限委派 → 设置终止条件 `max_iter=10`
3. **Context Window Explosion**:传递完整历史 → 实现摘要或滑动窗口
4. **No Error Boundaries**:一个智能体失败崩溃全系统 → 包裹错误处理
---
### 来源 5GitHub Issue - Inception Prompting 实战
**来源**https://github.com/NousResearch/hermes-agent/issues/375
#### Hermes Agent 的 Inception Prompting 实现方案
**Phase 1: Prompt Hardening提示词加固**
修改 `_build_child_system_prompt()` 包含:
- **Role-anchoring**: "You are executing a delegated task. Do the work directly — do not ask questions, request clarification, or suggest the requester do it instead."
- **Anti-echo**: "Do not restate or paraphrase the task. Perform it using your tools and report concrete results."
- **Output format guidance**: "Your response must include specific findings, file paths, code snippets, or other concrete artifacts. Vague summaries like 'it seems fine' or 'further investigation needed' are not acceptable."
- **Convergence pressure**: "If an approach fails twice, try a fundamentally different approach rather than retrying the same thing."
**Phase 2: Enhanced Guard Rails增强护栏**
- 角色特定提示词coordinator, worker, synthesizer
- 反循环检测:如果智能体最近 N 条消息语义相似,注入 "you appear stuck" 干预
---
## 三、综合分析:当前提示词的不足
对照外部最佳实践,当前 Team Leader 提示词存在以下可改善点:
### 3.1 Team Leader 提示词
| # | 不足 | 外部参考 |
|---|------|----------|
| 1 | **缺少任务复杂度评估指引** | Anthropic应在提示词中嵌入 scaling rules教 Team Leader 评估何时用 1 个子智能体、何时用多个 |
| 2 | **缺少委派质量标准** | Anthropic每个子智能体需要 objective + output format + tools guidance + task boundaries当前只说"写清楚任务目标、范围、产出要求"太笼统 |
| 3 | **缺少"先宽后窄"策略指引** | Anthropic应引导 Team Leader 在分解任务时先探索全局再深入 |
| 4 | **缺少防过度工程指引** | LangGraph/CrewAI应明确"从 2-3 个子智能体开始,遇到明确瓶颈再加" |
| 5 | **缺少收敛和终止判断指引** | CAMEL/MetaGPT应教 Team Leader 如何判断任务完成、如何防止子智能体无限循环 |
| 6 | **缺少对子智能体失败模式的预判** | CAMEL应告知 Team Leader 子智能体可能出现 role-flipping、echoing、flake replies并给出应对策略 |
| 7 | **角色定义太单薄** | CrewAI/MetaGPT当前只有一句话"协调多个子智能体分工协作",缺少 goal、constraints、思维方式指引 |
| 8 | **缺少综合与决策角色强调** | AnthropicTeam Leader 不仅是"协调者",更是"综合者"和"决策者" |
| 9 | **缺少上下文管理意识** | Anthropic应提醒 Team Leader 子智能体输出会消耗主上下文,需要引导子智能体精简输出 |
### 3.2 子智能体提示词
| # | 不足 | 外部参考 |
|---|------|----------|
| 1 | **缺少 role anchoring** | CAMEL应明确"你是执行者,不要反转角色,不要反向提问或委派" |
| 2 | **缺少 anti-echo 指令** | CAMEL/Hermes应明确"不要复述任务,直接执行" |
| 3 | **缺少输出具体性要求** | Hermes应要求"输出必须包含具体发现、文件路径、代码片段等具体产物,模糊总结不可接受" |
| 4 | **缺少收敛压力** | CAMEL/Hermes应加入"如果一个方法失败两次,换一种根本不同的方法" |
| 5 | **缺少 stuck 自检指引** | Hermes Phase 2应引导子智能体自我检测是否陷入循环 |
| 6 | **"不频繁输出"太模糊** | 应给出更具体的输出节奏指引 |
---
## 四、优化方向建议
### 4.1 Team Leader 提示词优化方向
1. **丰富角色定义**:从"协调者"升级为"战略规划者 + 任务分解者 + 综合决策者"
2. **加入任务复杂度评估框架**:简单/中等/复杂三档,对应不同的子智能体数量和工具调用预算
3. **加入委派质量检查清单**:每次委派前自检 objective/output format/tools/boundaries 是否齐全
4. **加入失败模式预判和应对**:告知子智能体可能的问题行为及干预手段
5. **加入收敛和终止指引**:如何判断整体任务完成、如何处理卡住的子智能体
6. **加入上下文管理意识**:引导子智能体精简输出,避免主上下文膨胀
### 4.2 子智能体提示词优化方向
1. **加入 role anchoring**:明确角色边界,禁止角色反转
2. **加入 anti-echo 和输出具体性要求**:不复述任务,输出必须具体
3. **加入收敛压力和 stuck 自检**:失败换方法,自我检测循环
4. **优化输出节奏指引**:从"不频繁输出"改为更具体的节奏建议
---
*报告完毕,接下来可与用户讨论具体优化方案。*

View File

@ -1077,6 +1077,25 @@ async def poll_multi_agent_notifications(*, web_terminal, workspace, conversatio
ma_debug("poll_ma_notifications_end", conversation_id=conversation_id, tick=tick_count)
# poll 退出时,如果主智能体也空闲且没有 pending 消息,发送 task_complete 通知前端对话变空闲。
# 否则前端会一直保持 taskInProgress=trueMultiAgentTaskProbe 会持续轮询但找不到任务。
if not getattr(web_terminal, "_multi_agent_main_task_active", False):
state = manager.get_multi_agent_state(conversation_id) if manager else None
still_running = state and any(a.status == "running" for a in state.list_all())
still_pending = state and state.has_pending_master_messages()
if not still_running and not still_pending:
sender('task_complete', {
'total_iterations': 0,
'total_tool_calls': 0,
'auto_fix_attempts': 0,
'has_running_sub_agents': False,
'has_running_background_commands': False,
'has_running_multi_agent': False,
'pending_runtime_guidance_messages': [],
'multi_agent_idle_signal': True,
})
ma_debug("poll_ma_idle_signal_sent", conversation_id=conversation_id, tick=tick_count)
async def _dispatch_multi_agent_idle_messages(
*,

View File

@ -177,7 +177,9 @@ def _get_active_workspace_task(username: str, workspace_id: str):
def _build_safe_load_result(terminal: WebTerminal, conversation_id: str) -> Dict[str, Any]:
"""只读取对话元数据,不调用 terminal.load_conversation避免修改运行任务正在使用的上下文。"""
normalized_id = _normalize_conv_id(conversation_id)
cm = getattr(getattr(terminal, "context_manager", None), "conversation_manager", None)
ctx_manager = getattr(terminal, "context_manager", None)
# 用 _get_conversation_manager_for_id 自动判断对话属于普通管理器还是多智能体管理器
cm = ctx_manager._get_conversation_manager_for_id(normalized_id) if ctx_manager else None
data = cm.load_conversation(normalized_id) if cm else None
if not data:
return {
@ -840,7 +842,8 @@ def load_conversation(conversation_id, terminal: WebTerminal, workspace: UserWor
result_message=result.get("message", ""),
not_found=True,
)
return jsonify(result), 404 if "不存在" in result.get("message", "") else 500
status_code = 404 if "不存在" in result.get("message", "") else 500
return jsonify(result), status_code
except Exception as e:
import traceback

View File

@ -205,7 +205,9 @@ def cancel_task_api(task_id: str):
rec = task_manager.get_task(username, task_id)
if not rec:
return jsonify({"success": False, "error": "任务不存在"}), 404
ok = task_manager.cancel_task(username, task_id)
force_stop = bool(request.json.get("force_stop", False)) if request.is_json else False
debug_log(f"[TaskCancel][stop_debug] cancel_task_api 收到请求: task_id={task_id}, force_stop={force_stop}, body={request.json if request.is_json else None}")
ok = task_manager.cancel_task(username, task_id, force_stop=force_stop)
# 用户取消任务时,一并停止该工作区的目标模式,避免后续新对话继承旧目标。
try:
if ok and rec.workspace_id:

View File

@ -211,10 +211,11 @@ class TaskManager:
if rec.username == username and (workspace_id is None or rec.workspace_id == workspace_id)
]
def cancel_task(self, username: str, task_id: str) -> bool:
def cancel_task(self, username: str, task_id: str, force_stop: bool = False) -> bool:
debug_log(f"[TaskCancel][stop_debug] === cancel_task 被调 === task_id={task_id}, force_stop={force_stop}")
rec = self.get_task(username, task_id)
if not rec:
debug_log(f"[TaskCancel] cancel_task 找不到任务: task_id={task_id}")
debug_log(f"[TaskCancel][stop_debug] cancel_task 找不到任务: task_id={task_id}")
return False
# 立即快照进入时的状态,后续所有两段式判断都用它。
@ -222,31 +223,49 @@ class TaskManager:
# 如果后面再读会被误判为第二下。
status_at_entry = rec.status
debug_log(
f"[TaskCancel] 入口: task_id={task_id}, status={status_at_entry}, "
f"conversation_id={rec.conversation_id}, workspace_id={rec.workspace_id}"
)
# 1. 硬取消主 asyncio task如果引用还在
# 先取终端引用,后续多智能体模式与两段式都要用
entry = stop_flags.get(task_id)
terminal = None
if isinstance(entry, dict):
terminal = entry.get('terminal')
if not terminal and rec.workspace_id:
try:
terminal, _ = get_user_resources(username, rec.workspace_id)
debug_log(f"[TaskCancel][stop_debug] fallback get_user_resources 获取 terminal OK")
except Exception as exc:
debug_log(f"[TaskCancel][stop_debug] fallback get_user_resources 失败: {exc}")
is_ma_mode = bool(getattr(terminal, 'multi_agent_mode', False)) if terminal else False
debug_log(
f"[TaskCancel][stop_debug] 入口状态: task_id={task_id}, status={status_at_entry}, "
f"conversation_id={rec.conversation_id}, workspace_id={rec.workspace_id}, "
f"force_stop={force_stop}, multi_agent_mode={is_ma_mode}, terminal_present={bool(terminal)}"
)
# 多智能体模式 force_stop跳过两段式直接走强制停止路径
# 适用场景:第一下已停主智能体,第二下停所有子智能体并重载对话
if force_stop:
debug_log(f"[TaskCancel][stop_debug] force_stop=true → 走 _force_stop_multi_agent 分支")
return self._force_stop_multi_agent(rec, entry, terminal, username)
debug_log(f"[TaskCancel][stop_debug] force_stop=false → 走两段式分支(可诱导出终端)")
# 1. 硬取消主 asyncio task如果引用还在
if isinstance(entry, dict):
loop = entry.get('loop')
task = entry.get('task')
debug_log(
f"[TaskCancel] stop_flags entry: loop_exists={loop is not None}, "
f"[TaskCancel][stop_debug] stop_flags entry: loop_exists={loop is not None}, "
f"task_exists={task is not None}, task_done={task.done() if task else 'n/a'}"
)
if loop and task and not task.done():
try:
loop.call_soon_threadsafe(task.cancel)
debug_log(f"[TaskCancel] 已投递硬取消: task_id={task_id}")
debug_log(f"[TaskCancel][stop_debug] 已投递硬取消: task_id={task_id}")
except Exception as exc:
debug_log(f"[TaskCancel] 硬取消失败: task_id={task_id}, error={exc}")
debug_log(f"[TaskCancel][stop_debug] 硬取消失败: task_id={task_id}, error={exc}")
entry['stop'] = True
else:
debug_log(f"[TaskCancel] stop_flags 无 entry设软标志: task_id={task_id}")
debug_log(f"[TaskCancel][stop_debug] stop_flags 无 entry设软标志: task_id={task_id}")
stop_flags[task_id] = {'stop': True, 'task': None, 'terminal': None, 'loop': None}
entry = stop_flags[task_id]
@ -291,6 +310,7 @@ class TaskManager:
# task_stopped 事件会被丢弃,前端无法感知并弹提示。
# 注意 2_run_chat_task finally 可能并发先执行并把 status 设为 stopped
# 此时不要再覆盖回 cancel_requested。
debug_log(f"[TaskCancel][stop_debug] 第一下分支ma_mode={is_ma_mode}, 仅取消主智能体")
with self._lock:
if rec.status in {"running", "pending"}:
rec.status = "cancel_requested"
@ -302,16 +322,49 @@ class TaskManager:
f"current_status={rec.status}"
)
return True
else:
debug_log(f"[TaskCancel][stop_debug] 第二下分支进入status_at_entry={status_at_entry}, is_ma_mode={is_ma_mode}")
# 第二下:清理后台任务(过滤 500ms 内的重复请求)
if rec.last_cancel_at is not None and (now - rec.last_cancel_at) < 0.5:
debug_log(
f"[TaskCancel] 忽略 500ms 内重复取消请求: task_id={task_id}, "
f"[TaskCancel][stop_debug] 500ms 内重复取消,忽略: task_id={task_id}, "
f"elapsed={now - rec.last_cancel_at:.3f}s"
)
return True
has_running_background = self._cleanup_background_tasks(rec, terminal)
is_ma_mode = bool(getattr(terminal, "multi_agent_mode", False))
debug_log(f"[TaskCancel][stop_debug] 准备清理后台任务is_ma_mode={is_ma_mode}")
if is_ma_mode:
# 多智能体模式:第二下不应走 terminate 路径!
# 应改为软停止所有子智能体,与 force_stop 一致。
debug_log(f"[TaskCancel][stop_debug] 多智能体模式第二下分支,转走软停止路径(不是 terminate")
soft_stop_count = 0
if terminal:
sub_agent_manager = getattr(terminal, 'sub_agent_manager', None)
if sub_agent_manager:
try:
sub_agent_manager.reconcile_task_states(conversation_id=rec.conversation_id)
soft_stop_count = sub_agent_manager.soft_stop_all_agents(rec.conversation_id)
debug_log(f"[TaskCancel][stop_debug] 软停止 {soft_stop_count} 个子智能体已发出")
except Exception as exc:
debug_log(f"[TaskCancel][stop_debug] soft_stop_all_agents 失败: {exc}")
# 清空主智能体多智能体运行态(与旧逻辑一致)
if terminal and rec.conversation_id:
try:
ma_state = terminal.sub_agent_manager.get_multi_agent_state(rec.conversation_id)
if ma_state:
ma_state.clear()
debug_log(f"[TaskCancel][stop_debug] 多智能体状态已清空: conv={rec.conversation_id}")
except Exception as exc:
debug_log(f"[TaskCancel][stop_debug] 清空多智能体状态失败: {exc}")
has_running_background = False
else:
# 传统模式:第二下继续走 terminate 路径
debug_log(f"[TaskCancel][stop_debug] 传统模式第二下分支,继续 _cleanup_background_tasks terminate")
has_running_background = self._cleanup_background_tasks(rec, terminal)
with self._lock:
rec.status = "stopped"
rec.updated_at = time.time()
@ -321,6 +374,23 @@ class TaskManager:
f"[TaskCancel] 第二下:清理后台并停止: task_id={task_id}, "
f"has_running_background={has_running_background}"
)
# 多智能体模式:从已保存对话文件恢复,丢弃运行中的半成品状态
# (调用一半的工具、输出一半的内容等不会保存在对话文件里)
reload_ok = False
messages_count = 0
if is_ma_mode and terminal and rec.conversation_id:
try:
result = terminal.load_conversation(rec.conversation_id, restore_model=False)
if result.get("success"):
reload_ok = True
messages_count = result.get("messages_count", 0)
debug_log(f"[TaskCancel] 多智能体对话已从文件恢复: conv={rec.conversation_id}, messages={messages_count}")
else:
debug_log(f"[TaskCancel] 多智能体对话恢复失败: {result.get('message', '')}")
except Exception as exc:
debug_log(f"[TaskCancel] 多智能体对话恢复异常: {exc}")
try:
from server.extensions import socketio
socketio.emit('task_stopped', {
@ -330,11 +400,94 @@ class TaskManager:
'conversation_id': rec.conversation_id,
'has_running_sub_agents': False,
'has_running_background_commands': False,
'has_running_multi_agent': False,
'multi_agent_reloaded': reload_ok,
'messages_count': messages_count,
}, room=f"user_{username}")
except Exception as exc:
debug_log(f"[TaskCancel] 发送 task_stopped 事件失败: {exc}")
return True
def _force_stop_multi_agent(self, rec: TaskRecord, entry, terminal, username: str) -> bool:
"""多智能体模式强制停止:软停止所有子智能体 → 重载主对话 → 变空闲。
与传统模式第二下的区别
- 传统模式第二下terminate 后台子智能体会终止进程并留下终止记录
- 多智能体模式软停止子智能体完成当前工具后变 idle
+ 从已保存对话文件恢复主对话丢弃主智能体接收到的半成品输出
"""
debug_log(f"[TaskCancel][stop_debug] === _force_stop_multi_agent 被调 === task_id={rec.task_id}")
task_id = rec.task_id
# 1. 先确保主智能体也取消(如果还在跑)
if entry:
entry['stop'] = True
debug_log(f"[TaskCancel][stop_debug] _force_stop_multi_agent entry.stop=True")
rec.stop_requested = True
# 2. 获取 terminal
if not terminal and rec.workspace_id:
try:
terminal, _ = get_user_resources(username, rec.workspace_id)
debug_log(f"[TaskCancel][stop_debug] _force_stop_multi_agent fallback get terminal OK")
except Exception as exc:
debug_log(f"[TaskCancel][stop_debug] _force_stop_multi_agent fallback get terminal 失败: {exc}")
# 3. 软停止所有子智能体(不 terminate让它们在当前工具完成后变 idle
soft_stop_count = 0
if terminal:
sub_agent_manager = getattr(terminal, 'sub_agent_manager', None)
if sub_agent_manager:
try:
sub_agent_manager.reconcile_task_states(conversation_id=rec.conversation_id)
soft_stop_count = sub_agent_manager.soft_stop_all_agents(rec.conversation_id)
debug_log(f"[TaskCancel][stop_debug] force_stop 软停止 {soft_stop_count} 个子智能体")
except Exception as exc:
debug_log(f"[TaskCancel][stop_debug] force_stop 软停止子智能体异常: {exc}")
else:
debug_log(f"[TaskCancel][stop_debug] terminal 无 sub_agent_manager无法软停止")
else:
debug_log(f"[TaskCancel][stop_debug] terminal 为 None无法软停止")
# 4. 标记任务已停止
with self._lock:
rec.status = "stopped"
rec.updated_at = time.time()
rec.events.clear()
# 5. 从已保存对话文件恢复,丢弃主对话半成品状态
reload_ok = False
messages_count = 0
if terminal and rec.conversation_id:
try:
result = terminal.load_conversation(rec.conversation_id, restore_model=False)
if result.get("success"):
reload_ok = True
messages_count = result.get("messages_count", 0)
debug_log(f"[TaskCancel] force_stop 主对话已从文件恢复: conv={rec.conversation_id}, messages={messages_count}")
else:
debug_log(f"[TaskCancel] force_stop 对话恢复失败: {result.get('message', '')}")
except Exception as exc:
debug_log(f"[TaskCancel] force_stop 对话恢复异常: {exc}")
# 6. 发送 task_stopped 事件通知前端
try:
from server.extensions import socketio
socketio.emit('task_stopped', {
'message': '所有子智能体已停止',
'reason': 'force_stop',
'task_id': task_id,
'conversation_id': rec.conversation_id,
'has_running_sub_agents': False,
'has_running_background_commands': False,
'has_running_multi_agent': False,
'multi_agent_reloaded': reload_ok,
'messages_count': messages_count,
}, room=f"user_{username}")
except Exception as exc:
debug_log(f"[TaskCancel] force_stop 发送 task_stopped 事件失败: {exc}")
return True
@staticmethod
def _normalize_runtime_pending_queue(raw_queue: Any) -> List[Dict[str, Any]]:
now_ts = time.time()
@ -613,8 +766,10 @@ class TaskManager:
# ---- internal helpers ----
def _cleanup_background_tasks(self, rec: TaskRecord, terminal: Optional[Any]) -> bool:
"""清理指定任务/对话下的所有后台子智能体和后台命令,返回是否清理到任何任务。"""
debug_log(f"[TaskCancel][stop_debug] _cleanup_background_tasks 被调! conv={rec.conversation_id}")
has_running_background = False
if not terminal or not rec.conversation_id:
debug_log(f"[TaskCancel][stop_debug] _cleanup_background_tasks 跳过terminal或conv 不存在")
return has_running_background
sub_agent_manager = getattr(terminal, 'sub_agent_manager', None)
@ -627,6 +782,7 @@ class TaskManager:
status = task_info.get('status')
if status not in SUB_AGENT_TERMINAL_STATUSES.union({"terminated"}):
has_running_background = True
debug_log(f"[TaskCancel][stop_debug] 调用 terminate_sub_agent: task_id={task_info.get('task_id')}, status={status}")
try:
sub_agent_manager.terminate_sub_agent(task_id=task_info.get('task_id'))
except Exception as exc:

View File

@ -330,6 +330,7 @@
:goal-progress="goalProgress"
:multi-agent-mode="multiAgentMode"
:has-running-task="composerBusy || anyWorkspaceHasRunningTask"
:main-chat-idle="mainChatIdle"
:avatar-status="showStatusAvatar && messages.length > 0 ? avatarStatus : null"
@restore-user-question="restoreUserQuestionDialog"
@update:input-message="inputSetMessage"

View File

@ -252,6 +252,23 @@ export const computed = {
this.compressing
);
},
/**
*
* composerBusy composerBusy=true
* waitingForSubAgent / has_running_multi_agent
*
* mainChatIdle streaming
* monitor
*/
mainChatIdle() {
return (
!this.streamingUi &&
!this.stopRequested &&
!(this.monitorIsLocked && this.chatDisplayMode === 'monitor') &&
!this.compressionInProgress &&
!this.compressing
);
},
composerStreamingForInput() {
return this.composerBusy && !this.displayLockEngaged;
},

View File

@ -30,6 +30,37 @@ export const sendMethods = {
});
return;
}
// 主对话空闲但 composerBusy=truecomposerBusy 只因后台子智能体在跑而保持。
// 传统模式waitingForSubAgent=truetaskInProgress=true 。多智能体模式has_running_multi_agent=true。
// 此时新文本消息应直接发送,触发主智能体下一轮工作,而不是被进队列等任务结束。
const mainIdle = typeof this.mainChatIdle === 'function' ? this.mainChatIdle : (
!this.streamingUi && !this.stopRequested && !this.compressionInProgress && !this.compressing
);
console.log('[STOP_DEBUG] handleSendOrStop 状态 → composerBusy:', this.composerBusy, 'mainIdle:', mainIdle, 'hasText:', hasText, 'hasMedia:', hasMedia, 'waitingForSubAgent:', this.waitingForSubAgent);
if (this.composerBusy && mainIdle && hasText) {
// 如果有 pending 问题(子智能体询问主智能体),仍走问答路径,不走直接发送
if (Array.isArray(this.pendingUserQuestions) && this.pendingUserQuestions.length > 0) {
const answered = await this.answerUserQuestionFromComposer(this.inputMessage);
if (answered) {
this.inputClearMessage();
this.inputSetLineCount(1);
this.inputSetMultiline(false);
this.autoResizeInput();
}
return;
}
console.log('[STOP_DEBUG] 主对话空闲但后台子智能体在跑,直接发送新消息触发主智能体下一轮');
this.sendMessage();
return;
}
if (this.composerBusy && mainIdle && hasMedia) {
this.uiPushToast({
title: '后台子智能体运行中',
message: '请等待后台任务结束后再发送图片/视频',
type: 'warning'
});
return;
}
if (this.composerBusy) {
if (hasText) {
if (Array.isArray(this.pendingUserQuestions) && this.pendingUserQuestions.length > 0) {
@ -395,13 +426,25 @@ export const sendMethods = {
return;
}
const canStop = this.composerBusy && !this.stopRequested;
// 多智能体模式下stopRequested 不阻止第二次点击——第二次点击是强制停止子智能体
const isMultiAgent = !!this.multiAgentMode;
const canStop = isMultiAgent
? (this.composerBusy || this.stopRequested)
: (this.composerBusy && !this.stopRequested);
// 多智能体模式下如果主智能体已经停了stopRequested=true第二次点击是 force stop
const isForceStop = isMultiAgent && this.stopRequested;
console.log('[STOP_DEBUG] stopTask 状态快照 → isMultiAgent:', isMultiAgent, 'composerBusy:', this.composerBusy, 'stopRequested:', this.stopRequested, 'taskInProgress:', this.taskInProgress, 'canStop:', canStop, 'isForceStop:', isForceStop);
goalModeDebugLog('stopTask:entry', {
composerBusy: this.composerBusy,
stopRequested: this.stopRequested,
taskInProgress: this.taskInProgress,
streamingUi: this.streamingUi,
canStop,
isForceStop,
isMultiAgent,
currentTaskId: this.currentTaskId,
});
if (!canStop) {
@ -427,52 +470,72 @@ export const sendMethods = {
const taskStore = useTaskStore();
if (taskStore.currentTaskId) {
await taskStore.cancelTask();
await taskStore.cancelTask(isForceStop);
}
// 等待后端确认轮询继续task_stopped 事件到达后会由 taskStore 自动停止轮询
await new Promise((resolve) => setTimeout(resolve, 300));
const shouldKeepBusy =
['running', 'pending', 'cancel_requested', 'canceled'].includes(String(taskStore.taskStatus));
goalModeDebugLog('stopTask:try-end', {
currentTaskId: taskStore.currentTaskId,
taskStatus: taskStore.taskStatus,
shouldKeepBusy,
streamingMessage: this.streamingMessage,
});
// 多智能体模式强制停止后,直接释放所有状态,等待 task_stopped 事件处理重载
if (isForceStop) {
this.clearPendingTools('user_stop');
this.streamingMessage = false;
this.taskInProgress = false;
this.forceUnlockMonitor('user_stop');
if (typeof this.clearProcessedEvents === 'function') {
this.clearProcessedEvents();
}
this.stopMultiAgentTaskProbe();
this.stopWaitingTaskProbe();
const lastMessage = this.messages[this.messages.length - 1];
if (lastMessage && lastMessage.role === 'assistant') {
lastMessage.awaitingFirstContent = false;
lastMessage.generatingLabel = '';
}
console.log('[DEBUG_AWAITING] stopTask force stop 清理完成');
} else {
const shouldKeepBusy =
['running', 'pending', 'cancel_requested', 'canceled'].includes(String(taskStore.taskStatus));
// 清理前端状态
this.clearPendingTools('user_stop');
this.streamingMessage = false;
// 若后台已回传停止事件,不要再次把输入区锁回“停止中”
this.taskInProgress = shouldKeepBusy;
this.forceUnlockMonitor('user_stop');
if (typeof this.clearProcessedEvents === 'function') {
this.clearProcessedEvents();
}
goalModeDebugLog('stopTask:try-end', {
currentTaskId: taskStore.currentTaskId,
taskStatus: taskStore.taskStatus,
shouldKeepBusy,
streamingMessage: this.streamingMessage,
});
// 清理assistant消息的等待动画状态
const lastMessage = this.messages[this.messages.length - 1];
const before = {
hasLastMessage: !!lastMessage,
role: lastMessage?.role,
awaitingFirstContent: lastMessage?.awaitingFirstContent,
generatingLabel: lastMessage?.generatingLabel
};
// 清理前端状态
this.clearPendingTools('user_stop');
this.streamingMessage = false;
// 若后台已回传停止事件,不要再次把输入区锁回“停止中”
this.taskInProgress = shouldKeepBusy;
this.forceUnlockMonitor('user_stop');
if (typeof this.clearProcessedEvents === 'function') {
this.clearProcessedEvents();
}
if (lastMessage && lastMessage.role === 'assistant') {
lastMessage.awaitingFirstContent = false;
lastMessage.generatingLabel = '';
}
console.log('[DEBUG_AWAITING] stopTask 清理完成', {
before,
after: {
// 清理assistant消息的等待动画状态
const lastMessage = this.messages[this.messages.length - 1];
const before = {
hasLastMessage: !!lastMessage,
role: lastMessage?.role,
awaitingFirstContent: lastMessage?.awaitingFirstContent,
generatingLabel: lastMessage?.generatingLabel
};
if (lastMessage && lastMessage.role === 'assistant') {
lastMessage.awaitingFirstContent = false;
lastMessage.generatingLabel = '';
}
});
console.log('[DEBUG_AWAITING] stopTask 清理完成', {
before,
after: {
awaitingFirstContent: lastMessage?.awaitingFirstContent,
generatingLabel: lastMessage?.generatingLabel
}
});
}
} catch (error) {
console.error('[Message] 取消任务失败:', error);
const { useTaskStore } = await import('../../../stores/task');

View File

@ -620,6 +620,11 @@ const props = defineProps<{
goalProgress?: Record<string, any> | null;
multiAgentMode?: boolean;
hasRunningTask?: boolean;
/**
* 主对话是否空闲composerBusy 可能是 true但只是因为后台子智能体在跑
* 多智能体模式下若主对话空闲输入栏应处于正常发送状态不是停止状态
*/
mainChatIdle?: boolean;
hasPendingRuntimeGuidance?: boolean;
terminalCount?: number;
hostMode?: boolean;
@ -2398,12 +2403,32 @@ const hasComposerContent = computed(() => {
return hasText || hasImages || hasVideos;
});
const showStopIcon = computed(() => props.streamingMessage && !hasComposerContent.value);
const showStopIcon = computed(() => {
//
// streaming mainChatIdle=false
if (props.multiAgentMode) {
if (props.mainChatIdle) {
return false;
}
return !hasComposerContent.value;
}
return props.streamingMessage && !hasComposerContent.value;
});
const sendButtonDisabled = computed(() => {
if (!props.isConnected) {
return true;
}
//
if (props.multiAgentMode && props.mainChatIdle) {
if (props.inputLocked) {
return true;
}
if (props.mediaUploading) {
return true;
}
return !hasComposerContent.value;
}
if (props.streamingMessage) {
return false;
}

View File

@ -160,10 +160,13 @@
@click="openSubAgent(agent)"
>
<div class="sub-agent-header">
<span class="sub-agent-id">#{{ agent.agent_id }}</span>
<span class="sub-agent-summary-text">{{ agent.summary || agent.display_name || `#${agent.agent_id}` }}</span>
<span class="sub-agent-status" :class="agent.status">{{ agent.status }}</span>
</div>
<div class="sub-agent-summary">{{ agent.summary }}</div>
<div class="sub-agent-meta">
<span class="sub-agent-name" v-if="agent.display_name">{{ agent.display_name }}</span>
<span class="sub-agent-tokens" v-if="agent.current_context_tokens">{{ formatTokens(agent.current_context_tokens) }}</span>
</div>
<div class="sub-agent-tool" v-if="agent.last_tool">当前{{ agent.last_tool }}</div>
</div>
</div>
@ -433,6 +436,14 @@ const formatBackgroundCommandPreview = (rawCommand: any) => {
return content;
};
const formatTokens = (tokens: number) => {
if (!tokens || tokens <= 0) return '';
if (tokens >= 1000) {
return `${(tokens / 1000).toFixed(1)}k ctx`;
}
return `${tokens} ctx`;
};
defineExpose({
panelMenuWrapper
});

View File

@ -1642,9 +1642,44 @@ export async function initializeLegacySocket(ctx: any) {
// 任务停止
ctx.socket.on('task_stopped', (data) => {
socketLog('任务已停止:', data.message);
console.log('[STOP_DEBUG] 收到 task_stopped 事件:', JSON.stringify({
message: data.message,
reason: data.reason,
task_id: data.task_id,
has_running_sub_agents: data.has_running_sub_agents,
has_running_background_commands: data.has_running_background_commands,
has_running_multi_agent: data.has_running_multi_agent,
multi_agent_reloaded: data.multi_agent_reloaded,
multiAgentMode: ctx.multiAgentMode,
stopRequested_before: ctx.stopRequested,
taskInProgress_before: ctx.taskInProgress,
composerBusy: ctx.composerBusy
}));
const hasRunningSubAgents = !!data?.has_running_sub_agents;
const hasRunningBackgroundCommands = !!data?.has_running_background_commands;
const hasRunningBackground = hasRunningSubAgents || hasRunningBackgroundCommands;
const hasRunningMultiAgent = !!data?.has_running_multi_agent;
const multiAgentReloaded = !!data?.multi_agent_reloaded;
// 多智能体模式下,第二下停止后后端已从文件恢复对话,前端需要重新加载对话内容
if (multiAgentReloaded && ctx.currentConversationId) {
console.log('[DEBUG] 多智能体对话已从文件恢复,前端重新加载');
// 触发前端重新加载对话内容(加载已保存的完整消息列表,丢弃半成品状态)
if (typeof ctx.loadConversation === 'function') {
ctx.loadConversation(ctx.currentConversationId, { force: true });
} else {
// 回退:直接调 API 重新加载
fetch(`/api/conversations/${ctx.currentConversationId}/load`, { method: 'PUT' })
.then(r => r.json())
.then(result => {
if (result.success && result.messages_count !== undefined) {
console.log('[DEBUG] 对话重新加载成功,消息数:', result.messages_count);
}
})
.catch(err => console.error('[DEBUG] 对话重新加载失败:', err));
}
}
// 多智能体模式下,主任务停止即可恢复输入区,不因子智能体后台运行保持停止按钮
if (ctx.multiAgentMode || !hasRunningBackground) {
ctx.taskInProgress = false;

View File

@ -179,6 +179,23 @@ export const useBackgroundCommandStore = defineStore('backgroundCommand', {
delete next[normalizedId];
this.stoppingCommandIds = next;
}
},
async stopAllCommands(conversationId?: string): Promise<{ success: boolean; stoppedCount?: number; error?: string }> {
try {
const resp = await fetch('/api/background_commands/stop_all', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(conversationId ? { conversation_id: conversationId } : {})
});
const data = await resp.json().catch(() => ({}));
if (!resp.ok || !data?.success) {
throw new Error(data?.error || `HTTP ${resp.status}`);
}
await this.fetchCommands();
return { success: true, stoppedCount: data?.data?.stopped_count || 0 };
} catch (error: any) {
return { success: false, error: error?.message || String(error) };
}
}
}
});

View File

@ -9,6 +9,8 @@ interface SubAgent {
last_tool?: string;
conversation_id?: string;
notice_pending?: boolean;
display_name?: string;
current_context_tokens?: number;
}
interface SubAgentActivityEntry {

View File

@ -538,16 +538,19 @@ export const useTaskStore = defineStore('task', {
this.currentTaskId = null; // 清除任务 ID
},
async cancelTask() {
async cancelTask(forceStop: boolean = false) {
if (!this.currentTaskId) {
return;
}
try {
debugLog('[Task] 取消任务:', this.currentTaskId);
debugLog('[Task] 取消任务:', this.currentTaskId, 'forceStop:', forceStop);
console.log('[STOP_DEBUG] cancelTask 发送请求 → taskId:', this.currentTaskId, 'forceStop:', forceStop);
const response = await fetch(`/api/tasks/${this.currentTaskId}/cancel`, {
method: 'POST'
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ force_stop: forceStop })
});
if (!response.ok) {

View File

@ -483,12 +483,24 @@
justify-content: space-between;
align-items: center;
font-weight: 600;
margin-bottom: 6px;
margin-bottom: 4px;
}
.sub-agent-summary-text {
font-size: 13px;
color: var(--text-primary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex: 1;
min-width: 0;
}
.sub-agent-status {
text-transform: capitalize;
font-size: 12px;
flex-shrink: 0;
margin-left: 8px;
}
.sub-agent-status.running {
@ -499,6 +511,10 @@
color: var(--state-success);
}
.sub-agent-status.idle {
color: var(--text-secondary);
}
.sub-agent-status.failed,
.sub-agent-status.timeout,
.sub-agent-status.terminated,
@ -506,6 +522,32 @@
color: var(--state-danger);
}
.sub-agent-meta {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 6px;
}
.sub-agent-name {
font-size: 12px;
color: var(--text-secondary);
font-weight: 500;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex: 1;
min-width: 0;
}
.sub-agent-tokens {
font-size: 11px;
color: var(--text-secondary);
opacity: 0.7;
flex-shrink: 0;
margin-left: 8px;
}
.sub-agent-summary {
font-size: 13px;
color: var(--claude-text);