全部文章
发布于 2026-07-19

技能 + 对话 → 报表应用:需求与实现说明

用对话把「出报表」固化成工作区里的小应用,不用自己搭界面。

来源 docs/技术博客/技能对话生成报表应用对齐指南.md

文档版本:1.0 日期:2026-07-19 状态:已实现(backend/internal/appfromchat关联docs/core-mechanisms/工作区应用.md §7.2 / §9、help/product-features/skill-content-rules.md


1. 背景案例

会话示例(debug-mirror):

轮次用户结果
1@日隆部门职级统计图 部门职级统计图成功:技能出 HTML 报表
2「请生成应用…点应用后也能直接出这个报表」曾失败:整应用 LLM context deadline exceeded

用户目标:应用内一键生成 = 对话里用技能出报表的同一效果(同一模板、同一归类、同一数字口径),且统计逻辑固化在应用代码中,不再依赖对话模型临场推演。


2. 关键结论(必须先分清)

2.1 统计逻辑在哪里?

以「日隆部门职级统计图」为例:

位置内容是否可执行计算
技能包Markdown 归类说明、HTML 模板、占位符清单(无 build_report / run_script
对话skill_read → 双 query.run模型当场归类填表file_write(逻辑在对话 LLM)

工具链实证:skill_readskill_script_readdata_source_invoke×2 → file_write没有 run_script

因此:

  • 技能提供的是口径说明 + 交付模板(权威规格);
  • 可执行的统计分析发生在对话中的模型步骤里;
  • 「做成应用」必须把这套对话中的对等计算,变成应用包内的 Python。

2.2 产品原则(本次拍板)

  1. 技能 + 对话 = 应用,主路径应由 LLM 完成(把对话统计编译成应用代码),而不是平台写死一套通用报表引擎。
  2. 所有计算落在生成的应用包内;平台只负责创建期编排与取数桥,运行时不二次做业务统计。
  3. 未来会有多种技能、多种报表、多种填充规则——各自进各自的应用包,互不共用「万能后台计算器」。
  4. 若技能已自带 scripts/ 计算脚本(含 build_report),创建时原样同步,不必再生成。

3. 早期失败根因(对照)

3.1 创建失败

  • 第 2 轮「请生成应用」常不再 @ 技能 → 无参考技能包 → HTML 报表快路径跳过。
  • 落入整应用 GenerateAppScaffold(长 handbook)→ Minimaxi 超时

3.2 即便创建成功也会漂移

平台通用 assemble_html_report.py 会:

  • 使用另一套职级桶;
  • 重写 HTML 骨架(只抽 CSS);
  • 通常只跑一条 query。

与技能「唯一模板 + 对话归类口径 + 双 query」不一致。


4. 目标架构

对话出报表(技能规格 + LLM 临场统计)
        │
        ▼ 用户说「生成应用」(可无 @,可继承本会话 skill_read)
        │
        ├─ 技能已有 build_report* ──► 同步进应用包
        │
        └─ 技能无计算脚本 ──► LLM(长超时)
              输入:技能正文 + HTML 模板 + 本会话出报表摘要
              输出:应用内 scripts/build_report.py
                    + handlers(取数 → 调应用内脚本 → save_upload)
        │
        ▼
应用桌面一键生成(仅执行应用包逻辑,不再对话临场推演)

5. 实现要点

5.1 会话继承参考技能

  • 文件:session_skill_inherit.go
  • 当前消息无 skill_ids 时,从近期助手 tool_traceskill_read / skill_script_read 解析 skill_id
  • 解决:「报表做得很好 → 请生成应用」不再 @ 却进错通道的问题。

5.2 对话摘要(供 LLM 对齐对话统计)

  • 文件:session_report_hint.go
  • 抽取最近一次成功出报表的:query_id 列表、助手结论摘要、对应用户请求。
  • 明确提示模型:统计由对话完成、技能未必有可执行脚本。

5.3 LLM 生成应用内计算脚本(主路径)

  • 文件:skill_report_build_llm.go
  • 入口:CompileAppBuildReportViaLLM
  • 要求输出含 def build_report(app_root, template_rel, period, emp_rows, dict_rows=None) 的完整 Python;
  • 保留技能 HTML 骨架,只更新数据区;禁止 matplotlib/CDN/PNG;
  • agentscript.ScanScriptContent 安全检查后写入应用 scripts/build_report.py
  • 超时:创建报表应用时使用 PlatformAppImproveLLMTimeout(约 10–15 分钟),避免再踩整应用短超时。

5.4 技能已有脚本则同步

  • 文件:app_local_build_report.goFindSkillReportComputeScript
  • 优先 def build_report;其次文件名含 fill/build/assemble/report 的非 matplotlib 脚本。

5.5 回退

  • LLM 失败且技能正文归类表可解析:GenerateAppLocalBuildReportPy(规则内联确定性脚本)。
  • 再失败:明确提示 @ 原技能或应用开发助手「整包对齐」,而非笼统「简化需求」。

5.6 handlers 职责

  • 文件:skill_faithful_report.goskillFaithfulHandlersPy
  • 仅:query_run(emp + dict)→ 加载应用内 BUILD_SCRIPTbuild_reportsave_upload + 历史表。
  • 不在平台后台做业务聚合。

5.7 编排入口

  • execute.goResolveReferenceSkillIDsTryScaffoldHTMLReportFromSkills(带 sessionID + 长超时 LLM)。
  • html_report_scaffold.go:忠实路径优先,否则旧通用 assemble(非推荐)。

6. 关键文件一览

路径作用
backend/internal/appfromchat/session_skill_inherit.go会话继承 skill_id
backend/internal/appfromchat/session_report_hint.go对话出报表摘要
backend/internal/appfromchat/skill_report_build_llm.goLLM 生成 build_report.py
backend/internal/appfromchat/skill_faithful_report.go报表应用草案组装
backend/internal/appfromchat/app_local_build_report.go技能脚本发现 / 确定性回退生成
backend/internal/appfromchat/skill_report_rules.go正文归类表解析(回退/对照)
backend/internal/appfromchat/html_report_scaffold.goHTML 报表脚手架分叉
backend/internal/appfromchat/execute.go对话创建应用总编排
backend/internal/appfromchat/persist.go落盘;禁止用平台常量覆盖应用内计算脚本

7. 推荐使用流程(用户侧)

  1. 在工作智能体对话中 @某报表技能,先成功出一版报表。
  2. 同一会话发送:「请生成应用,点应用后也能直接出这个报表」(可再 @ 该技能)。
  3. 打开应用桌面 → 一键生成 → 预览 HTML,与对话结果对照口径。
  4. 若技能后续要自给自足:把稳定后的 build_report.py 沉淀回技能 scripts/,供以后创建应用直接同步。

8. 技能写法建议(减少漂移)

skill-content-rules.md「取数 + 固定 HTML 报表」:

  • 正文写清归类表、占位符、唯一模板路径;
  • 推荐技能自带 build_report(...)(不画图);
  • 若统计仍只在对话完成:创建应用依赖 LLM 编译,正文归类表越清晰,生成质量越高。

9. 验收要点

  • [ ] 无 @ 的「生成应用」能继承本会话刚用的报表技能,不再整应用超时死路。
  • [ ] 应用包内存在计算脚本(技能同步或 LLM 生成的 scripts/build_report.py)。
  • [ ] 一键生成:双 query 取数 + 应用内脚本填模板;数字口径与对话成功报表一致(或可解释的差异说明)。
  • [ ] 修改应用内脚本不影响其它报表应用;无平台「万能报表服务」耦合。

10. 明确不在本期

  • 对话内直接 invoke 应用(机制文档 P2)。
  • 加长整应用 GenerateAppScaffold 超时作为报表主修复手段(治标不治本)。
  • 把某一种业务归类写死进 Go 后台常驻逻辑。

11. 一句话备忘

技能给规格与模板,对话完成统计;生成应用时用 LLM 把对话统计编译成应用内 Python,运行时只跑应用包。