语音代理可以听起来很流畅、响应迅速,但仍可能在一句话中引发信任危机:“不要再给我打电话了。”
如果该请求仅更新了短信路径,你的代理可能明天还会继续拨打。如果它只更新了通话记录,你的后续工作流可能仍在继续发送短信。对于正在交付 AI 拨号器、收件箱代理、调度机器人或多步骤外展工作流的构建者来说,同意不再是一个静态复选框。它是运行时状态。
这就是 AI 同意账本 的用武之地。它为每个代理操作提供一个简单规则:在联系、丰富、记录或升级某个人之前,从一个持久位置检查最新的同意状态。
本指南展示如何设计该账本,而不让你的产品变成合规迷宫。
这是技术架构指导,不是法律建议。如果你的工作流涉及受监管的外展、健康、金融、就业或敏感个人数据,请咨询合格的法律审查员。
为什么 AI 代理让同意更难管理
传统应用通常在可预测的时刻请求许可:注册、新闻通讯订阅、Cookie 横幅、电话号码捕获或账单同意。
AI 代理模糊了这一界限。
生产中的代理可能:
- 接听来电
- 总结语音邮件
- 发送后续链接短信
- 安排另一次通话
- 丰富 CRM 记录
- 触发下周的活动步骤
- 将案例转交给人工
- 在工具调用失败后重试
- 从语音切换到短信或电子邮件
每个步骤本身可能都有效。当一个渠道的同意发生变化而工作流的其余部分未察觉时,风险就出现了。
常见的失败模式很简单:
- 用户在他面前的渠道中撤销了许可。
- 代理将消息记录为对话文本。
- 另一个工作流继续运行,因为它从未检查过撤销状态。
这不是 LLM 的问题,而是状态管理的问题。
什么是 AI 同意账本?
AI 同意账本 是一个仅追加的权限事件记录,加上一个快速读取模型,用来回答一个问题:
这个特定的代理现在是否被允许为这个人执行这个特定的操作?
该账本应跨渠道、身份、代理、工作流、工具和时间跟踪同意与撤销。
它不仅仅是一个 subscribed: true 列。
一个有用的账本存储:
- 同意属于谁
- 它适用于哪个渠道
- 它涵盖什么目的
- 何时授予或撤销
- 是如何捕获的
- 哪个工作流或代理对其进行了操作
- 支持该决定的证据是什么
- 撤销是应停止一个渠道还是所有相关外展
对于 AI 工作流,最重要的部分不是日志,而是在操作前的策略检查。
团队最常忽略的同意接触点
首先映射代理可以创建、使用或更改权限状态的每一个位置。
1. 语音撤销
用户可能会说:
- “不要再给我打电话。”
- “把我从名单上删除。”
- “不要再联系这个号码。”
- “只给我发邮件。”
- “改用短信联系我。”
- “我没有要求这个。”
不要把这些短语埋在转录文本中。把它们提取为候选同意事件。
语音撤销之所以棘手,是因为代理可能在长时间对话中听到它。你需要一个单独的分类器或确定性短语层来监视权限变化,而不仅仅是最终摘要。
2. 短信关键词与自然语言
大多数团队首先处理 STOP、UNSUBSCRIBE 和 START。这是必要的,但用户并不总是使用确切的关键词。
你还需要捕获自然语言:
- “请不要再给我发短信”
- “打错号码了”
- “改打我办公室的电话”
- “不感兴趣,把我删除”
确切关键词可以是确定性的。自然语言可以分类,然后在不确定时路由到确认或人工审核。
3. 电子邮件和通知偏好
代理可能会从原本基于语音的工作流中起草或发送电子邮件。如果电子邮件有单独的同意目的,账本必须知道这一点。
同意不应仅仅因为代理有另一个可用工具而悄无声息地扩展。
4. CRM 导入与过时名单
许多 AI 工作流始于导入的联系人。该导入可能包含旧的同意标志、部分渠道历史,或根本没有证据。
将导入的许可视为较低信任度,直到验证为止。存储来源和时间戳,以便代理可以选择更安全的模式。
5. 人工覆盖
人工需要覆盖路径,但覆盖应是带有理由的明确事件,而不是隐形的管理员编辑。
一个好的覆盖记录应回答:
- 谁更改了状态
- 他们为什么更改
- 他们审查了什么证据
- 更改是临时的还是永久的
实用的同意数据模型
保持写入模型为仅追加。从中构建一个单独的当前状态视图。
这是一个紧凑的 TypeScript 风格模型:
type ConsentChannel = "voice" | "sms" | "email" | "push" | "in_app";
type ConsentPurpose =
| "support_followup"
| "appointment_reminder"
| "marketing_outreach"
| "transactional_update"
| "recording"
| "data_enrichment";
type ConsentEventType =
| "granted"
| "revoked"
| "limited"
| "confirmed"
| "expired"
| "human_override";
type ConsentEvent = {
id: string;
tenantId: string;
subjectId: string; // person/customer/contact
normalizedContact: string; // phone/email/device id hash
channel: ConsentChannel;
purpose: ConsentPurpose;
eventType: ConsentEventType;
scope: "single_channel" | "all_channels" | "all_outreach";
source: "voice_agent" | "sms_keyword" | "web_form" | "crm_import" | "human";
evidenceRef: string; // transcript span, form id, message id, admin note
confidence: number; // 0..1 for AI-extracted events
workflowRunId?: string;
agentId?: string;
createdAt: string;
expiresAt?: string;
};
Enter fullscreen mode Exit fullscreen mode
一些细节很重要:
-
scope可防止“停止打电话”意外变成“停止一切”,除非策略要求。 -
purpose可防止预约提醒的同意变成促销的同意。 -
evidenceRef允许你解释系统做出该决定的原因。 -
confidence允许不确定的 AI 提取事件暂停,而不是盲目行动。
每个代理操作所需的运行时检查
在任何状态更改或联系操作之前,向账本请求决策。
type ConsentDecision = {
allowed: boolean;
reason: string;
matchedEventIds: string[];
requiresHumanReview?: boolean;
safeAlternative?: "do_not_contact" | "in_app_only" | "ask_for_confirmation";
};
async function canAgentAct(input: {
tenantId: string;
subjectId: string;
channel: ConsentChannel;
purpose: ConsentPurpose;
action: "call" | "text" | "email" | "record" | "enrich";
workflowRunId: string;
}): Promise<ConsentDecision> {
const state = await consentStore.currentState(input);
if (state.hasGlobalRevocation) {
return {
allowed: false,
reason: "Subject revoked all outreach",
matchedEventIds: state.blockingEvents,
safeAlternative: "do_not_contact",
};
}
if (state.channelRevoked) {
return {
allowed: false,
reason: `${input.channel} permission was revoked`,
matchedEventIds: state.blockingEvents,
safeAlternative: "in_app_only",
};
}
if (!state.hasPurposeGrant) {
return {
allowed: false,
reason: `No active consent for ${input.purpose}`,
matchedEventIds: [],
safeAlternative: "ask_for_confirmation",
};
}
return { allowed: true, reason: "Active consent found", matchedEventIds: state.grantEvents };
};
Enter fullscreen mode Exit fullscreen mode
代理不应是最终权威。它可以请求操作。后端决定该操作是否被允许。
如何从语音转录中处理撤销
语音代理需要在转录周围有一个小型管道。
第 1 步:捕获转录片段
不要只存储完整的转录 blob。存储带时间码的片段。
{
"span_id": "span_928",
"speaker": "user",
"text": "Please stop calling this number. Texts too.",
"start_ms": 184200,
"end_ms": 188700
}
Enter fullscreen mode Exit fullscreen mode
第 2 步:提取同意意图
对明显短语使用确定性规则,对较软的语言使用 LLM 分类器。
{
"intent": "revocation",
"channels": ["voice", "sms"],
"scope": "all_outreach",
"confidence": 0.94,
"evidence_span_id": "span_928"
}
Enter fullscreen mode Exit fullscreen mode
第 3 步:应用置信度策略
示例策略:
- 置信度
>= 0.90:立即写入撤销事件 - 置信度
0.65 - 0.89:暂停工作流并请求人工审核 - 置信度
< 0.65:存储为信号,不自动更改状态
对于撤销,宁可误报也不要继续不受欢迎的联系。对于新的同意授予,要更严格。
第 4 步:停止活动工作流
账本写入应发出一个事件,取消或暂停相关工作流。
await eventBus.publish("consent.revoked", {
tenantId,
subjectId,
channels: ["voice", "sms"],
scope: "all_outreach",
evidenceRef: "call_123:span_928",
});
Enter fullscreen mode Exit fullscreen mode
然后工作者应停止未来步骤:
on("consent.revoked", async (event) => {
await workflowStore.pauseRuns({
tenantId: event.tenantId,
subjectId: event.subjectId,
affectedChannels: event.channels,
reason: "consent_revoked",
});
});
Enter fullscreen mode Exit fullscreen mode
如果撤销没有取消计划任务,账本就变成了日记,而不是控制系统。
设计渠道感知规则
并非每个权限事件都意味着相同的事情。
使用策略矩阵:
| 用户陈述 | 建议范围 | 默认操作 |
|---|---|---|
| “不要再给我发短信” | 仅短信 | 阻止短信,允许其他已获许可的渠道 |
| “不要再给我打电话” | 仅语音 | 阻止通话,允许其他已获许可的渠道 |
| “不要联系我” | 所有外展 | 阻止语音、短信、电子邮件、推送 |
| “打错号码了” | 联系方式 | 阻止该电话号码,标记身份质量 |
| “改用邮件联系我” | 渠道偏好 | 阻止当前渠道,要求检查电子邮件许可 |
| “不要记录这个” | 记录目的 | 停止记录,仅在工作流允许时继续 |
此矩阵应存在于代码或策略配置中,而不是在提示中。
账本在架构中的位置
一个简单的生产流程如下:
- 代理提出一个操作。
- 运行时策略检查工具权限。
- 同意账本检查用户权限。
- 速率限制器检查预算和频率。
- 工具执行器执行操作。
- 审计日志记录决策和证据。
这个顺序很重要。不要先调用工具再检查同意。
对于语音代理,在两个方向上都放置账本:
- 在拨出电话或短信之前
- 在实时通话中出现撤销时
- 在通话后处理摘要时
- 在活动重试之前
- 在人工交接后续之前
可观测性:记录什么
每个同意决策都应产生一个小收据。
{
"decision_id": "cd_456",
"workflow_run_id": "run_789",
"agent_id": "voice_followup_agent",
"subject_id": "contact_123",
"requested_action": "sms.followup",
"purpose": "appointment_reminder",
"allowed": false,
"reason": "sms permission revoked",
"matched_event_ids": ["ce_111"],
"created_at": "2026-07-30T06:08:00Z"
}
Enter fullscreen mode Exit fullscreen mode
这有助于调试和用户信任。当有人询问代理为什么联系或不联系他们时,你会有一个具体的答案。
跟踪这些指标:
- 按渠道检测到的撤销
- 需要审核的不确定同意事件
- 被阻止的代理操作
- 撤销后暂停的工作流
- 从撤销到工作流取消的时间
- 有导入同意但无证据的联系人
- 假阳性和假阴性审核结果
关键指标不是“发送了多少条消息”,而是“有多少操作被正确允许、阻止或暂停”。
常见错误
错误 1:将提示视为策略
系统提示可以告诉代理尊重同意。它无法在重试、工作线程、队列和集成中强制执行同意。
策略属于后端检查。
错误 2:仅存储当前状态
单个 can_contact=false 标志隐藏了决策发生的原因。你需要事件历史用于审计、调试和安全恢复。
错误 3:忽略目的
发送登录码的权限不是发送促销序列的权限。将同意与目的绑定。
错误 4:让计划任务绕过检查
排队任务应在执行时检查同意,而不仅仅是在安排时。同意可能在安排和发送之间发生变化。
错误 5:跨渠道扩展同意
如果用户为提醒提供电话号码,不要假设代理可以永远拨打、发送短信、丰富、记录和发送电子邮件。使扩展明确。
小型实施检查清单
用作首次检查:
- [ ] 列出代理联系、记录、丰富或更新个人的每一个操作。
- [ ] 为每个操作定义目的。
- [ ] 创建仅追加的同意事件。
- [ ] 构建当前状态读取模型。
- [ ] 在工具执行前添加后端同意检查。
- [ ] 从语音和短信中提取撤销。
- [ ] 撤销后暂停活动工作流。
- [ ] 存储证据引用,而不仅仅是标志。
- [ ] 为不确定的 AI 提取事件添加人工审核。
- [ ] 记录同意决策收据。
- [ ] 在撤销后测试排队任务。
- [ ] 单独审查导入的 CRM 同意。
测试账本
根据真实失败模式创建测试用例。
it("blocks scheduled SMS after spoken all-channel revocation", async () => {
await ledger.append({
subjectId: "c1",
channel: "voice",
purpose: "marketing_outreach",
eventType: "revoked",
scope: "all_outreach",
source: "voice_agent",
confidence: 0.96,
evidenceRef: "call_1:span_9",
});
const decision = await canAgentAct({
tenantId: "t1",
subjectId: "c1",
channel: "sms",
purpose: "marketing_outreach",
action: "text",
workflowRunId: "run_1",
});
expect(decision.allowed).toBe(false);
expect(decision.reason).toContain("revoked");
});
Enter fullscreen mode Exit fullscreen mode
还要测试:
- 短信
STOP在策略规定所有外展时阻止未来的语音。 - “改用邮件联系我” 不会发送邮件,除非存在邮件许可。
- 导入的 CRM 同意过期或需要验证。
- 低置信度撤销会暂停工作流。
- 人工覆盖会创建事件和收据。
- 重试的工作线程在执行前重新检查同意。
这如何与更广泛的 AI 架构连接
同意账本最好与其他运行时控制一起工作:
- 运行时策略 决定工具调用是否安全。
- 速率限制 控制频率和支出。
- 租户隔离 防止跨客户状态泄露。
- 输出来源 存储生成的决策的证据。
- 审批门 暂停有风险的操作以供审核。
同意是更大系统中的一个边界。但这是用户立即理解的边界。如果他们说停止,系统就应该停止。
常见问题
什么是 AI 同意账本?
AI 同意账本是一个仅追加的同意和撤销事件记录,加上一个运行时读取模型,用于决定 AI 代理是否可以联系、记录、丰富或为某人采取行动。
这仅适用于语音代理吗?
不是。语音代理使问题变得明显,但相同的模式适用于短信代理、电子邮件代理、支持副驾驶、CRM 自动化、通知系统以及使用个人数据的 AI 工作流。
LLM 可以决定是否存在同意吗?
LLM 可以帮助分类“请不要打扰我”这样的混乱语言,但它不应该是最终的执行层。写入候选事件,应用置信度规则,并让后端策略做出决定。
一个渠道的撤销是否应停止所有渠道?
这取决于用户陈述、产品策略和法律背景。“不要再给我发短信”可能是渠道特定的。“不要联系我”通常应停止所有外展。在策略矩阵中对此进行编码。
排队任务是否需要再次检查同意?
是的。昨天安排的任务今天可能变得无效。每个排队的联系操作应在执行前立即检查最新的同意状态。
我应该首先构建什么?
从撤销开始。捕获短信关键词、口头停止短语、外出操作前的当前状态检查,以及工作流取消。然后添加目的级授予、审核队列和更丰富的证据收据。
最终思考
AI 代理使工作流更快,但速度使同意错误代价更高。最安全的模式很简单:代理可以提议联系,但账本决定联系是否被允许。
如果一个人在一个地方撤销了许可,每个相关工作流都应在下一次工具调用运行之前听到它。
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.