快速开始
EnHeng AI 提供兼容 OpenAI 的 API 接口,只需修改两行配置即可从官方接口迁移过来。
https://api.enheng.ai/v1对话补全示例
import openai
client = openai.OpenAI(
api_key="sk-enheng-xxxxxxxx",
base_url="https://api.enheng.ai/v1"
)
response = client.chat.completions.create(
model="claude-4-sonnet",
messages=[
{"role": "user", "content": "你好,介绍一下自己"}
]
)
print(response.choices[0].message.content)认证方式
所有 API 请求通过 HTTP Authorization Header 传递 Bearer Token。
Authorization: Bearer sk-enheng-xxxxxxxx
ENHENG_API_KEY 注入。API 端点
所有端点均兼容 OpenAI API 规范,可直接使用 openai 官方 SDK 调用。
/v1/chat/completions参数
modelstring必填模型 ID,如 gpt-4o、claude-4-sonnetmessagesarray必填对话消息数组,包含 role 和 contentstreamboolean可选是否启用流式输出,默认 falsetemperaturenumber可选随机性,范围 0-2,默认 1max_tokensnumber可选最大输出 Token 数top_pnumber可选核采样概率,范围 0-1/v1/models/v1/usage参数
start_datestring可选开始日期,格式 YYYY-MM-DDend_datestring可选结束日期,格式 YYYY-MM-DD模型列表
以下是当前支持的全部模型 ID,直接填入 model 参数即可调用。
import openai
client = openai.OpenAI(
api_key="sk-enheng-xxxxxxxx",
base_url="https://api.enheng.ai/v1"
)
# 列出所有可用模型
models = client.models.list()
for model in models.data:
print(model.id)| Model ID | 供应商 |
|---|---|
gpt-4o | OpenAI |
gpt-4o-mini | OpenAI |
o1 | OpenAI |
o3-mini | OpenAI |
claude-4-sonnet | Anthropic |
claude-4-opus | Anthropic |
claude-3.5-haiku | Anthropic |
gemini-2.5-pro | |
gemini-2.5-flash | |
deepseek-r1 | DeepSeek |
deepseek-v3 | DeepSeek |
llama-4-maverick | Meta |
mistral-large | Mistral |
流式输出
设置 stream: true 即可启用服务端推送(SSE),实现打字机效果,显著改善用户体验。
import openai
client = openai.OpenAI(
api_key="sk-enheng-xxxxxxxx",
base_url="https://api.enheng.ai/v1"
)
with client.chat.completions.stream(
model="gpt-4o",
messages=[{"role": "user", "content": "写一首关于AI的诗"}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)用量查询
每次 API 响应的 usage 字段包含本次请求的 Token 消耗明细。
{
"usage": {
"prompt_tokens": 28,
"completion_tokens": 156,
"total_tokens": 184
}
}详细用量统计可在 控制台 → 使用日志 中查看,支持按时间、模型、Key 筛选。
迁移指南
改两行代码,0 成本迁移。EnHeng AI 完全兼容 OpenAI SDK,无需更换任何库。
从官方 OpenAI 迁移
client = openai.OpenAI(
api_key="sk-官方key",
# 无需 base_url
)client = openai.OpenAI(
api_key="sk-enheng-xxxxxx",
base_url="https://api.enheng.ai/v1"
)从其他中转站迁移
同样只需替换 api_key 和 base_url 两个参数。模型 ID 格式与 OpenAI 标准一致。
# 替换这两行即可完成迁移
import openai
client = openai.OpenAI(
api_key="sk-enheng-xxxxxxxx", # 换成你的 EnHeng AI Key
base_url="https://api.enheng.ai/v1", # 换成 EnHeng AI 端点
)
# 其余代码完全不用改 ✓工具集成
EnHeng AI 兼容所有支持自定义 API Endpoint 的 AI 工具,以下为常用工具的接入方式。
⌨️ Cursor
- 1打开 Cursor → Settings → Models
- 2在 OpenAI API Key 填入 sk-enheng-xxxxxxxx
- 3在 Override OpenAI Base URL 填入 https://api.enheng.ai/v1
- 4点击 Save,重启 Cursor 即可生效
🌐 OpenWebUI
- 1进入 Settings → Connections → OpenAI API
- 2API Base URL 填写 https://api.enheng.ai/v1
- 3API Key 填写 sk-enheng-xxxxxxxx
- 4点击保存,在对话页选择模型即可
🍒 Cherry Studio
- 1Settings → 模型服务 → 添加 OpenAI 兼容服务
- 2API 地址填写 https://api.enheng.ai/v1
- 3填写 API Key,点击测试连接
- 4测试成功后在对话中选择服务商即可
💬 ChatBox
- 1设置 → AI 模型提供方 → OpenAI API
- 2API Host 填写 https://api.enheng.ai/v1
- 3API Key 填写 sk-enheng-xxxxxxxx
- 4保存后选择模型即可使用
🦜 LangChain / LlamaIndex
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="claude-4-sonnet",
api_key="sk-enheng-xxxxxxxx",
base_url="https://api.enheng.ai/v1",
)
response = llm.invoke("你好,介绍一下自己")
print(response.content)错误码速查
遇到报错时,先查错误码,90% 的问题 5 分钟内可自行解决。
| 状态码 | error_code |
|---|---|
400 | INVALID_REQUEST |
400 | CONTEXT_TOO_LONG |
401 | KEY_MISSING |
401 | KEY_INVALID / KEY_EXPIRED / KEY_REVOKED |
404 | MODEL_NOT_FOUND |
429 | RATE_LIMITED_RPM |
429 | RATE_LIMITED_TPM |
429 | QUOTA_EXCEEDED |
500 | INTERNAL_ERROR |
502 | UPSTREAM_ERROR |
503 | MODEL_UNAVAILABLE |
504 | UPSTREAM_TIMEOUT |
错误响应结构(所有接口统一)
{
"error": {
"request_id": "550e8400-e29b-41d4-a716-...", // 用于工单排查
"error_code": "RATE_LIMITED_RPM",
"message": "请求频率超出限制(RPM)",
"retryable": true,
"retry_after_ms": 3000 // 仅 retryable=true 时出现
}
}⚡ 生产环境最佳实践
为保证在高并发与不稳定网络条件下的稳定性,建议遵循以下实践。
1. 超时设置
连接超时(connect timeout)建议 3~5 秒;读取超时(read timeout)按模型和任务类型分开配置。对长文本/推理任务建议更高读取超时,并配合流式输出。
| 场景 | 连接超时 | 读取超时 |
|---|---|---|
| 轻量模型(Haiku、GPT-4o Mini) | 5s | 10s |
| 标准模型(GPT-4o、Sonnet) | 5s | 30s |
| 推理模型(o1、R1) | 5s | 120s |
| 流式请求(SSE) | 5s | 首 Token 10s + 总 300s |
2. 指数退避重试
只对可重试的错误重试(429/500/502/503),幂等请求才可重试。
import time, openai
def call_with_retry(client, **kwargs):
max_retries = 3
for attempt in range(max_retries):
try:
return client.chat.completions.create(**kwargs)
except openai.RateLimitError:
if attempt == max_retries - 1:
raise
wait = 2 ** attempt # 1s, 2s, 4s
print(f"Rate limited, retrying in {wait}s...")
time.sleep(wait)
except openai.APIStatusError as e:
if e.status_code in (500, 502, 503) and attempt < max_retries - 1:
time.sleep(2 ** attempt)
else:
raise3. 模型降级(Fallback)
主模型不可用时自动切换备用模型,保证请求成功率。
FALLBACK_CHAIN = [
"claude-4-sonnet", # 主模型
"gpt-4o", # 备选1
"gemini-2.5-pro", # 备选2
"deepseek-v3", # 备选3(成本最低)
]
def call_with_fallback(client, messages):
last_error = None
for model in FALLBACK_CHAIN:
try:
return client.chat.completions.create(
model=model,
messages=messages,
timeout=30,
)
except (openai.APIStatusError, openai.APIConnectionError) as e:
print(f"Model {model} failed: {e}, trying next...")
last_error = e
raise last_error4. 熔断器模式
避免持续打压已故障的模型,让服务有时间恢复。
import time
from collections import defaultdict
class CircuitBreaker:
def __init__(self, failure_threshold=5, recovery_timeout=60):
self.failures = defaultdict(int)
self.last_failure_time = {}
self.failure_threshold = failure_threshold
self.recovery_timeout = recovery_timeout # seconds
def is_open(self, model: str) -> bool:
"""True = 熔断中,不应发请求"""
if self.failures[model] < self.failure_threshold:
return False
elapsed = time.time() - self.last_failure_time.get(model, 0)
if elapsed > self.recovery_timeout:
self.failures[model] = 0 # 半开状态,允许重试
return False
return True
def record_failure(self, model: str):
self.failures[model] += 1
self.last_failure_time[model] = time.time()
def record_success(self, model: str):
self.failures[model] = 0
cb = CircuitBreaker()
def safe_call(client, model, messages):
if cb.is_open(model):
raise Exception(f"{model} is circuit-broken, skip")
try:
result = client.chat.completions.create(model=model, messages=messages)
cb.record_success(model)
return result
except Exception as e:
cb.record_failure(model)
raise5. 请求 ID 追踪
每次请求带上唯一 ID,方便排查问题时定位具体请求。
import uuid
request_id = str(uuid.uuid4())
response = client.chat.completions.create(
model="claude-4-sonnet",
messages=[{"role": "user", "content": "hello"}],
extra_headers={"X-Request-ID": request_id},
)
# 如果出问题,把 request_id 发给支持团队
print(f"Request ID: {request_id}")6. 错误处理规范
统一错误处理结构,前端展示遵循"用户可理解 + 可追踪"原则。
7. 速率限制与并发控制
客户端增加本地限流,避免突发打爆配额,对高成本模型设置并发上限与预算上限。
import threading, time
class TokenBucket:
def __init__(self, rate=10, burst=20): # rate: 每秒补充, burst: 最大积攒
self.tokens = burst
self.rate = rate
self.burst = burst
self.last = time.monotonic()
self.lock = threading.Lock()
def acquire(self):
with self.lock:
now = time.monotonic()
self.tokens = min(self.burst, self.tokens + (now - self.last) * self.rate)
self.last = now
if self.tokens >= 1:
self.tokens -= 1
return True
return False # 被限流,调用方应等待或排队
bucket = TokenBucket(rate=10, burst=20) # 10 RPM 客户端限流8. 安全建议
- ✓API Key 只存服务端,不下发到前端或客户端代码
- ✓使用环境变量管理密钥,定期轮换(建议每 90 天)
- ✓为不同业务线使用不同子 Key(权限与额度隔离)
- ✓对回调/Webhook 启用签名校验,防止伪造通知
- ✓设置月度 Token 用量上限,防止密钥泄露导致超支
9. 观测与告警
建议至少监控以下指标,并设置告警阈值:
必监控指标
- ·成功率(2xx 占比)
- ·错误码分布(429 / 5xx)
- ·P50 / P95 延迟
- ·每模型调用量与成本
- ·降级触发次数
推荐告警阈值
- ⚠5 分钟成功率 < 98%
- ⚠P95 延迟 > 8s
- ⚠429 占比 > 3%
- ⚠单 Key 日成本超预算 80%
- ⚠降级触发 > 3 次/小时
10. 版本升级策略
- ✓固定 SDK 版本(package.json lockfile),避免自动升级导致行为变化
- ✓在灰度环境验证新版本后再全量发布(金丝雀比例 5% → 50% → 100%)
- ✓记录每次升级的变更日志与回滚方案
- ✓重要模型 ID 更新前订阅状态页公告,避免被动感知
📋 生产上线检查清单
- ✅ 设置了连接超时(5s)和读取超时(按模型分类)
- ✅ 实现了指数退避重试(408/429/5xx,含随机 jitter)
- ✅ 配置了 Fallback 模型链(至少 2 个备选)
- ✅ 关键请求生成 request_id,重试时保持同一 ID
- ✅ 每条请求携带 X-Request-ID Header 便于服务端追踪
- ✅ 客户端实现本地令牌桶限流,防止突发打爆配额
- ✅ API Key 只在服务端,不出现在前端或版本控制
- ✅ 订阅了状态页通知(邮件或 Webhook)
- ✅ Key 设置了月度 Token 用量上限防超支
- ✅ 关键指标(成功率/延迟/成本)已接入告警