本篇为介绍,具体使用安装教程地址:https://coldish.cn/post/29
起因
用 DeepSeek Harness(dsh)跑 Agent 任务很爽,但官方 API 按量计费,跑复杂任务时 token 消耗不低。而 DeepSeek 网页版是免费的,模型能力也不差。
于是我冒出一个想法:能不能把网页版包装成一个标准的 LLM Provider,让 Harness 像调用 API 一样驱动网页版?
经过几周迭代,这个插件已经稳定运行,支持全自动闭环、三种审核模式、MCP 工具扩展,以及前端可视化配置。这篇文章记录它的设计思路和关键技术实现。
一、整体架构
┌─────────────────────────────────────────────────┐
│ DeepSeek Harness │
│ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│ │Agent Loop│ │ Tools │ │ Session │ │
│ └────┬─────┘ └────┬─────┘ └──────────────┘ │
│ │ │ │
│ ┌────▼─────────────▼─────┐ │
│ │ LlmAdapter 接口 │ │
│ │ deepseek-official(API) │ │
│ │ deepseek-web(本插件) │ │
│ └──────────┬─────────────┘ │
└─────────────┼───────────────────────────────────┘
│
┌──────────▼──────────┐
│ deepseek-web 插件 │
│ ┌────────────────┐ │
│ │ 协议注入/解析器 │ │
│ └───────┬────────┘ │
│ ┌───────▼────────┐ │
│ │ Playwright 驱动 │ │
│ │ 真实 Edge 窗口 │ │
│ └───────┬────────┘ │
└──────────┼───────────┘
│
┌──────────▼──────────┐
│ chat.deepseek.com │
│ (免费网页版) │
└─────────────────────┘
核心思路:插件只实现 LlmAdapter.stream(),把 Harness 的请求翻译成网页提示词,再把网页回答解析回 StreamChunk。 Harness 的 agent loop、工具系统、会话管理完全复用,零改动。
二、关键技术实现
1. JSON 动作协议
网页版模型没有原生 tool calling。所以插件通过系统提示词约定了一个文本协议:
需要调用工具时只输出这个 JSON;任务完成时直接输出正文。response.ts 负责把自由文本解析回结构化动作。
2. SSE 碎片重组
DeepSeek 网页版的流式响应是碎片化的:先是 fragments 数组整段 upsert,随后是 JSON Pointer 补丁({"p":"response/fragments/-1/content","o":"APPEND","v":"..."}),还有只有 v 的连续增量。
插件实现了一个补丁状态机,按 fragment id 去重、按顺序拼接,最终重建出完整回复。
3. 浏览器常驻 + CDP 连接
不做无头浏览器,不做浏览器扩展。插件驱动一个真实有头 Edge 窗口,通过 CDP 连接:
- 浏览器由独立守护进程
browser-keeper.mjs启动,dsh 重启不影响它 - 使用
spawn启动(而非 Playwright 的launch()),规避navigator.webdriver标记 - 独立 profile 放在工作区外(
%LOCALAPPDATA%\DeepSeekWebAgent),避免 Agent 误读浏览器内部文件
4. 上下文卫生
免费通道的上下文有限,做了几层优化:
- 按需注入协议:只在首轮或格式漂移时注入完整协议
- 工具白名单:默认只暴露 7 个核心工具,过滤掉需要独立 API Key 的
web_search - 结果截断:工具结果超过 6000 字符按头尾截断
- 任务锚点:每轮重申
[当前用户任务],防止模型反问“请提供任务”
5. 上下文检查点
单个网页对话超过阈值(默认 12 轮 / 12 万字符)时,在网页弹出卡片,让用户选择“开启新对话继续”或“保持当前对话继续”。这是缓解超长上下文退化的关键机制。
三、可选审核通道
交付前可以开启审核,三种模式可选:
| 模式 | 特点 |
|---|---|
| DeepSeek 自审 | 同一对话内追加审核指令,不开新窗口、不复制内容,快但独立性弱 |
| Kimi 审核 | 独立窗口、独立上下文,更严格,但需要人工点击发送 |
| GLM 审核 | 通过 API 接入,无需人工点击,速度快 |
审核结论以 {ok, issues, suggestions} 格式返回。不通过时,审核意见回注 DeepSeek 要求修正,最多 maxRounds 轮。
四、全自动 vs 半自动
插件支持两种发送模式:
半自动(推荐):插件填入消息,由用户手动点击发送。保留真人操作特征,风控风险极低。
全自动:插件填入消息后模拟回车发送。速度快、稳定性好,但拆掉了“人工点击”这道护城河,行为节奏呈现程序化特征。
两种模式可以通过配置切换。日常开发用全自动,重要账号或敏感操作用半自动。
五、前端可视化配置
设置页集成了:
- 审核开关 / 审核器选择 / 审核轮数
- 工具白名单直接勾选,即时生效
- 发送模式切换
之前改工具白名单要手动编辑 cordis.yml 再重启,现在前端直接操作,无需重启。
六、MCP 工具扩展
通过 @deepseek-ai/dsh-mcp-client 连接 MCP 服务器,第三方工具自动注册为 mcp__<服务器名>__<工具名>。
例如连接 TapTap Maker 后,模型可以使用:
mcp__taptap-maker__generate_image
mcp__taptap-maker__text_to_dialogue
mcp__taptap-maker__batch_sound_effects
需要注意:MCP 工具描述通常较长,全部暴露会让工具清单臃肿,建议按任务类型动态调整白名单。
七、实测结果
用这套系统跑了一个完整的 TaskFlow 项目(Node.js + TypeScript 任务管理系统,16 个文件),8 个里程碑全部一次通过:
tsc --noEmit零类型错误npm test9/9 测试通过- CLI、REST API、Web 前端全部可运行
- Kimi 审核全程自动触发,结论准确
八、对官方仓库的改动面
- 新增:
scratch-plugin/(插件全部内容) - 修改:根
package.json+pnpm-lock.yaml(新增playwright-core依赖) - 修改:
packages/client/ui-settings-plugins下的设置卡片(新增审核配置 UI) - 其余:
packages/、apps/、vendor/官方代码零改动
这意味着官方 Harness 更新时,只需要 git pull,插件依然兼容。
九、已知限制
- 网页端可能遗忘早期细节(Harness 侧不丢,可重读文件恢复)
- 超长上下文下会退化,检查点机制是缓解而非根治
- 自审独立性与严格性弱于独立审核
- 全自动模式存在风控风险,重要账号建议半自动
十、总结
这个插件做了一件事:把 DeepSeek 免费网页版“伪装”成标准 LLM Provider,接入 Harness 的 agent 框架。
它通过真实浏览器 + JSON 文本协议 + 会话游标 + 上下文检查点,让 Harness 的 agent loop 能无缝驱动网页版对话,同时提供本地安全审查、可选审核和 MCP 工具扩展,且对官方仓库侵入极小。
如果你也在用 DeepSeek Harness,想降低 API 成本,或者想探索“网页版 + Agent”的可能性,这个插件值得一试。
本文由 AI 辅助整理,内容基于真实开发过程。