我给 DeepSeek Harness 写了个插件,把免费网页版变成了 Agent 引擎


本篇为介绍,具体使用安装教程地址: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 test 9/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 辅助整理,内容基于真实开发过程。


DeepSeek 免费网页版接入 dsh 保姆级教程

数据结构第一章:算法时间复杂度分析和算法设计的基本方法

评 论