StaffDeck 侧的“数字员工可见范围”和知识库侧的“文档权限”是两条独立的控制链路。只配一边,就会遇到数字员工在页面上看不到某个部门、提问时却仍检索到该部门文档的情况。可以按这个顺序处理:知识库按目录切开部门边界,并在检索入参里带过滤条件;StaffDeck 按部门和角色绑定数字员工;上线前用两个部门账号问同一个问题对照结果。只在页面上配了、日志里看不到实际过滤条件的,还不能算隔离生效。
判断:部门隔离要同时落在检索过滤和数字员工绑定两处,缺一处就会越权。做法是先把知识库目录按部门切分、公共文档单独归属,再把目录映射成 StaffDeck 的角色绑定,最后用两个部门账号各问一次同一个问题,检查回答引用和检索日志里的文档 ID 是否越界。边界:接入字段和鉴权形态取决于知识库侧实际提供的能力,需要结合环境逐项确认后再定配置。
先确认知识库侧支持的接入方式与鉴权方式
动手配置前,把知识库方给出的接入说明逐项对一遍。缺少任何一个字段,后面要么检索不全,要么无法按部门过滤。
- 服务地址与调用路径:检索、文档详情、目录列表分别是哪个入口,有没有测试环境地址。
- 知识库或空间标识:一个数字员工绑定一个知识库,还是绑定一个空间下的多个目录。
- 鉴权凭证:token、AK/SK、OAuth 客户端凭证,或由内部网关统一注入身份。
- 检索入参:查询语句、返回条数上限、目录或部门过滤字段、超时时间。
- 返回字段:文档 ID、标题、正文片段、原文链接、所属目录、可见范围标记。
- 同步方式:知识库推送变更,还是 StaffDeck 侧定时拉取目录结构。
鉴权方式通常有几种可选形态:静态 token 放请求头,实现最简单,但要额外管好轮换和最小权限;AK/SK 签名适合把调用方区分到具体数字员工;OAuth 客户端凭证适合已有统一授权服务的情况;由内部网关统一鉴权则把凭证留在网关上,StaffDeck 只传身份标识。选哪种取决于知识库侧支持到哪一步,不要假设它一定支持按调用方身份返回不同结果。
接入骨架可以先按下面的结构写,字段名以知识库实际说明为准,替换后再联调。关键是 filter 要留出目录过滤位置,返回映射里保留 doc_id 和 scope,这两个字段是后面查越权时唯一能对上号的依据。
knowledge_base:
base_url: "https://kb.internal.example/api" # 替换为实际地址
auth:
type: "token" # token / ak_sk / oauth / gateway
header: "Authorization"
token_ref: "secret://staffdeck/kb-token"
search:
path: "/search"
top_k: 8
timeout_ms: 3000
filter:
catalog_ids: [] # 由数字员工的可见范围填充
scope_tag: "dept" # 知识库侧可见范围字段名,需确认
response_map:
id: "doc_id"
title: "title"
snippet: "content"
url: "source_url"
scope: "visible_scope"
联调时先手工调用一次检索,看返回里到底有没有可见范围或目录字段。没有这类字段时,部门隔离只能靠 StaffDeck 侧按目录前缀过滤,那就得提前和知识库维护方约定目录命名规则。
把文档目录结构和部门划分对齐
按部门切分目录,是让“文档在哪里”和“谁能看”能长期维护的前提。目录按部门命名之后,加人加文档只改角色绑定,不用动数字员工配置。建议目录最多两层就落到部门,不要留跨部门混放的目录。
| 目录 | 内容 | 可见范围 | 绑定角色 | 维护方 |
|---|---|---|---|---|
| /kb/public | 制度、流程、通用问答 | 全员 | role_all_staff | 行政 / HR |
| /kb/sales | 报价、客户案例 | 销售部 | role_dept_sales | 销售运营 |
| /kb/finance | 预算、报销口径 | 财务部 | role_dept_finance | 财务 |
| /kb/rd/design | 设计文档 | 研发部 | role_dept_rd | 研发 |
公共文档的归属要有明文约定:统一放 /kb/public,只绑全员角色,不复制到各部门目录下。副本一多,权限和正文会各自漂移,检索时也判断不出命中的是哪一份。确需部门内补充说明的,放在部门目录下,并在标题里注明适用范围。
销售和财务都要看的价格政策这类跨部门文档,建议放公共目录,或在知识库侧给同一目录绑定多个角色,不要把文档复制成两份——改口径时必然漏改一处。
在平台侧为数字员工配置可见范围
StaffDeck 侧的动作拆成三步:数字员工绑定哪个知识库、可见范围包含哪些部门或角色、检索时下发什么过滤条件。先看配置页上有没有独立的“可见范围”和“检索过滤”两块,再决定是纯页面配置还是要落到配置文件。
| 页面字段 | 对应配置项 | 填法 |
|---|---|---|
| 数字员工名称 | agent.name | 按部门命名,如 sales-kb-assistant |
| 绑定知识库 | agent.kb_id | 选对应知识库,不建议多部门共用一个 |
| 可见范围 | agent.visible_scope | 部门或角色列表,未列出的部门不可见 |
| 检索过滤 | agent.search_filter | 目录 ID 或部门标签,下发到知识库检索入参 |
| 生效方式 | agent.effective_mode | 新会话生效 / 立即生效,按平台能力选 |
角色绑定示例,字段名按平台实际配置调整:
agents:
- name: "sales-kb-assistant"
kb_id: "kb_main"
visible_scope:
roles: ["role_dept_sales"]
departments: ["sales"]
search_filter:
catalog_ids: ["/kb/sales", "/kb/public"]
scope_tag: "dept"
effective_mode: "new_session"
生效方式要单独确认。保存配置后通常对新会话立即生效,但已有会话可能沿用旧可见范围或在缓存里保留旧过滤条件。改完部门归属后,验证一律新开会话,别拿历史会话的结果当依据。配置里同时出现角色和部门两个维度时,取交集还是并集需要按平台说明确认,配完用账号实测更可靠。
用两个不同部门的账号各问一次同一个问题
配置写完不等于隔离生效。准备两个部门账号,问一个只在 A 部门目录里有答案的事实,再问一个公共目录里的问题。前者看越权有没有被挡住,后者看正常检索有没有被误伤。
| 编号 | 账号 | 提问 | 期望结果 | 观察点 |
|---|---|---|---|---|
| V1 | sales 账号 | 季度报价审批口径 | 有答案,引用来源在 /kb/sales | 回答引用链接;日志命中 doc_id 的目录前缀 |
| V2 | finance 账号 | 季度报价审批口径 | 无答案,或明确提示无可见资料 | 日志中 catalog_ids 不含 /kb/sales |
| V3 | finance 账号 | 报销提交时限 | 有答案,引用来源在 /kb/finance | 反向对照,排除全局无结果 |
| V4 | 两个账号 | 公司考勤制度 | 都能答,引用 /kb/public | 公共目录未被误挡 |
观察点要落在能留下的证据上:回答里的引用链接或文档标题、检索请求日志里的过滤条件、召回文档 ID 列表、请求 ID 和时间戳。其中最有说服力的是日志里的 catalog_ids 和召回 doc_id 的目录前缀,而不是回答文本——回答里没出现某部门内容,也可能是模型没选上,不等于权限挡住了。
V2 是重点用例。finance 账号的回答里出现 sales 目录引用,或日志召回列表里含 /kb/sales 下的 doc_id,说明过滤条件没有下发到检索层,只在 StaffDeck 页面上限制了数字员工可见性。这时要回查第 1 节确认的 scope_tag 是否被知识库真正识别。
记录方式建议固定一张表,每次改配置后追加一行:验证编号、账号、提问原文、期望、实际、证据(截图文件名或日志时间戳加请求 ID)、结论。这份记录在后续调整部门归属时可以直接复用。验证通过后再放开给部门使用;新增目录时,先确认归属和角色绑定,再让数字员工可见,避免新目录默认落进全员可见范围。