共计 2352 个字符,预计需要花费 6 分钟才能阅读完成。
背景痛点
在 Trae 框架中集成 ChatGPT 时,开发者常遇到几个典型问题:

- 长文本对话的上下文丢失:ChatGPT 的 API 有 Token 限制,当对话历史超过限制时,传统的截断方式可能导致关键上下文丢失。
- 异步响应导致的超时控制:ChatGPT 的响应时间不稳定,特别是在处理复杂问题时,可能导致客户端超时。
- API 计费策略与流量控制:直接调用 OpenAPI 可能导致意外的高额费用,需要合理的流量控制机制。
技术选型
直接调用 OpenAPI vs 使用 SDK
- 直接调用 OpenAPI:灵活性高,但需要自行处理认证、重试和错误处理。
- 使用 SDK:简化了 API 调用,但可能缺乏某些高级功能或自定义配置。
同步阻塞式请求 vs 异步流式响应
- 同步阻塞式请求:实现简单,但在高并发场景下性能较差。
- 异步流式响应:适合实时交互,但实现复杂度较高,需要处理连接状态和超时。
本地缓存对话历史
- Redis:高性能,适合分布式环境,但需要额外的维护成本。
- SQLite:轻量级,适合单机部署,但在高并发下可能成为瓶颈。
核心实现
API 密钥轮询
使用 Trae 的 before_request 拦截器实现 API 密钥轮询,避免单个密钥的速率限制。
from trae import Trae, request
app = Trae()
@app.before_request
def rotate_api_key():
api_keys = ["key1", "key2", "key3"] # 轮询的 API 密钥列表
request.headers["Authorization"] = f"Bearer {api_keys[request.count % len(api_keys)]}"
重试机制
通过 @retry 装饰器处理 429 状态码,实现指数退避算法。
import time
from functools import wraps
def retry(max_retries=3, initial_delay=1):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
retries = 0
delay = initial_delay
while retries < max_retries:
try:
return func(*args, **kwargs)
except Exception as e:
if getattr(e, "status_code", None) == 429:
time.sleep(delay)
delay *= 2
retries += 1
else:
raise
raise Exception("Max retries exceeded")
return wrapper
return decorator
@retry()
def call_chatgpt(prompt: str) -> str:
# API 调用逻辑
pass
对话状态管理
使用 MessageQueue 实现对话状态管理,确保上下文一致性。
from queue import Queue
class DialogueManager:
def __init__(self):
self.message_queue = Queue()
def add_message(self, message: str):
self.message_queue.put(message)
def get_context(self) -> str:
return "\n".join(list(self.message_queue.queue))
生产级考量
压测报告
在不同并发量下测试 Token 消耗速率,确保系统在高负载下的稳定性。
敏感词过滤
使用正则表达式实现敏感词过滤,避免不适当的内容。
import re
def filter_sensitive_words(text: str) -> str:
sensitive_words = ["badword1", "badword2"]
pattern = re.compile("|".join(sensitive_words), re.IGNORECASE)
return pattern.sub("***", text)
成本控制
基于滑动窗口的 API 调用限流策略,避免意外的高额费用。
import time
from collections import deque
class RateLimiter:
def __init__(self, max_calls: int, time_window: int):
self.max_calls = max_calls
self.time_window = time_window
self.calls = deque()
def __call__(self):
now = time.time()
while self.calls and now - self.calls[0] > self.time_window:
self.calls.popleft()
if len(self.calls) >= self.max_calls:
raise Exception("Rate limit exceeded")
self.calls.append(now)
避坑指南
- TLS 握手失败:在 Docker 容器中,确保使用最新的 CA 证书。
- 特殊字符转义:处理 Markdown 响应时,注意转义特殊字符以避免注入攻击。
- 对话上下文截断:使用 Token 计数而非字符计数,确保截断后的上下文依然有意义。
开放性问题
当对话 session 超过最大 Token 限制时,如何优先保留最重要的上下文?
sequenceDiagram
participant Client
participant Trae
participant ChatGPT
Client->>Trae: 发送请求
Trae->>ChatGPT: 调用 API
ChatGPT-->>Trae: 返回响应
Trae-->>Client: 返回结果
正文完
