---
title: "搭配 AI 代理使用 AFP"
description: "安装 AFP 代理技能，让你的编程代理读取本站的 Markdown 和 llms.txt 副本，并确保它编写的活动图始终可构建。"
canonical: https://docs.afp.monster/zh-cn/guides/ai-agent-skill
updated: 2026-08-19
pageType: guide
---

用一条命令将 AFP 代理技能安装到你的项目中，然后让代理以 Markdown 形式读取本站。该技能锁定了模型无法猜到的内容：AFP 没有客户端 API，所以代理产出的是活动图而不是代码；画布实际能添加哪些节点类型；以及画布会拒绝哪些连接。这里的每个页面同时以 Markdown 形式提供——在任意页面 URL 后加上 `.md`——而 `/llms.txt` 会为它们全部建立索引。

## 你首先需要什么

- 一个能从你的项目中加载指令文件的代理：一个技能目录，或一个它在启动时读取的规则文件。
- 一个画布上的活动，用来构建结果。代理可以描述一个图；只有画布能保存它。参见 [在画布上构建活动](/zh-cn/guides/build-a-campaign)。

## 我如何安装代理技能？

从本站将该技能下载到你的项目中：

```bash
mkdir -p .claude/skills/afp
curl -fsSL https://docs.afp.monster/skills/afp/SKILL.md -o .claude/skills/afp/SKILL.md
```

该路径是 Claude Code 查找项目技能的位置。如果代理改为读取单一的规则或指令文件——Cursor 和大多数编辑器助手就是这样工作的——内容是一样的：将它下载到你其他代理指令旁边，并从你工具启动时加载的文件中引用它。

```bash
curl -fsSL https://docs.afp.monster/skills/afp/SKILL.md -o afp-skill.md
```

提交该文件，让每个贡献者的代理都基于相同的规则工作。文件开头的 `version` 字段记录了该文件描述的是 AFP 的哪个版本——当该值变化时重新下载。

该技能包含五项内容：产品模型、画布可以添加的每种节点类型及其配置键、画布强制执行的连接规则、一个完整图作为实例，以及一份模型对 AFP 常犯错误的清单。

## 代理应该读取哪些 URL？

四个入口，都是从与页面本身相同的 Markdown 生成的。

| URL | 包含内容 | 用途 |
|---|---|---|
| `https://docs.afp.monster/llms.txt` | 每个页面及其描述的索引 | 让代理选择要读取的内容 |
| `https://docs.afp.monster/llms-full.txt` | 一个文件中包含所有页面的完整文本 | 一次请求加载整个产品 |
| `https://docs.afp.monster/llms-small.txt` | 相同文本，空白字符已折叠 | 更小的上下文窗口 |
| 任意页面 URL 加上 `.md` | 该页面的纯净 Markdown 版本 | 阅读单个页面而不带导航 |

`.md` 规则适用于每个页面，所以代理可以从它当前所在的地址构建出它需要的地址：`/zh-cn/reference/node-types` 变成 `/zh-cn/reference/node-types.md`。

Markdown 副本包含页面标题、描述和正文——没有导航，没有侧边栏，没有脚本。这些副本以 `text/markdown` 形式提供，允许跨域读取，并被标记为不参与索引，所以它们永远不会与其镜像的页面竞争。

### 每个页面的 Markdown 地址

为每个地址加上 `https://docs.afp.monster` 前缀。

| 页面 | Markdown 地址 |
|---|---|
| [入门](/zh-cn/start) | `/zh-cn/start.md` |
| [创建你的账户](/zh-cn/start/create-your-account) | `/zh-cn/start/create-your-account.md` |
| [连接主页](/zh-cn/start/connect-a-page) | `/zh-cn/start/connect-a-page.md` |
| [发送你的第一条自动回复](/zh-cn/start/first-auto-reply) | `/zh-cn/start/first-auto-reply.md` |
| [为什么我的活动没有回复？](/zh-cn/start/troubleshooting) | `/zh-cn/start/troubleshooting.md` |
| [在画布上构建活动](/zh-cn/guides/build-a-campaign) | `/zh-cn/guides/build-a-campaign.md` |
| [将评论路由到私信](/zh-cn/guides/route-comments-to-dm) | `/zh-cn/guides/route-comments-to-dm.md` |
| [测试和调试活动](/zh-cn/guides/test-and-debug-campaigns) | `/zh-cn/guides/test-and-debug-campaigns.md` |
| [用关键词列表匹配评论](/zh-cn/guides/keyword-lists) | `/zh-cn/guides/keyword-lists.md` |
| [用标签细分联系人](/zh-cn/guides/tags) | `/zh-cn/guides/tags.md` |
| [管理联系人](/zh-cn/guides/contacts) | `/zh-cn/guides/contacts.md` |
| [在收件箱中处理会话](/zh-cn/guides/inbox) | `/zh-cn/guides/inbox.md` |
| [管理评论](/zh-cn/guides/comment-moderation) | `/zh-cn/guides/comment-moderation.md` |
| [使用清理工具批量移除评论](/zh-cn/guides/cleaner) | `/zh-cn/guides/cleaner.md` |
| [管理已连接主页](/zh-cn/guides/connected-pages) | `/zh-cn/guides/connected-pages.md` |
| [管理一个账户下的社交账号](/zh-cn/guides/profiles-and-master-accounts) | `/zh-cn/guides/profiles-and-master-accounts.md` |
| [套餐与账单](/zh-cn/guides/plans-and-billing) | `/zh-cn/guides/plans-and-billing.md` |
| [用推荐计划赚钱](/zh-cn/guides/referrals) | `/zh-cn/guides/referrals.md` |
| [接收通知](/zh-cn/guides/notifications) | `/zh-cn/guides/notifications.md` |
| [获取帮助](/zh-cn/guides/support-tickets) | `/zh-cn/guides/support-tickets.md` |
| 搭配 AI 代理使用 AFP（本页） | `/zh-cn/guides/ai-agent-skill.md` |
| [节点类型](/zh-cn/reference/node-types) | `/zh-cn/reference/node-types.md` |
| [触发事件](/zh-cn/reference/trigger-events) | `/zh-cn/reference/trigger-events.md` |
| [关键词匹配规则](/zh-cn/reference/keyword-matching) | `/zh-cn/reference/keyword-matching.md` |
| [执行状态](/zh-cn/reference/execution-states) | `/zh-cn/reference/execution-states.md` |
| [活动图模式](/zh-cn/reference/campaign-graph-schema) | `/zh-cn/reference/campaign-graph-schema.md` |
| [联系人字段](/zh-cn/reference/contact-fields) | `/zh-cn/reference/contact-fields.md` |
| [主页权限和令牌](/zh-cn/reference/page-permissions) | `/zh-cn/reference/page-permissions.md` |
| [套餐配额](/zh-cn/reference/plans-and-quotas) | `/zh-cn/reference/plans-and-quotas.md` |
| [订阅生命周期](/zh-cn/reference/subscription-lifecycle) | `/zh-cn/reference/subscription-lifecycle.md` |
| [通知目录](/zh-cn/reference/notifications) | `/zh-cn/reference/notifications.md` |
| [术语表](/zh-cn/reference/glossary) | `/zh-cn/reference/glossary.md` |
| [AFP 与其他方案的对比](/zh-cn/compare) | `/zh-cn/compare.md` |
| [AFP 对比 ManyChat](/zh-cn/compare/afp-vs-manychat) | `/zh-cn/compare/afp-vs-manychat.md` |
| [AFP 对比 Chatfuel](/zh-cn/compare/afp-vs-chatfuel) | `/zh-cn/compare/afp-vs-chatfuel.md` |
| [AFP 对比 Meta 内置自动化](/zh-cn/compare/afp-vs-meta-automations) | `/zh-cn/compare/afp-vs-meta-automations.md` |
| [更新日志](/zh-cn/changelog) | `/zh-cn/changelog.md`（即将推出） |

无法访问网络的代理可以离线使用相同的文件：获取一次 `/llms-full.txt` 并将它与技能一起提交。

## 代理应该遵循哪些活动图模式？

三种形状覆盖了人们要求代理设计的大多数情况。每一种都满足画布规则，所以可以逐个节点构建出来。

| 模式 | 节点顺序 | 适用情况 |
|---|---|---|
| 关键词评论转私信 | `trigger_comment` → `condition` → `reply_comment` → `send_dm` → `stop` | 一篇帖子要求人们评论某个词来获取东西 |
| 回复并筛选 | `trigger_dm` → `condition` → `send_dm` → `condition` → `add_tag` → `send_dm` → `stop` | 一条传入私信需要一个回答和一个后续问题 |
| 审核并回答 | `trigger_comment` → `condition` → Match 走 `hide_comment`，No Match 走 `reply_comment` | 不需要的评论被隐藏，其他所有评论得到公开回答 |

描述一个图的代理应说明每个节点的类型和配置键，以及每个连接的源输出。这些与已保存图使用的名称相同——连接携带 `from_node_id`、`to_node_id` 和 `output_index`——所以一个被描述的图和一个已保存的图可以逐字段比较。[活动图模式](/zh-cn/reference/campaign-graph-schema) 给出完整的结构。

### 关键词评论转私信

```d2 title="Comment to public reply to DM, with a stop on each branch"
direction: down
trigger: "trigger_comment\npost_scope all"
cond: "condition\nkeyword_list" {shape: diamond}
reply: reply_comment
dm: send_dm
haltMatch: stop
haltNoMatch: stop
trigger -> cond
cond -> reply: "Match, output 0"
reply -> dm -> haltMatch
cond -> haltNoMatch: "No Match, output 1"
```

在 `send_dm` 之前放一个公开的 `reply_comment` 是有意为之：它告诉评论者去查看私信，其他读者也能看到主页做出了回应。将条件的 `match_type` 设置为 `keyword_list`，并提供一个已保存列表的标识符；匹配的消息离开 output 0，其他所有内容离开 output 1。

### 回复并筛选

```d2 title="A DM campaign that asks a question, waits for the reply, then tags and answers, or falls back"
direction: down
trigger: trigger_dm
gate: "condition\nmatch_type any" {shape: diamond}
ask: "send_dm\n提出一个问题"
awaitReply: "condition\nmatch_type contains\nwait_for_reply" {shape: diamond}
tag: add_tag
answer: send_dm
haltMatch: stop
fallback: "send_dm\n兜底回复"
haltNoMatch: stop
trigger -> gate
gate -> ask: "output 0"
ask -> awaitReply
awaitReply -> tag: "Match, output 0"
tag -> answer -> haltMatch
awaitReply -> fallback: "No Match, output 1"
fallback -> haltNoMatch
```

设置了 `wait_for_reply` 的 `condition` 会将执行记录停在该节点，直到那个人回复，然后该回复会按第一条消息的方式进行匹配——包括他们点按的按钮标签。两个分支都需要各自的末端节点，因为一个节点只接受一个传入连接，两个分支不能合并。

设置为 `match_type: any` 的 `condition` 匹配所有内容，且只有一个输出：画布会去掉它的 No Match 输出，并移除从那里连出的任何连接。如果代理在一个 `any` 条件上画出 No Match 分支，它描述的图画布不会保留。

### 审核并回答

```d2 title="A moderation campaign that hides matching comments and replies to the rest"
direction: down
trigger: trigger_comment
cond: "condition\nkeyword_list" {shape: diamond}
hide: hide_comment
haltMatch: stop
reply: reply_comment
haltNoMatch: stop
trigger -> cond
cond -> hide: "Match, output 0"
hide -> haltMatch
cond -> reply: "No Match, output 1"
reply -> haltNoMatch
```

评论操作需要一条评论才能执行，所以这个模式只在 `trigger_comment` 下有效。把不想要的词放进关键词列表并隐藏 Match 分支，或者在条件上设置 `reverse_keywords`，让列表未匹配的所有内容改为走 Match 分支。

### 每个生成的图必须满足什么

1. 一个触发器，且它是唯一没有传入连接的节点。其他每个节点都必须有一个，否则启用会失败。
2. 触发器只能连接到 `condition`，且 `condition` 永远不能连接到另一个 `condition`。
3. 每个节点接受一个传入连接，每个输出句柄携带一个传出连接。
4. 没有循环。到达一个已经访问过的节点的执行记录会以循环错误结束。
5. 当触发器是 `trigger_dm` 时，评论操作不可用，且 `reply_comment` 和 `hide_comment` 在 `delete_comment` 的下游会被拒绝。
6. 在 `condition` 上，output 0 是 **Match**，output 1 是 **No Match**。

[活动图模式](/zh-cn/reference/campaign-graph-schema) 给出确切的字段名称和一个完整的 JSON 图；[节点类型](/zh-cn/reference/node-types) 给出代理可以写入的每个配置键。

## 代理对 AFP 会理解错什么？

| 模型会假设什么 | AFP 实际怎么做 | 技能会给模型什么替代认知 |
|---|---|---|
| 存在一个用于创建活动的 REST API | 没有客户端 API。活动是在画布上创作并从那里保存的 | 一条指令，要求它这样说明，而不是针对一个虚构的端点写请求 |
| 触发器可以直接连到 `send_dm` | 触发器只能连接到 `condition` | 连接规则，并将这一条列为最常见的无效图 |
| 运行时中的任何节点类型都可以使用 | 只有调色板中的类型才有设置面板，所以只有它们可以配置 | 调色板列表，以及永远不要使用的类型名称 |
| 两个分支可以合并回一个节点 | 一个节点只接受一个传入连接 | 一条规则：复制末端节点而不是合并 |
| 关键词直接输入到条件本身 | 一个条件匹配它自己的 `text`，或者按标识符引用一个你单独保存的关键词列表 | 四种匹配类型，以及每种读取哪个键 |
| 套餐的活动或主页配额是一个固定数字 | 配额来自账户上的套餐 | 一条指令，永远不要说出具体的配额数字 |
| 私信可以在任何时候发给任何人 | 第一条私信回答的是启动该执行记录的事件；之后的消息在那个人回复后才能到达其账户 | 一条说明：平台的消息发送窗口适用，AFP 不会覆盖它们 |
| 保存会让活动上线，编辑会改变正在进行的执行记录 | 保存会写入一个新版本，启用是单独的操作；一次执行记录会停留在它开始时的版本上 | 两条规则并列呈现给模型 |
| 这是一个聊天机器人构建工具，所以 "flow" 和 "bot" 这类词是合适的 | 这里的词汇是活动、节点、条件、执行记录 | 这套词汇，贯穿全篇使用 |

还有两点是该技能本身无法解决的，因为它们只有在图运行之后才会显现：

- `send_comment` 需要自己的 `post_id`。它不会回退到触发器所在的帖子，如果没有设置，执行记录到达它时什么都不会做。
- 一个人不能同时拥有同一活动的两次执行记录。当他们的执行记录处于活跃状态时，来自他们的第二个匹配事件会被跳过，所以后续消息应该放在同一个图内的 `delay` 之后，而不是依赖来自同一个人的第二个事件。

## 我如何检查代理给我的图？

1. 在画布上构建它。画布会在你拖拽时进行验证，所以它无法构建的图会在第一个错误连接处失败，而不是在保存之后。
2. 修复画布标记的任何节点。只要有节点存在配置错误，**Save campaign** 就会保持禁用。
3. 保存，然后运行一次测试执行。它会遍历已保存的图，并记录每个节点本应做什么，而不会给任何人发消息、操作评论，或更改联系人的标签。参见 [测试和调试活动](/zh-cn/guides/test-and-debug-campaigns)。
4. 只有在测试路径与代理的描述一致后才启用。

:::note
代理可能以画布能接受的方式出错。一个能顺利保存并启用的图，仍然可能把错误的消息发到错误的分支上，这正是测试执行存在的原因。
:::

## 为什么代理仍然产出画布拒绝的图？

| 症状 | 原因 | 修复方法 |
|---|---|---|
| 代理写出向 AFP 端点发起请求的代码 | 本次会话没有加载该技能 | 确认文件放在代理查找指令的位置，然后开始一个新会话 |
| 图将触发器直接连到一个操作 | 代理在按通用聊天机器人知识设计 | 请它在再次提出图之前重新陈述连接规则 |
| 图使用了一个没有设置面板的节点类型 | 节点列表来自技能之外的其他来源 | 替换它：`condition` 用于分支，`delay` 用于等待 |
| 代理引用了一个具体的活动或主页限制数字 | 配额是套餐配置，不是固定值 | 去掉这个数字，改为链接 [套餐配额](/zh-cn/reference/plans-and-quotas) |
| 两个分支汇合到同一个节点 | 汇入在图中看起来很自然，但画布会拒绝它 | 在每个分支上各自复制末端节点 |
| 描述的字段在设置面板中不存在 | 该技能早于界面的一次改动 | 重新下载文件并比较其 `version` 字段 |
| 站点的表格返回后变得混乱，或什么都没获取到 | 代理读取了 HTML 页面，或没有网络访问权限 | 给它 `.md` 地址或 `/llms-full.txt`，或者把这些文件保存到仓库中技能旁边 |

## 相关

- [活动图模式](/zh-cn/reference/campaign-graph-schema) — 代理必须遵循的字段名称和约束
- [节点类型](/zh-cn/reference/node-types) — 每个节点和每个配置键
- [在画布上构建活动](/zh-cn/guides/build-a-campaign) — 把一个提议的图变成已保存的图
- [测试和调试活动](/zh-cn/guides/test-and-debug-campaigns) — 检查图实际做了什么
- [用关键词列表匹配评论](/zh-cn/guides/keyword-lists) — 创建条件引用的列表
- [术语表](/zh-cn/reference/glossary) — 该技能要求代理遵循的词汇
