Bridge API 是什么?

本地运行的 AI Provider Runtime —— 一个 API,连接所有 AI 网页

Bridge API 是什么?

1. 概述与定位

Bridge API 是一个运行在用户本机的 AI Provider Runtime。它对外提供统一的 OpenAI Compatible API/v1/chat/completions/v1/models),并在内部通过 Chrome 扩展把请求转发给已经登录的 DeepSeek 网页。账号、Cookie 与项目文件全程不离开本机,Bridge 不保存账号、不代理账号、不托管 Cookie。

它“不是”什么 它“是”什么
不是 DeepSeek 官方 API(无需 API Key) AI Provider Runtime,DeepSeek 只是第一个 Provider
不是单纯浏览器插件(插件只控制网页) 本地文件系统 / Git 能力的受保护网关
不是一个被绑定的模型(Provider 无关) 让任意 OpenAI 客户端直接调用浏览器里的 AI

核心设计原则:Provider 无关、本地优先、开放接口、模块化扩展、最小权限。所有项目读取、Git 分析、上下文构建均在本地完成。

2. 系统架构

Bridge API 由三层组成:左侧任意 OpenAI 客户端、中间本地 Runtime、右侧浏览器与本地项目。Runtime 是唯一的“大脑”,所有业务逻辑都收敛在这里;浏览器扩展只是 DOM 控制终端,Native Host 是最小权限的文件系统代理。

关键解耦点:扩展不持有文件系统权限,文件访问要么由 Runtime 直接执行(当前 MVP),要么经由 Native Host 的白名单协议;浏览器侧只负责把 Prompt 写进网页、把回答读出来,业务规则(鉴权、队列、路径安全、工具解析)全部在 Runtime 完成。

3. 技术栈与工程结构

项目是一个 npm workspaces 单仓(monorepo),包含 apps/*packages/*providers/* 三组包。运行时直接以 node --experimental-strip-types 执行 TypeScript(Node 22+),无需构建步骤;类型检查用 tsc --noEmit

bridge-api/
├── apps/
│   ├── runtime/        # 核心 Runtime 入口(src/index.ts, server.ts, config.ts)
│   │   └── public/     # 本地图形控制台(index.html / app.js / styles.css)
│   ├── cli/            # bridge CLI(纯 HTTP 客户端)
│   ├── extension/      # Chrome MV3 扩展(background.js, content.js, popup.*)
│   └── native-host/    # 最小权限 Native Messaging Host(协议骨架)
├── packages/
│   ├── protocol/       # 类型契约:ChatMessage, ChatDelta, Provider, BrowserCommand/Event
│   ├── provider-manager/  # Provider 注册、切换、健康检查
│   ├── browser-bridge/    # Runtime ↔ 扩展的命令/事件桥
│   ├── agent-engine/      # 多轮代码代理 + 工具协议解析
│   ├── context-engine/    # ripgrep 检索 + 上下文构建
│   ├── project-engine/    # 多项目管理、路径保护、读写替身脱敏
│   ├── tool-engine/       # 工具执行、待批准变更
│   ├── git-engine/        # git status / diff 封装
│   ├── security-engine/   # 敏感路径判定、密钥脱敏
│   ├── queue/             # 单任务串行队列
│   └── shared/            # createId / toErrorMessage / expandHome
├── providers/
│   └── deepseek/       # DeepSeekWebProvider(实现 Provider 契约)
├── tests/              # core.test.ts(node --test)
├── PRD.md  README.md  progress.md  package.json  tsconfig.json

packages/* 之间是显式的依赖关系(通过相对 ../../packages/xxx/src/index.ts 导入),运行时由 apps/runtime/src/index.ts 统一实例化并注入:

const browser   = new BrowserBridge();
const projects  = new ProjectEngine(config.workspace, config.projects);
const git       = new GitEngine();
const providers = new ProviderManager([new DeepSeekWebProvider(browser)], config.provider);
const context   = new ContextEngine(projects, git);
const tools     = new ToolEngine(projects, context, git);
const agent     = new AgentEngine(providers, projects, tools);
const server    = createRuntimeServer({ config, browser, providers, projects, context, git, queue, tools, agent });

4. 一次对话请求的完整生命周期

所有请求进入 createRuntimeServer 的单一 Node http 处理器。下面以 POST /v1/chat/completions 为主线,展示从鉴权到 SSE 输出的全过程。

SSE 通道约定:模型正文走 data: 帧;Bridge 内部状态(队列位置、心跳)走 注释帧 : bridge-status ...,避免被 OpenAI 客户端误并入回答。OpenAI 客户端会把每个 data: 帧当作模型输出,因此内部状态必须放在注释帧里,只有图形控制台会读取并展示。

5. 多轮本地代码代理

当请求被判定为“代码请求”(bridge.mode=code 或末条消息命中 code|repo|项目|文件|修改|… 等关键词)时,AgentEngine 接管,进入一个最多 16 轮的工具循环。核心目标是让网页版 DeepSeek 既能“读”本地项目,又不会未经授权地改文件。

实现要点:

  • 状态页面复用:DeepSeek 网页本身是有状态的会话,所以每一轮只把“最新工具结果 / 修复指令”发给网页,绝不回放完整对话历史(否则它会重复回答早期问题)。见 providers/deepseek/src/index.tspromptForWebConversation
  • 协议自愈:若 DeepSeek 返回的工具指令不符合规范,Agent 会把它作为 assistant 消息连同修复提示再发一次,最多修复 2 次;仍失败则拒绝执行、不做任何文件修改。
  • 去重:模型可能在同一回答里以“规范信封 + 渲染兼容形式”重复同一动作,uniqueToolCalls 只执行一次,但会保留刻意不同的多次 Edit。
  • 写保护:Write/Edit 在默认配置下只生成“待批准变更”;仅当项目开启 autoApplyWrites 才直接落盘。

6. BRIDGE TOOL PROTOCOL V1

网页版模型无法直接调用函数,只能生成文本。Bridge 约定模型在需要工具时输出一个“信封”,Runtime 解析后本地执行。为兼容不同模型的输出风格,解析器支持多种形态(见 agent-engineparseToolCalls):

支持的信封格式

  • <bridge_tool>…</bridge_tool>
  • [[BRIDGE_TOOL]] … [[/BRIDGE_TOOL]]
  • `Calling:```json ```
  • Tool: … Arguments: {…}
  • Action: … Action Input: {…}
  • 【调用 xxx】{…} 本地化形式
  • <Glob>…</Glob> 等 XML 标签
  • <tool_call name="…">

规范信封(推荐)

[[BRIDGE_TOOL]]
{"name":"Write","arguments":{
  "path":"index.html",
  "content":"<!doctype html>..."
}}
[[/BRIDGE_TOOL]]

可用工具:Glob Read Grep Git_Status Git_Diff Write Edit。名称大小写敏感;Write 需非空 path+content;Edit 需 path+old_string+new_string。

工具分发表(ToolEngine.execute)

工具名(含别名) 底层动作 越界 / 敏感保护
Glob / list_files / list_directory ripgrep --files(失败回退 Node 递归) 过滤 node_modules/.git/敏感文件,限 300 条
Read / read_file / cat ProjectEngine.read 敏感文件返回 [REDACTED],输出限 80KB
Grep / search / search_files ContextEngine.search(ripgrep) 同 Glob
Git_Status / Git_Diff / diff GitEngine(git) 必须在项目根
Write / write_file / propose_write ToolEngine.proposeWrite 生成待批准变更(或直写),限 1MB
Edit / replace / replace_text ProjectEngine.replaceText 精确单处匹配,否则报错

7. Provider 抽象与 DeepSeek Web Provider

所有 AI 网页都通过统一的 Provider 契约接入(定义于 packages/protocol):

interface Provider {
  readonly id: string;
  readonly model: string;
  health(): Promise<ProviderStatus>;
  stream(request: ChatCompletionRequest, signal: AbortSignal): AsyncIterable<ChatDelta>;
}

ProviderManager 持有已注册 Provider 的映射,提供 active 访问器、switch(id)status()。当前仅注册 DeepSeekWebProvider,但切换到 ChatGPT/Claude/Gemini 等无需改动其它模块——这正是“Provider 无关”的体现。

DeepSeekWebProvider 的工作方式

  • 发 prompt:调用 browser.enqueuePrompt(provider, prompt),把消息压入命令队列,并返回异步事件流。
  • 读回答:从扩展 POST 回来的 BrowserEventdelta / complete / error)逐帧 yield 为 ChatDelta
  • 超时保护:首字超时(默认 75s)与单轮超时(默认 120s)通过 AbortController 中断;若页面有输出但读完无正文,提示刷新页面。
  • 健康health() 仅看扩展是否连上,不检查账号有效性。

8. 浏览器扩展与 Runtime 通信协议

Runtime 与 Chrome 扩展之间是一个 长轮询 + 事件回传 的 HTTP 协议(不依赖 WebSocket,部署更简单):

扩展侧实现细节:background.js 以约 400ms 间隔轮询 /bridge/browser/commands/next,拿到命令后定位 chat.deepseek.com 标签页,转发给 content.jscontent.js 负责在 DOM 中找到输入框(textarea#chat-input 或 contenteditable)、注入文本、点击发送按钮,并轮询页面直到回答稳定,再把 delta/complete 事件回传。选择器集中在 content.js,便于在 DeepSeek 改版时单点修复。

9. 安全模型

Bridge 的信任边界是 “本地、显式授权、最小权限”。所有文件 / Git 访问都经过以下层层关卡:

  • 路径越界保护ProjectEngine.resolvepath.resolve 后强制要求绝对路径以项目根开头,../outside 直接抛错。
  • 敏感文件拦截isSensitivePath 命中 .env**.pem/*.key/*.p12 时,读取返回 [REDACTED],写入直接拒绝。
  • 密钥脱敏redactapi_key / token / secret / password / authorization / cookie / private_key / jwt = … 的值替换为 [REDACTED],模型看到的是脱敏文本。
  • 写需审批:默认 Write/Edit 只生成待批准变更,需在控制台点击“批准并写入”才修改磁盘;开启 autoApplyWrites 的项目才会直写。
  • 尺寸上限:单文件写入 / 编辑拒绝超过 1MB 的内容。
  • 配置权限~/.bridge-api/config.json0o600 仅当前用户可读写;环境变量 BRIDGE_* 在下次启动时优先于已保存配置。

10. 模块清单

职责 关键类型 / 方法
packages/protocol 跨模块类型契约 ChatMessage ChatDelta Provider BrowserCommand BrowserEvent
packages/provider-manager Provider 注册/切换/健康 ProviderManager.active/switch/status
packages/browser-bridge 命令队列 + 事件桥 BrowserBridge.enqueuePrompt/waitForCommand/accept
packages/agent-engine 多轮代码代理 + 协议解析 AgentEngine.stream parseToolCalls validToolCall
packages/context-engine ripgrep 检索 + 上下文构建 ContextEngine.search/build
packages/project-engine 多项目、路径保护、读写 ProjectEngine.add/read/write/replaceText/tree/resolve
packages/tool-engine 工具执行、待批准变更 ToolEngine.execute/applyChange/discardChange
packages/git-engine git 封装 GitEngine.status/diff
packages/security-engine 敏感判定与脱敏 isSensitivePath redact
packages/queue 单任务串行队列 SingleTaskQueue.run/status
packages/shared 通用工具 createId toErrorMessage expandHome
providers/deepseek DeepSeek Web Provider DeepSeekWebProvider.health/stream
apps/runtime Runtime 入口 + HTTP 服务 + 控制台 createRuntimeServer loadConfig/saveConfig
apps/cli 纯 HTTP 客户端 bridge doctor|providers|ask|search|diff
apps/extension Chrome MV3 扩展 background.js content.js popup.*
apps/native-host 最小权限文件/Git 代理(骨架) 白名单 action:project.add / file.read / file.tree / git.*

11. API 速查

方法 路径 用途
GET /v1/models 列出当前模型(如 deepseek-web
POST /v1/chat/completions 对话补全(支持 OpenAI SSE;bridge.mode/projectKey 扩展字段)
GET/POST/DELETE /bridge/projects 管理本地项目
POST /bridge/search · /bridge/context 检索 / 构建上下文
POST /bridge/git/status · /bridge/git/diff Git 信息
POST /bridge/file/read · /bridge/file/tree 安全读取项目文件
GET/POST/DELETE /bridge/changes · …/:id/apply 查看 / 批准 / 丢弃待写入变更
GET/POST /bridge/providers · /bridge/provider/* Provider 状态与切换
GET/POST /bridge/config 读取 / 保存本地 Runtime 配置
GET /bridge/health Runtime 健康状态
GET /bridge/browser/commands/next 扩展长轮询拉取指令
POST /bridge/browser/events 扩展回传浏览器事件

鉴权:请求头 Authorization: Bearer <token>x-bridge-token: <token>。代码任务可通过 X-Bridge-Project-Key 请求头或请求体 bridge.projectKey 指定跨机可移植的工作区。

12. 运行与验证

# 安装依赖
npm install

# 生成并导出 Bridge Token,启动 Runtime(默认 127.0.0.1:3210)
export BRIDGE_TOKEN="$(openssl rand -hex 32)"
npm run dev

# 打开控制台 http://127.0.0.1:3210/ ,输入同一 Token 即可使用图形界面

# 验证
npm test        # node --test 单元测试(provider 切换、路径/密钥防护、队列、协议)
npm run typecheck

# CLI 示例
bridge doctor                       # 健康检查
bridge providers                    # 列出 Provider
bridge ask "解释这个项目"            # 发起对话
bridge search <project> login       # 检索
bridge diff <project>               # Git diff

Chrome 扩展联调:chrome://extensions → 开发者模式 → 加载 apps/extension;粘贴 http://127.0.0.1:3210 与 Token,测试连接后登录 DeepSeek 网页,状态变为“DeepSeek 已连接”。

KEEP READING