Files
lingma-openai-gateway/README.md
mmc b719bdeaa2 feat: add capability and admin introspection endpoints
Expose capability discovery plus admin-only config and request inspection endpoints so clients and operators can understand gateway behavior without reading code.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 14:30:08 +08:00

252 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Lingma OpenAI Gateway
将 Lingma 封装为 OpenAI / Anthropic 兼容网关,便于现有客户端直接接入。
- OpenAI`/v1/models``/v1/chat/completions`(含 stream
- Anthropic`/v1/messages``/v1/messages/count_tokens`(含 stream
- 能力探测:`/capabilities``/v1/capabilities`
- 内省端点:`/internal/effective-config``/internal/debug/requests`
- 内置多实例池、会话复用、Prometheus 指标、登录态 bundle 注入
- 工具事件桥接Lingma 上游返回 `tool` 事件时,网关会输出为 OpenAI `tool_calls`stream/non-stream和 Anthropic `tool_use` / `tool_result`stream/non-stream请求侧 `tools` / `tool_choice` 仅在 `TOOL_FORWARD_ENABLED=true` 时透传(默认开启,可显式关闭)
- 工具模拟回退:当 Lingma 未稳定外显原生 `tool/*` 事件时,网关会把注入后的 `json action` / `#Tool Call` 等动作文本归一化为 OpenAI `tool_calls`,并支持 tool result continuation
- 多模态降级OpenAI `image_url` / `input_image``[image]``input_audio``[audio]`Anthropic `image``[image]`
> 架构设计与二开细节请看 [`DESIGN.md`](./DESIGN.md)。
---
## 目录
1. [5 分钟启动](#5-分钟启动)
2. [常用命令](#常用命令)
3. [最小 API 示例](#最小-api-示例)
4. [部署与更新](#部署与更新)
5. [排障速查](#排障速查)
6. [文档入口](#文档入口)
---
## 5 分钟启动
### 1) 准备配置
```bash
git clone <repo>
cd lingma-openai-gateway
cp .env.example .env
```
至少配置这些变量(在 `.env`
- `API_KEYS`
- `LINGMA_USERNAME` / `LINGMA_PASSWORD`(或 `LINGMA_SESSION_BUNDLE(_FILE)`
### 2) Docker 启动(推荐)
```bash
mkdir -p data secrets
docker compose up -d --build
docker compose logs -f
```
### 3) 冒烟检查
```bash
PORT=$(grep '^PORT=' .env | cut -d= -f2)
API_KEY=$(grep '^API_KEYS=' .env | cut -d= -f2 | cut -d, -f1)
curl -s "http://127.0.0.1:${PORT}/healthz"
curl -s "http://127.0.0.1:${PORT}/v1/models" \
-H "Authorization: Bearer ${API_KEY}"
curl -s "http://127.0.0.1:${PORT}/capabilities"
```
---
## 常用命令
### 本地开发运行
```bash
pip install -r requirements.txt
uvicorn app.main:app --reload --port 8317
```
### Docker 常用
```bash
docker compose up -d --build
docker compose logs -f
docker compose ps
docker compose down
```
### 测试
```bash
# 重点回归套件
python3 -m unittest tests/test_tool_call_bridge.py
# 全量 unittest
python3 -m unittest discover -s tests -p "test_*.py"
# Docker 端到端工具调用冒烟
bash scripts/smoke_tool_calls.sh
```
---
## 最小 API 示例
先取 key
```bash
PORT=$(grep '^PORT=' .env | cut -d= -f2)
API_KEY=$(grep '^API_KEYS=' .env | cut -d= -f2 | cut -d, -f1)
```
### OpenAI非流式
```bash
curl -s "http://127.0.0.1:${PORT}/v1/chat/completions" \
-H "Authorization: Bearer ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "org_auto",
"messages": [{"role": "user", "content": "hi"}],
"stream": false
}'
```
### OpenAI流式
```bash
curl -N "http://127.0.0.1:${PORT}/v1/chat/completions" \
-H "Authorization: Bearer ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "org_auto",
"messages": [{"role": "user", "content": "say hi"}],
"stream": true
}'
```
### Anthropic非流式
```bash
curl -s "http://127.0.0.1:${PORT}/v1/messages" \
-H "x-api-key: ${API_KEY}" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-3-5-sonnet-20241022",
"max_tokens": 256,
"messages": [{"role": "user", "content": "hi"}],
"stream": false
}'
```
### Anthropic流式
```bash
curl -N "http://127.0.0.1:${PORT}/v1/messages" \
-H "x-api-key: ${API_KEY}" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-3-5-sonnet-20241022",
"max_tokens": 256,
"messages": [{"role": "user", "content": "say hi"}],
"stream": true
}'
```
### Anthropiccount_tokens
```bash
curl -s "http://127.0.0.1:${PORT}/v1/messages/count_tokens" \
-H "x-api-key: ${API_KEY}" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-3-5-sonnet-20241022",
"max_tokens": 64,
"messages": [{"role": "user", "content": "count me"}]
}'
```
### 能力探测
```bash
curl -s "http://127.0.0.1:${PORT}/capabilities"
curl -s "http://127.0.0.1:${PORT}/v1/capabilities" \
-H "x-api-key: ${API_KEY}" \
-H "anthropic-version: 2023-06-01"
```
### 内省端点admin
如果配置了 `ADMIN_TOKEN`,以下端点需要使用该 token否则会回退复用 `API_KEYS`
```bash
ADMIN_TOKEN=${ADMIN_TOKEN:-$API_KEY}
curl -s "http://127.0.0.1:${PORT}/internal/effective-config" \
-H "Authorization: Bearer ${ADMIN_TOKEN}"
curl -s "http://127.0.0.1:${PORT}/internal/debug/requests?limit=5" \
-H "Authorization: Bearer ${ADMIN_TOKEN}"
```
> `internal/debug/requests` 会对 token、session bundle、data URL 图片和超长工具参数做脱敏/截断。
---
## 部署与更新
### 服务器更新到最新 main
```bash
cd /root/lingma-openai-gateway
git fetch origin
git checkout -B main origin/main
git reset --hard origin/main
git clean -fd
docker compose up -d --build
docker compose ps
```
### 健康检查
```bash
PORT=$(grep '^PORT=' .env | cut -d= -f2)
curl -s "http://127.0.0.1:${PORT}/healthz"
```
---
## 排障速查
| 现象 | 常见原因 | 处理 |
|---|---|---|
| `/v1/*` 返回 401 | 缺失或错误 API key | 检查 `Authorization: Bearer``x-api-key` |
| `healthz` 正常但请求失败 | 用错端口 | 以 `.env``PORT` 为准,`docker compose ps` 再确认 |
| `git pull` 提示 not on a branch | 处于 detached HEAD | 执行 `git checkout -B main origin/main` |
| 自动登录不稳定 | 浏览器流程波动 | 优先使用 `LINGMA_SESSION_BUNDLE(_FILE)` |
| 日志出现 `extension main js path not found` / `ExtensionApi executor not inited` | Lingma 扩展运行时未完整提取MCP/工具执行器未初始化 | 重启容器触发 bootstrap 自愈;确认 `data/bin/<version>/extension/main.js` 已存在 |
| 工具调用未触发 | 模型未选择工具或当前协议路径不支持合成回退 | OpenAI 可配合 `tool_choice` 强制并约束输出 JSONAnthropic 当前仅 non-stream 支持合成 `tool_use` / `tool_result` 回退 |
---
## 文档入口
- 配置权威:[`/.env.example`](./.env.example)
- 架构/模块边界/设计决策:[`/DESIGN.md`](./DESIGN.md)
- 主要入口代码:[`/app/main.py`](./app/main.py)
- 测试:[`/tests/test_tool_call_bridge.py`](./tests/test_tool_call_bridge.py)
## License
MIT