|
Download README.md from li2895/ima2api: direct link, hf CLI and curl.
- Browser
- Download file 11.5 kB
-
https://huggingface.co/spaces/li2895/ima2api/resolve/main/README.md
- Command line
-
hf download hf://spaces/li2895/ima2api/README.md
-
curl -L -o README.md https://huggingface.co/spaces/li2895/ima2api/resolve/main/README.md
11.5 kB
| title: ima2api | |
| emoji: 🚀 | |
| colorFrom: blue | |
| colorTo: indigo | |
| sdk: docker | |
| sdk_version: "1.0.0" | |
| app_port: 7860 | |
| pinned: false | |
| # ima2api | |
| 逆向 IMA App 的 AI API,封装为 **OpenAI Chat Completions** 和 **Anthropic Messages** 兼容格式,支持 **tool calling**(prompt 注入方式)。 | |
| 一次抓包即可,之后都会自动刷新cookie。 | |
| ## 快速开始 | |
| ```bash | |
| cd ima2api | |
| npm install | |
| python3 ima_runner.py | |
| ``` | |
| ## 配置 | |
| 编辑 `config.json`: | |
| ```json5 | |
| { | |
| "server": { "port": 8080, "host": "0.0.0.0" }, | |
| "auth": { | |
| // 从 IMA App 抓包获取的完整 Cookie | |
| "cookie": "IMA-GUID=...;IMA-TOKEN=...;...", | |
| "refresh_token": "抓包https://ima.qq.com/auth_login/refresh请求获取", | |
| "registration_id": "抓包https://ima.qq.com/auth_login/refresh请求获取" | |
| }, | |
| "api_keys": ["sk-ima-demo-key-change-me"], | |
| "default_model": "glm-5.2" | |
| } | |
| ``` | |
| ### 获取 Cookie | |
| 1. 手机安装 IMA App,QQ/微信登录 | |
| 2. 配置 HTTPS 代理(mitmproxy / Charles / Fiddler) | |
| 3. 发送任意消息,复制请求中的 `x-ima-cookie` 值 | |
| 4. 填入 `config.json` → `auth.cookie` | |
| 5. 将 https://ima.qq.com/auth_login/refresh 这条请求里的refresh_token和registration_id也填入config.json (用于自动刷新cookie) | |
| ## API 端点 | |
| ### OpenAI 兼容 (`/v1`) | |
| ```bash | |
| # 模型列表 | |
| curl http://localhost:8080/v1/models -H "Authorization: Bearer YOUR_KEY" | |
| # 普通对话 | |
| curl http://localhost:8080/v1/chat/completions \ | |
| -H "Authorization: Bearer YOUR_KEY" \ | |
| -H "Content-Type: application/json" \ | |
| -d '{"model":"glm-5.2","messages":[{"role":"user","content":"你好"}]}' | |
| # 流式 | |
| curl http://localhost:8080/v1/chat/completions \ | |
| -H "Authorization: Bearer YOUR_KEY" \ | |
| -d '{"model":"glm-5.2","messages":[{"role":"user","content":"你好"}],"stream":true}' | |
| # Tool calling | |
| curl http://localhost:8080/v1/chat/completions \ | |
| -H "Authorization: Bearer YOUR_KEY" \ | |
| -d '{ | |
| "model":"glm-5.2", | |
| "messages":[{"role":"user","content":"执行 uname -a"}], | |
| "tools":[{ | |
| "type":"function", | |
| "function":{"name":"Bash","description":"执行命令","parameters":{"type":"object","properties":{"command":{"type":"string"}},"required":["command"]}} | |
| }], | |
| "tool_choice":"auto" | |
| }' | |
| # Tool 结果回传 (多轮) | |
| curl http://localhost:8080/v1/chat/completions \ | |
| -H "Authorization: Bearer YOUR_KEY" \ | |
| -d '{ | |
| "model":"glm-5.2", | |
| "messages":[ | |
| {"role":"user","content":"执行 uname -a"}, | |
| {"role":"assistant","tool_calls":[{"id":"call_1","type":"function","function":{"name":"Bash","arguments":"{\"command\":\"uname -a\"}"}}]}, | |
| {"role":"tool","tool_call_id":"call_1","content":"Linux ..."} | |
| ] | |
| }' | |
| ``` | |
| ### Anthropic 兼容 (`/v1`) | |
| ```bash | |
| # 流式对话 | |
| curl http://localhost:8080/v1/messages \ | |
| -H "Authorization: Bearer YOUR_KEY" \ | |
| -d '{"model":"glm-5.2","max_tokens":1024,"messages":[{"role":"user","content":"你好"}],"stream":true}' | |
| # Tool use | |
| curl http://localhost:8080/v1/messages \ | |
| -H "Authorization: Bearer YOUR_KEY" \ | |
| -d '{ | |
| "model":"glm-5.2", | |
| "max_tokens":1024, | |
| "messages":[{"role":"user","content":"执行 pwd"}], | |
| "tools":[{"name":"Bash","description":"执行命令","input_schema":{"type":"object","properties":{"command":{"type":"string"}},"required":["command"]}}] | |
| }' | |
| ``` | |
| ## Tool Calling 机制 | |
| 采用 **prompt 注入** 方式实现 function calling: | |
| ``` | |
| ## CRITICAL — YOU MUST USE FUNCTION CALLING | |
| <function name="Bash"> | |
| <description>执行 bash 命令</description> | |
| <parameters>{"type":"object","properties":{"command":{"type":"string"}},"required":["command"]}</parameters> | |
| </function> | |
| ## HOW TO CALL A FUNCTION | |
| 输出 <function_call>{"name":"...","arguments":{...}}</function_call>,然后立即停止。 | |
| ``` | |
| 工作流: | |
| 1. 客户端发送 `tools` 参数 → 服务器将工具定义注入 prompt | |
| 2. IMA 模型输出 `<function_call>…</function_call>` → 服务器解析为 `tool_calls` / `tool_use` 返回 | |
| 3. 客户端本地执行工具 → 将结果回传 | |
| 4. 服务器检测到 `tool_use` + `tool_result` → 用 `⚠️ 系统通知` 格式告知模型结果 | |
| 5. 模型基于结果直接回答用户 | |
| 特性: | |
| - 最多展示 8 个工具(截断保护) | |
| - Schema 自动压缩(去掉 `$schema`/`$defs`/`$ref` 等元数据) | |
| - 自动检测中文用户 → 要求中文回复 | |
| - 会话自动复用(基于首条消息 hash) | |
| ## 可用模型 | |
| | 模型 ID | 底座 | 说明 | | |
| |---------|------|------| | |
| | `glm-5.2` | GLM-5.2 | 默认 | | |
| | `glm-5.2-think` | GLM-5.2 | 思考模式 | | |
| | `deepseek-v4-flash` | DeepSeek V4 | 快速 | | |
| | `deepseek-v4-flash-think` | DeepSeek V4 | 思考模式 | | |
| | `hy3-preview` | 混元 Hy3 | 预览 | | |
| | `hy3-preview-think` | 混元 Hy3 | 思考模式 | | |
| ## 认证 | |
| - `Authorization: Bearer <key>` 或 `x-api-key: <key>` | |
| - 支持配置多个 API Key | |
| ## 客户端集成 | |
| ### OpenAI SDK (Python) | |
| ```python | |
| from openai import OpenAI | |
| client = OpenAI(base_url="http://localhost:8080/v1", api_key="your-key") | |
| response = client.chat.completions.create( | |
| model="glm-5.2", | |
| messages=[{"role": "user", "content": "你好"}], | |
| tools=[{"type":"function","function":{"name":"Bash","description":"执行命令","parameters":{"type":"object","properties":{"command":{"type":"string"}},"required":["command"]}}}], | |
| stream=True | |
| ) | |
| for chunk in response: | |
| if chunk.choices[0].delta.content: | |
| print(chunk.choices[0].delta.content, end="") | |
| ``` | |
| ### Anthropic SDK (Python) | |
| ```python | |
| from anthropic import Anthropic | |
| client = Anthropic(base_url="http://localhost:8080/v1", api_key="your-key") | |
| with client.messages.stream( | |
| model="glm-5.2", | |
| max_tokens=1024, | |
| messages=[{"role": "user", "content": "你好"}] | |
| ) as stream: | |
| for text in stream.text_stream: | |
| print(text, end="") | |
| ``` | |
| ## 局限性 | |
| - IMA 模型需要 prompt 注入才能触发 tool calling(非原生支持) | |
| - 流式输出中的 `<function_call>` 块会被服务器端过滤(客户端不可见) | |
| - IMA 会话限制约 20 轮,超出后需重新建立 | |
| ## 保姆级部署教程(零基础上手) | |
| 本教程不需要编程基础,不需要安装任何软件,全程在手机和网页上完成。总耗时约 15 分钟。 | |
| --- | |
| ### 准备工作:获取 IMA 的 Cookie | |
| 这一步是唯一需要花点时间的。你需要从手机上的 IMA App 抓取请求数据。 | |
| **你需要:** 一部安装了 IMA App 的手机(已用 QQ/微信登录)+ 一台电脑。 | |
| #### 1.1 安装抓包工具 | |
| 在电脑上安装 **mitmproxy**(免费、开源): | |
| - 打开 [mitmproxy.org](https://mitmproxy.org/),点击下载 Windows 安装包,一路「下一步」安装完成。 | |
| #### 1.2 配置手机代理 | |
| 1. 确保手机和电脑在**同一个 WiFi** 下 | |
| 2. 电脑上:Win+R → 输入 `cmd` → 回车,输入 `ipconfig`,找到 IPv4 地址(形如 `192.168.x.x`) | |
| 3. 手机上:设置 → WiFi → 点击当前连接的 WiFi → 代理 → 手动 | |
| - 服务器:填入电脑的 IPv4 地址,端口:`8080` | |
| 4. 手机浏览器打开 `mitm.it`,按提示安装 mitmproxy 的 CA 证书 | |
| - Android:选「用于 VPN 和应用」 | |
| - iOS:还需在 设置→通用→关于→证书信任设置 中开启信任 | |
| #### 1.3 抓取 Cookie | |
| 1. 电脑上 Win+R → `cmd` → 输入 `mitmweb` 回车(浏览器会自动打开 http://127.0.0.1:8081) | |
| 2. 手机上打开 IMA App,随便发一条消息(比如「你好」) | |
| 3. 回到电脑浏览器,在 mitmweb 界面找 `ima.qq.com` 开头的请求 | |
| 4. 点开任意一条,在 Request Headers 中找到 **`x-ima-cookie`**,完整复制它的值 | |
| > 这个值很长,类似 `IMA-GUID=xxx;APP-VERSION=xxx;IMA-Q36=xxx;...;IMA-TOKEN=xxx;...` | |
| #### 1.4 获取 refresh_token 和 registration_id | |
| 1. 在 mitmweb 页面的搜索框输入 `/auth_login/refresh` | |
| 2. 点开这个请求 → 点击 Request 标签 → 在内容区找: | |
| - `refresh_token`:一串很长的字符串 | |
| - `registration_id`:另一串字符串 | |
| 3. 分别复制保存 | |
| **把这三个值记在手边备用:** x-ima-cookie、refresh_token、registration_id。 | |
| > 抓完后记得**把手机代理关掉**(WiFi 设置里改回「无」),否则断开电脑后手机没法上网。 | |
| --- | |
| ### 第一步:注册 Hugging Face | |
| 1. 打开 [huggingface.co/join](https://huggingface.co/join) | |
| 2. 输入邮箱和密码 → Next → 完成人机验证 | |
| 3. 去邮箱点击确认链接激活账号 | |
| --- | |
| ### 第二步:创建 Space | |
| 1. 打开 [huggingface.co/new-space](https://huggingface.co/new-space) | |
| 2. 填写: | |
| - **Space name**:随便取,比如 `my-ima-api`(只能用英文字母、数字、短横线) | |
| - **License**:选 `mit` | |
| - **Space SDK**:选 **Docker** | |
| - **Space Template**:选 **Blank** | |
| - **Space Visibility**:选 **Private**(关键!不选这个别人能看见你的 API 地址) | |
| 3. 点 **Create Space** 按钮 | |
| --- | |
| ### 第三步:上传文件 | |
| 你现在在 Space 页面了。用网页拖拽上传,不需要装 Git。 | |
| 1. 点击顶部 **Files** 标签页 | |
| 2. 点击 **Add file** → **Upload files** | |
| 3. 把以下 4 个文件拖进去:`server.js`、`config.json`、`package.json`、`Dockerfile` | |
| 4. 往下滚,Commit message 随便填,点 **Commit to main** | |
| > 不用上传 `ima_runner.py`,HF 上不需要它。 | |
| --- | |
| ### 第四步:设置 Secrets(密码) | |
| 1. 在 Space 页面顶部点 **Settings** 标签页 | |
| 2. 往下滚找到 **Repository Secrets** | |
| 3. 点 **New secret**,逐个添加: | |
| | Name | Value | | |
| |------|-------| | |
| | `IMA_COOKIE` | 粘贴完整 x-ima-cookie | | |
| | `IMA_REFRESH_TOKEN` | 粘贴 refresh_token | | |
| | `IMA_REGISTRATION_ID` | 粘贴 registration_id | | |
| | `IMA_API_KEYS` | 自己编一个密码,如 `sk-my-secret-key-2024` | | |
| > `IMA_API_KEYS` 是你调用 API 用的「密码」。多个 key 用逗号分隔:`sk-key1,sk-key2`。 | |
| --- | |
| ### 第五步:等待启动 | |
| 1. 回到顶部点 **App** 标签页 | |
| 2. 看到 "Building..." 等待 1-2 分钟,变成绿色 "Running" 即成功 | |
| 3. 如果卡住,点右上角 → **Factory reboot** | |
| --- | |
| ### 第六步:测试 | |
| 浏览器打开 `https://你的用户名-你的空间名.hf.space/`,看到 JSON 数据含 `"service": "ima2api"` 就说明成功。 | |
| --- | |
| ### 第七步:接入 Claude Code / Codex | |
| **Claude Code(终端):** | |
| ```bash | |
| set ANTHROPIC_BASE_URL=https://你的用户名-你的空间名.hf.space/v1 | |
| set ANTHROPIC_API_KEY=sk-my-secret-key-2024 | |
| claude | |
| ``` | |
| **Codex(桌面版设置页):** | |
| - Provider: Anthropic 或 OpenAI Compatible | |
| - Base URL: `https://你的用户名-你的空间名.hf.space/v1` | |
| - API Key: `sk-my-secret-key-2024` | |
| - Model: `glm-5.2` | |
| **Cherry Studio / ChatGPT-Next-Web:** 创建自定义 Provider,填入相同的 Base URL 和 API Key。 | |
| --- | |
| ### 常见问题 | |
| **Q: 显示 "Running" 但访问报错?** | |
| 等 30 秒再试,启动后首次 token 刷新需要十几秒。 | |
| **Q: API 返回 401 Unauthorized?** | |
| 检查 Secrets 里的 `IMA_API_KEYS` 和请求里用的 key 是否完全一致。 | |
| **Q: 回复是乱码或空内容?** | |
| Cookie 可能过期了,重新抓一次 IMA Cookie,更新 Secret 后点 Factory reboot。 | |
| **Q: Token 会自动刷新吗?** | |
| 会。server.js 内置定时刷新,无需额外操作。 | |
| **Q: 免费层够用吗?** | |
| 完全够。16GB 内存 + 2 CPU,个人使用远达不到限制。长时间不活动会休眠,下次访问自动唤醒(等几秒就好)。 | |
| --- | |
| ### 本地开发仍可用 | |
| ```bash | |
| # 方式1:Python watchdog(token 刷新会重启 npm) | |
| python ima_runner.py | |
| # 方式2:纯 Node(HF 同款,token 热更新不重启) | |
| npm start | |
| ``` | |