← 全部文章
发布于 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_read → skill_script_read → data_source_invoke×2 → file_write,没有 run_script。
因此:
- 技能提供的是口径说明 + 交付模板(权威规格);
- 可执行的统计分析发生在对话中的模型步骤里;
- 「做成应用」必须把这套对话中的对等计算,变成应用包内的 Python。
2.2 产品原则(本次拍板)
- 技能 + 对话 = 应用,主路径应由 LLM 完成(把对话统计编译成应用代码),而不是平台写死一套通用报表引擎。
- 所有计算落在生成的应用包内;平台只负责创建期编排与取数桥,运行时不二次做业务统计。
- 未来会有多种技能、多种报表、多种填充规则——各自进各自的应用包,互不共用「万能后台计算器」。
- 若技能已自带
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_trace的skill_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.go→FindSkillReportComputeScript - 优先
def build_report;其次文件名含 fill/build/assemble/report 的非 matplotlib 脚本。
5.5 回退
- LLM 失败且技能正文归类表可解析:
GenerateAppLocalBuildReportPy(规则内联确定性脚本)。 - 再失败:明确提示
@原技能或应用开发助手「整包对齐」,而非笼统「简化需求」。
5.6 handlers 职责
- 文件:
skill_faithful_report.go→skillFaithfulHandlersPy - 仅:
query_run(emp + dict)→ 加载应用内BUILD_SCRIPT→build_report→save_upload+ 历史表。 - 不在平台后台做业务聚合。
5.7 编排入口
execute.go:ResolveReferenceSkillIDs→TryScaffoldHTMLReportFromSkills(带 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.go | LLM 生成 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.go | HTML 报表脚手架分叉 |
backend/internal/appfromchat/execute.go | 对话创建应用总编排 |
backend/internal/appfromchat/persist.go | 落盘;禁止用平台常量覆盖应用内计算脚本 |
7. 推荐使用流程(用户侧)
- 在工作智能体对话中
@某报表技能,先成功出一版报表。 - 同一会话发送:「请生成应用,点应用后也能直接出这个报表」(可再
@该技能)。 - 打开应用桌面 → 一键生成 → 预览 HTML,与对话结果对照口径。
- 若技能后续要自给自足:把稳定后的
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,运行时只跑应用包。