Access Tags
将知识条目限制为仅授权访客可用 — 在我们的服务器上强制执行,而不是由 AI 执行
概述
并非所有内容都面向所有人:仅限会员的文档、特定地区的材料、付费等级的资源。借助 Access Tags,一个聊天机器人就能安全地服务不同受众。您给知识条目打上标签,从那一刻起,该条目对所有访客都不可见 — 除非访客的页面出示了由您自己的服务器签名的该标签。限制在我们的检索查询中强制执行,此时 AI 模型尚未参与。没有标签的访客无法通过巧妙提问套出内容,因为对他而言内容根本没有被检索过。
工作原理
- 您给知识条目打标签 - 在 Access Tags 页面或直接通过 API;无标签的条目继续对所有人可用
- 您的服务器为每位访客的标签签名 - 登录会员打开您的页面时,您的后端判定其权限,并用只有您持有的密钥签名
- 挂件发送签名凭据 - 它随每条聊天消息一起传输;浏览器只负责传递,无法在不破坏签名的情况下更改它
- 我们验证并过滤 - 有效签名会解锁标签匹配的条目;凭据缺失、被篡改或已过期时,访客只能获得公开内容
如何设置
在控制台的 Access Tags 页面开启功能 — 签名密钥会自动生成。请只保存在您的服务器上;任何持有它的人都能制作有效凭据。
在同一页面为内容打标签,或在通过 API 提交条目时指定:
POST /api/v1/knowledge/text/
{
"title": "Members-only price list",
"content": "...",
"website_id": "123",
"access_tags": ["premium"]
}
然后让您的服务器在挂件代码旁输出签名凭据。要签名的消息是以逗号分隔的标签列表;使用过期时间时,用竖线连接:
<?php
$tags = "members,premium"; // this visitor's entitlements
$expires = time() + 3600; // unix seconds, optional but recommended
$sig = hash_hmac("sha256", $tags . "|" . $expires, $SECRET);
?>
<script>
window.Asyntai = window.Asyntai || {};
window.Asyntai.accessTags = "<?php echo $tags; ?>";
window.Asyntai.accessTagsExpires = "<?php echo $expires; ?>";
window.Asyntai.accessTagsSignature = "<?php echo $sig; ?>";
</script>
Node.js 和 Python 中的同一签名:
// Node.js
const crypto = require("crypto");
const sig = crypto.createHmac("sha256", SECRET)
.update(tags + "|" + expires).digest("hex");
# Python
import hmac, hashlib
sig = hmac.new(SECRET.encode(), f"{tags}|{expires}".encode(),
hashlib.sha256).hexdigest()
不用过期时间时,只需对标签字符串本身签名。使用过期时间时,凭据在过期那一刻立即失效 — 当权限可能被收回时很有用,因为访客必须重新加载由您控制的页面才能获得新凭据。
标签逻辑
条目的标签以「与」组合:只有当条目上的每一个标签都出现在访客的凭据中时,该条目才会被检索。访客的凭据可以携带任意多的权限,匹配会同时针对全部权限进行。
| 条目标签 | 访客凭据 | 结果 |
|---|---|---|
(none) | 任意 | 可见 — 无标签的条目是公开的 |
north | north, premium | 可见 |
north, premium | north | 隐藏 — 凭据中缺少 premium |
north, premium | north, premium, extra | 可见 — 多余的权限无妨 |
「与」是刻意设计。若采用「任一匹配」,给条目添加第二个标签反而会扩大可见范围,于是把一份文档收窄到两个群组,实际上等于向两个群组全面公开。采用「全部匹配」时,你添加的每个标签只会进一步收紧,错误因此倒向安全的一侧。
如何表达「任选其一」
在条目上省略该维度。如果每位访客的凭据都携带其地区,那么没有地区标签的文档对所有地区可用,而它的其他标签依然生效。因此仅标记 premium 的条目意味着「不限地区,仅限高级订阅者」。
若确实需要跨维度的选择 — 比如北部搭配基础版,或南部搭配高级版,别无其他 — 请将条目按每种组合各添加一次,或给两类受众一个共同标签,由你的服务器写入他们的凭据。
限制
- 每个知识条目最多 20 个标签
- 单个访客的凭据最多 50 个标签
- 每个标签 50 个字符;由于凭据是以逗号分隔的字符串,不允许使用逗号和竖线
之后更改标签
现有条目的标签可以替换,无需重新上传。更改从下一次提问起生效,内容本身不会重新处理。
POST /api/v1/knowledge/<id>/tags/
{
"access_tags": ["premium"]
}
发送空列表即可让条目重新公开。你也可以在控制台的 Access Tags 页面手动编辑标签。
有哪些保证
- 服务器端强制执行 - 过滤器在检索时运行于我们的数据库查询内部;对未授权访客,带标签的条目根本不会进入 AI 的上下文,因此无可泄露
- 处处默认拒绝 - 无签名、签名错误、凭据过期、功能关闭、套餐降级:在任何一种情况下,访客都只能获得公开内容,绝不会更多
- 浏览器无法伪造访问权限 - 在开发者工具中修改标签会破坏签名;密钥只在您的服务器上
- 您的权限逻辑仍归您所有 - 我们永远不知道您如何决定谁获得哪个标签;我们只验证您的服务器确实作了声明
值得了解
- Access Tags 是授权,User Context 是个性化 - 用 User Context 告诉 AI 会员是谁;用 Access Tags 控制 AI 可以引用哪些知识
- 抓取的网站内容始终公开 - 它来自您的公开网站,无需限制;标签适用于文本、文件和 API 条目
- 条目的标签以「与」组合 - 参见上方的标签逻辑;条目上的每个标签都必须出现在访客的凭据中
- 重新生成密钥会使所有旧凭据失效 - 若密钥可能泄露请执行此操作,然后更新页面改用新密钥签名
- 标签名称由您决定 - 每个条目最多 20 个,每个 50 字符,不含逗号和竖线;它们绝不会出现在访客看到的聊天中
与 User Context 搭配使用:一个功能控制 AI 可为该访客使用哪些知识,另一个告诉 AI 访客是谁。
用户上下文 将已登录用户的数据传递给 AI 聊天机器人,实现个性化对话注意: Access Tags 是 Enterprise 协议的一部分。请致信 [email protected],我们会为您详细讲解。