# Ask a Question：向客户提问

提问后暂停这次运行，直到客户回答或截止时间到 —— 打字回答按确定的规则匹配选项，绝不由模型去猜。

## 快速上手

1. 进入 **Automate → Workflows** 打开一个工作流。点 **+**，选 **Ask a Question**。
2. 写好 **Question Text**，再选一个 **Question Type** —— Multiple Choice、Number、Date 等等。
3. 选 Multiple Choice 时，最多添加 20 个答案。留空则接受客户输入的任何内容。
4. 可选，在 **Advanced Settings** 里：打开 **Add Timeout Branch**，设置等待时长，再在 **Failure: Timeout** 分支上添加步骤。
5. 在顶部工具栏把 **Status** 设成 **Published**，点 **Save**，再确认 **发布**。客服请找所有者或管理员。

## 注意

- **Add Timeout Branch** 关闭时，问题依然会过期 —— 默认 1 天后 —— 过期后流程会继续往下走，不会多做任何步骤。

## 在哪里找到它

**Automate → Workflows**，打开一个工作流，在画布上点 **+**，然后在 **Add Steps** 里选 **Ask a Question**。

## 开始之前

- **所有者**、**管理员** 或 **客服** 都可以添加这一步并保存工作流。只有 **所有者** 或 **管理员** 能发布它，而发布才会让它对真实对话生效。
- 能不能搭建和运行工作流取决于你的套餐，详见[价格](/pricing)。
- 不需要连接 Inchat 以外的任何东西。这一步会发到对话最近互动过的渠道。

## 设置步骤

1. 打开工作流，在需要提问的位置点 **+**。
2. 选 **Ask a Question**。
3. 写好 **Question Text**。
4. 选一个 **Question Type**：Text、Multiple Choice、Number、Date、Phone、Email、Website/URL、Rating 或 Location。Multiple Choice 不列任何答案时，会直接接收客户输入的内容，而不提供选项。
5. 选 Multiple Choice 时，最多添加 20 个答案；每个答案都可以设置额外可识别的写法（别名）。
6. 可选：在 **If the reply matches nothing** 里写文本用于重新提问；留空则改为静默等待。
7. 可选：打开 **Save Response As**，把答案写入联系人字段、变量，或者（仅 multiple choice）打上标签。
8. 可选，在 **Advanced Settings** 里：打开 **Add Timeout Branch** 并设置等待时长；问题本身发不出去时，用 **Add Message Failure Branch**。
9. 保存这一步。要发布：在编辑器顶部的工具栏把 **Status** 设成 **Published**，点 **Save**，再用 **发布** 确认。只改下拉框、不保存的话什么都不会生效。

## 字段

| 字段 | 含义 | 默认值 | 限制 |
| --- | --- | --- | --- |
| Question Text | 发给客户的消息内容。 | — | — |
| Question Type | Text、Multiple Choice、Number、Date、Phone、Email、Website/URL、Rating（2–10 星）或 Location。 | — | 非 multiple choice、不带选项的类型，接受回复之前仍会先验证格式（例如是不是一个真实的数字）。 |
| Choices | Multiple Choice 最多 20 个答案，每个都可以选配一份可识别写法（别名）列表。匹配客户输入的回复时会忽略大小写、空格和全角字符；输入「2」这样的数字会按位置选中对应答案。 | — | 以按钮形式发送 —— WhatsApp 最多显示 3 个按钮，其余放进选择列表；Messenger 会全部显示。无法识别的回复会重新提问，绝不会由模型去猜。 |
| If the reply matches nothing | 还有重试次数时，遇到无法识别的回复会重新发送这段文本。它和画布上的 **Failure: Invalid** 分支是两回事，后者放的是次数用完之后要运行的步骤。 | 留空 —— 改为静默等待，不重新提问 | — |
| WhatsApp pick-list label | 在 WhatsApp 上，当选项超过 3 个时，用来打开列表的按钮文字。 | Select | 最多 20 个字符。选项少于 4 个，或在其他渠道上不会用到。 |
| Save Response As | 三个各自独立的开关：把答案写入 **Contact Field**、作为 **Variable** 留给后面的步骤用，或者（仅 Multiple Choice）用选中的选项给联系人打上 **Tag**。 | — | — |
| Add Timeout Branch | 放弃等待、继续往下走之前，要等答案多久。打开后画布上会加一条 **Failure: Timeout** 分支 —— 想让客户在超时时看到一条消息，要自己在那条分支上加一个 **Send a Message** 步骤。 | 面板里默认关闭，但问题依然会过期 —— 见「它如何运作」 | 60 秒到 7 天；打开后面板自己的默认值是 7 天。 |
| Add Message Failure Branch | 问题本身发不出去时（没有渠道、窗口已关闭、服务商出错）要运行的一条分支 —— 和客户一直不回答是两回事。会在画布上加一条 **Failure: Sending Failed** 分支。 | 关闭 —— 发送失败时工作流没有分支可走 | — |

## 它如何运作

- 这一步会暂停当前流程：在客户回答、截止时间到，或未识别回复用完重试次数之前，工作流里排在它后面的都不会执行。
- 等待期间，客户的下一条回复会被当成这个问题的答案，而不是当成一条普通的客户消息：AI 不会回复它，任何由 **Message received** 触发的工作流也不会被它触发。
- 对其他设了自己的退出规则、会因客户发来消息而退出的运行中工作流来说，这条回复依然算一条客户发来的消息。一个设了「收到客户回复即退出」的催款流程，照样会因为它而退出，和收到任何其他消息时一样。
- 只有发起这个问题的工作流本身，在这条回复上豁免自己的退出规则；没设这种退出规则的其他运行中工作流，不受影响。
- 只要 Multiple Choice 至少有一个答案，就会按确定的规则匹配：忽略大小写、空格和全角字符，识别裸数字位置（「2」代表第二个选项），或者你列出的任何别名 —— 绝不由模型去猜。
- 回复什么都匹配不上时，如果设了重试文本就会重新提问，没设就静默等待；要等重试次数用完，才会判定为最终失败。
- Multiple Choice 不列任何答案时，这一步会切换成自由文本接收：客户下一条发来的内容会被直接当成答案，完全不做匹配。
- 非 multiple choice、不带选项的类型 —— Number、Date、Phone、Email、URL、Rating、Location —— 接受回复前仍会检查格式是否有效。无效回复和 Multiple Choice 不匹配一样，算作一次未识别尝试。
- 不管 **Add Timeout Branch** 有没有打开，这一步始终有截止时间。关闭时，问题默认在 1 天后过期 —— 如果消息窗口本来就会更早关闭，过期时间还会更早。
- 默认截止时间到了之后，它只是不再多做任何步骤，而不是一直等下去。打开开关并保持默认值，等待时长会变成 7 天。
- 在有窗口限制的渠道上，如果截止时间会落在消息窗口关闭之后，会被提前到刚好在窗口关闭之前。
- 没有这个提前机制的话，和窗口一样长的默认截止时间会跟窗口同时结束；流程接着用自由文本联系客户时，客户什么都收不到。
- 如果客户的回复在这个被提前的截止时间之前重新打开了窗口，下一次未识别的尝试会把截止时间往你原本设定的方向恢复，但不超过现在更晚的窗口边界。
- 一个卡住的问卷不会被留得比设定的更久，但只要客户显然还在说话，也不会被人为地截短。
- 截止时间是在客户下一条消息到达的那一刻检查的。如果那条消息晚了，就不会被当成答案。
- 截止时间也会由一个大约每分钟一次的后台扫描检查，所以即使没人会再回复，问题也能在合理时间内有个结果。
- 看起来像自动离线回复的消息会被忽略，既不算答案也不计入尝试次数。问题会保持原样，继续等客户自己回复。
- 记录下来的答案会作为 **Answer picked**（`answer.key`）、**Answer as typed**（`answer.text`）和 **Answer result**（`answer.status`）提供给后面的步骤。
- **Answer result** 的取值是 matched、unmatched、unanswered 或 captured，所以 **Condition** 步骤可以按这三个字段中的任意一个分支。

## 它在什么时候会失败

- 问题本身发不出去 —— 没有可发送的渠道、消息窗口已关闭、服务商出错 —— 而 **Add Message Failure Branch** 是关闭的。
- 这时联系人会直接离开工作流：没有东西在等待，它后面也不会运行任何内容。
- 问题发不出去，而 **Add Message Failure Branch** 是开启的：会改为运行那条分支的步骤。
- 未识别的回复、还有重试次数时：会重新发送重试文本（如果设了），这一步继续等待。这不算最终失败，下游内容还不会运行。
- 未识别回复用完所有重试次数：答案会判定为 unmatched，并运行 **Failure: Invalid** 分支上的步骤。
- 在那之前，答错只会收到 **If the reply matches nothing** 的文本；这条分支只在最后运行一次，作为最终结果。
- 工作流里排在这个问题后面的内容，会接在那条分支之后继续。
- 截止时间到了却完全没有回复：答案会判定为 unanswered，运行 **Add Timeout Branch** 上的步骤（开关关着就是空的），再接上问题后面原本的内容。
- 收到一条看起来像离线自动回复的消息：会被忽略 —— 既不会被取用，也不计入尝试次数，也不当成答案。问题原封不动，继续等待。
- 工作流被删除、工作区套餐不再包含自动化，或商家停止了这条流程并在停止对话框里勾选了「改为直接放弃他们」。
- 在这些情况下，问卷会被放弃，对话上会有一条系统备注说明 —— 除非对话已由同事接管，或 AI 被暂停（见下文）。
- 这样一来，客户的回复会被当成一条普通的客户消息处理，AI 现在可以回复它。
- 对话已由同事接管，或 AI 被暂停时，不会放弃问卷：这条回复不会被取用，会有一条备注说明问题仍在等待。
- 一旦对话被释放，流程会继续。
- 单纯的停止，或者停止后重新发布但没勾那个选项，都不会这样 —— 见「它不会做什么」：问题继续等待，并按客户当时实际看到的那个版本恢复。
- 原因和结果都能在工作流的 **Activity** 标签页、**Execution log** 下这一步对应的那一行看到。

## 它不会做什么

- 设置了超时的话，会被限制在 60 秒到 7 天之间；打开开关且不改数值时，默认是 7 天。
- 开关关闭不代表无限等待 —— 问题默认依然会在 1 天后过期，只是过期时不会附带多做任何步骤。
- 重试次数上限是 1 到 10 次，默认 3 次；只有未识别的回复才会计入次数 —— 被忽略的离线消息不算。
- 面板里没有可以手动修改重试次数上限的字段 —— 自己添加的问题会用默认值 3 次。预设模板或 **Build with AI** 可以设成不同的数字。
- Multiple Choice 最多提供 20 个答案；每个答案最多可以带 10 个别名。
- 它只暂停这一次运行，并且会把客户的下一条回复占为己用：AI 不会回复它，也不会有新的 **Message received** 流程被它触发。
- 任何设了自己「收到消息即退出」规则的其他运行中工作流，照样会因为这条回复而退出，和收到任何消息时一样 —— 只有发起提问的这个工作流，才豁免自己的这条规则。没设这种规则的运行中工作流不受影响。人工客服随时都能处理这个对话；停下来的只是自动化。
- 没有设置 **Add Message Failure Branch** 时，发送失败会直接让联系人离开这个工作流。没有默认的兜底分支可以走，这一点和流程中途发送失败、直接往下继续不同。
- 一个问题的后续，绑定的是客户当时看到的那个具体工作流版本，而不是工作流现在的样子。问题还在等待时编辑并重新发布工作流，最终的答案会按旧版本恢复，而不是按编辑后的版本。

## 最佳做法

- 给每个问题配一条超时分支，或者确认它不可能永远没人回答。否则客户不出声的话，流程默认会暂停整整一天，在那之前这个对话上不会发生其他任何事。
- 如果在意渠道表现，Multiple Choice 选项数尽量控制在 3 个以内 —— WhatsApp 最多只把 3 个显示成可点按钮，超过就变成选择列表。
- 为人们实际会打出来的答案写法（数字、单个字母、本地语言的词）配上别名，不要只依赖按钮文字 —— 即使显示了按钮，客户照样常常直接打字回复。
- 只有真的无法枚举的答案 —— 电话号码、公司名 —— 才用自由文本接收（不设选项），因为它会直接接受第一条回复，除了问题本身的类型校验之外不做任何验证。

## 使用场景

- 询问客户对哪个产品档位感兴趣，配 3 个按钮，并为常见的打字回答设置别名，再按客户选的那个给联系人打标签。
- 询问邮箱地址（类型选 Email），保存进联系人字段，再继续走报价步骤。
- 在流程结尾询问满意度评分，不需要超时分支，因为没人回答的话流程本来就会直接结束。

## 常见问题与排查

### 问题还开着的时候，AI 还会继续回复这个对话吗？

不会。严格来说只有这一次工作流运行被暂停了，但客户的下一条回复会被当成这个问题的答案。AI 不会回复它，也不会有新的 Message received 流程被它触发。设了自己「收到消息即退出」规则的其他运行中工作流，照样会因为这条回复而退出，和收到任何消息时一样；没设这种规则的运行中工作流则照常运行。人工客服随时都能处理这个对话。

### 我让 Add Timeout Branch 保持关闭。问题会永远等下去吗？

不会。它依然会过期 —— 默认 1 天后，如果消息窗口本来就会更早关闭，会更早 —— 过期时因为没设超时分支，只是不会多做任何步骤。想让超时时发生点什么，就打开这个开关。

### 客户如果一直给出跟任何选项都对不上的答案，会怎样？

只要还有重试次数，每一次未识别的回复都会重新发送你的重试文本，再继续等待。次数用完后，答案会判定为 unmatched，**Failure: Invalid** 分支作为最终结果运行，再接上问题后面原本的内容。

### 我能按客户到底有没有回答来分支吗？

可以 —— 在这一步后面接一个 Condition 步骤，就能读取 **Answer result**（`answer.status`：matched / unmatched / unanswered / captured），以及 **Answer picked**（`answer.key`）和 **Answer as typed**（`answer.text`）。

## 相关文章

- [Condition](https://inchat.inseller.my/help/workflows/condition)
- [AI Reply](https://inchat.inseller.my/help/workflows/ai-reply)
- [Wait：暂停流程](https://inchat.inseller.my/help/zh/workflows/wait)
- [Quote / confirm order](https://inchat.inseller.my/help/workflows/quote-or-confirm-order)
- [Workflows: how a flow runs](https://inchat.inseller.my/help/workflows/workflows-overview)

---

Source files: `src/lib/workflows/ai-builder/spec.ts`, `src/lib/workflows/canvas-model.ts`, `src/components/workflows/WorkflowStepConfigDrawer.tsx`, `src/lib/workflows/question.ts`, `src/lib/workflows/question-resolve.ts`, `src/lib/workflows/form-payload.ts`, `src/lib/workflows/dispatch.ts`, `src/lib/workflows/execution-guard.ts`, `src/lib/workflows/continue-parked-question.ts`, `src/components/workflows/WorkflowCanvasEditor.tsx`, `src/app/api/cron/pending-actions/route.ts`, `src/lib/inbox/wa-window.ts`, `src/lib/access/permissions.ts`
