本地代理 · 开源 · 零侵入

让 ZCode 不再被 WAF 误拦

一个本地反向代理,在请求到达第三方 API 供应商之前,自动改写 ZCode 注入的 git 上下文等触发内容审查的 prompt 片段。改写规则完全可配置,SSE 流式透传,自带可视化管理台。

$ npx @honlnk/zcode-prompt-sanitizer
快速开始 了解问题 查看源码

问题

WAF 误拦截是什么?

当你在 ZCode 中使用第三方 API 供应商(如腾讯 Copilot / WorkBuddy)时,在 git 项目里发任何消息都会被拦截,返回"检测到敏感内容"。这不是你的内容有问题——是 WAF 的误报。

ZCode 在 git 项目中自动注入 system prompt:
│ "Main branch (you will usually use this for PRs): master"

ZCode ──► 第三方 WAF ──✕── 模型
     "you will usually use this for PRs" 被误判为 prompt 注入
     请求被直接拦截,模型根本没处理(tokens = 0)
根因:ZCode 每次请求前在内存里把 git 上下文拼进 system prompt。腾讯 WAF 对 "you will usually use this for PRs" 做了模式匹配,误判为越狱语句。跨 6 个 git 项目、2 个不同模型全部复现。

排查路径

方案

本地代理 · 自动改写 · 流式透传

zcode-prompt-sanitizer 运行在 ZCode 和供应商之间,拦截请求、改写触发词、转发到真实上游——模型仍然能看到分支名,WAF 不再触发。

ZCode ──► [sanitizer :18790] ──► 供应商 (copilot.tencent.com)
                      
                       ├─ 解析 JSON 请求体
                       ├─ 对 system 消息做精确字符串替换
                       ├─ 重建请求体并转发
                       └─ SSE 响应逐 chunk 透传,不缓冲

核心特性

🛡️

精确改写

纯字符串匹配(非正则),只改 system 角色内容,不误改用户消息。可配置 scopes 扩展到其他角色。

SSE 流式透传

响应用 pipe 逐 chunk 流式转发,不缓冲完整响应。流式模型输出保持实时。

🎛️

可视化管理台

自带 Dashboard 网页,实时查看匹配统计,在线增删改规则,改动即时生效并持久化。

⚙️

规则可配置

YAML 配置文件定义匹配/替换规则,不硬编码。内置默认规则覆盖已知触发词。

🐳

双部署方式

npm 全局安装或 Docker 容器部署,配置统一存放在 ~/.zcode-prompt-sanitizer/

🔒

只绑本地

默认绑定 127.0.0.1,纯本地工具不暴露到网络。管理台不做鉴权,不过度设计。

规则

改写规则

规则是纯字符串匹配——在 system 消息内容中搜索 match 子串,替换为 replacement。所有匹配项都会被替换,规则按顺序执行可链式生效。

内置默认规则

触发 Main branch (you will usually use this for PRs): 安全 Default git branch:
触发 main branch (you will usually use this for PRs): 安全 Default git branch:
模型仍能看到分支名:改写后 Default git branch: master 保留了分支信息,只是去掉了触发 WAF 的句式。功能不受影响。

自定义规则示例

# ~/.zcode-prompt-sanitizer/config.yaml
rules:
  - id: redact-internal-token
    enabled: true
    scopes: [system, user]
    match: "INTERNAL-TOKEN-"
    replacement: ""           # 空字符串 = 删除匹配项

  - id: custom-waf-trigger
    enabled: true
    scopes: [system]
    match: "某些触发WAF的句子"
    replacement: "安全的表述"
字段必填说明
id唯一标识,用于统计/日志
match要匹配的字面量子串(非正则)
replacement替换文本,空字符串表示删除
scopes作用角色,默认 ["system"]
enabled是否启用,默认 true

使用

三步接入

需要 Node.js ≥ 18。无需克隆仓库,开箱即用。

1. 安装并启动代理

# 全局安装
npm install -g @honlnk/zcode-prompt-sanitizer

# 启动(内置默认规则,开箱即用)
zps

# 或临时运行
npx @honlnk/zcode-prompt-sanitizer
# docker compose
docker compose up -d

# 或纯 docker
docker run -d --name zps \
  -p 18790:18790 \
  -v "$PWD/config.yaml:/data/config.yaml" \
  honlnk/zcode-prompt-sanitizer

2. 创建配置文件

# ~/.zcode-prompt-sanitizer/config.yaml
port: 18790
host: 127.0.0.1

upstreams:
  # 把请求转发到腾讯 Copilot(唯一的 upstream 会自动路由,无需额外 header)
  workbuddy:
    target: https://copilot.tencent.com/v2
    changeHost: true

3. 修改 ZCode 的 provider 地址

在 ZCode 设置里,把供应商的 Base URL 从真实地址改成代理地址:

改之前:https://copilot.tencent.com/v2
改之后:http://127.0.0.1:18790/v2
API Key 不变。
完成!现在 ZCode 的请求会先经过代理改写触发词,再转发到腾讯。在 http://127.0.0.1:18790/__zps__ 可以打开管理台查看实时匹配统计。

CLI 参数

参数环境变量默认值说明
--config <path>ZPS_CONFIG配置文件路径
--port <n>ZPS_PORT18790监听端口
--host <addr>ZPS_HOST127.0.0.1绑定地址
--verboseZPS_VERBOSE=1打印每个请求的日志
--no-dashboardZPS_DASHBOARD=0关闭管理台