• 去年夏天

    简而言之就是OpenCode的风控要求,Go订阅的请求必须至少包含:

    X-Opencode-Session与user-agent这两个请求头

    - user-agent:用来辨识你用的是什么agent工具,opencode协议里其实隐形要求了 Go 订阅只能用于 agent 工具,比如XXXCode,XXXHarness之类的,所以他们暗含了仅限常见agent工具调用的限制。

    - X-Opencode-Session:他们依赖该标头进行 GPU 上下文缓存,对于同一个对话,所有的多轮请求会带上同一个固定的 Session ID;而不同的对话之间,使用不同的 Session ID, 这样可以将同一个对话的请求调度到同一个 GPU 复用上一轮已经生成的显存缓存,而不用跨GPU复制KV缓存。(就是为了节省算力,省钱)

    首先去抓包一下自己的请求头

    可以用https://webhook.site/抓包。访问网页后,复制网页上为你生成的唯一链接, 将 agent工具,对应模型的 Base URL 改成这个链接(记得把你的KEY改了,不然真实Key会被抓包到),去工具里随便发一次请求,看看你的工具,正常的请求头会是什么样的。

    我发现我的agent工具会为每个对话发送x-conversation-id和acp-connection-id请求头,其中的x-conversation-id完美符合x-opencode-session的要求:不同对话间不同,同一个对话中固定,断开网络或重启也不变(acp-connection-id工具重启后会变)

    所以newapi可以在对应渠道内这样做:

    找到「渠道 - 编辑 - 请求头覆盖」填入如下json

    • 简单粗暴版(透传所有请求头+转换为X-Opencode-Session)```

    {
    "*": true,
    "X-Opencode-Session": "{client_header:x-conversation-id}"
    ``- 只透传UA和X-Opencode-Session``
    {
    "User-Agent": "{client_header:user-agent}",
    "X-Opencode-Session": "{client_header:x-conversation-id}"
    }
    ```- 更精细一点(尽可能透传没问题的请求头,隐藏可能有问题的)

    正常的agent工具,请求头可能有十几个二十几个以上,如果只发关键的,其实也在暴漏你有个中间件在改请求头。

    所以可以看看抓包里到地方发了什么,只把什么x-real-ip(真实IP)remote-host(主机名)这种会暴漏你在用中转的参数给干掉。其他的都给透传了,这样更像真实的工具请求

    主楼
  • 粥粥启

    感谢老哥,难怪我现在不能用。 弄一下这个就行了。

    #1
  • SwiftUI

    其实没必要隐藏其他参数 直接透传加一个这个就行 官方说了随便你用的 就是要给会话加一个x-opencode-session方便他们做缓存 不知道为什么他们不自己处理常见工具的sessionid 不过hermes和pi最新版本你选opencode作为提供商都是直接支持传这个参数的

    #2
  • 去年夏天

    是的,其实用“简单粗暴版”就行,

    透传所有请求头和请求体,搞出符合要求的X-Opencode-Session字段

    #3
  • SwiftUI

    还有个办法 参数覆盖可以设置请求头复制而且会忽略不存在的 所以可以设置支持多种工具```
    {
    "operations": [
    {
    "mode": "copy_header",
    "keep_origin": true,
    "from": "X-Opencode-Session",
    "to": "X-Opencode-Session"
    },
    {
    "mode": "copy_header",
    "keep_origin": true,
    "from": "Session-Id",
    "to": "X-Opencode-Session"
    },
    {
    "mode": "copy_header",
    "keep_origin": true,
    "from": "Session_id",
    "to": "X-Opencode-Session"
    },
    {
    "mode": "copy_header",
    "keep_origin": true,
    "from": "X-Conversation-Id",
    "to": "X-Opencode-Session"
    },
    {
    "mode": "copy_header",
    "keep_origin": true,
    "from": "X-Claude-Code-Session-Id",
    "to": "X-Opencode-Session"
    }
    ]
    }
    ```试了下这样设置之后cc和codex都不会报错 然后还可以在最后加一个set header做fallback这样各种sessionid都不传的客户端也能用

    #4
  • myflavor

    好方法,建议后面补充一个设置请求头,如果都没传,直接写死一个固定值

    #5

发表回复

登录后回复