GA 伪装 Claude Code 全流程 SOP(通用脱敏版)

下载 .md

GA 伪装 Claude Code 全流程 SOP

SophHub 分享版:仅包含机制、排错经验与通用 9 工具映射口径;已移除本机增强工具映射、真实 token/session/device/account/capture 内容。部署前请按自己的 assets/tools_schema.jsonga.py do_* 重新校验。

来源与验证:本 SOP 基于当前 claude-max-proxy/proxy.pytool_name_mapping.json、脱敏后的真 CC/GA capture 样本 以及 L4 会话索引片段整理;写入前已用 py_compile、函数级构造测试、最新 capture diff 验证过关键行为。禁止写入易变 session/PID/时间戳/token。

目标

让 GenericAgent/GA 的 Anthropic /v1/messages 出口尽量贴近 Claude Code/CC,同时不破坏 GA 工具调用:

  • GA 入站工具名/参数仍由 GA 正常使用。
  • proxy 出站请求伪装为 CC headers/body/system/tools。
  • 上游响应中的 CC 工具名需映射回 GA/OC 工具名,避免工具调用链断裂。
  • identity/session 贴近 CC 行为,但不硬编码历史会话 ID。

当前组件与路径

  • 代理目录:claude-max-proxy/
  • 核心代理:claude-max-proxy/proxy.py
  • 工具映射:claude-max-proxy/tool_name_mapping.json
  • 真 CC MITM 样本:脱敏后的真 CC MITM 样本
  • GA/proxy 出站样本:脱敏后的 GA/proxy 出站样本
  • 默认端口:PORT=5678
  • 默认 upstream:https://api.anthropic.com
  • dry-run capture 目录:CAPTURE_DIR,默认 captures

已实现的 proxy 伪装点

1. dry-run 默认关闭

proxy.py 当前逻辑:

DRY_RUN = os.environ.get("DRY_RUN", "0").lower() in ("1", "true", "yes", "on")

含义:

  • 默认真实转发 upstream。
  • 只有显式 DRY_RUN=1/true/yes/on 才短路保存 capture。
  • 旧安全默认曾是 dry-run 开启;现在为便于真实联调已关闭。

2. CC 版本与 User-Agent 伪装

detect_cc_version()claude --version 获取主版本;.cc_build 可缓存 build 号;CC_VERSION 形如 2.x.x/<build>

headers 中伪装:

  • user-agent: 优先复用真 CC capture 的 user-agent,否则 fallback 为 claude-cli/{CC_VERSION} (...)
  • x-app: fallback cli
  • anthropic-dangerous-direct-browser-access: fallback true
  • anthropic-version: fallback 2023-06-01
  • X-Stainless-Lang: fallback js
  • X-Stainless-OS: 本机 OS 名
  • X-Stainless-Arch: 本机架构
  • X-Stainless-Runtime: fallback node
  • 可选透传真 CC capture 中的 X-Stainless-Package-VersionX-Stainless-Runtime-VersionX-Stainless-TimeoutX-Stainless-Retry-Count

注意:UA suffix 在样本中不是绝对固定;历史分析里 GA 默认 suffix 曾是 controlled,可改成更贴近 CC 的值,但不要假定唯一常量。

3. 认证与 cch/billing header

当前 proxy 用本机 ~/.claude/.credentials.json 取 access token,出站:

  • 需要同时写入认证相关 header;示例中必须使用占位符,禁止发布真实 token。

anthropic-beta fallback:

claude-code-20250219,oauth-2025-04-20,interleaved-thinking-2025-05-14,context-management-2025-06-27,prompt-caching-scope-2026-01-05,effort-2025-11-24

x-claude-code-client-sha256 / CCH:

  • CCH_SEED = 0x6E52736AC806831E
  • inject_system_and_cch() 会基于最终 body 字节计算 CCH,并写入 headers。
  • 历史核对过 CC 源码/gist 与 GA 当前算法;不要随意改算法。
  • billing 相关 header 在已收集 CC 样本中未出现;用户曾怀疑可能与缓存读取相关,但已有缓存样本不支持该推断。不要凭空补 billing header,需先抓到真 CC 证据。

4. session 行为:进程/会话级随机,header 与 metadata 同步

真 CC 多样本显示:同一会话内 X-Claude-Code-Session-Idmetadata.user_id.session_id 固定且相等;不同会话随机变化。当前 proxy 应模拟为“进程启动生成一次 UUID,会话内复用”。

当前规则:

  • proxy 启动时生成一次 SESSION_ID = str(uuid.uuid4())
  • build_headers()X-Claude-Code-Session-Id = SESSION_ID
  • sync_metadata_session(body, session_id)metadata.user_id.session_id = header session_id
  • 不要硬编码历史 CC 的 session_id。
  • 验证时看两点:
    • 同一 proxy 进程多次 build_headers() session 一致。
    • capture 中 header session 与 metadata session 相等。

5. metadata.user_id identity

当前最终规则:

  • device_id:复用最新真 CC capture 的 metadata.user_id.device_id
  • account_uuid:保留 GA/proxy 入站 body 原值,不再覆盖成真 CC capture 的 account_uuid。
  • session_id:同步为当前 proxy 会话 session。

这个点经历过修正:曾短暂把 account_uuid 也覆盖为真 CC 值,但用户要求“改回原版 proxy 逻辑”,所以现在只覆盖 device_id

6. system blocks 伪装

load_latest_cc_system_blocks() 从真 CC capture 中读取 system[0:3]

inject_system_and_cch(body) 当前行为:

  • 若存在真 CC 三段 system:
    • system[0] = 真 CC system[0]
    • system[1] = 真 CC system[1]
    • system[2] = 真 CC system[2] + GA 英文 system prompt
  • 保留/继承对应 cache_control
  • 保证 body["system"] 最终为三段结构。
  • 最新 diff 验证过:
    • system[0] 完全等于原版 CC。
    • system[1] 完全等于原版 CC。
    • system[2] 以原版 CC system[2] 开头,后面追加 GA 英文 SP。
  • 历史讨论结论:不要把 GA 长 system prompt 塞到 user message;应走 system 三段形态,否则与 CC 请求形态差异大。

7. 顶层 body 参数归一化

inject_system_and_cch() 中把 body 归一到当前 CC-like 目标:

  • model = "claude-opus-4-6"
  • max_tokens = 64000
  • thinking = {"type": "adaptive"}
  • context_management = {"edits": [{"type": "clear_thinking_20251015", "keep": "all"}]}
  • output_config.effort = "max"
  • stream 保留入站/配置值;历史讨论认为 CC 也可 false,因此 stream 差异本身不一定异常。

历史分析:

  • 真 CC 在不同参数/模型下可能没有 thinking 字段;GA 的 controlled/thinking/context 由 GA Native 配置与 beta 能力控制。
  • 不要只为了贴近某个样本盲删 thinking/context_management/output_config,需确认不会破坏当前模型能力。

8. tool name 双向映射与参数适配

tool_name_mapping.json 必须使用当前 GA 实际工具名作为本地侧 key;每个 value 必须唯一;不要再使用旧 OC 名如 exec/read/edit/write/sessions_*,否则反向映射会把模型 tool_use 还原到 ga.py 不存在的 do_*,报未知工具。

通用/原版 GA 9 个实际工具 direct 映射建议:

  • code_run -> Bash
  • file_read -> Read
  • file_patch -> Edit
  • file_write -> Write
  • web_scan -> WebFetch
  • web_execute_js -> WebSearch
  • update_working_checkpoint -> TodoWrite
  • ask_user -> AskUserQuestion
  • start_long_term_update -> TaskUpdate

SophHub/通用分享版只保留原版 GA 9 工具映射;本机增强工具(如后台 Agent/Skill 类工具)不纳入通用表,除非对方环境明确实现了对应 do_*

关键边界:

  • sessions_send/sessions_run/sessions_list/sessions_history 是历史旧名,只能在回程兜底中回收,禁止再暴露到当前工具 schema。
  • AskUserQuestion 只能回收为 ask_user;不要让旧 sessions_send -> AskUserQuestionask_user -> AskUserQuestion 同时参与普通反向 dict 生成,否则后者/前者覆盖会导致未知工具。
  • proxy 路径:CC_TO_OC = {v:k ...} 后必须 update(LEGACY_TO_OC),让旧/借用名只在模型输出回程时归一化。
  • llmcore 内置伪装路径也要同步 _CC_SEMANTIC_ALIASES_CC_LEGACY_TO_GA,否则绕过 proxy 或本地路径仍会复发。
  • llmcore 工具 schema 需兼容两种形态取名/设名:顶层 {"name": ...} 与 OpenAI 风格 {"function": {"name": ...}}

proxy/llmcore 回程不能只做字符串替换;必须结构化处理普通 JSON 与 SSE 流式 chunk 中的 tool_use

已验证的参数适配:

  • Bashcode_runcommandscript,默认补 type="powershell"cwd="./"
  • Readfile_readfile_pathpathoffsetstartlimitcount
  • Editfile_patchfile_pathpathold_stringold_contentnew_stringnew_content
  • Writefile_writefile_pathpathcontentnew_content
  • ga.pyfile_write 已兼容 args.content / args.file_text;否则 Claude Code 风格 Write(content=...) 回来但没有 <file_content> 标签时会失败。

排错信号:若伪装 GA 日志出现 Tool: exec / 未知工具: exec / 未知工具: sessions_send,优先检查:映射表是否仍有旧 OC/sessions key;alias value 是否重复;响应回程是否结构化处理 SSE JSON;AskUserQuestion/sessions_send 是否都被归一化成 ask_userBash(command=...) 是否被适配为 code_run(script=...)

9. capture 与 diff 验证

每次改伪装后至少做以下验证:

  1. py_compile.compile("claude-max-proxy/proxy.py", doraise=True);若改了 GA 工具兼容,也编译 ../ga.py;若改了内置伪装路径,也编译 ../llmcore.py
  2. 工具集合验证:从 assets/tools_schema.json 读取当前 GA 实际工具名,确认 tool_name_mapping.json 的 direct key 与 schema 完全一致、value 全唯一、无 sessions_* 暴露名。
  3. 函数级验证:
    • build_headers() 连续调用 session 一致。
    • sync_metadata_session() 后 device/account/session 符合规则。
    • inject_system_and_cch() 后 system 三段、顶层参数、CCH 写入。
    • 工具回程映射:AskUserQuestion 与旧 sessions_send 都应变为 ask_userBash(command=...) 最终应变为 code_run(script=..., type="powershell", cwd="./")Read/Edit/Write(file_path=...) 最终应变为 file_read/file_patch/file_write(path=...)
    • llmcore 内置伪装:_cc_disguise() 输出工具名应为当前唯一 alias 集合;顶层 name schema 与 function.name schema 都能改名。
  4. 如用户要求“不要外网测试”,只能做本地验证:精确重启 proxy 后确认 PORT=5678 监听;可访问本地 / 看 Flask 存活,但不要请求会转发 upstream 的 /v1/messages
  5. 需要真实联调时再发真实 GA 请求或 dry-run 请求。
  6. 对比:
    • mitm_cc_captures/latest.json
    • 脱敏后的 GA/proxy 出站样本

建议 diff 关注字段:

  • headers:
    • authorization/x-api-key 只确认存在和脱敏形态,禁止记 token。
    • user-agent
    • anthropic-beta
    • anthropic-version
    • X-Claude-Code-Session-Id
    • x-claude-code-client-sha256
    • stainless headers
  • body:
    • model
    • max_tokens
    • stream
    • thinking
    • context_management
    • output_config
    • metadata.user_id.device_id/account_uuid/session_id
    • system[0:3]
    • tools[].name
    • messages 数量与内容:真 CC 长会话 vs GA 测试请求不同属预期差异。

10. 进程操作注意

重启 proxy 时禁止无条件杀全部 python;只杀 cmdline/cwd 命中 claude-max-proxy/proxy.py 的精确进程。

示例思路:

  • 枚举 psutil.process_iter(['pid','cmdline','cwd'])
  • 匹配 proxy.py 且 cwd 为 .../claude-max-proxy
  • terminate 等待;必要时再 kill 精确 PID。
  • 用当前 Python/venv 启动 pythonw.exe proxy.py 或等价命令。
  • 重启后确认 proxy.py 进程存在。

当前最新 diff 结论模板

符合预期时应看到:

device_id_equal_orig: True
account_uuid_equal_orig: False  # 因保留 GA/proxy 入站 account_uuid
header_meta_session_equal: True
session_equal_orig: False       # 因当前会话随机,不复用历史 CC session
system[0] equal true
system[1] equal true
system[2] startswith orig true + append GA English SP
top-level model/max_tokens/thinking/context_management/output_config match target

预期差异:

  • messages_count 常不同:真 CC capture 可能是长会话,GA 测试可能只有 1 条。
  • tools 集合可能不同:GA 当前工具集与真 CC clean 9 工具不同;只要映射与回程能闭环,不必强行删到完全相同,除非用户明确要求且验证工具不坏。

SophHub 分享前脱敏清单

发布到 SophHub 前只分享机制与最小补丁思路,禁止包含本机隐私和可复用凭据:

  • 删除/替换本机绝对路径、用户名、PID、端口占用日志、真实 capture 文件名中的会话标识。
  • 禁止发布 authorizationx-api-key、cookie、token、真实 account_uuid、真实 device_id、真实 session_id
  • capture/diff 只保留字段名、是否相等、脱敏后的形态;不要贴完整请求体,尤其不要贴用户消息、项目源码、长 system prompt 全文。
  • 可以公开的核心经验:工具 alias 必须一对一唯一;历史旧名只做回程归一化不暴露;普通 JSON 与 SSE 都要结构化 remap;proxy 与 llmcore 两条路径要同时维护;改后必须编译、离线映射测试、精准重启并验证端口。
  • 若仓库里包含 mitm_cc_captures/captures/、日志、.env、临时任务输出,发布前用脚本扫描关键词:authorization|x-api-key|cookie|session|account_uuid|device_id|Bearer|sk-

已知 gap / 不要误判

  • prompt 完全改成 CC 可能影响 GA 能力;当前策略是 CC system[0:2] + CC system[2] 前缀 + GA 英文 SP 追加。
  • tools 数量未必等于 clean CC 的 9 个;历史中 9/11/48 来源不同,需按实际 capture 与当前工具注册判断。
  • stream 可 true/false,单独不是强异常。
  • UA suffix 不固定,不要把某个 suffix 当唯一真值。
  • billing header 未抓到真 CC 证据前不要补。
  • session 不是硬编码;是每个 proxy 会话随机一次、会话内固定。

评论(1)

登录 后可发表评论。

@ru1 ★★★★★ 成功

目前稳定奔放2天