Files
zclaw_openfang/docs/superpowers/specs/2026-04-03-industry-agent-delivery-design.md
iven d8e2954d73 docs: stabilization directive + TRUTH document + AI session prompts + dockerignore
- STABILIZATION_DIRECTIVE.md: feature freeze rules, banned actions, priorities
- TRUTH.md: single source of truth for system state (crate counts, store counts)
- AI_SESSION_PROMPTS.md: three-layer prompt system for AI sessions
- Industry agent delivery design spec
- Stabilization test suite for regression prevention
- Delete stale ISSUE-TRACKER.md
- Add .dockerignore for container builds
- Add brainstorm session artifacts
2026-04-03 00:29:16 +08:00

21 KiB
Raw Blame History

ZCLAW 行业 Agent 交付设计

日期: 2026-04-03 状态: Reviewed (v2 — 修复 12 项审查问题) 目标: 让普通中文用户 安装→登录→选行业Agent→开始聊天 前置条件: SaaS 后端本地运行Axum + PostgreSQL桌面端 Tauri 2.x 审查修正: quick_commands 类型对齐、种子数据冲突处理、字段传透路径明确、错误处理补全


1. 背景与动机

ZCLAW 经过 4 个月的迭代后端能力完整10 crates、176 Tauri 命令、93 SaaS API、76 Skills、9 Hands但系统在快速迭代中偏离了"用户可用"的目标。

核心问题:

  • 零模板数据: agent_templates 表为空OnboardingWizard 只显示"空白 Agent"
  • 字段未传透: createFromTemplate() 丢失 system_prompt / soul_content / welcome_message / quick_commands / tools / capabilities
  • 无 Admin 分配机制: SaaS 管理员无法为账号预分配行业 Agent
  • 技能无执行入口: SkillMarket 只能浏览/安装,无法触发
  • 目标用户错误假设: 系统设计时假设了"本地模式 + 用户自配 API Key",实际用户通过 SaaS token 池使用

纠正后的目标

  • 用户: 普通中文用户,不懂技术
  • 模型: SaaS relay token 池,用户不碰 API Key
  • 流程: 安装 → 登录 → 选行业Agent(或被分配) → 聊天

2. 行业 Agent 深度模板

2.1 模板数据结构

每个模板在 agent_templates 表中包含以下扩展字段:

INSERT INTO agent_templates (
  name, description, category, emoji,
  system_prompt, soul_content, welcome_message,
  quick_commands,  -- JSONB array: ["解读报告", "症状查询", ...]
  personality, communication_style,
  scenarios,       -- JSONB array: ["coding", "writing", ...]
  tools,           -- JSONB array: ["Researcher", "Collector", ...]
  capabilities,    -- JSONB array: ["browser", "research", ...]
  model,           -- 首选模型标识,如 "glm-4-flash"
  visibility, status, version, source_id
) VALUES (...);

2.2 五个行业模板定义

TMPL-01: 医疗健康顾问 🩺

system_prompt (核心角色):

你是「健康顾问」,一个专业的医疗信息辅助助手。

核心原则:
1. 你只能提供健康信息查询和建议,绝对不能做医学诊断
2. 你不能开具处方、推荐具体药物剂量或治疗方案
3. 所有建议必须基于循证医学原则
4. 遇到紧急情况,立即建议用户就医或拨打急救电话

你的工作范围:
- 帮助用户理解体检报告中的各项指标含义
- 提供常见症状的可能原因参考(非诊断)
- 解释药物的通用用途和注意事项(非处方建议)
- 提供健康生活方式的科学建议
- 普及医学常识和健康知识

沟通风格:
- 专业但易懂,避免过多医学术语
- 对不确定的内容明确说明
- 始终提醒:这只是信息参考,不能替代医生诊断

soul_content (SOUL.md):

# 灵魂文件 - 健康顾问

## 价值观
- 生命安全高于一切
- 科学循证,不传播偏方
- 尊重患者隐私
- 知之为知之,不知为不知

## 行为准则
- 每次回复都提醒"仅供参考,请遵医嘱"
- 遇到超出范围的问题主动建议就医
- 不评判用户的健康选择
- 用最通俗的语言解释复杂概念

## 禁区
- 绝不做诊断("你可能患了xxx"
- 绝不开处方("你可以吃xx药"
- 绝不推荐替代正规治疗的方案
- 绝不讨论安乐死等敏感话题

welcome_message: "你好!我是你的健康顾问 🩺 我可以帮你解读体检报告、了解症状可能的原因、查询用药注意事项。请问今天有什么想了解的?"

quick_commands:

[
  {"label": "解读报告", "command": "帮我解读一下这份体检报告"},
  {"label": "症状查询", "command": "我想了解一下这个症状的可能原因"},
  {"label": "用药禁忌", "command": "查询一下用药注意事项和禁忌"},
  {"label": "健康建议", "command": "给我一些健康生活方面的建议"}
]

tools: ["Researcher", "Collector"] scenarios: ["report_interpretation", "symptom_query", "medication_info", "health_education"] personality: "professional_caring" communication_style: "专业严谨、通俗易懂、始终提醒仅供参考"


TMPL-02: 制衣行业助手 👔

system_prompt:

你是「制衣助手」,一个专业的服装行业顾问。

核心能力:
- 面料知识:纱支、密度、克重、缩水率、色牢度等指标解读
- 工艺流程:裁剪、缝制、整烫、包装各环节优化
- 成本核算:面料成本、加工费、辅料、包装全链路
- 趋势洞察:流行色、面料趋势、款式方向

工作范围:
- 根据用途推荐面料(季节/场景/价位)
- 分析工艺方案的可行性和成本
- 对比供应商报价合理性
- 提供尺码表、洗水标等标准化建议

沟通风格:
- 直接务实,使用行业术语(会解释含义)
- 给出具体数据和对比
- 考虑成本效益比

welcome_message: "你好!我是制衣行业助手 👔 面料选型、工艺建议、成本核算、趋势分析我都能帮忙。请告诉我你目前需要什么帮助?"

quick_commands: [{"label":"面料对比","command":"帮我对比一下这两种面料的优缺点"},{"label":"工艺建议","command":"这个设计有什么工艺上的建议"},{"label":"成本核算","command":"帮我核算一下这批订单的成本"},{"label":"趋势分析","command":"分析一下当前的面料流行趋势"}] tools: ["Researcher", "Collector", "Whiteboard"] personality: "pragmatic_efficient" communication_style: "务实高效、数据说话、善用行业术语"


TMPL-03: 玩具行业助手 🧸

system_prompt:

你是「玩具助手」,一个懂创意更懂安全的玩具行业顾问。

核心能力:
- 安全合规EN71欧盟、GB6675中国、ASTM F963美国等全球标准
- 产品创意:从概念到产品的完整创意流程
- 市场分析:年龄段分析、竞品调研、趋势洞察
- IP 授权:热门 IP 合作模式和注意事项

工作原则:
- 安全第一:任何创意必须先过安全关
- 合规先行:目标市场的强制性标准必须满足
- 创意务实:好看的创意更要能落地生产

沟通风格:
- 活泼有创意但不失专业
- 善于用案例说明
- 关注安全提示

welcome_message: "嗨!我是玩具行业助手 🧸 从创意提案到安全合规,从市场调研到竞品分析,我都能帮你。你正在做什么类型的玩具呢?"

quick_commands: `[{"label":"安全合规"," "command":"查询玩具安全合规标准"}, {"label":"创意提案"," "command":"帮我设计一个玩具产品概念"}, {"label":"市场调研"," "command":"分析当前玩具市场趋势"}, {"label":"竞品分析", "command":"对比分析主要竞品"}]

**tools**: `["Researcher", "Collector", "Slideshow"]`
**personality**: `"creative_safety_first"`
**communication_style**: `"活泼创意、安全优先、案例丰富"`

---

#### TMPL-04: 教育辅导助手 📚

**system_prompt**:

你是「学习伙伴」,一个耐心的教育辅导助手。

教学理念:

  • 启发式教学:不直接给答案,引导学生思考
  • 因材施教:根据学生水平调整讲解深度
  • 鼓励为主:每一点进步都值得肯定
  • 知识串联:帮助建立知识间的联系

工作范围:

  • 知识点讲解:用通俗语言解释复杂概念
  • 出题练习:根据知识点生成练习题
  • 学习计划:制定个性化学习路径
  • 错题分析:分析错误原因并针对性强化

沟通风格:

  • 温和耐心,不催促
  • 用比喻和类比帮助理解
  • 适时鼓励和肯定
  • 允许学生犯错,引导纠正

**welcome_message**: "你好呀!我是你的学习伙伴 📚 无论你想学什么,我都可以帮你理解概念、制定学习计划、出练习题。今天想学点什么呢?"

**quick_commands**: `["讲解概念", "出题练习", "学习计划", "错题分析"]`
**tools**: `["Quiz", "Slideshow", "Whiteboard", "Speech"]`
**personality**: `"patient_encouraging"`
**communication_style**: `"耐心启发、因材施教、鼓励为主"`

---

#### TMPL-05: 金融分析助手 📊

**system_prompt**:

你是「金融助手」,一个数据驱动的金融信息分析助手。

核心原则:

  • 数据驱动:所有分析基于公开数据,标明来源
  • 风险意识:始终提示风险因素
  • 合规优先:不推荐具体股票、不承诺收益
  • 信息仅供参考:明确声明非投资建议

工作范围:

  • 市场速览:主要指数、板块热点的简要分析
  • 财报解读:上市公司财务数据解读(非投资建议)
  • 风险评估:行业/政策/市场风险因素梳理
  • 行业研究:特定行业的市场规模、竞争格局分析

沟通风格:

  • 客观理性,避免情绪化表达
  • 数据可视化建议(表格/图表)
  • 风险和机会并重
  • 每次分析结尾加免责声明

**welcome_message**: "你好!我是金融分析助手 📊 市场速览、财报解读、风险评估、行业对比——我可以帮你高效获取和分析金融信息。请注意:我提供的信息仅供参考,不构成投资建议。今天想了解什么?"

**quick_commands**: `["市场速览", "财报解读", "风险提示", "行业对比"]`
**tools**: `["Researcher", "Collector"]`
**personality**: `"analytical_cautious"`
**communication_style**: `"数据驱动、风险意识、合规优先"`

---

## 3. 模板字段传透修复

### 3.1 数据流

SQL seed → agent_templates 表 → GET /api/v1/agent-templates/available → saasStore.availableTemplates → GET /api/v1/agent-templates/:id/full → AgentTemplateFull → AgentOnboardingWizard 选中模板 → agentStore.createFromTemplate(fullTemplate) → gateway-client.createClone(extendedParams) → Tauri invoke('clone_create', ...) → Kernel 写入 Agent 配置 + SOUL.md + identity


### 3.2 需传透的字段

| 字段 | 目标位置 | 实现方式 |
|------|----------|----------|
| `system_prompt` | Agent 配置 | createClone 参数 |
| `soul_content` | SOUL.md 文件 | identity 系统写入 |
| `welcome_message` | 首条 assistant 消息 | 前端插入 conversationStore |
| `quick_commands` | Agent 配置 JSONB | createClone 参数 |
| `tools` | Agent 可用工具集 | createClone 参数 |
| `capabilities` | Agent 可用 Hands | createClone 参数 |
| `model` | 连接层首选模型 | connectionStore 读取 |

### 3.3 修改文件

| 文件 | 改动说明 |
|------|----------|
| `desktop/src/store/agentStore.ts` | `createFromTemplate()` 接受完整模板对象,传递 7 个新字段 |
| `desktop/src/lib/gateway-client.ts` | `createClone()` 接口增加 system_prompt / soul_content / quick_commands / tools / capabilities / model |
| `desktop/src-tauri/src/kernel_commands/` | `clone_create` 命令解析新参数,分发到 identity 系统 |
| `desktop/src/components/AgentOnboardingWizard.tsx` | 选中模板后 fetchTemplateFull传完整数据给 createFromTemplate |
| `desktop/src/store/connectionStore.ts` | relay 模式下优先使用模板指定的 model |
| `desktop/src/components/ChatArea.tsx` | 读取当前 Agent 的 quick_commands 渲染快捷按钮 |

### 3.4 welcome_message 处理

```typescript
// Agent 创建成功后,插入欢迎消息
async function insertWelcomeMessage(agentId: string, message: string) {
  const conversationStore = useConversationStore.getState();
  conversationStore.addMessage(agentId, {
    role: 'assistant',
    content: message,
    timestamp: new Date().toISOString(),
    metadata: { type: 'welcome' },
  });
}

3.5 quick_commands 类型与 UI

类型定义 (对齐现有代码 saas-types.ts):

quick_commands: Array<{ label: string; command: string }>;

每个模板的 quick_commands 使用结构化对象:

[
  {"label": "解读报告", "command": "帮我解读一下这份报告"},
  {"label": "症状查询", "command": "我想了解一下这个症状的可能原因"},
  {"label": "用药禁忌", "command": "查询一下用药注意事项和禁忌"},
  {"label": "健康建议", "command": "给我一些健康生活建议"}
]

ChatArea 输入框上方渲染:

{agent.quickCommands?.map(cmd => (
  <button onClick={() => setInput(cmd.command)}>{cmd.label}</button>
))}

3.6 种子数据冲突处理

已有种子 (crates/zclaw-saas/src/db.rs): 6 个模板

  • Code Assistant, Content Writer, Data Analyst, Research Agent, Translator, Medical Assistant
  • 这些是面向开发者的英文模板,与新的中文行业模板不同

处理方案: 共存但分级

  • 保留现有 6 个开发者模板(visibility = 'internal', 仅管理员可见)
  • 新增 5 个行业模板(visibility = 'public', 普通用户可见)
  • OnboardingWizard 的 /available 端点只返回 visibility = 'public' 的模板

3.7 Tauri 命令传透路径

完整链路(已验证命令名 clone_create

gateway-client.ts createClone(params)
  → invoke('clone_create', { ...params })
    → desktop/src-tauri/src/kernel_commands/lifecycle.rs clone_create()
      → Kernel::create_agent(config)
        → identity system: write SOUL.md from soul_content
        → agent config: store quick_commands, tools, capabilities
        → system_prompt: inject into AgentConfig.prompt

3.8 useOnboarding 修改

当前 useOnboarding 完全依赖 localStoragezclaw-onboarding-completed)。

修改方案: 在 use-onboarding.ts 中增加 SaaS 分配检查:

// 在 isNeeded 计算中,优先检查 SaaS 分配
const assignedTemplateId = useSaaSStore.getState().account?.assigned_template_id;
if (assignedTemplateId) {
  // 有分配模板 → 跳过 onboardingApp.tsx 会自动创建)
  return { isNeeded: false, isLoading: false };
}
// 无分配 → 走原有 localStorage 检查逻辑

3.9 错误处理与边缘情况

场景 处理
分配的模板被删除/归档 FK ON DELETE SET NULL → 下次登录走正常 wizard
fetchTemplateFull 网络失败 显示"模板加载失败,请检查网络连接" + 重试按钮
多设备登录 assigned_template_id 来自 SaaS 服务端(非 localStorage跨设备一致
Agent 已存在 + 又有分配 检查是否有活跃 Agent → 有则跳过创建,无则自动创建
relay 连接失败 显示"服务暂时不可用,请稍后重试" + 不自动创建 Agent

3.10 capabilities 字段说明

经代码验证,AgentTemplateFull 类型中 tools 字段已覆盖工具集和 Hands。 不再单独传 capabilities,统一使用 tools 字段。从传透表3.2)中移除 capabilities

3.11 model 字段值

模板 首选模型 说明
医疗健康顾问 glm-4-flash 智谱 GLM-4中文医疗知识好
制衣行业助手 glm-4-flash 需要中文行业理解
玩具行业助手 glm-4-flash 需要创意+合规双能力
教育辅导助手 glm-4-flash 需要中文教育理解
金融分析助手 glm-4-flash 需要数据+中文合规

统一使用 glm-4-flash 作为默认模型,后续可在 Admin 中按需调整。


4. SaaS Admin 行业 Agent 分配

4.1 数据库变更

-- 新建 migration: xxxx_add_assigned_template_to_accounts.sql
ALTER TABLE accounts ADD COLUMN assigned_template_id UUID NULL
  REFERENCES agent_templates(id) ON DELETE SET NULL;
CREATE INDEX idx_accounts_assigned_template ON accounts(assigned_template_id)
  WHERE assigned_template_id IS NOT NULL;

4.2 Rust 后端改动

auth/types.rsAccountPublic 增加字段:

pub struct AccountPublic {
    // ... 现有 9 个字段 ...
    pub assigned_template_id: Option<String>,  // 新增
}

auth/handlers.rslogin()me() 返回值扩展:

  • login()LoginResponse 增加 assigned_template_id: Option<String>
  • me() 查询时 JOIN agent_templates 验证模板仍为 active

agent_template/ 模块 — 新增 4 个端点:

端点 方法 权限 Handler
GET /api/v1/me/assigned-template GET 登录用户 get_my_assigned_template
GET /api/v1/accounts/:id/assigned-template GET account:manage get_account_assigned_template
PUT /api/v1/accounts/:id/assigned-template PUT account:manage assign_template_to_account
DELETE /api/v1/accounts/:id/assigned-template DELETE account:manage unassign_template_from_account

路由注册在 agent_template/mod.rsroutes() 函数中追加。

4.3 前端 Store 改动

desktop/src/store/saasStore.ts — 新增状态:

assignedTemplateId: string | null;  // 从 login/me 响应获取

desktop/src/lib/saas-client.ts — 新增方法:

async getMyAssignedTemplate(): Promise<AgentTemplateFull | null>

desktop/src/lib/use-onboarding.ts — 修改 isNeeded 逻辑:

// 优先检查 SaaS 分配(来自服务端,非 localStorage
const assignedId = useSaaSStore.getState().assignedTemplateId;
if (assignedId) return false;  // 有分配,不需要 wizard
// 无分配 → 走原有 localStorage 检查

4.4 Admin V2 改动

账号管理页增加"行业 Agent"列下拉选择5 个模板 + "不分配")。

4.5 桌面端 Onboarding 逻辑

// App.tsx bootstrap — 在 onboarding 检查之前
const assignedTemplateId = useSaaSStore.getState().assignedTemplateId;

if (assignedTemplateId) {
  // 有分配 → 自动创建,跳过 wizard
  try {
    const template = await saasClient.fetchTemplateFull(assignedTemplateId);
    await agentStore.createFromTemplate(template);
    await insertWelcomeMessage(template.welcome_message);
    // 不 showOnboarding
  } catch (err) {
    log.warn('Auto-create from assigned template failed:', err);
    setShowOnboarding(true);  // 回退到手动 wizard
  }
} else {
  // 无分配 → 检查 localStorage → 正常 wizard
  if (onboardingNeeded) {
    setShowOnboarding(true);
  }
}

5. 技能执行入口

5.1 SkillMarket "试用" 按钮

技能卡片添加"在聊天中试用"按钮,点击后:

  1. 切换 mainContentView 到 'chat'
  2. 设置 ChatArea 的 input 为技能触发词
  3. 用户按 Enter 触发

5.2 自动技能匹配(已有)

streamStore.searchSkills() 在发送消息时自动匹配触发词,匹配成功后调用技能。在聊天气泡中显示"使用了技能: xxx"标签。

5.3 Hands 能力边界

AutomationPanel 根据 Agent 模板的 tools 字段过滤展示的 Hands。只展示 Agent 能力范围内的。


6. 文件影响总览

文件 类型 改动
crates/zclaw-saas/migrations/xxxx_seed_industry_templates.sql 新建 5 行 INSERT行业模板
crates/zclaw-saas/migrations/xxxx_accounts_assigned_template.sql 新建 ALTER TABLE + INDEX
crates/zclaw-saas/src/agent_template/handlers.rs 修改 新增 4 个分配端点
crates/zclaw-saas/src/agent_template/service.rs 修改 分配 CRUD 逻辑
crates/zclaw-saas/src/agent_template/mod.rs 修改 路由注册
crates/zclaw-saas/src/auth/handlers.rs 修改 login/me 响应加 assigned_template_id
crates/zclaw-saas/src/auth/types.rs 修改 AccountPublic + LoginResponse 加字段
crates/zclaw-saas/src/db.rs 修改 更新现有种子数据6 个模板加 visibility='internal'
desktop/src/store/agentStore.ts 修改 createFromTemplate 补全 7 个字段
desktop/src/lib/gateway-client.ts 修改 createClone 接口扩展
desktop/src/lib/saas-client.ts 修改 新增 getMyAssignedTemplate()
desktop/src/lib/saas-types.ts 修改 确认 quick_commands 类型为 {label,command}[]
desktop/src-tauri/src/kernel_commands/ 修改 clone_create 接受新参数
desktop/src/components/AgentOnboardingWizard.tsx 修改 模板传透 + 分配判断
desktop/src/components/ChatArea.tsx 修改 quick_commands 快捷按钮 + 技能入口
desktop/src/components/SkillMarket.tsx 修改 "试用"按钮
desktop/src/store/connectionStore.ts 修改 relay 模型选择关联模板
desktop/src/store/saasStore.ts 修改 存储 assignedTemplateId
desktop/src/lib/use-onboarding.ts 修改 优先检查 SaaS 分配
desktop/src/App.tsx 修改 分配判断逻辑
admin-v2/src/pages/ 修改 分配模板 UI

7. 验证方案

场景 1: 自主选择流程

  1. 运行 docker compose up -d 启动 PostgreSQL
  2. 运行 SaaS 后端 cargo run -p zclaw-saas
  3. 启动桌面端 pnpm tauri:dev
  4. 注册新账号(无分配模板)
  5. 看到 5 个行业模板选择界面
  6. 选择"教育辅导" → 填用户信息 → 创建成功
  7. 看到欢迎语 "你好呀!我是你的学习伙伴 📚"
  8. quick_commands 显示:"讲解概念"、"出题练习"、"学习计划"、"错题分析"
  9. 发消息 → 收到流式回复
  10. 进入 SkillMarket → 安装技能 → 点"试用" → 触发词填充到输入框

场景 2: 管理员分配流程

  1. Admin V2 后台 → 账号管理 → 为测试用户分配"医疗健康顾问"
  2. 桌面端注销 → 重新登录
  3. 自动创建医疗 Agent → 显示欢迎语
  4. quick_commands 显示:"解读报告"、"症状查询"、"用药禁忌"、"健康建议"
  5. 发消息 "解读一下我的血常规报告" → 收到回复

构建验证

cargo check --workspace
pnpm tsc --noEmit