> For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt.

# 产品设计准则

本目录回答"**用户看到什么**" — 功能规格、业务规则、schema 设计理由、AI prompt 设计。

这页是 Retaintive 团队以后做产品 / 系统 / AI workflow 设计时的默认工作方式。

核心原则:

```text
先定义系统真实对象
再定义 API 和状态变化
最后才写 prompt
```

不要一上来问 AI “prompt 应该怎么写”。Prompt 只是系统的一层。真正长期稳定的东西是 schema、API、state transition、database transaction 和 audit trail。

***

## 一句话原则

**AI 应该帮我们理解语义,不应该成为系统状态的 source of truth。**

系统的 source of truth 应该是:

| 层                    | 负责什么                                |
| -------------------- | ----------------------------------- |
| Schema               | 系统有哪些稳定对象、字段、关系和约束                  |
| API                  | 前端、内部服务、第三方系统、CLI、AI agent 怎么读写这些对象 |
| State machine        | 一个对象能从什么状态变到什么状态,谁能改,什么情况下能改        |
| Database transaction | 真正落库时如何保证一致性、幂等、并发安全和审计             |
| Prompt / AI          | 理解文本、语义、意图和模糊场景,输出 proposal         |

### 核心架构模式: Code as Guardrail, AI as Judgment

以后所有 AI workflow 默认按这个模式设计：

```text
AI proposes structured action
Code validates policy / state / idempotency
Code executes database mutation
System records audit trail
```

也可以理解成：**AI 做 judgment，code 做 authority。**

| 职责                                           | 默认归属                 | 原因                            |
| -------------------------------------------- | -------------------- | ----------------------------- |
| 语义理解、意图分类、内容总结                               | AI                   | 需要处理自然语言和模糊语义                 |
| action proposal 和 evidence                   | AI structured output | AI 可以建议做什么，但必须 typed          |
| enum validation、权限、DNC、store isolation       | Code / Policy Guard  | 不能被 prompt injection 或模型不稳定影响 |
| lifecycle transition、idempotency、transaction | Code                 | 必须 deterministic、可审计、可重放      |
| audit trail / timeline                       | Code                 | 系统必须知道谁提议、谁执行、为什么执行或拒绝        |

所以 prompt output 不应该是“最终事实”，而应该是一个 typed proposal。真正改变 `contacts` / `tasks` / `contact_timeline` / `calls` / `messages` / `leads` 的动作，必须经过代码层的 schema validation、policy guard 和 transaction。

***

## 推荐顺序

### 1. Schema-first: 先定义业务对象

先问:

- 这个系统里真正稳定的 business objects 是什么?
- 哪些是 source of truth?
- 哪些只是 projection / view / cache / audit feed?
- 哪些字段表达当前状态,哪些字段表达历史事件?

Task 领域的 selected Target：

```text
Task           = 一件需要解决到底的客户机会、问题或目标
Next Action    = 当前已经采用的下一步计划
Activity       = 实际发生的处理记录
Business Progress = 已发生、但尚未构成最终 Outcome 的业务进展
Outcome        = Task 最后怎么样、为什么结束、证据是什么
```

Task V3 已是选定的产品与领域 Target。术语和目标边界以 [Task V3 Product / Domain Contract](/product-design/v3/tasks-feature/task-domain-lifecycle.md) 为准；merge、deployment、TEST acceptance 与 PROD readiness 分开看 [Task V3 Rollout 状态快照](/product-design/v3/tasks-feature/task-v3-rollout-status.md)。`Target` 不表示代码已部署、通过 TEST 或向 PROD 开放；当前 schema、config 与 runtime 行为仍须从 live evidence 复核。

[Task V2+ 工程审计与实施基线](/product-design/v2/tasks-feature/task-v2-plus-engineering-audit.md) 保留为历史审计和兼容背景，不再是当前实施路线。

工程实现上,Schema-first 还意味着 schema 要尽量是机器可读 contract,例如 Drizzle schema、OpenAPI spec、GraphQL SDL、Zod / JSON Schema。它不只是文档描述,还应该能驱动类型、校验、mock、测试或 SDK。

不要把所有东西都塞进一个字段。比如:

```text
Next Action       = 当前计划做什么
AI Suggestion     = AI 建议做什么，但尚未采用
Activity          = 实际发生了一通电话 / 一条 SMS / 线下工作
Task Outcome      = 整件客户事项最终如何结束
Funnel Projection = 现有 evidence 显示 Lead 走到哪里
```

这些不是同一个概念。

***

### 2. API-first: 再定义别人怎么读写

设计时要假设未来不只有当前前端会用这套数据。还可能有:

- internal services
- dashboard
- OAuth API
- CLI
- third-party integrations
- customer-owned AI agent
- Codex / Claude Code 这类 agent

所以 API 返回必须是机器可读的 typed objects,不要要求调用方解析 prompt 文本或 timeline JSON。

问设计时,应该问:

- `GET` 一个对象时,外部调用方能不能一眼看懂当前状态?
- 它能不能看到最近发生了什么?
- 它能不能知道下一步应该做什么?
- 它能不能区分 progress 和 final outcome?
- 它能不能安全地提交一次 update / close / progress event?

目标 API 应该像这样分层（不是当前 live endpoint 清单）：

```text
GET /tasks/:taskId
POST /tasks/:taskId/activities
POST /tasks/:taskId/activity-and-next-action
POST /tasks/:taskId/next-action
POST /tasks/:taskId/close
POST /tasks/:taskId/reopen
GET /contacts/:contactId/timeline
GET /contacts/:contactId/tasks
```

如果 API 会被多个消费者使用,需要有 versioning strategy。比如 `v3` API 不能随意 breaking change;如果对象语义要大改,应该新版本或兼容字段过渡。

***

### 3. State-machine-first: 先定状态变化规则

在 prompt 之前,先定义代码层允许哪些状态变化。

问:

- object 有哪些 lifecycle status?
- 哪些操作会改变 lifecycle?
- 哪些操作只是追加 progress?
- 什么情况下允许 close?
- 什么情况下必须 no-op?
- 人和 AI 同时操作时谁赢?
- DNC、wrong number、跨门店隔离这些硬规则在哪里执行?

例子:

```text
Task.status = open | closed

record_activity:
  append Activity; Task does not silently close
  optionally update adopted Next Action atomically

change_next_action:
  replace current plan; append audit event
  do not move Task deadline implicitly

close_task:
  open Task -> closed Task + typed Outcome + evidence
```

避免用多个 boolean flag 表达状态。`isOpen + isClosed + isAttempted + isResolved` 这类设计会产生大量不可能组合。优先使用明确 enum lifecycle 和显式 transition。

代码层必须负责:

| 代码层职责           | 为什么不能交给 prompt               |
| --------------- | ---------------------------- |
| enum validation | prompt 可能输出不存在的值             |
| store guard     | prompt 不能保证跨门店隔离             |
| idempotency     | prompt 不知道这次请求是不是重复          |
| concurrency     | prompt 不能处理人和 AI 同时写同一个 task |
| transaction     | prompt 不能保证多表同时成功或失败         |
| DNC hard stop   | DNC 是硬约束,不能靠模型自由判断           |
| audit trail     | 系统必须能回放是谁在什么时候改了什么           |

***

### 4. Prompt-last: 最后才设计 AI 输入输出

Prompt 的职责不是直接改变数据库。Prompt 应该在 schema/API/state machine 允许的动作空间里输出 proposal。

Prompt 可以做:

- 理解 transcript / SMS / notes
- 判断客户意图
- 判断 Task kind 和合理的 Next Action
- 判断 evidence 是否可能满足 Task Outcome contract
- 生成 suggested actions
- 给出 evidence 和 confidence

Prompt 不应该做:

- invent `taskId`
- 绕过 allowed enum
- 决定 transaction 是否成功
- 直接改 database state
- 把 Activity outcome 当 Task Outcome
- 忽略 store / DNC / idempotency / concurrency guard

AI action output 必须是 structured output,不要让 free text 决定系统动作。优先用 Zod / JSON Schema / OpenAPI schema 约束可选 action、enum 和字段。低置信度时不要自动写库,而是 `no_op`、`needs_review` 或进入人工确认流程。

目标 prompt output 应是 proposal，而不是 database row。示意：

```json
{
  "taskProposals": [
    {
      "action": "record_activity",
      "taskId": "task_123",
      "activity": {
        "channel": "phone",
        "action": "call_completed",
        "outcome": "connected",
        "conversationDisposition": "follow_up_agreed"
      },
      "nextAction": {
        "text": "Call Friday afternoon",
        "reasonCode": "customer_requested"
      },
      "evidenceRefs": ["call:store-scoped-id"]
    },
    {
      "action": "propose_close",
      "taskId": "task_123",
      "resultCode": "booked",
      "closureReasonCode": "goal_achieved",
      "verificationType": "communication_explicit",
      "evidenceRefs": ["message:store-scoped-id"]
    }
  ]
}
```

代码收到 proposal 后再决定是否执行。

***

## Engineering Guardrails

这些不是额外流程,而是防止 AI 系统变脆的底线。

| Guardrail                 | 准则                                                                                                                 |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| Machine-readable contract | 关键 schema 不只写 prose,要尽量落到 Drizzle / OpenAPI / Zod / JSON Schema 等可校验形式                                             |
| Schema drift check        | docs、DB schema、API response、TypeScript types、prompt output schema 必须持续对齐;需要 contract tests 或 schema checks 防 drift |
| API versioning            | 多消费者 API 要有版本策略,避免无意 breaking change                                                                               |
| Explicit state machine    | 用 enum + transition 表达状态,避免 boolean flag explosion                                                                 |
| Structured AI output      | AI 只能输出结构化 proposal;free text 只能当 evidence/note,不能当 action contract                                                |
| Low-confidence fallback   | 低置信度不自动 commit;默认 no-op、needs\_review 或人工确认                                                                        |
| Blast radius limit        | AI 出错时影响范围要小:单个对象、单个 store、单次 transaction,并可审计/回滚                                                                  |

***

## 问 AI 的标准方式

以后让 AI 帮忙做系统设计时,请直接复制下面这段作为开头:

```text
请不要先设计 prompt。

请先帮我定义:
1. 这个系统的核心 business objects 是什么?
2. 每个 object 的 source of truth 是哪里?
3. 每个 object 的 lifecycle / state transition 是什么?
4. 外部 API 应该如何读写这些 object?
5. 哪些判断必须由代码 deterministic 执行?
6. 哪些判断需要 AI 做 semantic proposal?
7. Prompt 的 input/output schema 应该如何从 API/schema 反推?
8. 这个设计如何处理 idempotency、concurrency、audit、fallback?
9. 人和 AI 同时操作时,谁是 authority,系统怎么记录 override?
10. 这个设计如何让未来 CLI、OAuth API、第三方系统和 AI agent 也能读懂?
```

***

## 判断一个 AI 方案是否靠谱

一个好的 AI 系统设计应该能回答:

| 问题            | 合格答案应该包含                                                     |
| ------------- | ------------------------------------------------------------ |
| 数据对象是什么?      | 清楚区分 source of truth、projection、audit                        |
| API 怎么长?      | 读写路径明确,外部调用方不用猜                                              |
| 状态怎么变?        | lifecycle、progress、outcome 分清楚                               |
| AI 输出什么?      | proposal,不是直接 mutation                                       |
| 代码执行什么?       | validation、state transition、transaction、guardrail            |
| 失败怎么办?        | parse fail、timeout、low confidence、race condition 都有 fallback |
| 怎么审计?         | 谁在什么时候基于什么 evidence 改了什么                                     |
| 未来 agent 怎么接? | API typed,对象稳定,不用解析 prompt 文本                                |

如果一个方案只讲:

```text
我们改一下 prompt,让 AI 更聪明地判断
```

那通常还不够。它还没有进入真正的系统设计。

***

## Retaintive 的默认设计口径

Retaintive 是 AI-native product,但不是 prompt-only product。

我们的默认架构应该是:

```text
Code controls the world state.
AI proposes semantic interpretation.
Database stores source of truth.
API exposes typed objects.
Timeline records audit and display history.
```

中文表达:

```text
代码控制系统状态。
AI 提出语义判断。
数据库保存事实。
API 暴露稳定对象。
Timeline 记录审计和展示历史。
```

这就是以后做产品设计、prompt 设计、schema 设计、API 设计时的默认准则。
