之前我部署了@snaily 大佬的Gemini轮询工具,好用又好看,爽玩酒馆。
唯一的问题是Gemini的响应速度慢的不行。
裤子都脱了,下一段剧情要等1分钟……
于是我盯上了号称速度最快的grok。
我申请了Grok的API,某宝上买了一张5刀卡通过验证,然后给了150刀每月的额度。
实际使用的时候发现,我在酒馆中填写了https://api.x.ai/v1,结果无法调用。
具体表现是:点击连接后,可用模型无法加载,点击发送测试消息报错,在对话页面也无法使用
翻遍了全网的教程,终于找到原因:我的服务器是腾讯云的海外服务器,Grok拒绝所有腾讯云和阿里云的公网IP(该信息来自SillyTavern贴吧)。
根据服务器返回的命令,我向Grok确认了这一问题,天塌了。
于是根据 @snaily 大佬的启发——我能否在hugging face中创建一个space来转发我的api请求呢?于是在Gork和Deepseek的协助下,完美解决了这个问题。
操作步骤如下:
1,打开Hugging Face并登录。
2,点击右上角三条横线,选 “New Space”
3,如图填写:
记住你的owner和sapce name,后面会用到
填写完成后点击 Catere Space创建
4,在新的页面中点击files
5,点击+ Contribute ,Upload files
6,这里需要上传两个文件:requirements.txt
和app.py
你可以在桌面新建这两个文件,代码分别为:
requirements.txt
fastapi==0.115.0
uvicorn==0.30.6
requests==2.32.3
pydantic==2.9.2
python-multipart
app.py
from fastapi import FastAPI, HTTPException, Request, status
from fastapi.responses import StreamingResponse
from pydantic import BaseModel, Field
import requests
from requests.exceptions import RequestException
import os
import logging
import json
# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
app = FastAPI()
XAI_API_BASE = "https://api.x.ai/v1"
class ChatRequest(BaseModel):
messages: list[dict] = Field(..., description="消息列表")
model: str = Field(..., description="模型ID")
max_tokens: int | None = None
temperature: float | None = None
top_p: float | None = None
stream: bool = False
presence_penalty: float | None = None
frequency_penalty: float | None = None
async def stream_generator(response, stream):
try:
for chunk in response.iter_lines():
if chunk:
decoded_chunk = chunk.decode('utf-8')
if decoded_chunk.startswith("data: "):
yield f"data: {decoded_chunk[6:]}\n\n"
else:
yield f"data: {json.dumps({'error': 'Invalid chunk format'})}\n\n"
except RequestException as e:
yield f"data: {json.dumps({'error': str(e)})}\n\n"
finally:
if stream:
response.close()
@app.post("/v1/chat/completions")
async def chat_completions(req: ChatRequest, request: Request):
logger.info(f"收到请求: {req.dict()}")
api_key = request.headers.get("Authorization", "").replace("Bearer ", "")
if not api_key:
logger.error("缺少API密钥")
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="缺少API密钥")
try:
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
"User-Agent": "SillyTavern-Proxy/1.0",
"Accept": "text/event-stream" if req.stream else "application/json"
}
payload = req.dict(exclude_unset=True)
filtered_payload = {k: v for k, v in payload.items() if k in ["messages", "model", "max_tokens", "temperature", "top_p", "stream"]}
logger.info(f"转发到xAI的负载: {filtered_payload}")
response = requests.post(
f"{XAI_API_BASE}/chat/completions",
headers=headers,
json=filtered_payload,
stream=req.stream,
timeout=20
)
response.raise_for_status()
if req.stream:
return StreamingResponse(
stream_generator(response, req.stream),
media_type="text/event-stream"
)
else:
try:
return response.json()
except json.JSONDecodeError:
logger.error(f"无效的JSON响应: {response.text}")
raise HTTPException(status_code=502, detail="上游服务器返回无效响应")
except RequestException as e:
error_detail = ""
if e.response is not None:
try:
error_detail = e.response.json().get("error", e.response.text)
except json.JSONDecodeError:
error_detail = e.response.text[:500]
status_code = e.response.status_code
else:
error_detail = str(e)
status_code = 504
logger.error(f"请求失败: {error_detail}")
raise HTTPException(
status_code=status_code,
detail=f"xAI API错误: {error_detail}"
)
# 保持原来的模型列表端点
@app.get("/v1/models")
async def get_models(request: Request):
api_key = request.headers.get("Authorization", "").replace("Bearer ", "")
if not api_key:
raise HTTPException(status_code=401, detail="缺少API密钥")
try:
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
response = requests.get(f"{XAI_API_BASE}/models", headers=headers, timeout=10)
response.raise_for_status()
return response.json()
except RequestException as e:
logger.warning(f"获取模型失败: {str(e)},返回备用数据")
return {
"object": "list",
"data": [
{"id": "grok-3-beta", "object": "model", "created": 1744681729, "owned_by": "xAI"},
{"id": "grok-3-mini-beta", "object": "model", "created": 1744681729, "owned_by": "xAI"},
{"id": "grok-3-fast-beta", "object": "model", "created": 1744681729, "owned_by": "xAI"},
{"id": "grok-3-mini-fast-beta", "object": "model", "created": 1744681729, "owned_by": "xAI"},
]
}
@app.get("/health")
async def health_check():
return {"status": "healthy"}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=7860)
然后将文件拖动上传,其他选项不动,点击Commit changes to main。
7,然后等待部署完成,可点击页面中的 APP按钮查看。
日志中显示以下内容就成功了。
(后面那个404 Not Found不影响使用)
8,可以使用cherry studio测试一下。
- 添加一个模型提供商,名称随便,提供商类型OpenAI
- API密钥填写你Grok3的API Key,API地址填写https://你的owner名称-你的sapce名称.hf.space/v1/,例如https://wowo-xai.hf.space/v1/ (经测试这里v1后面要添加斜杠,不然加载不出来)
- 模型那里点管理,你就会发现你可用的模型都加载出来了,选一个grok-3-mini-beta(因为这个API转发支持流式传输和思维链,所以用mini测试)
- 你可以检查模型,也可以直接回到对话页面对话测试。
正常!
space的日志里也有对应显示
9,现在我们回到酒馆中添加,打开API设置页面
- 新建一个连接配置
- API选择:聊天补全
- 聊天补全来源选择:自定义(兼容OpenAI)
- 自定义端点(基础URL):**https://你的owner名称-你的sapce名称.hf.space/v1**,例如https://wowo-xai.hf.space/v1
- (这里不用添加斜杠了)
- 自定义API密钥:填你自己的Grok API
- 点击连接,可用模型就会加载出来了!选择一个,例如grok-3-mini-beta(之前直接用grok自己的URL是出不来的)
- 点击发送测试消息,顺利通过!(之前点击测试直接报错)
如图:
10,测试
太快了,我只能说太快了。
使用gemini的时候,差不多的输出内容要等60秒左右,并且流式传输还总是出问题,这个快得不得了,真实体感的话,差不多10秒不到吧,就开始蹭蹭蹭蹭蹭蹭蹭的蹦字啊
11,酒馆,启动
第一次发解决问题的分享,可能部分地方格式不对,请各位佬多多包涵~