为什么搞这个#
DeepSeek V4 出来之后我一直在用,百万 token 上下文窗口意味着整个项目塞进去都不用分段。我就想:能不能让 Codex 吃 DeepSeek 的推理?
查了一圈,,发现有个开源项目,Moon Bridge 正好是干这事的。说白了就是个本地转发代理,把 Codex 的 OpenAI 格式请求翻译成 DeepSeek 能懂的话。
先看架构#
项目目录 → Codex CLI ↔ Moon Bridge(本地:38440)↔ DeepSeek APIMoon Bridge 就是个协议转换器,跑在本地,不存任何数据。
准备工作#
先确认环境:
node --version # 需要 20+
go version # 需要 1.25+装 Codex:
npm install -g @openai/codex去 DeepSeek 开放平台 搞个 API Key,存好。
配置 Moon Bridge#
克隆项目:
git clone https://github.com/ZhiYi-R/moon-bridge.git
cd moon-bridge根目录下建 config.yml:
mode: "Transform"
server:
addr: "127.0.0.1:38440"
models:
deepseek-v4-pro:
context_window: 1000000
max_output_tokens: 384000
default_reasoning_level: "high"
supported_reasoning_levels:
- effort: "high"
description: "High reasoning effort"
- effort: "xhigh"
description: "Extra high reasoning effort"
supports_reasoning_summaries: true
default_reasoning_summary: "auto"
extensions:
deepseek_v4:
enabled: true
deepseek-v4-flash:
context_window: 1000000
max_output_tokens: 384000
default_reasoning_level: "high"
supported_reasoning_levels:
- effort: "high"
description: "High reasoning effort"
- effort: "xhigh"
description: "Extra high reasoning effort"
supports_reasoning_summaries: true
default_reasoning_summary: "auto"
extensions:
deepseek_v4:
enabled: true
providers:
deepseek:
base_url: "https://api.deepseek.com/anthropic"
api_key: "sk-你的key" # ← 改成你的
offers:
- model: deepseek-v4-pro
- model: deepseek-v4-flash
routes:
moonbridge:
model: deepseek-v4-pro # 默认路由,后面可以在 Codex 里切换
provider: deepseek
defaults:
model: moonbridge
max_tokens: 65536踩坑提醒:api_key 那行别漏了,我第一遍就漏了,查了半天 401。
启动#
go run ./cmd/moonbridge --config config.yml看到日志输出说明起来了。默认监听 127.0.0.1:38440,暴露的接口是 /v1/responses,跟 OpenAI 的 Responses API 格式一样。
别关这个终端,开个新窗口搞下一步。
生成 Codex 配置#
CODEX_HOME_DIR="${CODEX_HOME:-$HOME/.codex}"
mkdir -p "$CODEX_HOME_DIR"
# 有老配置的话先备份
cp "$CODEX_HOME_DIR/config.toml" "$CODEX_HOME_DIR/config.toml.bak" 2>/dev/null || true
MODEL="$(go run ./cmd/moonbridge --config config.yml --print-codex-model)"
go run ./cmd/moonbridge \
--config config.yml \
--print-codex-config "$MODEL" \
--codex-base-url "http://127.0.0.1:38440/v1" \
--codex-home "$CODEX_HOME_DIR" \
> "$CODEX_HOME_DIR/config.toml"这步干了两个事:
- config.toml — Codex 的 provider 配置
- models_catalog.json — 模型能力描述,上下文窗口、推理档位这些
打开Codex进行测试 如果一切正常,Codex 发出的每个请求都会走 Moon Bridge → DeepSeek。
验证通没通#
开第三个终端(是的,有点多):
# 看模型列表
curl http://127.0.0.1:38440/v1/models
# 发条测试
curl http://127.0.0.1:38440/v1/responses \
-H "Content-Type: application/json" \
-d '{
"model": "moonbridge",
"input": "泥嚎 deepseek",
"max_output_tokens": 1024
}'
POST /v1/responses 的日志。
推理档位#
DeepSeek V4 支持多档推理,写复杂逻辑的时候挺有用。在配置里已经预置了两档:
- high — 日常够用
- xhigh — 需要深度推理的时候开
curl http://127.0.0.1:38440/v1/responses \
-H "Content-Type: application/json" \
-d '{
"model": "moonbridge",
"input": "输入的内容",
"reasoning": {"effort": "high"},
"max_output_tokens": 4096
}'踩坑记录#
| 问题 | 原因 | 怎么搞 |
|---|---|---|
connection refused | Moon Bridge 没启动或端口不对 | 看 config.yml 的 server.addr,确认进程活着 |
| Codex 不认模型 | 缺 models_catalog.json | 重新跑配置生成那一步 |
field provider not found | 配置格式老了 | 用新格式:顶层 providers / models / routes / defaults |
| 401 | API Key 不对 | 检查 key 配没配对 |
| 402 | 账户没钱了 | 去 DeepSeek 开放平台充值 |
| 图片传不进去 | 视觉功能要额外配置 | 要么配 Kimi 的视觉 Provider,要么关掉 visual 扩展 |
一点感受#
用了一周,说几个感受:
- V4 Flash 写日常代码完全够用,响应速度比 Pro 快不少,大部分场景不需要上 Pro
- 百万上下文是真的香,之前用别的模型经常写到一半忘了前面的上下文,DeepSeek 这边基本没遇到
- Moon Bridge 很稳,跑了几天没崩过,日志也干净
- 唯一不爽的是要多开一个终端,不过我已经写成脚本一键启动了(mac),也不算事
总的来说,这套组合的成本大概只有直接走 OpenAI 的十分之一,实际体验没啥差别。如果你是独立开发者或者小团队,很值得折腾一下。
start script#
#!/bin/bash
# 一键启动 Codex + Moon Bridge + DeepSeek V4
#
# 用法:
# ./start-codex-with-deepseek.sh [项目目录]
#
# 如果省略项目目录,默认当前目录。
#
set -e
PROJECT_DIR="${1:-$(pwd)}"
MOON_BRIDGE_DIR="${MOON_BRIDGE_DIR:-$HOME/moon-bridge}"
DEEPSEEK_API_KEY="${DEEPSEEK_API_KEY:-}"
# ── 颜色 ──
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log() { echo -e "${GREEN}[✓]${NC} $1"; }
warn() { echo -e "${YELLOW}[!]${NC} $1"; }
err() { echo -e "${RED}[✗]${NC} $1"; }
# ── 检查依赖 ──
check_deps() {
command -v node >/dev/null 2>&1 || { err "需要 Node.js 18+"; exit 1; }
command -v go >/dev/null 2>&1 || { err "需要 Go 1.25+"; exit 1; }
command -v codex >/dev/null 2>&1|| { err "需要 Codex CLI,装一下:npm install -g @openai/codex"; exit 1; }
log "依赖检查通过"
}
# ── 检查/拉取 Moon Bridge ──
setup_moon_bridge() {
if [ ! -d "$MOON_BRIDGE_DIR" ]; then
log "克隆 Moon Bridge 到 $MOON_BRIDGE_DIR"
git clone https://github.com/ZhiYi-R/moon-bridge.git "$MOON_BRIDGE_DIR"
else
log "Moon Bridge 已存在,跳过克隆"
fi
# 写 config.yml(如果不存在)
if [ ! -f "$MOON_BRIDGE_DIR/config.yml" ]; then
log "生成 config.yml"
cat > "$MOON_BRIDGE_DIR/config.yml" <<EOF
mode: "Transform"
server:
addr: "127.0.0.1:38440"
models:
deepseek-v4-pro:
context_window: 1000000
max_output_tokens: 384000
default_reasoning_level: "high"
supported_reasoning_levels:
- effort: "high"
description: "High reasoning effort"
- effort: "xhigh"
description: "Extra high reasoning effort"
supports_reasoning_summaries: true
default_reasoning_summary: "auto"
extensions:
deepseek_v4:
enabled: true
deepseek-v4-flash:
context_window: 1000000
max_output_tokens: 384000
default_reasoning_level: "high"
supported_reasoning_levels:
- effort: "high"
description: "High reasoning effort"
- effort: "xhigh"
description: "Extra high reasoning effort"
supports_reasoning_summaries: true
default_reasoning_summary: "auto"
extensions:
deepseek_v4:
enabled: true
providers:
deepseek:
base_url: "https://api.deepseek.com/anthropic"
api_key: "$DEEPSEEK_API_KEY"
offers:
- model: deepseek-v4-pro
- model: deepseek-v4-flash
routes:
moonbridge:
model: deepseek-v4-pro
provider: deepseek
defaults:
model: moonbridge
max_tokens: 65536
EOF
fi
# 检查 API Key
if grep -q 'sk-you' "$MOON_BRIDGE_DIR/config.yml" 2>/dev/null; then
err "config.yml 里的 API Key 还是占位符 sk-you…-key,请改成你的 DeepSeek Key"
err "设置环境变量:export DEEPSEEK_API_KEY=sk-xxx,然后重新运行"
exit 1
fi
log "Moon Bridge 配置就绪"
}
# ── 启动 Moon Bridge ──
start_moon_bridge() {
if lsof -i :38440 >/dev/null 2>&1; then
warn "38440 端口已被占用,Moon Bridge 可能已经在跑"
return
fi
log "启动 Moon Bridge(监听 :38440)"
cd "$MOON_BRIDGE_DIR"
go run ./cmd/moonbridge --config config.yml &
MOON_PID=$!
cd - >/dev/null
# 等它起来
for i in $(seq 1 10); do
if lsof -i :38440 >/dev/null 2>&1; then
log "Moon Bridge 已就绪"
return
fi
sleep 1
done
err "Moon Bridge 启动超时,检查日志"
exit 1
}
# ── 生成 Codex 配置 ──
gen_codex_config() {
local codex_home="${CODEX_HOME:-$HOME/.codex}"
mkdir -p "$codex_home"
# 备份
[ -f "$codex_home/config.toml" ] && cp "$codex_home/config.toml" "$codex_home/config.toml.bak"
local model
model="$(cd "$MOON_BRIDGE_DIR" && go run ./cmd/moonbridge --config config.yml --print-codex-model)"
(cd "$MOON_BRIDGE_DIR" && go run ./cmd/moonbridge \
--config config.yml \
--print-codex-config "$model" \
--codex-base-url "http://127.0.0.1:38440/v1" \
--codex-home "$codex_home" \
> "$codex_home/config.toml")
log "Codex 配置已生成到 $codex_home/config.toml"
}
# ── 启动 Codex ──
start_codex() {
if [ ! -d "$PROJECT_DIR" ]; then
err "项目目录不存在:$PROJECT_DIR"
exit 1
fi
log "进入项目目录:$PROJECT_DIR"
cd "$PROJECT_DIR"
log "启动 Codex(按 Ctrl+C 退出)"
echo ""
codex
}
# ── 清理 ──
cleanup() {
if [ -n "$MOON_PID" ]; then
warn "关闭 Moon Bridge (PID $MOON_PID)"
kill "$MOON_PID" 2>/dev/null || true
fi
}
trap cleanup EXIT
# ── 开始 ──
echo ""
echo "╔══════════════════════════════════════╗"
echo "║ Codex + DeepSeek 一键启动 ║"
echo "╚══════════════════════════════════════╝"
echo ""
check_deps
setup_moon_bridge
start_moon_bridge
gen_codex_config
start_codex相关链接: