---
title: p5jsAi API
emoji: 🚀
colorFrom: blue
colorTo: purple
sdk: docker
pinned: false
---
# p5js.ai 2 API
[English](#english) | [中文](#中文)
---
## p5js.ai 2 API — 将 p5js.ai 免费接口包装为 Anthropic / OpenAI 兼容 API
`p5js.ai 2 API` 是一个轻量级的反向代理适配器,将 `https://p5js.ai/api/ai-chat` 免费聊天接口同时包装成 **Anthropic Messages API** 和 **OpenAI Chat Completions API** 兼容接口。
这意味着任何支持 Anthropic 或 OpenAI 协议的工具——Claude Code、Chatbox、NextChat、LobeChat、one-api、Cherry Studio 等——都可以直接接入,就像连接一个真正的 Anthropic 或 OpenAI 端点一样。
### 核心特性
- **双协议兼容** — 同时提供 `/v1/messages`(Anthropic)和 `/v1/chat/completions`(OpenAI)端点
- **Tool Use 仿真** — 上游不支持原生 tool_use,本服务通过 XML 格式的 `` 提示词注入实现伪工具调用,并自动将响应中的 XML 解析回标准 `tool_use` / `tool_calls` 格式
- **p5.js 噪声过滤** — 自动检测并剥离上游注入的 p5.js 助手问候语、前缀和尾缀
- **SSE 修复** — 上游会输出畸形的 `ddata:` / `ata:` 前缀,本服务自动修正为标准 SSE 格式
- **双层缓存** — 内存缓存 + 可选 Redis 二级缓存,相同请求自动命中,流式/非流式共用同一份完成结果
- **In-flight 合并** — 并发相同请求不会重复打上游,follower 等待 leader 结果
- **连接池复用** — 共享 httpx 异步连接池,适合高并发场景
- **代理支持** — 支持 `UPSTREAM_PROXY_URL` 或标准 `HTTP_PROXY` / `HTTPS_PROXY` 环境变量
### 项目结构
```
p5js/
├── main.py # FastAPI 应用入口、路由定义
├── config.py # 常量、环境变量、模型列表、正则模式
├── filters.py # p5.js 噪声过滤、工具感知文本缓冲
├── tools.py # Tool XML 提示词构建、解析、提取
├── translate.py # 协议转换(Anthropic/OpenAI → 上游消息格式)
├── upstream.py # 上游 HTTP 客户端、SSE 解析、实时捕获
├── render.py # Artifact → Anthropic/OpenAI JSON/SSE 渲染
├── stream.py # 实时流处理(带/不带工具,带缓存集成)
├── response_cache.py # 双层缓存系统(内存 + Redis)
├── tests/ # 测试套件
│ ├── test_response_cache.py
│ └── test_filters.py
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
├── start.sh
├── .env.example # 环境变量示例
└── README.md
```
### 快速开始
#### 本地运行
```bash
./start.sh
```
首次运行会自动创建 `venv` 并安装依赖,然后在 `http://127.0.0.1:18185` 监听。
#### Docker 部署
```bash
# 直接构建
docker build -t p5js2api:latest .
docker run --rm -p 18185:18185 p5js2api:latest
# 或使用 docker compose(自带 Redis)
docker compose up -d --build
```
默认 compose 配置同时启动一个本地 Redis 实例,端口通过 `P5JS2API_PORT` 环境变量控制(默认 `18185`)。
### 支持的模型
| 模型 | 说明 |
|------|------|
| `claude-opus-4-7` | 最新旗舰 |
| `claude-opus-4-6` | |
| `claude-opus-4-1` / `claude-opus-4-1-20250805` | |
| `claude-opus-4-20250514` | |
| `claude-sonnet-4-6` | |
| `claude-sonnet-4-5` / `claude-sonnet-4-5-20250929` | **默认模型** |
| `claude-sonnet-4-20250514` | |
| `claude-haiku-4-5` / `claude-haiku-4-5-20251001` | 轻量快速 |
### 接口一览
| 路径 | 方法 | 说明 |
|------|------|------|
| `/health` | GET | 健康检查,返回服务状态、缓存统计、上游配置 |
| `/v1/models` | GET | 模型列表(Anthropic 格式) |
| `/v1/messages` | POST | **Anthropic Messages API**,支持 `stream` |
| `/v1/chat/completions` | POST | **OpenAI Chat Completions API**,支持 `stream` |
> 服务不校验 API Key,任意非空字符串均可通过认证。
### 使用示例
#### Claude Code(Anthropic 协议)
```bash
export ANTHROPIC_BASE_URL=http://127.0.0.1:18185
export ANTHROPIC_AUTH_TOKEN=dummy
export ANTHROPIC_MODEL=claude-opus-4-7
export ANTHROPIC_SMALL_FAST_MODEL=claude-haiku-4-5
claude
```
#### OpenAI Python SDK
```python
from openai import OpenAI
client = OpenAI(
base_url="http://127.0.0.1:18185/v1",
api_key="sk-dummy",
)
resp = client.chat.completions.create(
model="claude-sonnet-4-5",
messages=[{"role": "user", "content": "你好"}],
stream=True,
)
for chunk in resp:
print(chunk.choices[0].delta.content or "", end="", flush=True)
```
#### 第三方工具(Chatbox / NextChat / LobeChat / one-api / Cherry Studio 等)
- **Base URL / API 地址**: `http://127.0.0.1:18185/v1`
- **API Key**: 任意非空字符串(如 `sk-dummy`)
- **模型名**: 填写上方「支持的模型」中的任一项
#### curl
```bash
# Anthropic 协议
curl http://127.0.0.1:18185/v1/messages \
-H 'content-type: application/json' \
-H 'x-api-key: dummy' \
-d '{"model":"claude-sonnet-4-5","max_tokens":1024,"messages":[{"role":"user","content":"hi"}]}'
# OpenAI 协议
curl http://127.0.0.1:18185/v1/chat/completions \
-H 'content-type: application/json' \
-d '{"model":"claude-sonnet-4-5","messages":[{"role":"user","content":"hi"}]}'
```
### 缓存系统
服务默认启用完整响应缓存:
- 先走进程内内存缓存(LRU,默认 256 条)
- 配置 `RESPONSE_CACHE_REDIS_URL` 后升级为 **内存 + Redis** 双层缓存
- 相同请求并发命中 miss 时做 **in-flight 合并**,避免同时打爆上游
- `stream=true` 和 `stream=false` 共用同一份完成结果缓存
#### 环境变量
完整环境变量列表见 `.env.example`,核心配置:
| 变量 | 默认值 | 说明 |
|------|--------|------|
| `RESPONSE_CACHE_ENABLED` | `true` | 是否启用缓存 |
| `RESPONSE_CACHE_TTL_SECS` | `300` | 普通请求缓存 TTL(秒) |
| `RESPONSE_CACHE_TOOL_TTL_SECS` | `120` | 带工具请求缓存 TTL(秒) |
| `RESPONSE_CACHE_MAX_ENTRY_BYTES` | `33554432` | 单条缓存最大字节数(0 = 不限) |
| `RESPONSE_CACHE_REDIS_URL` | — | Redis 连接地址,配置后启用二级缓存 |
#### 响应头
- `X-Proxy-Cache: HIT | MISS | BYPASS | DISABLED`
- `X-Proxy-Cache-Source: memory | redis | inflight | live`
#### 跳过缓存
任一方式:
- 请求头 `X-Proxy-Cache: bypass`
- 请求头 `Cache-Control: no-cache`
### 代理配置
容器内支持两种代理方式:
- 显式设置 `UPSTREAM_PROXY_URL`
- 标准环境变量 `HTTP_PROXY` / `HTTPS_PROXY` / `NO_PROXY`
`/health` 里的 `upstream.proxy_configured` 会显示当前是否检测到代理配置。
### 工作原理
```
┌─────────────┐ ┌──────────────────┐ ┌─────────────┐
│ Client │────▶│ p5js.ai 2 API │────▶│ p5js.ai │
│ (Claude/ │◀────│ (this project) │◀────│ upstream │
│ OpenAI) │ │ │ │ │
└─────────────┘ └──────────────────┘ └─────────────┘
│ ├─ 协议转换 │
│ ├─ Tool XML 注入/解析 │
│ ├─ p5.js 噪声过滤 │
│ ├─ SSE 修复 │
│ └─ 双层缓存 │
```
1. **协议转换**:将 Anthropic 或 OpenAI 格式的请求转换为 p5js.ai 上游格式(`messages` + `provider` + `model` + `deviceId` + `sessionId`)
2. **Tool Use 仿真**:将工具定义注入系统提示词为 XML 格式,将上游文本响应中的 `` XML 块解析回标准 `tool_use` / `tool_calls`
3. **噪声过滤**:检测并剥离上游自动注入的 p5.js 助手问候语、标题、尾缀推荐
4. **SSE 修复**:上游输出的畸形 `ddata:` / `ata:` 前缀自动修正为标准 `data:`
5. **缓存**:完整响应缓存,流式和非流式共用,支持 in-flight 合并
### 注意事项
- 上游 p5js.ai 会在没有 system 字段时注入 p5.js 助手提示词,客户端显式传 `system`(Anthropic)或 `{"role":"system"}` 消息(OpenAI)即可覆盖
- 流式缓存命中时会重新生成新的响应 ID / 时间戳,并按本地协议重新渲染
- 默认缓存上限 32 MiB,超过不会截断返回,只是跳过缓存,在 `/health` 的 `cache.oversize_skips` 可见
- 设 `RESPONSE_CACHE_MAX_ENTRY_BYTES=0` 可取消上限
- 本服务依赖 p5js.ai 接口可用性,上游变更可能影响使用
### 致谢
- 感谢 [小辣椒的临时邮箱](https://vip.215.im) 提供注册支持
### 许可证
MIT License
---
## p5js.ai 2 API — Wrap p5js.ai Free Chat as Anthropic / OpenAI Compatible API
`p5js.ai 2 API` is a lightweight reverse-proxy adapter that wraps the free chat endpoint at `https://p5js.ai/api/ai-chat` into both an **Anthropic Messages API** and an **OpenAI Chat Completions API** compatible interface.
This means any tool that speaks either protocol — Claude Code, Chatbox, NextChat, LobeChat, one-api, Cherry Studio, etc. — can connect to it as if it were a real Anthropic or OpenAI endpoint.
### Key Features
- **Dual protocol** — Serves both `/v1/messages` (Anthropic) and `/v1/chat/completions` (OpenAI)
- **Pseudo tool use** — The upstream doesn't support native tool_use; this service injects an XML-based `` prompt and parses the XML back into proper `tool_use` / `tool_calls` format
- **p5.js noise filter** — Automatically detects and strips p5.js assistant greetings, headings, and trailing recommendations injected by the upstream
- **SSE fix-up** — The upstream emits malformed `ddata:` / `ata:` prefixes; this service auto-corrects them to standard SSE
- **Two-tier caching** — In-memory + optional Redis second-level cache; streaming and non-streaming share the same completion cache
- **In-flight deduplication** — Concurrent identical requests don't hammer the upstream; followers wait for the leader's result
- **Connection pooling** — Shared httpx async connection pool for high-concurrency scenarios
- **Proxy support** — Supports `UPSTREAM_PROXY_URL` or standard `HTTP_PROXY` / `HTTPS_PROXY` env vars
### Project Structure
```
p5js/
├── main.py # FastAPI app entry point, route definitions
├── config.py # Constants, env vars, model list, regex patterns
├── filters.py # p5.js noise filtering, tool-aware text buffering
├── tools.py # Tool XML prompt building, parsing, extraction
├── translate.py # Protocol translation (Anthropic/OpenAI → upstream format)
├── upstream.py # Upstream HTTP client, SSE parsing, live capture
├── render.py # Artifact → Anthropic/OpenAI JSON/SSE rendering
├── stream.py # Live stream handling (with/without tools, with cache integration)
├── response_cache.py # Two-tier cache system (memory + Redis)
├── tests/ # Test suite
│ ├── test_response_cache.py
│ └── test_filters.py
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
├── start.sh
├── .env.example # Environment variable template
└── README.md
```
### Quick Start
#### Local
```bash
./start.sh
```
The first run automatically creates a `venv`, installs dependencies, and listens on `http://127.0.0.1:18185`.
#### Docker
```bash
# Build and run
docker build -t p5js2api:latest .
docker run --rm -p 18185:18185 p5js2api:latest
# Or with docker compose (includes Redis)
docker compose up -d --build
```
The default compose config spins up a local Redis instance. Port is controlled via the `P5JS2API_PORT` env var (default `18185`).
### Supported Models
| Model | Notes |
|-------|-------|
| `claude-opus-4-7` | Latest flagship |
| `claude-opus-4-6` | |
| `claude-opus-4-1` / `claude-opus-4-1-20250805` | |
| `claude-opus-4-20250514` | |
| `claude-sonnet-4-6` | |
| `claude-sonnet-4-5` / `claude-sonnet-4-5-20250929` | **Default** |
| `claude-sonnet-4-20250514` | |
| `claude-haiku-4-5` / `claude-haiku-4-5-20251001` | Lightweight & fast |
### API Endpoints
| Path | Method | Description |
|------|--------|-------------|
| `/health` | GET | Health check — returns service status, cache stats, upstream config |
| `/v1/models` | GET | Model list (Anthropic format) |
| `/v1/messages` | POST | **Anthropic Messages API**, supports `stream` |
| `/v1/chat/completions` | POST | **OpenAI Chat Completions API**, supports `stream` |
> The service does not validate API keys — any non-empty string is accepted.
### Usage Examples
#### Claude Code (Anthropic Protocol)
```bash
export ANTHROPIC_BASE_URL=http://127.0.0.1:18185
export ANTHROPIC_AUTH_TOKEN=dummy
export ANTHROPIC_MODEL=claude-opus-4-7
export ANTHROPIC_SMALL_FAST_MODEL=claude-haiku-4-5
claude
```
#### OpenAI Python SDK
```python
from openai import OpenAI
client = OpenAI(
base_url="http://127.0.0.1:18185/v1",
api_key="sk-dummy",
)
resp = client.chat.completions.create(
model="claude-sonnet-4-5",
messages=[{"role": "user", "content": "Hello"}],
stream=True,
)
for chunk in resp:
print(chunk.choices[0].delta.content or "", end="", flush=True)
```
#### Third-party Tools (Chatbox / NextChat / LobeChat / one-api / Cherry Studio etc.)
- **Base URL**: `http://127.0.0.1:18185/v1`
- **API Key**: Any non-empty string (e.g. `sk-dummy`)
- **Model**: Pick one from the "Supported Models" table above
#### curl
```bash
# Anthropic protocol
curl http://127.0.0.1:18185/v1/messages \
-H 'content-type: application/json' \
-H 'x-api-key: dummy' \
-d '{"model":"claude-sonnet-4-5","max_tokens":1024,"messages":[{"role":"user","content":"hi"}]}'
# OpenAI protocol
curl http://127.0.0.1:18185/v1/chat/completions \
-H 'content-type: application/json' \
-d '{"model":"claude-sonnet-4-5","messages":[{"role":"user","content":"hi"}]}'
```
### Caching
The service enables full-response caching by default:
- In-process memory cache first (LRU, default 256 entries)
- Configure `RESPONSE_CACHE_REDIS_URL` to upgrade to **memory + Redis** two-tier caching
- Concurrent identical cache misses are **in-flight deduplicated** — followers wait for the leader
- `stream=true` and `stream=false` share the same completion cache
#### Environment Variables
See `.env.example` for the full list. Key settings:
| Variable | Default | Description |
|----------|---------|-------------|
| `RESPONSE_CACHE_ENABLED` | `true` | Enable/disable caching |
| `RESPONSE_CACHE_TTL_SECS` | `300` | Cache TTL for plain requests (seconds) |
| `RESPONSE_CACHE_TOOL_TTL_SECS` | `120` | Cache TTL for tool-use requests (seconds) |
| `RESPONSE_CACHE_MAX_ENTRY_BYTES` | `33554432` | Max cache entry size in bytes (0 = unlimited) |
| `RESPONSE_CACHE_REDIS_URL` | — | Redis URL; set to enable second-level cache |
#### Response Headers
- `X-Proxy-Cache: HIT | MISS | BYPASS | DISABLED`
- `X-Proxy-Cache-Source: memory | redis | inflight | live`
#### Bypass Cache
Either of:
- Request header `X-Proxy-Cache: bypass`
- Request header `Cache-Control: no-cache`
### Proxy Configuration
Two proxy options inside the container:
- Explicit `UPSTREAM_PROXY_URL`
- Standard env vars `HTTP_PROXY` / `HTTPS_PROXY` / `NO_PROXY`
The `/health` endpoint's `upstream.proxy_configured` field shows whether a proxy is detected.
### How It Works
```
┌─────────────┐ ┌──────────────────┐ ┌─────────────┐
│ Client │────▶│ p5js.ai 2 API │────▶│ p5js.ai │
│ (Claude/ │◀────│ (this project) │◀────│ upstream │
│ OpenAI) │ │ │ │ │
└─────────────┘ └──────────────────┘ └─────────────┘
│ ├─ Protocol translation │
│ ├─ Tool XML inject/parse │
│ ├─ p5.js noise filtering │
│ ├─ SSE fix-up │
│ └─ Two-tier caching │
```
1. **Protocol translation**: Converts Anthropic or OpenAI format requests into the p5js.ai upstream format (`messages` + `provider` + `model` + `deviceId` + `sessionId`)
2. **Tool use emulation**: Injects tool definitions as XML into the system prompt, parses `` XML blocks from upstream text responses back into standard `tool_use` / `tool_calls`
3. **Noise filtering**: Detects and strips p5.js assistant greetings, headings, and trailing recommendations auto-injected by the upstream
4. **SSE fix-up**: Auto-corrects malformed `ddata:` / `ata:` prefixes to standard `data:`
5. **Caching**: Full-response caching shared between streaming and non-streaming, with in-flight deduplication
### Caveats
- The upstream p5js.ai injects a p5.js assistant prompt when no `system` field is present. Passing `system` (Anthropic) or a `{"role":"system"}` message (OpenAI) overrides it.
- Cache hits re-generate new response IDs/timestamps and re-render per the local protocol.
- Default cache entry limit is 32 MiB. Oversized entries are not truncated — they're simply not cached. Check `/health` → `cache.oversize_skips`.
- Set `RESPONSE_CACHE_MAX_ENTRY_BYTES=0` to remove the limit.
- This service depends on p5js.ai availability. Upstream changes may affect functionality.
### Acknowledgements
- Special thanks to [小辣椒的临时邮箱 (Xiaolajiao Temp Mail)](https://vip.215.im) for registration support
### License
MIT License