一个开源的 AI Agent 网关:统一协议、统一会话、统一模型与权限,但不重造 Agent 运行时。
我们面对的现实
2026 年的 coding agent 已经很多:OpenCode 、Claude Code 、Codex CLI 、Gemini CLI……它们各自很强,但一旦你要把它们接进自己的系统,问题就来了:
- 每个 agent 只说自己的协议( Claude Code 说 Anthropic Messages ,Codex 说 OpenAI Responses ,OpenCode 是自有
/api/*); - 模型、鉴权、会话、权限、观测,全都散落在各个工具里;
- 想在它们之间切换、统一计费、统一审计,几乎要重写一遍 glue 。
Janus 想解决的就是这一层。
Janus 是什么
一句话:
Agent 负责「怎么做」,Janus 负责「谁可以怎么用」。
Janus 是一个 OpenAI / Anthropic 兼容的网关 + 控制平面:把只有 /api/* 的 OpenCode server 包装成标准 /v1/*,让各类 OpenAI / Anthropic 客户端( Trae 、CodeBuddy 、Cursor 、OpenAI SDK 、LangChain…)直接可用;同时把会话、工具、权限、用量统一管起来。
它不重造 Agent runtime 、Tool runtime 、MCP runtime 、Session runtime —— 这些交给 OpenCode 等现成的 agent ,Janus 只做控制平面该做的事。
源码与安装
项目地址: https://github.com/qist/janus( MIT 许可)
方式一:下载预编译包(推荐)
到 Releases 下载对应架构的包( amd64 / arm64 / arm / 386 ):
VERSION=v0.3.5
curl -LO https://github.com/qist/janus/releases/download/$VERSION/janus_${VERSION}_linux_amd64.tar.gz
tar xzf janus_${VERSION}_linux_amd64.tar.gz
sudo install -m 0755 janus_linux_amd64 /usr/local/bin/janus
janus --version
方式二:源码编译
git clone https://github.com/qist/janus.git
cd janus
make build # 自动注入版本号( git tag / VERSION 文件)
sudo install -m 0755 janus /usr/local/bin/janus
依赖:Go 1.23+;上游需要已安装 OpenCode(未装时 Janus 会在日志里提示安装命令)。
方式三:Docker / systemd
# Docker ( distroless 非 root 静态镜像)
docker build -t janus https://github.com/qist/janus.git
# systemd:仓库自带加固单元
# deploy/janus.service
运行
# 0. 先装 OpenCode ( Janus 的上游 agent ;未装时 Janus 会在日志里提示)
curl -fsSL https://opencode.ai/v2/install | bash
cp janus.env.example janus.env
$EDITOR janus.env # 至少设 BRIDGE_API_KEY 与 BRIDGE_DIRECTORY
./scripts/run.sh # 启动 Janus
OpenCode 不用你手动启动:Janus 启动时会自动发现已在跑的
opencode serve,没有就自己拉一个(随机端口 + 随机密码)。你只要把它装好即可 —— 所以也没有「填端口/密码」这一步。
客户端把 Base URL 指到 http://127.0.0.1:2810/v1、API Key 填 BRIDGE_API_KEY 即可,零改动; Anthropic 客户端则把 ANTHROPIC_BASE_URL 指到 http://127.0.0.1:2810。
已实现端点:/v1/models、/v1/chat/completions(流式+非流式)、/v1/completions、/v1/responses、/v1/messages( Anthropic )、/v1/usage、/v1/requests、/v1/settings、/ui、/metrics、/healthz。
三种执行模式(执行边界很清楚)
「工具在哪执行」由 BRIDGE_AGENT + BRIDGE_TOOL_CALLING 决定,按部署形态选一种:
| 模式 | 工具在哪执行 | 适合 |
|---|---|---|
native |
服务端( Janus 主机、会话目录) | 本机自用,链路最短 |
remote-tools |
客户端(走内置 MCP 工具桥) | 集中部署、代码在本地 |
none |
无工具(纯推理) | Chat / Review / 规划 |
remote-tools 里,MCP 只存在于 Janus ↔ agent 之间,对客户端始终是标准的 tool_calls / tool_use —— 客户端不用懂 MCP 。
自用配置(可直接抄)
这是我们自己在用的一份 janus.env(已脱敏,路径请改成你自己的):
# 监听与鉴权
BRIDGE_ADDR=127.0.0.1:2810
BRIDGE_API_KEY=change-me-to-a-random-secret
# 会话默认工作目录( native 模式下工具在此目录执行)
BRIDGE_DIRECTORY=/path/to/your/project
# 执行模式:remote-tools (工具在客户端执行)
BRIDGE_AGENT=orchestrator
BRIDGE_TOOL_CALLING=true
BRIDGE_PERMISSION_REPLY=once
BRIDGE_TOOL_CALL_WAIT=5m
# 上游 OpenCode:自动发现;总是自己拉起(以便注入生成的 agent 配置)
OPENCODE_URL=auto
OPENCODE_REUSE_EXTERNAL=false
# 面板 / 限流
BRIDGE_USAGE_ENABLED=true
BRIDGE_RATE_LIMIT=600
BRIDGE_RATE_BURST=120
BRIDGE_LOG_LEVEL=info
切 native 模式:
BRIDGE_AGENT=build+BRIDGE_TOOL_CALLING=false。 切 none 模式:BRIDGE_AGENT=orchestrator+BRIDGE_TOOL_CALLING=false。OPENCODE_REUSE_EXTERNAL=false让 Janus 总是自己拉起 OpenCode —— 这是「自动注入 agent 配置」生效的前提。
一个叫 janus 的虚拟模型
痛点很具体:很多 IDE 用自定义模型名时没法设置思考档位( low/high/max ),换模型还得改配置文件。
于是加了:
- 一个**虚拟模型
janus**:映射到/ui面板里选定的默认模型; - 面板「模型」页每行「设为 janus」;「思考档位」列是点选按钮组(点一下即设、当前高亮);
- 客户端/IDE 里模型名固定填
janus,换模型/换档位在面板点一下,不用改 env 、不用改客户端。
关键是切换时机:面板改完,下一条请求就原地切换( Janus 调 POST /api/session/{id}/model),不重开会话、上下文保留——不需要等会话结束,也不用新开会话。
解析优先级:面板选择(存 DB ) > BRIDGE_DEFAULT_MODEL > 上游默认。
default / 留空 仍指向上游默认(旧语义不变);真实 provider/id 仍原样透传。两个都保留,互不干扰。
配置也不用手写了
跑 remote-tools 需要一个「禁用所有内置工具、只用客户端工具」的 agent 。以前要手写 ~/.config/opencode/opencode.jsonc,问题是黑名单会随 OpenCode 版本改工具名而失效。
现在 Janus 拉起 OpenCode 时,通过 OPENCODE_CONFIG_CONTENT 自动注入自己生成的 agent 配置,而且是白名单:
{
"agents": {
"orchestrator": {
"mode": "primary",
"permissions": [
{ "action": "*", "resource": "*", "effect": "deny" }, // 禁掉所有内置工具
{ "action": "execute", "resource": "*", "effect": "allow" }, // Code Mode 必需
{ "action": "ob-*", "resource": "*", "effect": "allow" } // 只放行工具桥的客户端工具
]
}
}
}
不再手写、不怕版本改名、也不覆盖你自己的配置。
可观测:不用开官方 console
/v1/requests + /ui 提供逐条请求的缓存命中率、思考 token 、耗时、费用,支持搜索/排序/分组汇总。面板拆成了 用量 / 最近请求 / 模型 / 运行 几个标签页。
Token 统计同时给出 OpenAI 的 prompt_tokens_details.cached_tokens 与 DeepSeek 风格的 prompt_cache_hit_tokens / prompt_cache_miss_tokens。
结语
如果你也在把各种 coding agent 往自己的系统里接,欢迎试试 Janus:它不替你造 agent ,只把 agent 管好。
(本文对应版本:v0.3.5 。)