agent-Specialization/modules/multi_agent/tools.py
JOJO 811974d6e7 feat(multi-agent): 在现有架构上直接实现多智能体模式实验功能
放弃完全隔离策略,改为在现有 MainTerminal/SubAgentManager/SubAgentTask 主链路
按对话级开关 metadata.multi_agent_mode=true 增加多智能体分支。

新增模块:
- modules/multi_agent/__init__.py: 模块入口
- modules/multi_agent/role_store.py: 角色 Markdown Frontmatter 解析与归档
- modules/multi_agent/state.py: 多智能体会话状态机与消息格式化
- modules/multi_agent/prompts.py: 主智能体(Team Leader) + 子智能体提示词
- modules/multi_agent/tools.py: 9 个主智能体工具 + 4 个子智能体工具定义
- server/multi_agent.py: /multiagent/new 页面 + /api/multiagent/* 蓝图

现有代码改动:
- modules/sub_agent/task.py: 扩展 multi_agent_mode/multi_agent_state/display_name 字段,
  增加 ask_master/ask_other_agent/answer_other_agent/list_active_sub_agents 工具处理逻辑,
  子智能体自然结束 assistant 输出即本轮结束(不调用 finish_task),上下文保留。
- modules/sub_agent/manager.py: create_sub_agent 增加 multi_agent_mode/role_id/display_name 参数,
  增加 get_or_create_multi_agent_state/get_multi_agent_state/inject_message_to_sub_agent/_on_multi_agent_task_done 方法。
- core/main_terminal_parts/tools_definition/agent_tools.py: 多智能体模式下用 modules.multi_agent.tools 替换旧版工具集。
- core/main_terminal_parts/context/messages.py: 多智能体模式下追加 Team Leader 系统提示词。
- core/main_terminal_parts/tools_execution.py: create_sub_agent handler 增加多智能体分支,新增 send_message_to_sub_agent/ask_sub_agent/answer_sub_agent_question/create_custom_agent/list_agents/list_active_sub_agents handler。
- core/web_terminal.py: load_conversation 时检测 metadata.multi_agent_mode 设置 self.multi_agent_mode。
- server/app_legacy.py: 注册 multi_agent_bp 蓝图。

前端改动:
- static/src/auth/LoginApp.vue: 登录页增加'多智能体模式(beta)'按钮
- static/src/app/methods/ui/route.ts: 识别 /multiagent/new 和 /multiagent/conv_xxx 路径,进入多智能体模式并创建带 metadata.multi_agent_mode=true 的对话
- static/src/app/state.ts: 增加 multiAgentMode 状态字段

数据:
- ~/.astrion/astrion/host/mutiagents/agents/: 4 个预置角色 ui-operator / full-stack-engineer / code-reviewer / researcher
- ~/.astrion/astrion/host/mutiagents/conversations/: 会话数据

验证:所有 Python 文件语法检查通过;冒烟测试 test.test_server_refactor_smoke 6 项全通过;前端构建通过(6.04s);模块导入与功能断言测试全部通过。
2026-07-12 03:26:02 +08:00

323 lines
13 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""多智能体工具定义OpenAI Function Calling 格式)。
主智能体侧master替换原有的 4 个旧版子智能体工具,新增 9 个多智能体工具。
子智能体侧sub_agent在现有 8 个基础工具之外新增 4 个通信工具。
工具处理函数handler不在这里实现而是在 SubAgentManager/SubAgentTask 中
注册回调,工具执行入口仍走 SubAgentManager.execute_tool_for_sub_agent。
"""
from __future__ import annotations
from typing import Any, Dict, List, Optional
def _inject_intent(properties: Dict[str, Any]) -> Dict[str, Any]:
"""为所有 properties 注入 intent 字段(与现有工具规范保持一致)。"""
out: Dict[str, Any] = {}
for k, v in properties.items():
if k == "intent":
out[k] = v
continue
out[k] = v
# 在末尾追加 intent 字段
if "intent" not in out:
out["intent"] = {
"type": "string",
"description": "用不超过15个字向用户说明你要做什么例如派遣UI Operator设计配色。",
}
return out
# ----- 主智能体工具 -----
def _master_tool_create_sub_agent() -> Dict[str, Any]:
return {
"type": "function",
"function": {
"name": "create_sub_agent",
"description": (
"创建一个属于多智能体团队的子智能体实例并启动。必须指定 role_id。"
"实例会注入该角色的专属 prompt 与多智能体协作工具ask_master 等)。"
),
"parameters": {
"type": "object",
"properties": _inject_intent({
"role_id": {
"type": "string",
"description": "角色标识,例如 'ui-operator'/'full-stack-engineer'/'code-reviewer'/'researcher'。先用 list_agents 查看可用角色。",
},
"task": {
"type": "string",
"description": "要交给该子智能体执行的任务描述。要求包含:目标、范围、产出、注意事项。",
},
"agent_id": {
"type": "integer",
"description": "(可选)手动指定实例编号;不传时自动递增。",
},
"deliverables_dir": {
"type": "string",
"description": "(可选)交付目录相对路径,留空则用 sub_agent_results/agent_{N}",
},
"timeout_seconds": {"type": "integer", "description": "超时秒数,默认 600。"},
"thinking_mode": {
"type": "string",
"enum": ["fast", "thinking"],
"description": "(可选)覆盖角色默认思考模式。不填使用角色配置。",
},
}),
"required": ["role_id", "task", "thinking_mode"],
},
},
}
def _master_tool_terminate_sub_agent() -> Dict[str, Any]:
return {
"type": "function",
"function": {
"name": "terminate_sub_agent",
"description": "强制终止指定子智能体实例。终止后无法恢复,已生成的文件保留。",
"parameters": {
"type": "object",
"properties": _inject_intent({
"agent_id": {"type": "integer", "description": "要终止的子智能体编号。"},
}),
"required": ["agent_id"],
},
},
}
def _master_tool_send_message_to_sub_agent() -> Dict[str, Any]:
return {
"type": "function",
"function": {
"name": "send_message_to_sub_agent",
"description": (
"运行时引导/干预:向指定子智能体插入一条引导消息或新任务,立刻返回不等待回复。"
"用于看到子智能体中间输出后立即纠正方向、追加要求。消息接收方根据当前状态"
"running/idle自行决定是 inline 插入还是触发新一轮任务。"
),
"parameters": {
"type": "object",
"properties": _inject_intent({
"agent_id": {"type": "integer", "description": "目标子智能体编号。"},
"message": {"type": "string", "description": "要插入的消息或新任务正文。"},
}),
"required": ["agent_id", "message"],
},
},
}
def _master_tool_ask_sub_agent() -> Dict[str, Any]:
return {
"type": "function",
"function": {
"name": "ask_sub_agent",
"description": (
"向指定子智能体提出一个明确问题并阻塞等待一轮回答(不是发起任务,是问问题)。"
"问题会以 `来自 Team Leader 的提问` 格式插入子对话,子智能体下一轮 assistant 输出"
"作为回答返回到此工具结果中。"
),
"parameters": {
"type": "object",
"properties": _inject_intent({
"agent_id": {"type": "integer", "description": "目标子智能体编号。"},
"question": {"type": "string", "description": "要询问的问题,应简短明确。"},
"timeout_seconds": {"type": "integer", "description": "等待回答超时秒数,默认 600。"},
}),
"required": ["agent_id", "question"],
},
},
}
def _master_tool_answer_sub_agent_question() -> Dict[str, Any]:
return {
"type": "function",
"function": {
"name": "answer_sub_agent_question",
"description": (
"回答子智能体通过 ask_master 工具提出的问题。回答内容会直接返回到子智能体"
"ask_master 工具的 tool_call 结果里(不会以 user 消息插入子对话)。"
),
"parameters": {
"type": "object",
"properties": _inject_intent({
"question_id": {"type": "string", "description": "提问消息里给出的 id如 ask_xxx。"},
"answer": {"type": "string", "description": "给子智能体的回答正文。"},
}),
"required": ["question_id", "answer"],
},
},
}
def _master_tool_create_custom_agent() -> Dict[str, Any]:
return {
"type": "function",
"function": {
"name": "create_custom_agent",
"description": "创建/保存一个自定义角色到后端(~/.astrion/astrion/host/mutiagents/agents/)。后续可用 create_sub_agent 指定该角色。",
"parameters": {
"type": "object",
"properties": _inject_intent({
"role_id": {"type": "string", "description": "角色标识(英文小写下划线,如 api-designer"},
"name": {"type": "string", "description": "显示名(如 API Designer"},
"description": {"type": "string", "description": "一句话简述职责。"},
"body_prompt": {"type": "string", "description": "角色的自定义 prompt bodyMarkdown"},
"thinking_mode": {"type": "string", "enum": ["fast", "thinking"], "description": "默认思考模式。"},
}),
"required": ["role_id", "name", "body_prompt"],
},
},
}
def _master_tool_list_agents() -> Dict[str, Any]:
return {
"type": "function",
"function": {
"name": "list_agents",
"description": "列出所有可用的预置/自定义角色role_id / name / 描述)。用于在 create_sub_agent 前选角色。",
"parameters": {"type": "object", "properties": _inject_intent({})},
},
}
def _master_tool_list_active_sub_agents() -> Dict[str, Any]:
return {
"type": "function",
"function": {
"name": "list_active_sub_agents",
"description": "列出当前多智能体会话中所有活跃/已创建的子智能体实例agent_id/role/display_name/status",
"parameters": {"type": "object", "properties": _inject_intent({})},
},
}
def _master_tool_get_sub_agent_status() -> Dict[str, Any]:
return {
"type": "function",
"function": {
"name": "get_sub_agent_status",
"description": "查询一个或多个子智能体的详细状态。",
"parameters": {
"type": "object",
"properties": _inject_intent({
"agent_ids": {"type": "array", "items": {"type": "integer"}, "description": "要查询的子智能体编号列表。"},
}),
"required": ["agent_ids"],
},
},
}
MULTI_AGENT_MASTER_TOOLS: List[Dict[str, Any]] = [
_master_tool_create_sub_agent(),
_master_tool_terminate_sub_agent(),
_master_tool_send_message_to_sub_agent(),
_master_tool_ask_sub_agent(),
_master_tool_answer_sub_agent_question(),
_master_tool_create_custom_agent(),
_master_tool_list_agents(),
_master_tool_list_active_sub_agents(),
_master_tool_get_sub_agent_status(),
]
# ----- 子智能体工具 -----
def _sub_tool_ask_master() -> Dict[str, Any]:
return {
"type": "function",
"function": {
"name": "ask_master",
"description": (
"向 Team Leader主智能体提问工具调用会阻塞等待主智能体通过 answer_sub_agent_question 给出回答。"
"用于需要主智能体决策的场合。"
),
"parameters": {
"type": "object",
"properties": _inject_intent({
"question": {"type": "string", "description": "向 Team Leader 提问的内容。"},
"question_id": {"type": "string", "description": "(可选)问题 id不传自动生成。"},
}),
"required": ["question"],
},
},
}
def _sub_tool_ask_other_agent() -> Dict[str, Any]:
return {
"type": "function",
"function": {
"name": "ask_other_agent",
"description": (
"向另一个子智能体提问,阻塞等待对方调用 answer_other_agent 回答。"
"**注意**:调用此工具的同时,你必须在你的文本输出里向 Team Leader 输出一条汇报,"
"说明你为何问、问谁、期望什么——不要偷偷沟通。"
),
"parameters": {
"type": "object",
"properties": _inject_intent({
"target_agent_id": {"type": "integer", "description": "目标子智能体编号。"},
"question": {"type": "string", "description": "提问内容。"},
"question_id": {"type": "string", "description": "(可选)问题 id。"},
}),
"required": ["target_agent_id", "question"],
},
},
}
def _sub_tool_answer_other_agent() -> Dict[str, Any]:
return {
"type": "function",
"function": {
"name": "answer_other_agent",
"description": (
"回答其他子智能体通过 ask_other_agent 提出的问题。"
"answer 内容会直接返回到对方 ask_other_agent 工具结果中。"
),
"parameters": {
"type": "object",
"properties": _inject_intent({
"source_agent_id": {"type": "integer", "description": "提问方 agent_id。"},
"question_id": {"type": "string", "description": "提问消息中的 id。"},
"answer": {"type": "string", "description": "回答内容。"},
}),
"required": ["source_agent_id", "question_id", "answer"],
},
},
}
def _sub_tool_list_active_sub_agents() -> Dict[str, Any]:
return {
"type": "function",
"function": {
"name": "list_active_sub_agents",
"description": "查询当前多智能体会话中所有活跃/已创建的子智能体。",
"parameters": {"type": "object", "properties": _inject_intent({})},
},
}
MULTI_AGENT_SUB_AGENT_TOOLS: List[Dict[str, Any]] = [
_sub_tool_ask_master(),
_sub_tool_ask_other_agent(),
_sub_tool_answer_other_agent(),
_sub_tool_list_active_sub_agents(),
]
# ----- 构造函数(供现有 tools_definition 调用) -----
def build_master_tools_for_conversation() -> List[Dict[str, Any]]:
"""返回主智能体在多智能体模式下应额外提供的工具列表。"""
return list(MULTI_AGENT_MASTER_TOOLS)
def build_sub_agent_tools_for_role() -> List[Dict[str, Any]]:
"""返回子智能体在多智能体模式下应额外提供的工具列表。"""
return list(MULTI_AGENT_SUB_AGENT_TOOLS)