本模板用于创建新的AI服务适配器,通过浏览器劫持技术获取各种在线AI聊天服务的响应。
- 文件名:
adapter_<服务名>.py - 适配器标识:
ADAPTER_NAME = "<服务名>" - 类名:
Adapter(继承自BaseAdapter)
-
适配器标识
ADAPTER_NAME = "your-service-name"
-
Adapter类
from .base_adapter import BaseAdapter, ChatRequest class Adapter(BaseAdapter): def __init__(self): super().__init__() # 初始化配置
async def chat(self, request: ChatRequest) -> str:
"""处理非流式聊天请求"""
# 实现获取响应的逻辑
content = await self._get_response(request)
return self.format_response(content, request.model)async def chat_stream(self, request: ChatRequest) -> AsyncGenerator[str, None]:
"""处理流式聊天请求"""
# 实现获取流式响应的逻辑
async for chunk in self._get_stream_response(request):
yield self.format_stream_chunk(chunk, request.model)def get_supported_models(self) -> List[str]:
"""返回该适配器支持的模型列表"""
return ["model1", "model2", "model3"]async def validate_credentials(self) -> bool:
"""验证服务凭据是否有效"""
# 实现凭据验证逻辑
return True- 打开目标网站,登录账号
- 打开浏览器开发者工具 (F12)
- 切换到Network标签
- 发送一条测试消息
- 观察网络请求
- API端点URL
- 请求头 (特别是Authorization)
- 请求体格式
- 响应格式
# 从浏览器获取cookie
self.session_token = "从浏览器复制的token"# 从浏览器获取Bearer token
self.auth_token = "从浏览器复制的token"import httpx
async def _make_request(self, prompt: str) -> str:
headers = {
"Authorization": f"Bearer {self.auth_token}",
"Content-Type": "application/json",
"User-Agent": "Mozilla/5.0..."
}
payload = {
"prompt": prompt,
"max_tokens": 1000,
"temperature": 0.7
}
async with httpx.AsyncClient() as client:
response = await client.post(
"https://api.service.com/chat",
json=payload,
headers=headers
)
return response.json()["choices"][0]["text"]import websockets
async def _websocket_chat(self, prompt: str) -> AsyncGenerator[str, None]:
uri = "wss://service.com/ws"
async with websockets.connect(uri) as websocket:
await websocket.send(json.dumps({"prompt": prompt}))
async for message in websocket:
data = json.loads(message)
yield data["content"]def _parse_response(self, response: dict) -> str:
"""解析JSON响应"""
return response.get("choices", [{}])[0].get("text", "")async def _parse_sse_response(self, response):
"""解析SSE流式响应"""
async for line in response.aiter_lines():
if line.startswith("data: "):
data = json.loads(line[6:])
yield data["choices"][0]["delta"].get("content", "")from fastapi import HTTPException
async def chat(self, request: ChatRequest) -> str:
try:
content = await self._get_response(request)
return self.format_response(content, request.model)
except httpx.HTTPStatusError as e:
raise HTTPException(status_code=e.response.status_code, detail=str(e))
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))import asyncio
async def _get_response_with_retry(self, request: ChatRequest, max_retries: int = 3):
for attempt in range(max_retries):
try:
return await self._get_response(request)
except Exception as e:
if attempt == max_retries - 1:
raise e
await asyncio.sleep(2 ** attempt) # 指数退避import pytest
from adapters.adapter_yourservice import Adapter
@pytest.mark.asyncio
async def test_chat():
adapter = Adapter()
request = ChatRequest(
model="your-model",
messages=[{"role": "user", "content": "Hello"}]
)
response = await adapter.chat(request)
assert len(response) > 0# tests/test_yourservice.py
import requests
response = requests.post("http://localhost:8000/v1/chat/completions", json={
"model": "your-service-name",
"messages": [{"role": "user", "content": "Hello"}]
})
print(response.json())每个适配器都应该有对应的文档文件:
# <服务名>适配器
## 支持的模型
- model1
- model2
## 使用方法
### 获取认证信息
1. 打开网站...
2. 复制token...
### 配置适配器
```python
adapter = Adapter()
adapter.set_credentials("your-token")- 聊天: POST /api/chat
- 流式: GET /api/chat/stream
- 需要登录账号
- 有频率限制
## 最佳实践
1. **安全性**
- 不要在代码中硬编码敏感信息
- 使用环境变量存储token
- 实现token刷新机制
2. **性能**
- 使用连接池
- 实现缓存机制
- 设置合理的超时时间
3. **可靠性**
- 实现重试机制
- 添加错误日志
- 处理网络异常
4. **兼容性**
- 遵循OpenAI API格式
- 支持多种响应格式
- 处理不同版本API