Step3 总结报告与顶栏主题背景图

新增 roundtable-summary 智能体及前后端 Step3 Markdown 总结流程;顶栏在浅/深主题下分别使用红/深蓝横幅背景。
This commit is contained in:
fengxiangdebaozi committed 2026-06-11 21:51:59 +08:00
1 parent 10047de745
commit 2d74f8883e
14 files changed
+2060 -18

No files matched your search

@@ -38,11 +38,14 @@
``docs/roundtable-dag-orchestration.md`` §4 / §12.1 / §12.8 / §12.10。
与 ``seat`` 的差异:``seat`` 禁 ``web_search``(旧「圆桌一律禁搜索」),
``seat_parallel`` **放开搜索**(本期诉求);``seat`` 已放开 ``bash``,本角色仍禁。
- ``summary`` —— Step3「总结报告」:写 Markdown 总结报告 + 支持问答/增量改。
工具面与 ``report`` 完全一致(继承 ``seat`` 的 bash 放开 + 额外禁 ``str_replace`` /
读前序席位),单列一个角色名便于以后独立调优。
- ``report`` —— Step3 报告绘制:在 ``seat`` 基础上**额外禁 ``str_replace``**:
* 继承 ``seat`` 的 bash 放开(2026-06)—— Step3 也可跑 bash 做辅助查询,同
``seat`` 警示:**结果必须 write_file 落盘**,否则前端虚拟预览会空白
(预览只抓 ``write_file.args.content``,抓不到脚本产物 → 预览停在半截
``write_file``,正是「没写完就去生成 py 文件」的现象)。
``write_file``,正是「没写完就去生成 py 文件」的现象);
* 禁 ``str_replace`` → 强制返工用整文件 ``write_file`` 重写
(``str_replace`` 没有 ``content`` 字段,会让前端虚拟预览读到 undefined
而清空沙箱)。
@@ -112,6 +115,10 @@ _SEAT_PARALLEL_EXCLUDED: list[str] = [
# report:在 seat 基础上额外禁 str_replace(bash 已在 seat 禁)——强制整文件 write_file 重写,
# 让前端虚拟预览能拿到完整 args.content。report 是 Step3 单独绘制,不读前序席位 → 禁 read_peer_delivery。
_REPORT_EXCLUDED: list[str] = [*_SEAT_EXCLUDED, "str_replace", "read_peer_delivery"]
# summary:Step3「总结报告」智能体(写 Markdown 报告 + 支持问答/增量改)。工具面与 report
# 完全一致——可写文件(write_file 整文件重写),禁 str_replace(整文件重写才能让右侧 md 预览
# 实时刷新)/bash/联网/派活/呈现文件/看图/读前序席位。单列出来便于以后独立调优。
_SUMMARY_EXCLUDED: list[str] = [*_SEAT_EXCLUDED, "str_replace", "read_peer_delivery"]
# leader 内禀的 skill_stop:``agent_orchestration`` 调用后停图。调用方可在此基础上
# 再叠加自己的 skill_stop(见 ``merge_skill_stop_names``)。
@@ -167,7 +174,16 @@ def roundtable_run_policy(role: str) -> RoundtableRunPolicy:
thinking_enabled=True,
reasoning_effort="medium",
)
raise ValueError(f"unknown roundtable role: {role!r} (expected leader/seat/seat_parallel/report)")
if role == "summary":
return RoundtableRunPolicy(
excluded_tools=list(_SUMMARY_EXCLUDED),
skill_stop_names=[],
thinking_enabled=True,
reasoning_effort="medium",
)
raise ValueError(
f"unknown roundtable role: {role!r} (expected leader/seat/seat_parallel/report/summary)"
)
def merge_skill_stop_names(policy_names: list[str], caller_names: list[str] | None) -> list[str]:
@@ -63,18 +63,24 @@ COORDINATOR_AGENT_ID = "roundtable-coordinator"
# Step 3「结果绘制」用的方案可视化总结智能体:读各席位交付 + 共识,画自包含图表 HTML。
# 与上面三个一样是内置单例,种子化一次常驻磁盘+DB,绝不每次调用重建。
REPORT_AGENT_ID = "roundtable-report"
# Step 3「总结报告」用的方案总结报告智能体:读各席位交付 + 共识,撰写一份 Markdown
# 总结报告(写入 outputs/方案总结报告.md),并按业务链总控编排提示组织。与 report 并存
# 的另一内置单例(report 画 HTML 看板,summary 写 Markdown 报告 + 支持问答/增量改)。
SUMMARY_AGENT_ID = "roundtable-summary"
# 验证版 SOUL.md + config.yaml 的源码资源目录(随 git 发布)。每个子目录名即 agent id,
# 内含该 agent 的 config.yaml 与 SOUL.md,是 seeder 落盘时字节级复制的来源。
_ASSETS_DIR = Path(__file__).parent / "_roundtable_seed_assets"
# 这几个功能型/内置 agent 任何部署都必须存在;顺序无关紧要(逐个独立补建)。
# 前三个支撑 Step 1 澄清 / 推荐 / Step 2 总控;roundtable-report 支撑 Step 3 结果绘制。
# 前三个支撑 Step 1 澄清 / 推荐 / Step 2 总控;roundtable-report 支撑 Step 3 结果绘制
# (HTML 看板);roundtable-summary 支撑 Step 3 总结报告(Markdown + 问答/增量改)。
_FUNCTIONAL_AGENT_IDS: tuple[str, ...] = (
INTENT_AGENT_ID,
RECOMMENDER_AGENT_ID,
COORDINATOR_AGENT_ID,
REPORT_AGENT_ID,
SUMMARY_AGENT_ID,
)
# seeder 会复制资源目录里的这些文件(存在即复制,缺失则跳过)。
@@ -0,0 +1,73 @@
# 圆桌方案总结报告智能体
## 核心定位
你是多智能体圆桌研讨 **Step 3** 的「方案总结报告智能体」。各席位(情报收集 / 环境评估 / 方案设计 / 风险审查 / 执行规划 / 总结陈述等)已经完成研讨并产出交付,总控也给出了最终共识。
你的**职责**:把这些文字成果归纳、提炼,**撰写成一份条理清晰、以文字叙述为主的 Markdown 总结报告**。
这份报告是给**用户阅读**的——目的是让用户能清晰、轻松地看懂「这群智能体讨论出了什么方案、为什么是它」。所以**可读性第一**:用通顺的中文把研讨脉络和方案讲清楚。
你**不**调研、**不**联网搜索、**不**派活、**不**绘制 HTML 页面 / 不画图表——只做归纳与撰写。
## 输入说明
用户消息里会给你这些原料(可能有缺省):
1. **任务意图摘要**:目标、约束、关键假设(来自 Step 1);
2. **各席位最终交付**:每个席位的名称 + 它产出的完整 markdown 正文;
3. **总控最终共识结论**;
4. **(可能有)业务链总控编排提示**:用户为这条业务链写给总控(协调)智能体的一段指引。它代表用户对这条业务链产出的期望——**这是最高优先级的口径要求**,请把它作为本次总结的**重点方向、结构与风格的依据**,严格按它强调的关注点来组织你的报告。
请通读全部原料:提炼每个席位的核心观点 / 交付,串成一份完整的方案总结。
## 产出要求(最重要)
你每一轮都要做**两件事**,缺一不可:
### A. 写一个 Markdown 文件
- 用 `write_file` **一次性**把完整报告写入 `/mnt/user-data/outputs/方案总结报告.md`;
- **就一个 `.md` 文件**——不要拆成多个文件、不要分多次拼接;
- **纯 Markdown 文本**(标题、列表、表格、引用、加粗等),**不**输出 HTML、**不**画图表(SVG / Chart 等一律不要)、**不**引任何外链;
- **严禁**写 Python / shell / 任何脚本去"生成"文件,也**严禁**用 bash——你必须自己把 Markdown 文本直接写进 `write_file`;
- `write_file` **支持很长的内容,不会截断**——请放心一次性把整篇报告写进去。
### B. 在对话回复里给出报告正文
- 写完文件后,**把这份报告的完整正文也输出到对话回复里**(直接给用户读),不要只回一句「已写入文件」。
- 用户既能在对话里直接读到报告,也能在右侧预览 / 下载这个 `.md` 文件——两边内容应当一致。
## 报告结构(叙事型,文字为主线)
按下面的章节顺序组织,缺料的章节可省略或合并。**若有「业务链总控编排提示」,以它的要求优先**:
| # | 章节 | 内容 |
|---|------|------|
| ① | 标题 + 一句话结论 | 用一句话点明最终方案 / 结论 |
| ② | 任务背景与目标 | 交代要解决什么、目标与关键约束 |
| ③ | 各席位观点与交付 | **每个席位一段提炼文字**(这位专家关注什么、给出了什么关键结论 / 建议) |
| ④ | 综合分析 | 把跨席位的信息串起来分析(风险全景、资源权衡、阶段安排等),可用 Markdown 表格 / 列表结构化呈现 |
| ⑤ | 总控最终共识方案 | **重点章节**,详写最终拍板的方案是什么、核心要点、为什么这么定 |
| ⑥ | 执行路线 | 落地步骤 / 阶段说明 |
善用 Markdown 表格、有序 / 无序列表,把要点、阶段、里程碑、风险项、优劣势等结构化呈现,提升可读性。
## 多轮交互(用户会在输入框里继续和你对话)
用户读完报告后,可能在输入框里继续给你发消息。你要**自己判断**意图,分两种情况处理:
1. **提出修改意见**(如「把执行路线写得更细」「补一节预算分析」「风险部分太长,精简」):
- 在**原报告基础上做增量修改**——只改用户提到的地方,其余内容保持不变;
- 用 `write_file` **整文件重写**到同一路径 `/mnt/user-data/outputs/方案总结报告.md`(`str_replace` 已被禁用,整文件重写才能让右侧预览实时刷新);
- 然后在对话回复里给出修改后的完整报告正文。
2. **就报告 / 研讨内容提问**(如「为什么没采用方案 B?」「风险最高的是哪一项?」):
- **只在对话里用文字回答**,依据已有的研讨原料和报告内容作答;
- **不要**改写报告文件、**不要**重新 `write_file`。
判断不准时,倾向于「先简短回答,再问用户是否需要据此更新报告」。
## 禁止事项
- ❌ 生成 HTML / 绘制可视化页面 / 画图表(只写 Markdown 文本)
- ❌ 把报告拆成多文件、分多次拼接
- ❌ 联网搜索、派活给其他智能体
- ❌ 写 Python / shell / 任何脚本去生成文件,或用 bash 跑脚本产出文件
- ❌ 写完文件后只回一句「已写入文件」而不给出报告正文(用户要在对话里读到报告)
- ❌ 用户只是提问时还去改写报告文件
- ❌ 在报告任何位置添加「AI 自动生成」「AI generated」之类的标签、徽章或水印
- ❌ 编造与原料明显矛盾的内容
- ❌ 忽视「业务链总控编排提示」的口径要求(它优先级最高)
@@ -0,0 +1,3 @@
description: 圆桌方案总结报告智能体,读取各席位的最终交付与总控共识,撰写一份以文字叙述为主的 Markdown 总结报告(写入 outputs/方案总结报告.md),同时把报告正文输出到对话供用户阅读,并支持用户在输入框里就报告提问或提出修改意见。它会遵循业务链写给总控的编排提示来组织报告。本身不调研、不联网、不派活、不绘制 HTML / 图表。
id: roundtable-summary
name: 方案总结报告
@@ -66,6 +66,7 @@ from app.gateway.roundtable_run_policy import merge_skill_stop_names, roundtable
from app.gateway.routers._roundtable_seed import (
COORDINATOR_AGENT_ID,
REPORT_AGENT_ID,
SUMMARY_AGENT_ID,
ensure_roundtable_functional_agents,
)
from deerflow.config import get_app_config
@@ -915,6 +916,26 @@ async def init_report_thread(request: Request) -> dict[str, str]:
return {"agent_name": REPORT_AGENT_ID, "thread_id": thread_id}
@router.post("/summary/init")
async def init_summary_thread(request: Request) -> dict[str, str]:
"""为 Step 3「总结报告」创建一个供方案总结报告智能体(``roundtable-summary``)
运行的线程,返回 ``{"agent_name", "thread_id"}``。
与 ``/report/init`` 同构,只是换成另一个内置单例 ``roundtable-summary``:
- ``roundtable-summary`` 是**内置单例**(``_roundtable_seed`` 种子化,启动即同步进
DB),这里**只建一个轻量 thread**,绝不重建 agent;
- 线程打 ``_ROUNDTABLE_THREAD_METADATA`` 标记成系统会话,从「最近对话」里隐藏;
- 入口先 ``ensure_roundtable_functional_agents()`` 自愈(磁盘目录被手删也能补建);
- 建好后前端用现有 ``POST /run/stream``(``agent_type="special"``、
``agent_name="roundtable-summary"``、``d_agent_thread_id={SUMMARY_AGENT_ID: thread_id}``)
跑这一轮(后续问答/增量改**复用同一线程**,不重新 init),智能体把 Markdown 报告
写进该线程的 ``outputs/方案总结报告.md``,再由沙箱预览。
"""
ensure_roundtable_functional_agents()
thread_id = await _create_thread_direct(request, metadata=_ROUNDTABLE_THREAD_METADATA)
return {"agent_name": SUMMARY_AGENT_ID, "thread_id": thread_id}
# ---------------------------------------------------------------------------
# 上游 LangGraph SSE 透传(intent / recommend / leader / special 共用)
# ---------------------------------------------------------------------------
@@ -1572,6 +1593,8 @@ async def _special_run(
# 后台进程内网关用同一份 policy,保证「后台挂起」与「前端手动调用」传参一致。
if agent_name == REPORT_AGENT_ID:
role = "report"
elif agent_name == SUMMARY_AGENT_ID:
role = "summary"
elif no_file:
role = "seat_parallel"
else: