📚 产品定制无人化 系列文章

Spec执行:基于OpenSpec的AI代理设计

第二篇回答了"如何把产品提取成Spec",这篇回答"如何基于Spec让AI执行产品操作"。但在此之前,我们需要先搞清楚一个关键问题:SpecExecute是否必须存在?

一、问题的提出

在设计Spec执行方案之前,我们需要回答一个根本问题:

SpecExecute是必须存在的吗?


二、两种思路的对比

思路A:需要独立的SpecExecute层

OpenSpec (设计时) + SpecExecute (运行时)

SpecExtract ──→ OpenSpec格式Spec ──→ 用户指令
                                              ↓
                                       SpecExecute
                                              ↓
                                         执行产品操作

理由:
• OpenSpec只解决"理解产品"的问题
• 执行需要额外的"运行时"能力
• 两者配合才能完成"定制无人化"

思路B:OpenSpec本身就能执行

OpenSpec = 设计工具 + 执行工具

SpecExtract ──→ OpenSpec格式Spec ──→ OpenSpec内置执行
                                              ↓
                                    OpenSpec CLI / Agent

理由:
• OpenSpec已经有workflow和变更管理
• 也许不需要额外的执行层
• 一切都可以通过OpenSpec + LLM解决

三、OpenSpec的定位分析

OpenSpec提供了什么:
1. 一种Markdown格式的Spec描述规范
2. CLI工具(validate, publish, changes等)
3. Spec管理的workflow(changes/目录结构)
4. 支持多AI coding agent集成

OpenSpec本质上是一个"Spec编辑和管理工具":
- 它定义了什么是一个好的Spec
- 它提供了Spec版本管理的机制
- 它支持变更提案的工作流

但OpenSpec不包含:
- 如何让AI代理"操作"产品
- 用户指令如何转成产品操作
- 产品状态如何读取和更新

结论:OpenSpec ≠ 执行工具。它解决的是"如何描述Spec",不解决"如何基于Spec执行"。


四、SpecExecute必须存在的理由

理由1:职责分离

OpenSpec的职责:                   SpecExecute的职责:
├─ 定义Spec格式                   ├─ 读取并解析Spec
├─ 管理Spec版本                   ├─ 理解用户指令
├─ 处理变更提案                   ├─ 规划执行路径
└─ 不涉及运行时                   └─ 调用产品接口

理由2:执行需要"动作"

OpenSpec中的内容是"陈述性的":
- Entity定义了"客户是什么"
- Action定义了"创建客户需要什么"
- Rule定义了"折扣规则是什么"

但这些都不包含"执行":
- 谁来调用API?
- 参数从哪里来?
- 结果返回给谁?

理由3:产品操作需要"桥接"

用户指令                    产品API
   │                          │
   │                          │
   ↓                          │
"创建客户" ──→ 需要解析 ──→ POST /api/clients
   │                          │
   │                          │
"改样式" ──→ 需要解析 ──→ 修改CSS文件
   │                          │
   │                          │
"加功能" ──→ 需要解析 ──→ 新增代码模块
                                   │
这个"解析-转换-调用"的桥梁,就是SpecExecute

五、SpecExecute的三种形式

形式说明优点缺点
独立Skill完整的SpecExecute Skill完整、独立、可测试需要额外维护
OpenSpec插件作为OpenSpec的扩展与OpenSpec深度集成受扩展机制限制
Prompt模式只是一组Prompts极简、无需额外代码缺乏结构化执行保障

六、最终选择:Prompt模式 + OpenSpec集成

┌─────────────────────────────────────────────────────────────┐
│                    选择理由                                    │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  1. 与SpecExtract保持一致                                    │
│     - SpecExtract也是基于Prompt的Skill                        │
│                                                              │
│  2. 最小化额外复杂度                                        │
│     - 不需要额外的执行引擎                                     │
│     - 基于LLM的理解能力自然执行                              │
│                                                              │
│  3. OpenSpec提供了必要的"脚手架"                            │
│     - CLI工具验证Spec格式                                   │
│     - changes/目录管理变更                                  │
│                                                              │
│  4. 灵活性                                                  │
│     - Prompt可以描述任何执行逻辑                             │
│                                                              │
└─────────────────────────────────────────────────────────────┘

七、SpecExecute Prompt设计

7.1 核心Prompt:基于Spec执行

# 基于OpenSpec执行用户指令 Prompt

## 角色
你是一个产品操作代理,擅长基于OpenSpec格式的产品规格执行用户指令。

## 执行流程

### Step 1: 理解用户指令
分析用户想做什么:
1. 识别意图类型(查询/操作/分析/定制)
2. 提取涉及的实体
3. 确定需要执行的操作

### Step 2: 路由到Spec中的定义
在Spec中查找匹配的定义:
1. 找到对应的Entity
2. 找到对应的Action
3. 检查相关的Rule

### Step 3: 规划执行步骤
制定执行计划:
1. 需要哪些前置操作
2. 调用哪个API端点
3. 传入什么参数

### Step 4: 执行并返回结果
执行业务操作:
1. 调用产品API
2. 处理返回结果
3. 应用相关规则
4. 返回格式化结果

## 输出格式

```json
{
  "intent": "用户意图",
  "intent_type": "query/operation/customization",
  "matched_entity": {...},
  "matched_action": {...},
  "execution_plan": {
    "steps": [...]
  },
  "execution_result": {...},
  "response_to_user": "自然语言响应"
}
```

八、完整执行示例

为了更好地理解SpecExecute的实际工作,我们以一个CRM系统为例,展示三种典型的定制场景。

8.1 场景一:改界面样式

用户:"把登录页面的登录按钮改成蓝色"

Step 1: 理解用户指令

{
  "intent": "修改登录按钮样式",
  "intent_type": "customization",
  "action_type": "ui_modification",
  "target": "登录页面/登录按钮",
  "change": {
    "property": "color",
    "value": "蓝色(#1890ff)"
  }
}

Step 2: 路由到Spec定义

在Spec中查找匹配的Action:

找到 Action: update_ui_component
- target_entity: UIComponent
- params: { component_id, property, value }
- preconditions: []
- rules_applied: ["theme_consistency"]

找到 Entity: UIComponent
- properties: { id, page, element, styles }
- relationships: UIComponent → belongs_to → Page

Step 3: 规划执行步骤

{
  "steps": [
    {
      "step": 1,
      "action": "find_component",
      "target": "登录按钮",
      "params": { "page": "登录页", "element": "登录按钮" }
    },
    {
      "step": 2,
      "action": "validate_change",
      "params": { "property": "color", "value": "#1890ff" }
    },
    {
      "step": 3,
      "action": "update_component_style",
      "endpoint": "PATCH /api/ui/components/{id}",
      "params": { "color": "#1890ff" }
    },
    {
      "step": 4,
      "action": "publish_change",
      "params": { "reason": "用户定制:改按钮颜色" }
    }
  ]
}

Step 4: 执行结果

AI:"已完成!登录按钮颜色已改为蓝色(#1890ff)。变更已记录:change-20260328-login-button-color"


8.2 场景二:加功能模块

用户:"给订单模块加上批量导出的功能"

Step 1: 理解用户指令

{
  "intent": "新增批量导出功能",
  "intent_type": "customization",
  "action_type": "add_feature",
  "target": "订单模块",
  "feature": {
    "name": "批量导出",
    "description": "支持导出订单列表为Excel/CSV",
    "scope": ["已付款订单", "待发货订单"]
  }
}

Step 2: 路由到Spec定义

在Spec中查找匹配的Entity和Action:

找到 Entity: Order
- attributes: { id, customer, amount, status, created_at }
- relationships: Order → belongs_to → Customer

找到 Entity: ExportJob
- attributes: { id, type, status, created_at, file_url }

找到 Action: create_export_job
- target_entity: ExportJob
- params: { type, filters }
- post_effects: ["生成导出任务", "发送通知"]

发现:没有"批量导出"Action → 这是一个新功能需求

Step 3: 规划执行步骤

{
  "steps": [
    {
      "step": 1,
      "action": "analyze_existing_code",
      "target": "Order模块",
      "params": { "scope": ["查询逻辑", "数据结构"] }
    },
    {
      "step": 2,
      "action": "design_new_action",
      "params": {
        "name": "batch_export_orders",
        "endpoint": "POST /api/orders/export",
        "params": { "filters": "订单筛选条件", "format": "excel/csv" }
      }
    },
    {
      "step": 3,
      "action": "implement_action",
      "params": { "language": "Python", "framework": "Django" }
    },
    {
      "step": 4,
      "action": "update_spec",
      "params": { "entity": "ExportJob", "action": "batch_export_orders" }
    },
    {
      "step": 5,
      "action": "create_change_proposal",
      "params": { "reason": "用户定制:新增批量导出功能" }
    }
  ]
}

Step 4: 执行结果

AI:"已分析订单模块结构,准备新增批量导出功能。\n\n我将:\n1. 创建 ExportJob 数据模型\n2. 实现 POST /api/orders/export 接口\n3. 支持按状态、日期、客户筛选\n4. 支持导出为Excel和CSV\n\n是否需要我开始实现?"


8.3 场景三:改业务流程

用户:"把订单审批流程改成需要部门经理和总监两级审批"

Step 1: 理解用户指令

{
  "intent": "修改订单审批流程",
  "intent_type": "customization",
  "action_type": "modify_workflow",
  "target": "订单审批流程",
  "change": {
    "from": "一级审批(仅部门经理)",
    "to": "两级审批(部门经理 + 总监)",
    "triggers": ["订单金额 > 10000"]
  }
}

Step 2: 路由到Spec定义

在Spec中查找匹配的Rule:

找到 Rule: order_approval_workflow
- type: approval
- current_logic: "订单金额>10000 → 部门经理审批"
- decision_table: [
    { amount: ">10000", approvers: ["部门经理"] }
  ]

需要修改为:
- decision_table: [
    { amount: ">10000 AND <50000", approvers: ["部门经理"] },
    { amount: ">=50000", approvers: ["部门经理", "总监"] }
  ]

Step 3: 规划执行步骤

{
  "steps": [
    {
      "step": 1,
      "action": "analyze_current_workflow",
      "params": { "rule": "order_approval_workflow" }
    },
    {
      "step": 2,
      "action": "validate_new_workflow",
      "params": {
        "new_approvers": ["部门经理", "总监"],
        "approval_chain": "sequential"
      }
    },
    {
      "step": 3,
      "action": "update_rule",
      "rule": "order_approval_workflow",
      "new_decision_table": [
        { amount: ">10000 AND <50000", approvers: ["部门经理"] },
        { amount: ">=50000", approvers: ["部门经理", "总监"] }
      ]
    },
    {
      "step": 4,
      "action": "notify_stakeholders",
      "params": { "message": "订单审批流程已更新" }
    },
    {
      "step": 5,
      "action": "create_change_proposal",
      "params": { "change_type": "workflow_modification" }
    }
  ]
}

Step 4: 执行结果

AI:"订单审批流程已更新!\n\n新规则:\n| 订单金额 | 审批流程 |\n|---------|---------|\n| ≤10000 | 无需审批 |\n| 10001-50000 | 部门经理审批 |\n| >50000 | 部门经理 + 总监两级审批 |\n\n变更记录:change-20260328-order-approval-workflow\n\n提示:有3个正在审批的订单将适用新流程,是否需要通知相关审批人?"


8.4 场景四:Spec变更到代码生成(完整流程)

这是最完整的定制场景,展示从用户需求到代码生成的完整链路。

用户:"新增一个'客户意向评分'功能,当销售录入客户动态时,自动计算客户意向等级(高/中/低)"

Step 1: 理解用户指令

{
  "intent": "新增客户意向评分功能",
  "intent_type": "customization",
  "action_type": "add_feature",
  "target": "客户模块",
  "feature": {
    "name": "客户意向评分",
    "description": "销售录入客户动态时,自动计算意向等级",
    "output": "意向等级(高/中/低)"
  }
}

Step 2: 路由到Spec定义

在Spec中查找匹配的Entity和Action:

找到 Entity: CustomerInteraction(客户动态)
- attributes: { id, customer_id, type, content, created_at }

找到 Rule: scoring_rule(需要新增)
- inputs: CustomerInteraction
- logic: "根据动态类型和内容计算意向分"

找到 Entity: CustomerScore(客户评分,需新增)
- attributes: { customer_id, score, level, updated_at }

发现:
- 需要新增 Entity: CustomerScore
- 需要新增 Action: calculate_score
- 需要新增 Rule: intent_scoring_logic

Step 3: 规划执行步骤

{
  "steps": [
    {
      "step": 1,
      "action": "analyze_existing_entities",
      "params": { "entities": ["CustomerInteraction"] }
    },
    {
      "step": 2,
      "action": "design_new_entities",
      "params": {
        "entities": [
          {
            "name": "CustomerScore",
            "attributes": [
              {"name": "customer_id", "type": "FK", "required": true},
              {"name": "score", "type": "integer", "required": true},
              {"name": "level", "type": "enum", "required": true},
              {"name": "updated_at", "type": "datetime", "required": true}
            ]
          }
        ]
      }
    },
    {
      "step": 3,
      "action": "design_scoring_rule",
      "params": {
        "rule_name": "customer_intent_scoring",
        "trigger": "新增CustomerInteraction时",
        "logic": "高=3分活动/演示,中=2分报价/合同,低=1分其他"
      }
    },
    {
      "step": 4,
      "action": "update_spec",
      "params": {
        "add_entities": ["CustomerScore"],
        "add_actions": ["calculate_score"],
        "add_rules": ["customer_intent_scoring"]
      }
    }
  ]
}

Step 4: Spec变更(OpenSpec格式)

# 新增 Entity: CustomerScore (客户评分)

## Overview
记录客户的意向评分和等级。

## Attributes

| Name | Type | Required | Description |
|------|------|----------|-------------|
| customer_id | FK | Yes | 关联客户ID |
| score | integer | Yes | 意向分数 |
| level | enum(高/中/低) | Yes | 意向等级 |
| updated_at | datetime | Yes | 更新时间 |

## Relationships
- CustomerScore → N:1 → Customer

---

# 新增 Action: calculate_score (计算意向评分)

## Overview
当销售录入客户动态时,自动计算客户的意向等级。

## Trigger
新增 CustomerInteraction 记录后自动触发

## Logic
```
IF interaction.type IN ['活动参与', '产品演示'] THEN score += 3
ELIF interaction.type IN ['询价', '合同洽谈'] THEN score += 2
ELSE score += 1

IF score >= 5 THEN level = '高'
ELIF score >= 3 THEN level = '中'
ELSE level = '低'
```

## Effects
- 更新 CustomerScore 记录

Step 5: 代码生成

# 根据Spec生成的代码

## 1. Model层 (models/customer_score.py)

```python
from django.db import models

class CustomerScore(models.Model):
    """客户意向评分"""
    
    LEVEL_CHOICES = [
        ('高', '高'),
        ('中', '中'),
        ('低', '低'),
    ]
    
    customer = models.ForeignKey(
        'Customer',
        on_delete=models.CASCADE,
        related_name='scores'
    )
    score = models.IntegerField(default=0, verbose_name='意向分数')
    level = models.CharField(
        max_length=10,
        choices=LEVEL_CHOICES,
        default='低',
        verbose_name='意向等级'
    )
    updated_at = models.DateTimeField(auto_now=True)
    
    class Meta:
        db_table = 'customer_score'
        unique_together = ['customer']
    
    def update_score(self, interaction_type):
        """根据动态类型更新评分"""
        score_map = {
            '活动参与': 3,
            '产品演示': 3,
            '询价': 2,
            '合同洽谈': 2,
        }
        self.score += score_map.get(interaction_type, 1)
        
        if self.score >= 5:
            self.level = '高'
        elif self.score >= 3:
            self.level = '中'
        else:
            self.level = '低'
        self.save()
```

## 2. Signal层 (signals.py)

```python
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import CustomerInteraction, CustomerScore

@receiver(post_save, sender=CustomerInteraction)
def calculate_customer_score(sender, instance, created, **kwargs):
    """当新增客户动态时,自动计算意向评分"""
    if created:
        score, _ = CustomerScore.objects.get_or_create(
            customer=instance.customer
        )
        score.update_score(instance.type)
```

## 3. API层 (api/customer_score.py)

```python
@router.get("/api/customers/{customer_id}/score/")
def get_customer_score(request, customer_id):
    """获取客户意向评分"""
    score = CustomerScore.objects.get(customer_id=customer_id)
    return {
        "customer_id": customer_id,
        "score": score.score,
        "level": score.level,
        "updated_at": score.updated_at
    }
```

Step 6: 执行结果

AI:"已完成客户意向评分功能的开发和部署!\n\n📋 Spec变更已记录:\n- 新增 Entity: CustomerScore\n- 新增 Action: calculate_score\n- 新增 Rule: customer_intent_scoring\n\n💻 代码变更:\n- models/customer_score.py(Model)\n- signals.py(自动触发逻辑)\n- api/customer_score.py(API接口)\n\n🔗 API文档:\n- GET /api/customers/{id}/score/ - 获取客户意向评分\n\n变更记录:change-20260328-customer-intent-scoring"


8.5 完整定制流程总结

┌─────────────────────────────────────────────────────────────┐
│              SpecExecute 完整定制流程                                │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  1. 用户指令                                                 │
│     "新增客户意向评分功能"                                     │
│                                                              │
│  2. 意图理解(SpecExecute)                                  │
│     → 分析需求,确定需要新增的Entity/Action/Rule            │
│                                                              │
│  3. Spec变更                                                 │
│     → 在OpenSpec中新增定义                                   │
│     → 生成changes/目录下的变更提案                           │
│                                                              │
│  4. 代码生成                                                 │
│     → 基于Spec定义,用LLM生成代码                            │
│     → Model / Signal / API                                  │
│                                                              │
│  5. 变更发布                                                 │
│     → 创建Pull Request                                       │
│     → 更新OpenSpec已发布版本                                 │
│                                                              │
└─────────────────────────────────────────────────────────────┘

8.6 五种场景的对比

维度场景一:改样式场景二:加功能场景三:改流程场景四:Spec→代码
用户意图UI定制功能扩展流程调整完整功能新增
操作类型修改现有新增模块规则变更Spec→代码
执行方式直接修改代码生成Spec更新完整链路
影响范围局部新增代码全局规则多文件
Spec变化无需变更新增Action修改Rule新增多元素
代码生成部分是(完整)

九、与OpenSpec的集成

┌─────────────────────────────────────────────────────────────┐
│                   OpenSpec + SpecExecute 集成                       │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  Layer 1: OpenSpec基础设施                                    │
│  ├─ Spec格式定义                                             │
│  ├─ CLI工具(validate, publish)                            │
│  └─ 工作流(changes/目录)                                  │
│                                                              │
│  Layer 2: SpecExtract                                         │
│  └─ Prompt实现                                               │
│                                                              │
│  Layer 3: SpecExecute                                         │
│  └─ Prompt实现                                               │
│                                                              │
└─────────────────────────────────────────────────────────────┘

完整工作流:

1. 设计时(SpecExtract)
   代码 ──→ Prompt ──→ LLM ──→ OpenSpec格式Spec

2. 运行时(SpecExecute)
   用户指令 ──→ Prompt ──→ LLM ──→ 执行结果
                        │
                        ↓
                 读取OpenSpec Spec
                        │
                        ↓
                 解析Entity/Action/Rule
                        │
                        ↓
                   执行业务操作

十、核心观点总结

观点一:SpecExecute必须存在。

OpenSpec解决的是"如何描述Spec",不解决"如何基于Spec执行"。执行需要单独的职责层。

观点二:选择Prompt模式而非独立Skill。

与SpecExtract保持一致,最小化复杂度,基于LLM的理解能力自然执行。

观点三:产品定制无人化 ≠ 简单查询。

真正的定制场景包括:改界面样式、加功能模块、改业务流程。这是SpecExecute的核心价值。

观点四:OpenSpec是基础设施,不是全部。

OpenSpec提供格式定义和CLI工具,SpecExecute提供执行能力。两者是互补关系。


十一、写在最后

这篇文章的核心,不是给出"SpecExecute的完整实现",而是回答一个更根本的问题:

在设计产品定制无人化的工程方案时,我们需要先想清楚每个组件的定位和关系,而不是一开始就写代码。

SpecExtract解决了"如何描述产品"的问题
OpenSpec解决了"如何管理Spec"的问题
SpecExecute解决了"如何基于Spec执行"的问题

三个组件各司其职,共同完成"产品定制无人化"的目标

真正的验证,需要在实践中完成。


📚 产品定制无人化 系列文章