Skip to content

docs(usage): CLIProxy 首次使用 + 模型路由 + 负载均衡 + 熔断配置(#167 Phase 2 PR4)#181

Merged
g1331 merged 1 commit into
masterfrom
docs/phase2-usage-batch-2
May 23, 2026
Merged

docs(usage): CLIProxy 首次使用 + 模型路由 + 负载均衡 + 熔断配置(#167 Phase 2 PR4)#181
g1331 merged 1 commit into
masterfrom
docs/phase2-usage-batch-2

Conversation

@g1331
Copy link
Copy Markdown
Owner

@g1331 g1331 commented May 23, 2026

Summary

补齐 Phase 1 漏掉的第 8 篇 + Phase 2 使用侧 3 篇,共 4 篇,每段断言都带 src/...:line 引用。

  • docs/guide/usage/cliproxy-first-time.md — CLIProxyAPI 首次使用指南:实例表字段 / 登记 UI / 连通性测试四态判定 / OAuth 三 provider 流程 / 池上游按 provider 自动预设 route_capabilities 与 base_url 后缀 / Codex 与 Claude Code CLI 的 profile 升级触发条件 / 踩坑速查
  • docs/guide/usage/model-routing.md — 模型路由规则:8 种 RouteCapability + 协议族匹配 + CLI profile 升级;model_rules / model_redirects / allowed_models 三字段关系与向后兼容;filterCandidatesByModelRules 「未显式拒绝即默认放行」精确语义;旧版 getProviderTypeForModel 已不再影响主路由选路;客户端 Key allowed_models 与上游 model_rules 两层叠加
  • docs/guide/usage/load-balancing.md — 负载均衡与权重:weight + priority 字段语义、performTieredSelection 分层过滤顺序、selectWeightedWithHealthScore 加权随机叠加延时分(latencyPenalty 封顶 0.5)、延时数据来源(health-checker 单次 RTT、非滑动平均)、会话亲和 TTL(5 分钟滑动 / 30 分钟绝对)、熔断与并发槽位过滤
  • docs/guide/usage/circuit-breaker-config.md — 熔断器配置:状态机一句话回顾(详细行为引用 docs/circuit-breaker.md)/ 上游级 6 个阈值字段(API 秒 / DB 毫秒双单位)/ upstream_failure_rules 抑制熔断计数但不阻止 failover 的语义 / circuit_breaker_states 持久化语义(重启不重置 OPEN)/ Admin force-open / force-close 接口 / 与 failover 的关系

事实校验

所有断言由 Explore 子代理直接读源码采证,重点校验:

  • RouteCapability 枚举位置与升级触发条件
  • selectWeightedWithHealthScorelatencyPenalty / score / effectiveWeight 三步计算
  • filterCandidatesByModelRules 的「未显式拒绝即默认放行」三种情形
  • recordFailure 与 failure rule 的协同:matchedFailureRule === null 才计入熔断
  • CLIProxy is_webui=true 自动追加位置与三 provider 端点表

关于 issue todo

Phase 1 task list 中「撰写第一批 10 篇文档」实际是 9/10(漏了 cliproxy-first-time),本 PR 合入后即补齐 10/10;issue body 已同步对齐。

Test plan

  • pnpm docs:build 通过(首轮因表格内裸 <N> 被 vue compiler 当作未闭合 HTML 元素而失败,已用反引号包裹修复)
  • pnpm format:check 通过
  • pre-commit 钩子通过
  • Docs CI(PR workflow)
  • 人工 review 四篇正文事实准确性

按既定规则:CI 通过即停,不自合并,等 review。

补齐 Phase 1 漏掉的第 8 篇 + Phase 2 使用侧 3 篇,4 篇均做了源码采证、
每段断言带 file:line 引用:

- `docs/guide/usage/cliproxy-first-time.md` — CLIProxyAPI 首次使用指南:
  实例表字段、登记 UI、连通性测试四态判定、OAuth 三 provider 流程、池上游
  按 provider 自动预设 route_capabilities 与 base_url 后缀、客户端 CLI
  profile 升级触发条件、踩坑速查
- `docs/guide/usage/model-routing.md` — 模型路由规则:
  RouteCapability 8 种 + 协议族匹配 + CLI profile 升级;model_rules /
  model_redirects / allowed_models 三字段关系与向后兼容;
  filterCandidatesByModelRules 「未显式拒绝即默认放行」精确语义;旧版
  getProviderTypeForModel 已不再影响主路由选路;客户端 Key
  allowed_models 与上游 model_rules 两层叠加规则
- `docs/guide/usage/load-balancing.md` — 负载均衡与权重:
  weight + priority 字段语义、performTieredSelection 分层过滤顺序、
  selectWeightedWithHealthScore 加权随机叠加延时分(latencyPenalty 封顶
  0.5)、延时数据来源(health-checker 单次 RTT、非滑动平均)、
  会话亲和 TTL(5 分钟滑动 / 30 分钟绝对)与不可用降级语义、
  熔断与并发槽位过滤
- `docs/guide/usage/circuit-breaker-config.md` — 熔断器配置:
  状态机一句话回顾(详细行为引用 docs/circuit-breaker.md)、
  上游级 6 个阈值字段(API 秒 / DB 毫秒双单位)、
  upstream_failure_rules 抑制熔断计数但不阻止 failover 的语义、
  circuit_breaker_states 持久化语义(重启不重置 OPEN)、
  Admin force-open / force-close 接口、与 failover 的关系

VitePress 构建小坑:cliproxy-first-time 表格里裸 `<N>` 占位符被 vue
compiler 当作未闭合 HTML 自定义元素,已用反引号包裹修复。
@g1331 g1331 merged commit ef7295e into master May 23, 2026
14 checks passed
@g1331 g1331 deleted the docs/phase2-usage-batch-2 branch May 23, 2026 13:14
g1331 added a commit that referenced this pull request May 23, 2026
* docs(usage): fill cliproxy-modes + cliproxy-egress-proxy (#167)

承接 PR #181 的 CLIProxyAPI 首批文档,补齐两篇姊妹篇:

- cliproxy-modes:以源码事实(cliproxy-instance-crud.ts 的 validateInstanceAddress
  分支)阐明 managed/external 的真实差异(SSRF 校验、URL 校验、地址填法),
  纠正 enabled 字段「关闭即停摆」的误印象(实际任何调度代码都不读 enabled),
  说明删除实例时上游记录 onDelete:set null 的副作用。
- cliproxy-egress-proxy:拆清三方责任——AutoRouter 自身不支持出站代理
  (proxy-client.ts 直接用 Node fetch),全局 CLIPROXY_PROXY_URL 通过
  docker-compose env → docker-entrypoint.sh → config.yaml.template 注入
  CPA 容器,账号粒度 proxy_url 经管理 API PATCH /v0/management/auth-files/fields
  下发;并说明两者优先级、生效时机差异、external 模式下 .env 失效。

Phase 2 使用侧进度 4/9 → 6/9,剩余:logs-stats、request-recording、troubleshooting。

* docs(usage): fix three review findings on PR #182 (#167)

P2 cliproxy-modes 删除行为:原文档说删除实例时外键 set null 会让上游记录
保留并继续按 base_url 直发;实际上 deleteCliproxyInstance
(cliproxy-instance-crud.ts:290-320) 在 SQL 删除前会先校验缓存账号与上游引用,
任一存在即抛 CliproxyInstanceInUseError,路由层返 HTTP 409。
onDelete: set null 仅在数据被绕过应用层删除时兜底。改为给出正确的三步
删除顺序(先上游、再账号、最后实例),并强调没有强制删除开关。

P2 cliproxy-modes SSRF 校验:原文档暗示 external 模式能拦截所有指向私有
地址的请求;实际上 isUrlSafe (upstream-ssrf-validator.ts:69-94) 在 hostname
不是 IP 字面量时直接 safe: true、不查 DNS。补一个 warning 说明 SSRF 防护
只对 IP 字面量生效,对 cpa.internal 这种内网域名即使解析到 192.168.x.x
也会通过;同时把校验差异表加一列「域名解析到私有 IP」以体现该限制。

P3 cliproxy-egress-proxy 配置路径:docker-entrypoint.sh:12 默认把渲染后的
config.yaml 写到 /CLIProxyAPI/config.yaml,而非原文档写的 /app/config/config.yaml。
更新校验命令路径,并提醒可以被 CLIPROXY_CONFIG_TARGET 覆盖。

* docs(usage): sync ASCII diagram with SSRF-limit warning (#167)

「一图看懂」框图里仍写「external 拒绝私有/内网/loopback/元数据」,与下文的
SSRF 仅在 IP 字面量生效的 warning 矛盾。改为「拒绝私有/loopback IP 字面量」
以避免误导读者认为 cpa.internal 也会被拦。

* docs(usage): fix three review findings round 2 on PR #182 (#167)

P2 IPv6 SSRF:原 warning 把限制描述为「只对 IP 字面量生效」,但实测
new URL("http://[::1]/").hostname === "[::1]"(保留方括号),正则
/^[\d.:]+$/ 不匹配,IPv6 字面量同样走「普通域名」分支被 safe: true。
也就是说仅 IPv4 字面量会被拦,IPv6 字面量 + 域名都通过。修正 warning、
表格列分拆为「IPv4 字面量 / IPv6 字面量 / 域名解析到私有 IP」三列,明确
external 模式无法挡住 [::1] / [fc00::1] / [fe80::1] 等。

P2 账号删除步骤:原文档让用户去管理后台账号列表点「删除按钮」,但当前账号
子路由([accountName]/route.ts + status + upstream)都没导出 DELETE,
UI 也只有启停/编辑字段/映射上游三个动作,没有删除账号的 AutoRouter 操作。
改为说明唯一可行路径:在 CPA 侧删 auth-file → 触发 sync → 同步逻辑
(cliproxy-auth-account-service.ts:189-197)会把本地 cliproxy_auth_accounts
中 CPA 侧已不存在的行 db.delete 清掉;并补 CPA 不可达时直接操作表的兜底。

P3 cliproxy-first-time enabled 描述:first-time 文档字段表里仍写
「关闭后所有依赖该实例的池上游不可用」,与 modes 章节里「任何调度代码都
不读 enabled」直接矛盾。同步纠正为「仅作管理后台标识,不参与路由 / 调度」,
并引用 modes 文档作为详细说明。

* docs(usage): fix two review findings round 3 on PR #182 (#167)

P2 docker compose restart:原文档建议 `docker compose restart cliproxyapi`
让 CPA 重新读 .env,但实际上 restart 只是重启已有容器,env 仍是容器创建
时捕获的旧值。改为推荐用叠加文件再次 up -d(compose 检测到 env 变化会
自动重建容器),并给出显式 --force-recreate 的替代写法;同时同步「校验
方法」一节的引用文案。

P3 managed→external 校验:原文档说切到 external 时「内网地址」会被校验
失败。这与已经修正过的 SSRF 限制矛盾——isUrlSafe 不查 DNS、不拦 IPv6
字面量、不拦域名,只有 IPv4 字面量为私有/loopback/链路本地时才被拦。
http://cliproxyapi:8317 这种服务名能通过校验。改为:只有内网 IPv4 字面量
会被拦,但服务名/域名虽能通过校验,切到 external 后仍不可达,因此切 mode
时仍应同步改地址,「校验通过」不是判定能切的依据。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant