thomas-m-brown/straddle
GitHub: thomas-m-brown/straddle
一个轻量级的 Ollama 反向代理,提供统一 OpenAI 兼容端点、持久系统提示注入、实时数据上下文丰富和 KV 缓存固定。
Stars: 0 | Forks: 0
# Straddle




一个兼容 OpenAI 的推理网关,用于自托管的 Ollama。单一端点服务于所有客户端,持久化系统提示注入,实时数据上下文(邮件、日历),以及 API 密钥认证。
## 为什么我要构建它
我运行着 Open WebUI、自定义脚本和各类 API 客户端——它们都指向本地服务器上的 Ollama。每个客户端都需要自己的配置、系统提示和端点。当我更新系统提示时,必须逐个更新所有地方。当我想为响应添加邮件上下文时,每个客户端都需要单独的集成。
Straddle 通过置于每个客户端和 Ollama 之间来解决这个问题:一个地址,一个需要编辑的系统提示,一个添加上下文丰富化的地方。所有客户端共享相同的行为,无需逐个客户端配置。
## 功能
**统一端点。** 所有客户端——Web UI、脚本、API 调用——共享一个地址。无需逐个客户端配置 Ollama。
**系统提示注入。** 只需编辑一次 `prompts/system_prompt.md`。每次请求都会自动注入。
**实时数据上下文。** 在消息到达模型之前,系统会进行模式匹配并用真实数据丰富内容——收件箱摘要、日历事件、提醒——无需任何工具调用往返。
**KV 缓存稳定性。** 请求以固定的 `num_ctx` 和 `keep_alive: -1` 转发至 Ollama。模型常驻 VRAM,请求之间无需冷启动重载。
**API 密钥认证。** 所有推理端点均需 `X-API-Key` 头。健康检查保持公开。
## 架构
```
Clients (WebUI / scripts / API)
│
▼
┌─────────────────────────┐
│ Straddle :11435 │
│ │
│ auth → X-API-Key │
│ inject → system prompt │
│ enrich → email / cal │
└────────────┬────────────┘
│
▼
┌─────────────────────────┐
│ Ollama :11434 │
│ local inference │
└─────────────────────────┘
```
## 快速开始
```
git clone https://github.com/equ1nox-git/straddle.git
cd straddle
cp .env.example .env # fill in required values
pip install -r requirements.txt
python3 api_server.py
```
测试:
```
curl http://localhost:11435/ # health (no key needed)
curl http://localhost:11435/v1/models \
-H "X-API-Key: your-key"
curl http://localhost:11435/v1/chat/completions \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"model":"qwen2.5:7b","messages":[{"role":"user","content":"hello"}]}'
```
## 配置
所有设置通过 `.env`(从 `.env.example` 复制)进行:
| 变量 | 默认值 | 描述 |
|---|---|---|
| `OLLAMA_URL` | `http://localhost:11434` | Ollama 后端 |
| `STRADDLE_HOST` | `127.0.0.1` | 绑定地址——使用 Tailscale IP 仅暴露在网格内 |
| `STRADDLE_PORT` | `11435` | 监听端口 |
| `STRADDLE_API_KEY` | (空) | 必需的 `X-API-Key` 值;若未设置则禁用认证 |
| `DEFAULT_MODEL` | (空) | 当客户端未指定模型时的回退模型 |
| `NUM_CTX` | `8192` | 固定上下文窗口——防止请求间 KV 缓冲区大小调整 |
| `KEEP_ALIVE` | `-1` | `-1` 表示模型永远保持加载,`0` 表示每次请求后卸载 |
| `PROMPTS_DIR` | `./prompts` | `system_prompt.md` 和 `master_context.md` 所在的目录 |
## 提示文件
| 文件 | 用途 |
|---|---|
| `prompts/system_prompt.md` | 每次请求注入的基础指令 |
| `prompts/master_context.md` | 系统提示后追加的额外上下文 |
两者均为可选,不包含在仓库中——请在本地创建。
## 实时数据注入
Straddle 对最后一条用户消息进行模式匹配,并在转发给 Ollama 之前,将真实数据作为预解析的上下文块前置。无需工具调用,无需往返。
| 模式 | 获取的数据 |
|---|---|
| "列出我的邮件"、"最近5封邮件" | 通过 `himalaya` 获取收件箱(iCloud / Gmail / Yahoo) |
| "发送邮件给……" | 通过 SMTP 发送,返回状态 |
| "我这周有什么安排"、"即将到来的事件" | 通过 iCloud CalDAV 获取事件 |
| "提醒"、"即将到来的事项" | 通过 CalDAV 获取 Apple 提醒 |
邮件和日历的凭证从 `.env` 中读取——绝不硬编码。
## API
| 方法 | 端点 | 认证 | 描述 |
|---|---|---|---|
| `GET` | `/` | — | 健康检查 |
| `GET` | `/v1/models` | ✓ | 列出模型(OpenAI 格式) |
| `GET` | `/api/tags` | ✓ | 列出模型(Ollama 原生格式) |
| `POST` | `/v1/chat/completions` | ✓ | 带注入和流式传输的聊天 |
## Systemd(用户服务)
```
# 启用并启动
systemctl --user enable --now straddle.service
# 状态 / 日志
systemctl --user status straddle
journalctl --user -u straddle -f
```
## 系统要求
- Python 3.10+
- 本地运行 [Ollama](https://ollama.ai)
## 许可证
MIT
标签:AI推理网关, AI风险缓解, API密钥认证, API认证, AV绕过, FastAPI, GPT代理, KV缓存, LLM评估, Ollama, OpenAI兼容, Python, 上下文增强, 上下文注入, 代理, 单端点, 大模型网关, 提示注入, 无后门, 无文件攻击, 本地AI, 系统提示, 缓存优化, 自托管, 轻量级代理, 逆向工具, 集群管理