A lightweight, OpenAI-compatible proxy server for USTC Chat. It exposes the USTC Chat backend as a standard /v1/chat/completions endpoint so you can use it with any OpenAI client.
Alternative: If you have access to the USTC LLM Public Service Platform, you can call models directly via the official API without this proxy. See the Platform API Guide below.
- OpenAI-compatible API — Drop-in replacement for OpenAI Chat Completions (
/v1/chat/completions) - Streaming & non-streaming — Full SSE streaming support with automatic recovery
- Tool calls — Supports function-calling with retry guidance for large payloads
- Reasoning content — Exposes DeepSeek reasoning chains when available
- Auto-retry — Recovers from idle timeouts, chunked encoding errors, and connection issues
- Queue management — Handles USTC queue system transparently (
tick→ai-mother→ wait queue → chat) - Request capture — Optional JSONL logging of requests/responses for debugging
-
Get your USTC Chat token
- Log in to https://chat.ustc.edu.cn/ustchat/
- Open browser console (F12) and run:
copy(JSON.parse(localStorage.getItem('ustchat-user-store')).state.token)
- Paste the token into
ustc.chat.txtin the same directory as the proxy script.
-
Run the proxy
python ustc_openai_proxy.py
The server listens on
http://127.0.0.1:1958by default. -
Configure your client
- Base URL:
http://127.0.0.1:1958/v1 - API Key: any non-empty string (real auth uses
ustc.chat.txt) - Model:
deepseek-v4-pro(default) ordeepseek-v4-flash
- Base URL:
| Variable | Default | Description |
|---|---|---|
USTC_PROXY_HOST |
127.0.0.1 |
Proxy bind address |
USTC_PROXY_PORT |
1958 |
Proxy port |
USTC_TOKEN_FILE |
ustc.chat.txt |
Path to token file |
USTC_CAPTURE_REQUESTS |
0 |
Set to 1 to enable request/response logging |
USTC_CAPTURE_DIR |
copilot-captures |
Directory for capture logs |
USTC_QUEUE_TIMEOUT_SECONDS |
120 |
Max time to wait in USTC queue |
USTC_UPSTREAM_MAX_RETRIES |
4 |
Max retries for upstream requests |
oai4ustc/
├── ustc_openai_proxy.py # Main proxy server
├── ustc.chat.txt # USTC Chat token (create manually)
└── README.md # This file
- The proxy reads
ustc.chat.txton every request, so you can update the token without restarting. deepseek-v4-prodefaults toenable_thinking=truewithreasoning_effort=high.- Responses API is not supported; only Chat Completions.
The USTC LLM Public Service Platform provides direct API access to multiple large language models hosted on campus. The API is OpenAI-compatible, so any OpenAI SDK or tool works out of the box.
- Log in — Visit https://llm.ustc.edu.cn and authenticate via the university's unified identity system (统一身份认证).
- Create a project — Go to Project Management → New Project. Provide a project name, usage scenario (research / teaching / development), and contact info.
- Request an API Key — Enter the project detail page → API Key Management → Create API Key. You will receive a key in the format
sk-xxxxxxxxxxxxxxxx. Save it immediately — it is only shown once.
| Model | Params | Context | Use Case |
|---|---|---|---|
deepseek-v4-flash |
284B (13B active) | 1M | Default recommendation — general purpose / long text / high concurrency |
deepseek-v4-flash-ascend |
284B (13B active) | 1M | Optimized for domestic NPU (Ascend) — high concurrency |
deepseek-v4-pro |
1.6T (49B active) | 1M | Top-tier reasoning — research / complex tasks |
qwen3.6-27B |
27B | 262K | High-concurrency basic — teaching / Q&A |
qwen3.6-35BA3B |
35B-A3B | 262K | Enhanced — long documents / Agent |
qwen3.5-non-thinking |
397B | 262K | Long-context — document summarization |
qwen3.5-thinking |
397B | 262K | Reasoning-enhanced — research analysis |
| Item | Value |
|---|---|
| Base URL | https://api.llm.ustc.edu.cn/v1 |
| Chat Completions | POST /v1/chat/completions |
| List Models | GET /v1/models |
| Embeddings | POST /v1/embeddings |
| Auth Header | Authorization: Bearer sk-YourKey |
curl https://api.llm.ustc.edu.cn/v1/chat/completions \
-H "Authorization: Bearer sk-YourKey" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-v4-flash",
"messages": [{"role": "user", "content": "Hello"}]
}'from openai import OpenAI
client = OpenAI(
api_key="sk-YourKey",
base_url="https://api.llm.ustc.edu.cn/v1"
)
response = client.chat.completions.create(
model="deepseek-v4-flash",
messages=[{"role": "user", "content": "Hello"}],
temperature=0.3
)
print(response.choices[0].message.content)stream = client.chat.completions.create(
model="deepseek-v4-flash",
messages=[{"role": "user", "content": "Explain LLMs in detail."}],
stream=True
)
for chunk in stream:
content = chunk.choices[0].delta.content
if content:
print(content, end="")| Parameter | Description | Default |
|---|---|---|
model |
Model name | — |
messages |
List of message objects | — |
temperature |
Randomness (0–2) | 0.3 |
max_tokens |
Max output length | 1024 |
stream |
Enable SSE streaming | false |
| Protocol | Supported |
|---|---|
| OpenAI API (chat/completions) | ✅ |
| Anthropic API (/v1/messages) | ✅ |
| SSE Streaming | ✅ |
| Tool Calling / Function Calling | ✅ |
| Embeddings | ✅ |
| Multi-turn conversation | ✅ |
| Code | Meaning | Action |
|---|---|---|
| 401 | Invalid or expired API Key | Check your key |
| 403 | No permission for the model | Check project permissions |
| 404 | Wrong endpoint | Verify Base URL and path |
| 429 | Rate limit / quota exceeded | Reduce concurrency or check quota |
| 500 | Server error | Retry later or contact support |
- Do not expose API keys in frontend code or public repositories.
- Use separate API keys per project.
- Enable
stream: truefor long-form generation. - Lower
temperaturefor more deterministic outputs. - Use retry and rate-limiting mechanisms for high-concurrency scenarios.
- Human-review any critical research conclusions generated by models.
For full documentation, see the Platform User Guide.