DeepSeek Harness 工具执行流水线与权限门禁
DeepSeek Harness 在 LLM 调用工具的链路中,内置了一套完整的工具执行流水线,并在流水线关键节点插入权限门禁(Permission Gate)。它的目标不是简单调用函数,而是对工具调用请求做校验、拦截、沙箱隔离、审计、放行或拒绝,防止越权操作、危险指令、恶意参数执行。
绝大多数工具调用报错、工具被静默拒绝、模型无法执行文件读写/命令,根源都在于权限门禁拦截,或是对流水线执行顺序理解错误。

一、工具执行流水线完整链路
整体流程:模型输出工具调用请求 → 前置校验 → 权限门禁 → 参数预处理 → 沙箱执行 → 结果采集 → 后置钩子 → 返回结果给大模型。
完整7个阶段,按顺序执行:
- 工具请求解析阶段(Parse)
内核解析 LLM 输出的 function call / tool_call 消息,识别工具名称、入参、会话上下文。
内核校验:该工具是否存在、是否在当前会话可用、工具定义(Definition)是否合法。
若工具不存在,直接终止流水线,返回错误信息给模型。
- 前置钩子阶段(Before Hook)
触发工具注册的beforeInvoke事件钩子,插件可在此修改入参、追加上下文、提前做自定义校验。
多个插件注册的前置钩子按事件分发顺序依次执行。 - 权限门禁校验阶段(Permission Gate,核心节点)
这是安全拦截核心。内核读取工具声明的权限规则、Profile 配置、用户会话权限策略,逐项校验。
不通过直接终止流水线,不会执行工具本体代码。 - 参数校验与转换(Schema Validate)
使用工具 defineTool 声明的 JSON Schema,校验传入参数类型、取值范围、必填项。参数不合法直接拒绝。
支持自动类型转换、参数清洗、过滤敏感字段。 - 沙箱环境实例化 & 执行(Execute)
在隔离沙箱内运行工具 Provider 的业务逻辑。
沙箱由服务作用域控制,遵循前面介绍的服务隔离规则,限制文件、网络、子进程访问。 - 后置钩子阶段(After Hook)
工具执行完成(无论成功或异常),触发afterInvoke事件钩子。
可用于结果改写、日志记录、数据脱敏、统计耗时。即使工具抛出异常,后置钩子依然执行。 - 结果封装与返回(Return)
将工具输出、异常信息、审计日志打包,组装成消息返回给 LLM,进入下一轮推理。
流水线关键特性:阶段串行,任意阶段失败都会中断后续流程;后置钩子是例外,执行失败时依然会触发。
二、权限门禁 Permission Gate:校验规则与权限类型
权限门禁是一组可配置、可扩展的校验器,在工具执行前集中校验。支持内置权限,也支持插件自定义权限校验器。
2.1 内置权限分类
- 声明式权限(工具定义内写死)
在defineTool定义工具时,直接声明该工具需要哪些权限,属于工具的固有能力契约。
示例:文件读取工具声明scope:fs.read,命令行工具声明scope:shell.exec。
defineTool({
name: "read_file",
description: "读取文件内容 Read file content",
permission: ["scope:fs.read"],
// ...参数定义
})
- 运行时权限(Profile / 会话配置)
在cordis.patch.yml或 Profile 配置中,控制是否允许该权限。
可以全局开关、按会话、按用户角色控制权限启用/禁用。
permissions:
"scope:fs.read": allow
"scope:shell.exec": deny
支持三种策略:
allow:允许执行 Allowdeny:直接拒绝 Denyprompt:弹窗二次确认 Prompt(桌面版/WebUI 可用,SDK 模式会返回等待确认事件)
- 资源权限(路径、网络白名单)
针对文件、网络请求增加细粒度白名单:
- 文件:仅允许访问指定目录,拒绝访问系统敏感路径
/etc、C:\Windows - 网络:只允许白名单域名,禁止内网扫描、访问内网数据库
2.2 门禁校验顺序
- 检查工具本身是否启用(全局开关)
- 检查工具所需权限列表是否全部放行
- 检查资源白名单(文件路径、目标域名)
- 检查会话/用户角色权限
- 执行自定义权限校验插件钩子
任意一项不满足,门禁直接拦截,返回权限拒绝错误。
三、流水线事件与三角色联动

这套流水线完全复用 Definition / Provider / Consumer 三角色架构:
- Definition:
defineTool,定义工具名称、描述、入参Schema、所需权限(契约) - Provider:工具实现,提供执行逻辑,在沙箱内运行
- Consumer:LLM 智能体,发起工具调用请求
权限校验读取的是 Definition 中声明的权限,但是放行策略由 Profile 运行时配置控制。
工具开发者只需要声明需要什么权限;平台使用者(Profile)决定是否开放该权限,实现能力定义与权限管控解耦。
四、工具执行的异常分支
流水线包含两套异常路径:
- 门禁/前置校验失败:不会进入工具执行阶段,直接返回权限错误。
- 工具执行阶段报错:代码抛出异常,依然会执行 afterInvoke 后置钩子,记录审计日志,异常信息包装后返回模型。
五、审计与日志
流水线全链路埋点,每一次工具调用都会生成审计日志,包含:
- 调用时间、工具名称、入参
- 权限门禁校验结果(放行 / 拒绝)
- 执行耗时、返回结果或异常信息
日志可通过事件系统订阅,插件可以实现审计、告警功能。
六、实战示例:权限弹窗 prompt 模式
当权限策略设置为 prompt,工具执行会暂停流水线,向外抛出权限确认事件:
- LLM 请求执行 shell 命令;
- 流水线走到权限门禁,识别
scope:shell.exec策略为 prompt; - 暂停执行,抛出事件,WebUI/桌面版弹出确认框,向用户展示工具名称、参数、风险说明;
- 用户同意 → 继续流水线,执行工具;用户拒绝 → 终止流水线,返回拒绝信息。
SDK 场景下,事件会暴露给上层应用,由业务层实现自定义确认弹窗逻辑。
七、常见问题排查
- 模型调用工具,请求被静默拒绝
排查:查看日志,确认权限门禁返回 deny。检查当前 Profile 的 permissions 配置。 - 本地开发工具,本地调试可以执行,打包分发后被拦截
排查:工具定义缺少 permission 声明;或者目标 Profile 默认禁止该 scope。 - 参数校验失败,门禁没拦截
排查:参数校验在门禁之后,属于独立阶段;权限门禁只管权限,参数合法性由 Schema 校验。 - afterHook 没有执行
只有在流水线正常进入执行阶段后,后置钩子才会触发;门禁直接拦截的请求不会触发 afterInvoke。
八、最佳实践
- 开发工具时,最小权限原则:只声明必须的 scope,不要一次性申请全部权限。
- 生产环境:shell、文件写入、网络请求等高风险权限,默认策略设为 prompt 或 deny。
- 权限策略统一放在 Profile 的 patch 配置,不要硬编码在插件代码内,方便环境切换。
- 高风险工具,在后置钩子增加审计日志,记录全部调用行为。
- 自定义权限校验逻辑,建议注册到权限门禁事件,不要写在工具业务代码内部,实现解耦。
小结
DeepSeek Harness 的工具执行流水线是一套分阶段、可拦截的串行执行链路,而权限门禁嵌入在流水线靠前的位置,作为安全网关。
- 流水线:解析 → 前置钩子 → 权限门禁 → 参数校验 → 沙箱执行 → 后置钩子 → 返回结果
- 权限门禁支持声明式权限、运行时策略、资源白名单,支持自动拒绝、二次确认两种安全模式。
结合三角色架构,将工具能力定义和运行时权限管控分离,让插件开发者专注工具逻辑,使用者统一管控安全策略。
0 条笔记