google-ai-mode
by XD06
README.md
# google-ai-mode
本地调用 Google AI Mode(`udm=50`),提供 **OpenAI 兼容 API**、MCP 与 CLI。
双层请求引擎:`curl_cffi`(快速路径)→ 被 TLS 指纹检测拦截时**自动回退到真实 Chrome 浏览器**(CDP 连接),绕过 Google SG_REL soft-block。
> 违反 Google ToS,仅供个人研究。上游随时可能改协议。
## 文档导航
| 文档 | 内容 |
|------|------|
| [README.md](README.md) | 安装、配置、启动、OpenAI 用法 |
| [DESIGN.md](DESIGN.md) | 模块划分与数据流 |
| [docs/PROTOCOL.md](docs/PROTOCOL.md) | **抓包路径 / folwr·folif / cookie / 风控(接手必读)** |
| [docs/REFERENCES.md](docs/REFERENCES.md) | 外部参考(精简) |
## 快速开始
### 1. 安装
```bash
cd google-ai-mode
python -m venv .venv
.venv\Scripts\activate
pip install -e ".[api]"
```
**可选依赖**(浏览器回退需要):
```bash
pip install playwright
playwright install chromium
```
### 2. 配置
```bash
copy config.example.json ai-mode.config.json
```
```json
{
"cookie_file": "cookies.json",
"proxy": "http://127.0.0.1:10808",
"host": "www.google.com",
"bind_host": "127.0.0.1",
"port": 18080,
"verbose": false
}
```
优先级:**环境变量 > 配置文件 > 默认值**。
也支持 `config.json` / `.ai-mode.json`,或 `AI_MODE_CONFIG=路径`。
### 3. 导出 Cookies
Chrome **没有**「全选 → Copy as JSON」。用 Cookie-Editor:
1. 安装 [Cookie-Editor](https://cookie-editor.com/)
2. 登录 https://www.google.com
3. Export → **JSON**(数组格式即可)
4. 放到项目根,命名 `cookies.json`
加载时只读每条的 `name` + `value`,多余字段无妨。
最少需要:
| Cookie | 说明 |
|--------|------|
| `__Secure-1PSID` | 长期登录 |
| `__Secure-1PSIDTS` | 短期签名;会尝试 `RotateCookies` 续 |
**只保证 PSID 不过期不够**。建议全量导出 SID/HSID/APISID 等。
### 4. 启动 API
**推荐**:双击项目根 `start-api.bat`(先 cd 到根再启,窗口保持开着)。
**停止**:双击 `stop-api.bat`(读配置里的 `port`,结束占用进程;默认 18080)。
```bash
ai-mode-api
# 或
.venv\Scripts\ai-mode-api.exe
```
```bash
curl --noproxy "*" http://127.0.0.1:18080/health
```
Cherry Studio / 任意 OpenAI 客户端:
```
base_url = http://127.0.0.1:18080/v1
model = google-ai-mode
API Key = 任意非空占位即可
```
## 双层请求引擎
```
请求 → curl_cffi (impersonate=chrome*) ─── 快速路径
│
├─ 200 + AI Mode tokens → 正常返回
│
└─ SG_REL soft-block → 自动回退
│
▼
BrowserBridge (真实 Chrome via CDP)
├─ 启动 Chrome + 代理 + cookies
├─ 预热首页 (关键:直接访搜索页会被 /sorry 拦截)
├─ page.goto() → 搜索页 → 解析 tokens
└─ fetch() → /async/folif → AI 回答
```
### 为什么需要浏览器回退?
Google 于 2026 年升级了 TLS/HTTP2 指纹检测。`curl_cffi` 的所有 impersonate profile(chrome131~146)均被识别为自动化流量,返回 `SG_REL` soft-block(HTTP 200 但无 AI Mode tokens)。
真实 Chrome 浏览器的 TLS 指纹无法被 Google 拦截(因为就是真实浏览器)。通过 CDP(Chrome DevTools Protocol)连接到 Chrome 进程不会注入 `navigator.webdriver` 等自动化标志,因此可以绕过检测。
### 浏览器回退的关键细节
- **预热必须**:直接导航到 `/search` 会被重定向到 `/sorry/index`;必须先访问首页再搜索
- **Playwright headless 无效**:Playwright 控制的浏览器(即使 `channel="chrome"`)仍被检测
- **subprocess + CDP 有效**:用 `subprocess` 启动 Chrome,再通过 CDP 连接,不注入自动化标志
## OpenAI 兼容
```bash
curl --noproxy "*" -X POST "http://127.0.0.1:18080/v1/chat/completions" ^
-H "Content-Type: application/json" ^
-d "{\"model\":\"google-ai-mode\",\"stream\":false,\"messages\":[{\"role\":\"user\",\"content\":\"hello\"}]}"
```
- `GET /v1/models`
- `POST /v1/chat/completions`(`stream=false|true`;流式为**真渐进** SSE:chunked HTML → 稳定 MD 前缀 → delta)
- 另有:`GET /search`、`POST /v1/chat`、`POST /rotate`、`GET /health`
### system 消息
上游无 system 角色。**`role=system` 会被忽略**,只取最后一条 user 文本发给 Google。
### 多轮(无需 thread_id)
客户端只传标准 `messages` 历史即可。服务端用 assistant 正文指纹 + user 问题映射 + `.ai_mode_threads.json` 落盘自动挂 Google thread。
## 错误码(OpenAI `error` 体)
| code | HTTP | 处理 |
|------|------|------|
| `cookie_expired` | 401 | 从 Chrome 重导 `cookies.json` |
| `rate_limit` | 429 | 冷却 1–5 分钟 |
| `soft_block` | 503 | 引擎已自动回退到浏览器模式;若仍失败,刷新 cookies/换代理 |
| `blocked` | 403 | 换 IP、人工过验证后重导 cookie |
| `incomplete_answer` | 502 | 上游答案结构不完整,服务已自动重试仍失败 |
| `bootstrap_tokens` / `upstream_http` | 502 | 查网络/host/登录态 |
| `internal_error` | 500 | 看服务端日志 |
## 核心原理
```
GET /search?udm=50 → tokens (stkp / garc / xsrf_folif / srtst / ei)
GET /async/folwr → 首答 HTML + mstk (legacy, 已弃用)
GET /async/folif → 首答/续聊 HTML + mstk (当前协议)
HTML → Markdown([[cite](url)] + Images)
```
Google ~2026-08 移除了 `data-lro-token` / `data-lro-signature`,弃用 `/async/folwr`。新对话也改用 `/async/folif`。
## 项目结构
```
google-ai-mode/
├── ai-mode.config.json # 本地配置(gitignore,从 example 复制)
├── config.example.json
├── cookies.example.json
├── start-api.bat # Windows 推荐启动
├── stop-api.bat # 按配置端口结束 API
├── DESIGN.md
├── docs/
│ ├── PROTOCOL.md # 协议与逆向结论
│ └── REFERENCES.md
├── scripts/
│ ├── build_cookies.py
│ └── extract-cookies.js
├── tests/
│ ├── test_answer_structure.py
│ ├── test_stream_delta.py
│ └── test_thread_store.py
└── src/ai_mode_mcp/
├── config.py
├── cookie_manager.py
├── browser_backend.py # 浏览器回退:真实 Chrome via CDP
├── engine.py # 协议 + 解析 + Markdown + 线程 + 流式
├── models.py
├── cli.py
└── handlers/
├── api_server.py # FastAPI / OpenAI
└── mcp_server.py
```
## MCP / CLI
```bash
ai-mode-mcp # stdio:search / chat / rotate_cookies
ai-mode-cli "query" -c cookies.json -v
```
## 常见问题
**Q: 浏览器回退时 Chrome 窗口会弹出来?**
不会。`BrowserBridge` 使用 `--headless` 模式(若 Playwright 可用)或 `subprocess` 启动真实 Chrome(带 `--remote-debugging-port`),在后台运行。
**Q: 浏览器回退很慢?**
首次回退需要启动 Chrome(~3 秒)。之后 Chrome 保持运行,后续请求复用。整体比 `curl_cffi` 慢约 5-10 秒,但能绕过 SG_REL。
**Q: PSID 不过期还要重导吗?**
TS 失效或 soft-block 时仍要重导。RotateCookies 不能解决所有失效。
**Q: 和网页答案差很多?**
解析依赖 HTML 片段结构;引用已统一为 `[[标题](url)]`。若缺图/表,开 `verbose` 对照上游 HTML。
**Q: 商业使用?**
不建议;违反 ToS,且协议不稳定。
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues