---
title: "关键词匹配规则"
description: "条件节点如何将评论或私信与关键词列表或已配置文本进行比较，一个空列表会匹配什么，以及每种结果走哪个分支。"
canonical: https://docs.afp.monster/zh-cn/reference/keyword-matching
updated: 2026-08-19
pageType: reference
---

条件节点会将到达它的消息文本与该节点上配置的词进行比较，然后将执行记录从 **Match**（output 0）或 **No Match**（output 1）发出。使用 **Keyword list** 匹配类型时，消息只要包含列表中的至少一个关键词就算匹配。反转匹配会翻转这个结果，而一个没有关键词的列表——或一个已被删除的列表——会匹配所有消息。

## 概览

| 匹配类型 | 读取的设置 | 消息匹配的条件 |
|---|---|---|
| `any` | 无 | 总是匹配。该节点只有一个输出，每条消息都走它 |
| `contains` | `text` | 消息包含已配置的文本 |
| `exact` | `text` | 消息就是已配置的文本，没有其他内容 |
| `keyword_list` | `keyword_list_id`、`reverse_keywords` | 消息包含列表中的至少一个关键词；若开启反转匹配，则不包含其中任何一个 |

## 匹配算法

1. 条件节点获取启动该执行记录的消息文本——评论文本，或私信文本。
2. 设置为等待回复的条件会将执行记录停留，而不进行任何比较，等回复到达时再比较其文本。按下的按钮算作文本：条件比较的是按钮的标签。
3. 匹配类型决定比较方式。`keyword_list` 会按标识符加载已保存的列表，并用该列表的关键词测试消息。
4. 反转匹配会翻转 `keyword_list` 比较的结果，所以一条不包含任何关键词的消息也会匹配。
5. 一个没有关键词的列表，以及一个指向已不存在列表的引用，都会在不进行任何比较的情况下直接产生匹配。
6. 结果决定输出。Match 是 output 0，No Match 是 output 1，执行记录会沿携带连接的那一个继续。没有连接的输出会让执行记录在该条件节点结束。
7. 同一节点上的媒体过滤器——图片、GIF 和链接——是独立的设置，不参与关键词比较，不过未通过某个过滤器的消息仍会从 **No Match** 离开。

```d2 title="How a condition node picks the text to match, applies the match type, and chooses its output"
direction: down
arrives: "消息到达条件节点"
waits: "是否在等待回复？" {shape: diamond}
parks: "执行记录停留，直到回复到达"
replyText: "获取回复文本"
triggerText: "获取触发消息的文本"
matchType: "匹配类型" {shape: diamond}
matched: "Match，output 0"
nodeText: "与节点的文本比较"
listWords: "与列表的关键词比较"
reverse: "是否开启反转匹配？" {shape: diamond}
invert: "翻转结果"
keep: "保留结果"
decide: "是否匹配？" {shape: diamond}
unmatched: "No Match，output 1"
arrives -> waits
waits -> parks: 是
parks -> replyText
waits -> triggerText: 否
replyText -> matchType
triggerText -> matchType
matchType -> matched: any
matchType -> nodeText: keyword_list
matchType -> listWords: 是
listWords -> reverse
reverse -> invert: 否
reverse -> keep: 是
nodeText -> decide
invert -> decide
keep -> decide
decide -> matched: 否
decide -> unmatched: no
```

关键词设置位于条件节点上。触发节点决定哪些事件启动活动，完全不包含任何关键词配置，所以活动只有在其执行记录到达条件节点后才会过滤文本。[节点类型](/zh-cn/reference/node-types) 列出了两者的配置。

## `any`

- **读取：** 无
- **输出：** 1

每条消息都匹配，不进行任何比较。将条件切换为 `any` 会去掉该节点的第二个输出，并移除从那里离开的任何连接，所以选择该匹配类型时，No Match 分支不能存在。

## `contains`

- **读取：** `text`
- **输出：** 2

当已配置的文本出现在消息中时即为匹配。`text` 存放的是单个字符串，而不是一组备选项——如果需要多个，请使用关键词列表。

## `exact`

- **读取：** `text`
- **输出：** 2

当消息就是已配置的文本、且没有其他内容时即为匹配。 

## `keyword_list`

- **读取：** `keyword_list_id`、`reverse_keywords`
- **输出：** 2

消息会与从节点下拉菜单中选择的已保存关键词列表进行比较，只要包含该列表中的至少一个关键词即为匹配。列表在匹配时按标识符读取，所以编辑列表会改变该节点匹配的内容，而无需重新保存活动。[用关键词列表匹配评论](/zh-cn/guides/keyword-lists) 介绍了如何创建列表并附加它。

```json
{
  "type": "condition",
  "config": {
    "match_type": "keyword_list",
    "keyword_list_id": 41,
    "reverse_keywords": false,
    "wait_for_reply": false,
    "filter_images": false,
    "filter_gifs": false,
    "filter_links": false
  }
}
```

关键词是在列表保存时清理的，而不是在消息到达时：前导和尾随空格会被修剪，空白条目会被丢弃，重复条目会合并为一个。提交时没有关键词的列表会被拒绝。

一个列表可以支持任意数量的条件节点，跨越活动和主页，因为节点存储的是列表的标识符，而不是其词语的副本。

## 反转匹配

`reverse_keywords` 适用于 `keyword_list` 匹配类型，会翻转比较的结果。此时 **Match** 携带不包含任何关键词的消息，**No Match** 携带包含至少一个关键词的消息。比较的其他部分都不会改变。

## 空的或已删除的关键词列表

| 情况 | 条件节点的行为 |
|---|---|
| 列表中没有关键词 | 匹配所有消息 |
| 节点指向的列表已被删除 | 匹配所有消息 |

一个突然对一切都有反应的条件节点，通常是这两个原因之一。条件节点对列表的引用存在于活动的已保存图中，这就是为什么一个列表可以在一个仍指向它的节点之下消失——[用关键词列表匹配评论](/zh-cn/guides/keyword-lists) 介绍了删除操作会拒绝什么、不会拒绝什么。

## 完整示例

| 评论文本 | 条件设置 | 反转匹配 | 走的分支 |
|---|---|---|---|
| `How much is shipping?` | 关键词列表包含 `shipping` 和 `price` | 关闭 | Match |
| `How much is shipping?` | 关键词列表包含 `shipping` 和 `price` | 开启 | No Match |
| `Beautiful, congratulations` | 关键词列表包含 `shipping` 和 `price` | 关闭 | No Match |
| `Beautiful, congratulations` | 关键词列表包含 `shipping` 和 `price` | 开启 | Match |
| `Beautiful, congratulations` | 关键词列表中没有关键词 | 关闭 | Match |
| `Beautiful, congratulations` | 关键词列表已被删除 | 关闭 | Match |
| 没有文本的贴纸，以 `{{sticker}}` 到达 | 关键词列表包含 `shipping` 和 `price` | 关闭 | No Match |
| 没有文本的贴纸，以 `{{sticker}}` 到达 | 关键词列表包含 `{{sticker}}` | 关闭 | Match |
| `How much is shipping?` | `contains`，`text` 设置为 `shipping` | 不适用 | Match |
| `Anything at all` | `any` | 不适用 | Match，走该节点唯一的输出 |

## 大小写、整词、标点符号和表情符号

消息通过包含关键词来匹配，但这两个字符串在测试前是如何处理的尚未确认。请将下面每条陈述视为预期行为，而不是保证，并测试你的活动所依赖的那些行为：

- 字母大小写会被忽略，所以内容为 `Shipping` 的评论会匹配关键词 `shipping`。 
- 一个关键词可以在更长的单词内部匹配，所以 `ship` 会匹配内容为 `shipping` 的评论。 
- 关键词旁边的标点符号不会阻止匹配，所以 `shipping?` 会匹配关键词 `shipping`。 
- 表情符号会作为普通字符进行比较，所以一个包含某个表情符号的关键词，会匹配包含该表情符号的评论。 

无论比较最终如何进行，关键词列表存储的内容是确定的：条目周围的空格会在保存时被修剪，所以关键词永远不会带着前导或尾随空白进入比较。

在其余部分得到确认之前，请用画布上的测试执行来验证每个关键词：针对你预期会收到的确切文本运行活动，并查看条件节点走了哪个输出。参见 [测试和调试活动](/zh-cn/guides/test-and-debug-campaigns)。

## 说明

- 没有文本的评论会以占位符代替消息到达——Facebook 上是 `{{sticker}}`，Instagram 回复上是 `{{media}}`——所以条件节点始终有内容可以比较。一个包含该确切字符串的关键词列表会匹配这些评论。
- 停留在条件节点等待回复的执行记录，会保留它开始时的关键词集合。在你编辑列表之后到达的回复，会按旧关键词进行匹配；下一次执行记录会使用新的关键词。
- 开启了图片过滤器的条件节点，不会匹配不带图片的回复，无论关键词如何设置，都会将其路由到 **No Match**。
- 在画布上更改条件节点的匹配类型或文本，只会改变你浏览器中的活动。一个正在运行的执行记录会与它开始时所在图的已保存版本进行比较，所以更改只有在你保存之后才适用于新的执行记录。
- 条件节点永远不会连接到另一个条件节点，所以一个分支只测试一次消息文本。同一条路径上的两次测试需要两个分支，或者一个覆盖两组词语的关键词列表。

## 相关

- [用关键词列表匹配评论](/zh-cn/guides/keyword-lists) — 创建列表、将其附加到节点，以及编辑或删除列表时会发生什么。
- [节点类型](/zh-cn/reference/node-types) — 条件节点的完整配置，以及其他每个节点。
- [活动图模式](/zh-cn/reference/campaign-graph-schema) — 条件节点的配置在已保存图中的位置。
- [触发事件](/zh-cn/reference/trigger-events) — 产生条件节点所比较文本的事件。
- [联系人字段](/zh-cn/reference/contact-fields) — 执行记录离开 **Match** 输出之后可以对联系人做出的更改。
