DEEPSEEK HARNESS 插件工具包
让业务包只写业务。
连接、推送、委托、校验——这几件与业务无关、却每个项目都要重写一遍的事,收进一个包里,默认安全,按需启用。
v0.3.0
五类能力
底层由七个 Cordis Service 实现,钉钉使用已登录的 user 身份,飞书、企业微信使用机器人身份。
壹 · 连接 WebSocket 客户端 · ctx.agentWs 仅 wss:// 的 WebSocket 客户端:可刷新的鉴权请求头、心跳、指数退避重连、并发与背压控制;鉴权失败或指定关闭码时进入 failed 状态并可慢速重试。 贰 · 消息 钉钉消息 · ctx.dingtalk 通过钉钉 dws CLI 的 user 身份发送消息;统一监听群内 @ 消息,并按群 ID 与内容规则下发给业务插件。 叁 · 通知 通知渠道 · ctx.notify 通知入口:业务包通过 ctx.notify.send() 发送,默认发往配置的默认渠道,也可按调用指定渠道。 肆 · 委托 Agent 任务 · ctx.agentTasks 调用 dsh 已注册的 subagent provider(如 claude-code、codex)执行一次性任务:默认只读权限、每个任务独立目录、类型化的 JSON Schema 输出、并发与排队上限。 伍 · 校验 Jev 判断 · ctx.jev 调用 TypeSafe Jev 或本地部署的 Laya(二选一),返回 Choice / Noul / Score 的类型化判断和概率;一次 judge() 有严格的总时长。 陆 · 收发 飞书 · ctx.feishu 飞书机器人:发送文本或 Markdown 卡片,接收群内 @ 机器人与私聊机器人的消息并按会话分发给业务插件。 柒 · 收发 企业微信 · ctx.wecom 企业微信智能机器人:以 Markdown 发送消息,长连接接收群内 @ 机器人与单聊消息,按会话分发;可直接回复收到的消息。
默认安全
- 密钥只从环境变量、钥匙串或 dsh 凭据文件读取,不传给本包启动的任何子进程;钉钉凭据由 dws 管理。
- 来自 WebSocket 的数据和 Agent 的输出都视为不可信:Agent 默认只读、在独立的空目录中运行,输出经过 Schema 与业务白名单校验后才应触发副作用。
- 只允许
wss://,不关闭证书校验,不跟随重定向。 - 日志和错误统一脱敏,不记录鉴权头、API Key 与完整消息正文。
按需启用
七个 Service 在本包的 bundle 中以禁用状态注册。只有在 Profile 的 cordis.patch.yml 中启用的 Service 才会加载并校验配置;使用通知时启用默认渠道(钉钉、飞书或企业微信)和 notify 即可。
- id: agent-kit-ws
disabled: false
- id: agent-kit-dingtalk
disabled: false
config:
identity: user
- id: agent-kit-notify
disabled: false
config:
channel: dingtalk 装了可选的运维工具 @baoyx/dsh-agent-kit-admin 时,也可以用 setup 交互式生成这段配置,或在 dsh Web 的设置页里直接勾选。
业务包长这样
业务包只 inject 用到的 Service,协议、路由、模板和流程留在自己的代码里。发通知用 ctx.notify。
export const inject = ['agentWs', 'notify', 'agentTasks', 'jev']
export function apply(ctx: Context, config: Config) {
ctx.agentWs.connect<Frame>({
url: config.url,
headers: async () => ({ 'X-Token': await getToken() }),
onMessage: async (frame, { signal }) => {
// 委托:外部数据用 untrusted() 包裹,Agent 默认只读
const draft = await ctx.agentTasks.run<Result>({
provider: 'claude-code',
title: `classify ${frame.id}`,
prompt: [CLASSIFY_INSTRUCTIONS, untrusted('event', frame.input)],
outputSchema: ResultSchema,
signal,
})
// 校验:用 Jev 判断候选结果是否与输入相符
const { answers } = await ctx.jev.judge({
state: { input: frame.input, candidate: draft.output },
questions: { wrong: noul('候选结果与输入证据不符') },
signal,
})
// 通知:不相符时通过钉钉告警
if (answers.wrong.noul >= 0.7) {
await ctx.notify.send({ title: '需要人工复核', markdown: render(frame, draft), targets: { dingtalk: config.alertTarget }, idempotencyKey: frame.id })
}
},
})
} 三步开始
$dsh plugin --profile my-agent add @baoyx/dsh-agent-kit @baoyx/dsh-agent-kit-admin $npx @baoyx/dsh-agent-kit-admin setup --profile my-agent $npx @baoyx/dsh-agent-kit-admin doctor --profile my-agent @baoyx/dsh-agent-kit-admin 是可选的运维工具(setup、doctor 与设置页);不装它时,直接编辑 cordis.patch.yml 即可。