mmc 3c9d419726 fix: stop replaying OpenAI stream text
Avoid replaying buffered text at the end of OpenAI streams so text-only responses are emitted once while forced tool fallback behavior stays intact.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-25 15:20:13 +08:00

Lingma OpenAI Gateway

将 Lingma 封装为 OpenAI / Anthropic 兼容网关,便于现有客户端直接接入。

  • OpenAI/v1/models/v1/chat/completions(含 stream
  • Anthropic/v1/messages/v1/messages/count_tokens(含 stream
  • 内置多实例池、会话复用、Prometheus 指标、登录态 bundle 注入
  • 工具事件桥接Lingma 上游返回 tool 事件时,网关会输出为 OpenAI tool_callsstream/non-stream和 Anthropic tool_use / tool_resultstream/non-stream请求侧 tools / tool_choice 仅在 TOOL_FORWARD_ENABLED=true 时透传(默认开启,可显式关闭)
  • 多模态降级OpenAI image_url / input_image[image]input_audio[audio]Anthropic image[image]

架构设计与二开细节请看 DESIGN.md


目录

  1. 5 分钟启动
  2. 常用命令
  3. 最小 API 示例
  4. 部署与更新
  5. 排障速查
  6. 文档入口

5 分钟启动

1) 准备配置

git clone <repo>
cd lingma-openai-gateway
cp .env.example .env

至少配置这些变量(在 .env

  • API_KEYS
  • LINGMA_USERNAME / LINGMA_PASSWORD(或 LINGMA_SESSION_BUNDLE(_FILE)

2) Docker 启动(推荐)

mkdir -p data secrets
docker compose up -d --build
docker compose logs -f

3) 冒烟检查

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}"

常用命令

本地开发运行

pip install -r requirements.txt
uvicorn app.main:app --reload --port 8317

Docker 常用

docker compose up -d --build
docker compose logs -f
docker compose ps
docker compose down

测试

# 重点回归套件
python3 -m unittest tests/test_tool_call_bridge.py

# 全量 unittest
python3 -m unittest discover -s tests -p "test_*.py"

最小 API 示例

先取 key

PORT=$(grep '^PORT=' .env | cut -d= -f2)
API_KEY=$(grep '^API_KEYS=' .env | cut -d= -f2 | cut -d, -f1)

OpenAI非流式

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流式

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非流式

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流式

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

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"}]
  }'

部署与更新

服务器更新到最新 main

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

健康检查

PORT=$(grep '^PORT=' .env | cut -d= -f2)
curl -s "http://127.0.0.1:${PORT}/healthz"

排障速查

现象 常见原因 处理
/v1/* 返回 401 缺失或错误 API key 检查 Authorization: Bearerx-api-key
healthz 正常但请求失败 用错端口 .envPORT 为准,docker compose ps 再确认
git pull 提示 not on a branch 处于 detached HEAD 执行 git checkout -B main origin/main
自动登录不稳定 浏览器流程波动 优先使用 LINGMA_SESSION_BUNDLE(_FILE)
工具调用未触发 模型未选择工具或当前协议路径不支持合成回退 OpenAI 可配合 tool_choice 强制并约束输出 JSONAnthropic 当前仅 non-stream 支持合成 tool_use / tool_result 回退

文档入口

License

MIT

Description
No description provided
Readme 1.3 MiB
Languages
Python 98.8%
Shell 0.9%
Dockerfile 0.3%