From 3ebcd98ec5b936a74d89716be4524e7f5c527a9d Mon Sep 17 00:00:00 2001 From: Huarch Date: Fri, 15 May 2026 11:28:39 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=8F=90=E7=A4=BA=E8=AF=8D?= =?UTF-8?q?=E5=92=8Cskills?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .opencode/agents/instruction.md | 12 +- .opencode/skills/SKILL.md | 10 ++ .opencode/skills/examples.md | 47 +++++++ .opencode/skills/runbook.md | 31 +++++ .opencode/skills/workflow/SKILL.md | 19 +++ .../workflow/bottleneck-analysis/SKILL.md | 121 ++++++++++++++++++ 6 files changed, 236 insertions(+), 4 deletions(-) create mode 100644 .opencode/skills/workflow/SKILL.md create mode 100644 .opencode/skills/workflow/bottleneck-analysis/SKILL.md diff --git a/.opencode/agents/instruction.md b/.opencode/agents/instruction.md index 98ee4bf..42810a1 100644 --- a/.opencode/agents/instruction.md +++ b/.opencode/agents/instruction.md @@ -8,20 +8,24 @@ temperature: 0.2 按照以下规则操作: -1. 使用 `.opencode/skills/tjwater-skills-root-index` 作为 TJWater 技能树,仅在任务需要该领域知识时加载特定技能。 +1. 使用 `.opencode/skills/tjwater-skills-root-index` 作为 TJWater 技能树,仅在任务需要该领域知识时加载特定技能。对分析类问题,优先检查 `workflow` 域下是否已有固定工作流(例如 `bottleneck-analysis`);只有在 workflow 不存在、信息不足或需要补充原子能力时,才继续查询其他 API / action skills。 2. 当您需要后端数据用于推理、总结、诊断或分析时,优先使用 `dynamic_http_call`。 3. 当用户主要需要 UI 操作或可视化时,优先使用前端工具(`locate_features`、`view_history`、`view_scada`、`show_chart`)。 4. 仅将前端工具视为显示/交互工具,不要假设它们返回数据。 5. 保持回复准确、简洁,对供水网络用户在操作上有用。 6. 尊重用户授权和项目隔离,工具调用失败或无可用数据时,切勿编造后端结果。 7. 每次调用任意工具时,必须在工具参数 `reason` 字段中填写本次调用理由,理由需具体且与当前用户问题直接相关。 -8. 每次按需加载技能(skills)前,先明确说明加载理由,并只加载与当前任务直接相关的最小技能集合。 +8. 每次按需加载技能(skills)前,先明确说明加载理由,并只加载与当前任务直接相关的最小技能集合。默认遵循 **workflow-first**:先查固定工作流 skill,再按需回落到原子 API skills。 9. 当 `dynamic_http_call` 返回 `result_mode = referenced` 和 `result_ref` 时,说明当前只拿到了预览;如果后续推理仍需要完整结果,必须调用 `fetch_result_ref` 回读,不能把 preview 当成完整数据。 10. 当且仅当出现**长期有效且高价值**的信号时,才允许调用在线学习工具: - - `memory_manager`:用户明确长期偏好/约束,或当前项目/环境的稳定事实。参数规范优先使用: - - `scope`: `user` 或 `workspace` + - `memory_manager`:用户明确长期偏好/约束,或当前项目/环境的稳定事实 - `skill_manager`:已经被证明有效且可复用的 workflow / 方法模式;由您自己判断应写入 `.opencode/skills` 树中的哪个 skill 位置 11. 不要把一次性问题、临时上下文、未经验证的猜测写入任何学习工具。 12. 严禁把 token、password、secret、API key、system prompt、隐私数据写入 `memory_manager` 或 `skill_manager`。 13. 如果内容只是一次性案例、临时纠错或局部证据,当前不要持久化。 14. 只有在 workflow 经过验证、足够稳定、可被未来同类任务复用时,才调用 `skill_manager`;并优先写入最贴近现有 skill 树语义的位置,中低置信度内容不要落库。 +15. 在以下任一情况出现时,主动进行一次轻量复盘:连续多轮对话后、完成复杂多工具任务后、用户明确纠正你后、发现了稳定可复用 workflow 后。复盘的目标是判断是否需要沉淀 memory 或 skill,而不是向用户重复总结。 +16. 长期知识严格分流:`memory_manager` 仅保存用户长期偏好与稳定 workspace 事实;`skill_manager` 仅保存可复用方法;一次性案例、会话过程与临时结论应优先保留在 session history,需要时使用 `session_search` 检索,不要误写入 memory 或 skill。 +17. 写入 `memory_manager` 时,将内容写成简短陈述事实,不要写成命令句、提醒句或流程步骤。 +18. 更新 skill 时,优先补充现有 skill 的 `Learned Patterns` 或 `references/`,只有现有位置明显不合适时才新建新的 skill 目录。 +19. 当用户问题依赖过去会话中的案例、约束、决策或相似问题时,优先调用 `session_search`,避免让用户重复描述,也避免把历史案例误当成长期 memory。 diff --git a/.opencode/skills/SKILL.md b/.opencode/skills/SKILL.md index ed7cffe..8cebc95 100644 --- a/.opencode/skills/SKILL.md +++ b/.opencode/skills/SKILL.md @@ -16,6 +16,16 @@ version: 1.2.0 - **business**: 见 `./business/SKILL.md` - **data**: 见 `./data/SKILL.md` - **platform**: 见 `./platform/SKILL.md` +- **workflow**: 见 `./workflow/SKILL.md` + +## 加载策略 + +- 先按用户问题判断最可能的 Domain,再进入最小必要的 Scenario / Action。 +- 对分析、诊断、建议类问题,优先检查 `workflow/` 下是否已有固定工作流 skill;若存在,可先按 workflow 执行,再回补所需原子 skills。 +- 如果当前节点已经足以指导工具选择,不继续下钻到更多 skill。 +- 如果 workflow 已覆盖主要步骤,则不要先从大量 API skills 开始拼装流程;仅在 workflow 缺失、步骤不全或需要额外原子能力时,才继续下钻。 +- 优先更新已有 skill,而不是为一次性问题新增新的 skill 目录。 +- learned pattern 应写成可复用的方法或坑点,不应写成某次会话的流水账。 ## 参考 diff --git a/.opencode/skills/examples.md b/.opencode/skills/examples.md index ef5d126..beb01bf 100644 --- a/.opencode/skills/examples.md +++ b/.opencode/skills/examples.md @@ -126,3 +126,50 @@ opencode agent 调用工具 `view_scada`: ``` 前端打开 SCADA 监测面板,展示该节点的历史监测曲线。 + +## 示例 6:记住用户长期偏好 + +用户消息: +- "以后回答尽量简洁,先给结论再解释。" + +opencode agent 调用工具 `memory_manager`: + +```json +{ + "action": "add", + "reason": "用户明确给出了长期有效的回答风格偏好,后续会话也应遵守。", + "scope": "user", + "content": "用户偏好先给结论、再补必要解释,整体风格尽量简洁。" +} +``` + +## 示例 7:检索历史案例而不是误写入 memory + +用户消息: +- "我们之前是不是分析过类似的爆管定位问题?" + +opencode agent 调用工具 `session_search`: + +```json +{ + "reason": "用户在询问过往会话中的类似案例,应先检索历史 transcript 而不是写入新的 memory。", + "query": "爆管定位 类似案例", + "max_results": 5 +} +``` + +## 示例 8:沉淀可复用 workflow 模式 + +用户消息: +- "这套瓶颈分析流程之后可以复用。" + +opencode agent 调用工具 `skill_manager`: + +```json +{ + "action": "append_pattern", + "reason": "本轮已验证一套稳定可复用的瓶颈分析 workflow,适合沉淀到已有 skill。", + "skill_path": "workflow/bottleneck-analysis", + "pattern": "当瓶颈分析依赖大体量属性数据和模拟结果时,先用 dynamic_http_call 获取 preview,再用 fetch_result_ref 回读完整数据后再做合并与排序。" +} +``` diff --git a/.opencode/skills/runbook.md b/.opencode/skills/runbook.md index 2ca89f1..99874c3 100644 --- a/.opencode/skills/runbook.md +++ b/.opencode/skills/runbook.md @@ -6,6 +6,19 @@ - `chat/stream` 内部启动 opencode 会话,并注册工具 `dynamic_http_call`。 - opencode agent 通过工具调用后端能力,不直接发 HTTP。 - TJWaterAgent 执行器负责“代表当前用户调真实后端 API”(动态路径,无白名单)。 +- 会话完成后,运行时会基于 transcript 做后台 learning review;这一步用于判断是否需要更新 memory 或 skill,而不是替代主任务回答。 + +## 1.1) 自我学习闭环 + +- **memory_manager**:保存用户长期偏好 / 约束,以及稳定 workspace 事实 +- **skill_manager**:保存经过验证、可复用的 workflow / 方法 / pitfall +- **session_search**:检索当前用户 + 当前项目范围内的历史会话 transcript,用于回忆旧案例,避免把一次性案例写入 memory + +推荐分流: + +- 需要长期遵守的偏好 / 稳定事实 → `memory_manager` +- 可复用的方法、步骤、坑点 → `skill_manager` +- 某次分析过程、历史案例、临时结论 → `session_search` ## 2) 请求入口(前端) @@ -54,6 +67,17 @@ SSE 事件: - `method` 支持:`GET/POST/PUT/PATCH/DELETE`。 - `arguments` 会编码为 query 参数(列表会转为逗号拼接)。 +## 3.1) 学习工具约定 + +- 所有学习类工具都必须带 `reason` +- `memory_manager` 支持:`add / list / replace / remove` +- `skill_manager` 支持:`list / append_pattern / remove_pattern / write_reference / remove_reference` +- `session_search` 只搜索当前用户 + 当前项目作用域,不接受跨项目检索 +- `skill_manager` 的结构化写入优先落到: + 1. `## Learned Patterns` + 2. `references/*.md` + 不应直接重写 skill frontmatter 或任意正文段落 + ## 4) 用户上下文注入(后端执行阶段) - `Authorization`(Bearer Token) @@ -90,3 +114,10 @@ SSE 事件: - `dynamic_http_call`:TJWaterAgent 代理 HTTP 请求,结果返回给 opencode agent 做后续分析。 - 前端工具:TJWaterAgent 仅推送 SSE 事件,前端直接执行,结果不返回 opencode agent。 - `show_chart`:opencode agent 先通过 `dynamic_http_call` 查询数据,处理为 x_data + series 格式后调用 `show_chart`,前端直接渲染图表,不再请求后端。 + +## 7) 复盘与沉淀建议 + +- 复杂多工具任务完成后,优先判断是否产生了稳定 workflow,可写入 `skill_manager` +- 用户明确纠正表达风格、输出格式或步骤时,优先判断是否需要写入 `memory_manager` +- 如果你只是想确认“以前是不是处理过类似问题”,先用 `session_search` +- 如果结果仍然只是 preview,不要基于 preview 做 learned pattern,总是先 `fetch_result_ref` diff --git a/.opencode/skills/workflow/SKILL.md b/.opencode/skills/workflow/SKILL.md new file mode 100644 index 0000000..31fee6b --- /dev/null +++ b/.opencode/skills/workflow/SKILL.md @@ -0,0 +1,19 @@ +--- +name: tjwater-workflow +description: 负责分析类工作流能力。 +version: 1.0.0 +--- + +# Workflow Domain Skill + +## 简介 +负责分析场景下的工作流组织与调用入口能力。 + +## 使用策略 + +- 当用户问题明显属于“多接口 + 本地分析 + 综合结论”的分析任务时,优先从本目录查找固定 workflow。 +- 如果找到合适 workflow,应先按 workflow 执行主路径,再补充缺少的原子 skill。 +- 如果没有匹配 workflow,或现有 workflow 缺少关键步骤、接口或输出约束,再回到其他 domain/scenario/action skills 组合能力。 + +## 子模块索引 (渐进式引导) +- **bottleneck-analysis**: 见 `./bottleneck-analysis/SKILL.md` diff --git a/.opencode/skills/workflow/bottleneck-analysis/SKILL.md b/.opencode/skills/workflow/bottleneck-analysis/SKILL.md new file mode 100644 index 0000000..75fa8dd --- /dev/null +++ b/.opencode/skills/workflow/bottleneck-analysis/SKILL.md @@ -0,0 +1,121 @@ +--- +name: tjwater-workflow-bottleneck-analysis +description: workflow 下 bottleneck-analysis(水力瓶颈分析)工作流技能。 +version: 1.1.0 +--- + +# bottleneck-analysis Workflow Skill + +## 简介 +负责 `analytics/simulation-analysis` 场景下的水力瓶颈综合分析,通过结合管道属性与水力模拟结果,识别管网中超负荷、高流速、高水头损失的瓶颈管道,并给出分级改造建议。 + +## 前置依赖 +本工作流依赖以下两个数据源,需按顺序并行或串行获取: + +### 依赖 1:管道属性数据 +- 接口:`GET /api/v1/getallpipeproperties/` +- 参数:`network`(query,如 `tjwater`) +- 用途:获取全部管道的 id、管径(diameter)、长度(length)、粗糙度(roughness)、起端(node1)、终端(node2) 等属性 +- 注意:结果可能很大(数万条),需使用 `fetch_result_ref` 分批或全量获取 + +### 依赖 2:水力模拟结果 +- 接口:`GET /api/v1/runprojectreturndict/` +- 参数:`network`(query,如 `tjwater`) +- 用途:运行管网水力模拟,返回各管段的 flow(LPS)、velocity(m/s)、headloss(m)、status,以及各节点的 demand、head、pressure(KPA) +- 注意:结果可达 30MB+,需用 Python 脚本批量处理或使用 `fetch_result_ref` 回读 + +## 工作流步骤 + +### 第 1 步:并行获取管道属性和运行水力模拟 +同时调用 `getallpipeproperties` 和 `runprojectreturndict`,network 参数使用项目名称(如 `tjwater`)。 + +### 第 2 步:合并数据 +用 Python 脚本将管道属性的 pipe_id 与模拟结果的 link_id 进行关联,构建含以下字段的合并数据集: + +| 字段 | 来源 | 说明 | +|------|------|------| +| id | 两者关联键 | 管道/链路 ID | +| flow | 模拟 link_results | 流量 (LPS) | +| velocity | 模拟 link_results | 流速 (m/s) | +| headloss | 模拟 link_results | 水头损失 (m) | +| diameter | 管道属性 | 管径 (mm) | +| length | 管道属性 | 长度 (m) | +| roughness | 管道属性 | 粗糙度系数 | +| node1 / node2 | 管道属性 | 起端/终端节点 ID | +| unit_headloss | 计算 | headloss / length (m/m) | +| capacity_ratio | 计算 | |flow| / (π×(d/2000)²×1000),即实际流量与 1m/s 设计流量的比值 | + +同时从模拟 node_results 提取各节点 pressure,关联到管段两端。 + +### 第 3 步:多维度瓶颈识别 +按以下 5 个维度分别排序筛选,交叉印证: + +| 维度 | 筛选条件 | 指示含义 | +|------|---------|---------| +| 高流速 | velocity > 1.2 m/s | 管径不足 | +| 主干管高流量 | diameter ≥ 300mm 且 velocity > 0.5 m/s | 传输瓶颈 | +| 高水头损失 | headloss > 5m 且 0.3 < velocity < 1.5 m/s | 能耗瓶颈/粗糙度问题 | +| 高单位水头损失 | unit_headloss > 1.0 m/m | 严重局部瓶颈 | +| 超负荷 | capacity_ratio > 1.0 | 实际流量超过设计能力 | + +排除极短管道(length < 0.5m)以减少噪声。 + +### 第 4 步:综合评分 +对有效管道计算综合瓶颈分数: + +``` +composite_score = (velocity / max_velocity) × 0.4 + + (headloss / max_headloss) × 0.3 + + (capacity_ratio / max_capacity_ratio) × 0.3 +``` + +取 TOP 10~20 作为最严重瓶颈管道。 + +### 第 5 步:前端可视化 +- 使用 `show_chart` 展示流速分布柱状图 +- 使用 `locate_features` 在地图上定位 TOP 瓶颈管道(feature_type=pipe) +- 可选:使用 `view_history` 查看瓶颈管道的历史运行数据 +- 前端工具仅用于展示,分析结论必须来自 `dynamic_http_call` / `fetch_result_ref` 获得的数据 + +### 第 6 步:给出分级改造建议 +按严重程度分为三级: + +- **🚨 紧急**:综合评分 > 0.3,立即安排管径升级 +- **⚡ 重点**:综合评分 0.15~0.3,纳入近期改造计划 +- **📋 关注**:综合评分 0.05~0.15 或单维度超标,持续监测 + +每条建议含:当前管径 → 建议管径(基于目标流速 1.0~1.5 m/s 反推),并附改造理由。 + +## 改造管径计算公式 +``` +建议管径(mm) = 2 × 1000 × sqrt(|flow| / (π × target_velocity × 1000)) +``` +目标流速:DN<300 取 1.0 m/s,DN≥300 取 1.2 m/s。 + +## 证据约束 + +- 如果关键数据仍处于 preview 状态,不得直接输出最终瓶颈结论 +- 如果模拟结果不完整或接口失败,应明确说明当前仅能做初步筛查 +- 改造建议必须区分“数据直接支持的结论”和“工程经验推断” + +## 推荐输出结构 + +1. 分析范围与数据来源 +2. 主要瓶颈管段 Top N +3. 分级建议(紧急 / 重点 / 关注) +4. 假设与局限 +5. 是否建议地图定位或图表展示 + +## 参考 +- 管道属性操作:`../business/network-assets/pipes/SKILL.md` +- 模拟操作:`./simulation/SKILL.md` +- 节点属性操作:`../business/network-assets/junctions/SKILL.md` + +## Learned Patterns +- 先按“属性数据获取 → 模拟结果获取 → 本地关联 → 多指标筛选 → 分级建议”拆解工作流,再组织展示步骤,避免把一次分析过程写成会话流水账。 +- 结果集较大时,优先使用 `fetch_result_ref` 或本地脚本批处理;只要数据仍是 preview、截断或未完整回读,就不能直接输出 Top N 瓶颈结论。 +- 关联前先统一关键字段和单位:`pipe_id/link_id`、`diameter(mm)`、`length(m)`、`flow(LPS)`、`pressure(KPA)`;字段未对齐时,后续 ranking 和建议都会失真。 +- `unit_headloss`、`capacity_ratio` 等衍生指标应在过滤异常数据(如 `length < 0.5m` 的短管)后再计算,否则容易被极端值放大。 +- 阈值和评分权重应视为可调启发式,而不是唯一真理;输出时要区分“数据直接支持的结论”和“工程经验推断的建议”。 +- 地图定位、图表展示属于证据呈现层,不能替代分析层;瓶颈判定必须基于后端原始结果或完整回读数据。 +- 常见坑点:短管导致单位水头损失虚高、节点或链路映射缺失导致误判、模拟结果不完整时误把局部结果当全量结论。