DeepSeek Harness 生产级最佳实践
一、生产级 Harness 运行时全景
DeepSeek Harness(以下简称 DSH)的生产部署,核心不是「把 Web UI 跑起来」,而是把 Agent = Model + Harness 这一等式在可控边界内长期稳定运行。Harness 侧负责 Cordis 插件生命周期、工具管道、Session 事件溯源与安全审批;Model 侧负责推理。生产事故往往发生在 Harness 层:Profile 混用、Teardown 遗漏、审批矩阵空洞、Session 磁盘打满、Token 预算失控。
| 平面 | 生产关注点 | 常见失误 |
|---|---|---|
| 控制面 | Bundle / Profile / Patch 版本锁定 | 生产误用 Creator 或评测 Minimal |
| 数据面 | Session Log 保留与压缩 | 无归档策略导致磁盘满 |
| 执行面 | 工具审批、沙箱路径 | 审批矩阵只有「允许/拒绝」两档 |
| 观测面 | OTel trace + 业务指标 | 只看模型延迟不看工具失败率 |
二、Profile 分离:评测 Minimal vs 生产 Standard
2.1 为什么要分离 Profile
DSH 提供 Standard、Code、Minimal、Creator 四种预设 Bundle。它们不是「UI 皮肤」,而是不同的工具图谱、审批策略与 Token 预算默认值的集合。生产环境最常见的架构失误是:用 Minimal 做线上对话(工具不足导 致任务失败),或用 Creator 做批量评测(权限过大且不可复现)。
原则:评测路径与生产路径必须使用不同 Profile,且通过 Patch 显式声明差异,而非在运行时手工切换。
2.2 Minimal 评测 Profile 设计要点
Minimal 预设的设计目标是低 Token、少工具、可重复。适用于:回归基准、插件挂载 smoke test、CI 中的 Harness 集成测试。生产级 Minimal Profile Patch 建议:
| 配置项 | 评测 Minimal 建议值 | 说明 |
|---|---|---|
| 工具集 | 仅保留 read_file、list_dir 等只读工具 | 避免写操作污染评测环境 |
| 审批 | 全自动通过(仅评测机) | 减少人工变量 |
| Session 保留 | 7 天或 CI 产物归档 | 评测 Session 可丢弃 |
| 模型 | 固定型号与 temperature | 保证基准可比 |
| 并发 | 单 Session 串行 | 避免资源争抢扭曲指标 |
实操步骤:
- 在仓库中维护
profiles/eval-minimal.patch.yaml,与profiles/prod-standard.patch.yaml分目录存放。 - CI 流水线只加载
eval-minimal;staging / production 加载prod-standard或prod-code。 - 在 预设对比实验室 录制同一任务的 Minimal vs Standard 对比截图,作为团队 onboarding 材料。
2.3 生产 Standard Profile 设计要点
Standard 是大多数对话与轻量工具场景的默认生产 Profile。生产 Patch 应明确:
- 工具白名单:按业务域分组(文件、网络、MCP 外部工具)。
- 审批默认值:写操作、网络出站、子 Agent Spawn 需分级审批。
- 上下文压缩阈值:长会话触发 summarization 的 token 水位线。
- Creator 插件禁用:生产 Standard Bundle 不得挂载 Creator 高权限插件。
2.4 Code Profile 的边界
Code Profile 面向仓库操作与开发辅助。生产上建议独立实例或独立命名空间,与面向终端用户的 Standard 隔离,避免开发工具(如 shell、git push)进入用户会话图谱。
2.5 常见误区
| 误区 | 后果 | 纠正 |
|---|---|---|
| 「Minimal 更省 Token,生产也用」 | 任务完不成,用户反复追问 | 生产用 Standard,Minimal 仅评测 |
| 「Creator 功能多,staging 也用 Creator」 | staging 成为权限突破口 | Creator 仅隔离沙箱 + 人工监督 |
| Profile 切换不写 Patch | 配置漂移、无法回滚 | 一切差异进版本库 Patch |
三、Teardown 纪律:可逆副作用的生产契约
Cordis 插件通过 ctx.effect() 注册可逆副作用。生产环境中 Teardown 遗漏 会导致:内存泄漏、文件句柄耗尽、重复注册工具、幽灵 MCP 连接。这是 DSH 与「一次性脚本」框架的本质区别之一。
3.1 Teardown 检查清单
每个 ctx.effect() 必须回答以下问题:
- 注册了 event listener?→ Teardown 中
removeListener - 打开了 MCP 连接?→ Teardown 中
close()/disconnect() - 创建了定时器?→ Teardown 中
clearInterval - 写入了临时目录?→ Teardown 中清理或使用 scoped temp
- 向全局工具表注册?→ Teardown 中注销
- 修改了 process 级 handler?→ Teardown 中恢复
// 生产级插件 Teardown 示例
export default {
name: "prod-mcp-bridge",
apply(ctx) {
const clients: MCPClient[] = [];
ctx.effect(() => {
const client = connectMCP(process.env.MCP_URL!);
clients.push(client);
ctx.provide("externalTools", client.listTools());
return () => {
clients.forEach((c) => c.close());
clients.length = 0;
};
});
},
};
3.2 热重载与滚动升级
生产滚动升级时,旧实例卸载插件必须完整 Teardown,否则新旧版本可能同时持有 MCP 连接。建议:
- 优雅关闭:SIGTERM 时先停止接受新 Session,等待进行中工具完成,再卸载 Bundle。
- 健康检查:卸载后检查连接数、内存是否回落(见 技能实验室泄漏调试)。
- Code Review:见本文第十二节插件检查表。
3.3 Teardown 与 Session 的关系
Session Log 记录 的是对话与工具调用事件,不替代插件 Teardown。即使 Session 已归档,泄漏的 MCP 连接仍占用进程资源。运维告警应同时看 Session 数 与 进程级连接数。
四、审批矩阵设计:从二元到分级
工具执行管道支持审批策略。生产级审批不是「全开」或「全关」,而是分级矩阵:按工具类型、路径前缀、命令模式、用户角色四维决策。
4.1 审批矩阵模板
| 工具 / 操作 | 风险等级 | 默认策略 | 生产 override | 审计字段 |
|---|---|---|---|---|
read_file 沙箱内 | 低 | 自动通过 | 自动通过 | path, session_id |
write_file 沙箱内 | 中 | 首次确认 | 白名单路径自动 | path, hash |
write_file 沙箱外 | 高 | 拒绝 | 拒绝 | — |
shell 只读命令 | 中 | 模式匹配 | allowlist regex | cmd |
shell 写/网络 | 高 | 人工审批 | 双人或工单 | cmd, approver |
spawn_agent | 高 | 人工审批 | 配额 + 审批 | parent, child_profile |
| MCP 外部工具 | 中-高 | 按 server 分级 | server 级策略 | mcp_server, tool |
4.2 设计原则
- 默认拒绝出站网络:仅 MCP 白名单 server 可访问外网。
- 命令 allowlist 优于 blocklist:
rm -rf类 blocklist 永远不全。 - 审批结果写入 Session Log:满足合规审计与 Replay 复盘。
- 与 Creator 隔离:Creator Profile 的审批矩阵应更严而非更松。
在 安全与审批模拟器 中预演矩阵变更,再推生产 Patch。
4.3 常见误区
- 误区:「内部系统不需要审批。」→ 模型幻觉可能构造危险工具参数,审批防的是模型而非用户。
- 误区:「审批通过一次就永久信任。」→ 应 Session 级或 time-boxed 授权,见 Session 策略。
五、沙箱边界:诚实声明而非营销话术
DSH 文件系统沙箱限制 Agent 工 具的读写路径。生产文档与对用户承诺必须诚实声明边界:沙箱防的是误操作与模型越界,不是防恶意插件或已攻破的运行时。
5.1 沙箱能做什么、不能做什么
| 能力 | 沙箱内 | 沙箱外 / 需知 |
|---|---|---|
| 限制 read/write 路径 | ✅ 可配置根目录 | 符号链接、挂载绕过需额外加固 |
| 隔离多租户 Session | ✅ 每 Session workspace | 共享卷需 OS 级权限 |
| 阻止任意 shell | ⚠️ 依赖工具注册与审批 | Creator + shell 可突破 |
| 防恶意 npm 插件 | ❌ 非沙箱职责 | 供应链审查 + 镜像签名 |
| 防 API Key 泄露 | ❌ 需密钥管理 | 环境变量 + Vault |
诚实声明示例(可放入对外 SLA 附录):
本服务 Agent 文件操作默认限制在
/data/sessions/{id}/workspace。不包含对宿主机其他路径的强安全保证。Creator 模式与 shell 工具未启用。如需更高隔离级别,请联系开通独立容器实例。
5.2 生产沙箱加固清单
- workspace 根目录按 Session ID 隔离,禁止
../逃逸(路径规范化) - 只读挂载系统配置与插件目录
- 禁止或严格审批
shell、git push、网络 fetch(非 MCP) - 容器以非 root 运行,readOnlyRootFilesystem where possible
- 定期扫描 Session workspace 异常大文件或外传模式
详见 开发指南 · 工具与安全。
六、Creator 隔离:高权限模式的生产禁令
Creator 预设提供更高权限的工具集,适合受控创作环境。生产默认应禁用 Creator,或仅在独立集群 + 网络隔离 + 人工监督下短期开启。
6.1 Creator 隔离架构
| 控制项 | 用户生产 | Creator 隔离区 |
|---|---|---|
| 网络 egress | MCP 白名单 | 更严或完全离线 |
| 文件系统 | Session workspace | 专用卷,定期 wipe |
| 审批 | 分级矩阵 | 全人工 |
| 日志保留 | 标准策略 | 延长 + 不可篡改存储 |
| 实例生命周期 | 长期 | 短生命周期 VM |
6.2 误用 Creator 的事故模式
- 批量任务脚本挂载 Creator Bundle → 模型一次调用删除大量文件
- 「为了方便调试」在生产 Profile Patch 中启用 Creator 插件 → 权限持久化
- Creator Session 与用户 Session 共用存储 → 横向数据泄露
规范:Creator 相关 Patch 文件命名必须含 creator,CI 禁止将该 Patch 部署到 production 命名空间。
七、Session Log 保留策略
Session Log 是 append-only 事件流,支撑 Resume、Fork、Replay 与审计。生产必须定义保留周期、归档格式、删除合规三要素。
7.1 分级保留建议
| Session 类型 | 热存储 | 温归档 | 冷删除 | 备注 |
|---|---|---|---|---|
| 普通用户对话 | 30 天 | 180 天 S3/OSS | 按合规 | 含 PII 需脱敏 |
| Code 开发辅助 | 14 天 | 90 天 | 可更短 | 可能含代码片段 |
| 评测 Minimal | 7 天 | 可选 | 30 天 | 无 PII 优先 |
| Creator / 高敏 | 90 天 | 1-3 年 | 法务审批 | WORM 存储 |
7.2 磁盘与性能
- Compaction:历史事件段合并,保留 fork 指针
- 索引:按 session_id、user_id、created_at 建索引,避免全目录扫描
- 配额:单 Session 大小上限,超限触发压缩或拒绝新工具大 payload
- 监控:磁盘使用率 >80% 告警,>90% 自动归档最旧热数据
7.3 Fork 与合规
Fork 产生新 Session 分支,保留策略应继承源 Session 分类。Replay 用于事故复盘时,只读挂载归档,避免重放时再次执行写工具(Replay 沙箱模式)。
八、OpenTelemetry 指标:生产可观测性基线
DSH 可集成 OpenTelemetry 导出 trace 与 metrics。生产至少应采集以下信号,并接入现有 Prometheus / Grafana / Jaeger 栈。
8.1 推荐指标清单
| 指标名 | 类型 | 标签 | 用途 |
|---|---|---|---|
dsh.session.active | Gauge | profile, instance | 活跃 Session 数 |
dsh.tool.calls.total | Counter | tool, result, profile | 工具调用量与成功率 |
dsh.tool.latency.ms | Histogram | tool | 工具延迟 P99 |
dsh.model.tokens | Counter | model, direction | Token 消耗 |
dsh.model.latency.ms | Histogram | model | 模型 RTT |
dsh.approval.pending | Gauge | — | 待审批积压 |
dsh.plugin.mount.errors | Counter | plugin | 插件挂载失败 |
dsh.session.log.bytes | Gauge | — | Log 体积 |
8.2 Trace 跨度设计
一次用户消息处理链建议 span:session.message → model.completion → tool.execute(可多个)→ context.compress。在 trace 中标注 profile、session_id(哈希)、tool_name,便于定位「哪类 Profile 工具失败率高」。
8.3 告警规则示例
rate(dsh.tool.calls.total{result="error"}[5m]) / rate(dsh.tool.calls.total[5m]) > 0.05→ 工具错误率超 5%dsh.approval.pending > 100持续 10m → 审批积压dsh.session.log.bytes增长率异常 → 可能 Log 膨胀攻击或压缩失效
九、上下文压缩策略
长 Session 中历史消息与工具输出累积导致 Token 成本上升与上下文窗口溢出。DSH 支持上下文压缩策略,生产需显式配置而非依赖模型默认。
9.1 压缩触发条件
| 策略 | 触发条件 | 行为 | 适用 |
|---|---|---|---|
| 水位线压缩 | token > 70% 窗口 | 摘要早期轮次 | Standard 对话 |
| 工具输出裁剪 | 单次 tool output > N KB | 保留摘要 + 哈希 | Code Profile |
| 滑动窗口 | 保留最近 K 轮 | 丢弃更早 | Minimal 评测 |
| 结构化归档 | 检测到 plan 完成 | 将 plan 存 Session 元数据 | 多 Agent |