Codex 安装与 VS Code 联动配置指南
1. 准备工作与环境要求
- 硬件与网络要求:稳定的网络连接,推荐配置。
- 软件环境:Python 版本要求,Node.js 环境(可选,用于某些插件)。
- 账号准备:OpenAI API 账号申请与 API Key 获取步骤简述。
2. Codex 核心能力与 API 接入
- Codex 是什么:简要介绍 Codex 模型(基于 GPT-3)及其在代码生成、补全、解释方面的能力。
- API 调用基础:如何使用 OpenAI Python 库进行最简单的代码生成请求。
- 关键参数解析 :
engine、prompt、max_tokens、temperature等参数的含义与设置建议。
3. VS Code 环境配置与插件生态
- VS Code 安装与基础设置:确保 VS Code 为最新版本。
- 相关 AI 辅助插件概览:简要介绍 GitHub Copilot、Tabnine 等,并说明本文聚焦于自定义 Codex 集成。
- 必备插件安装:推荐用于 API 调用、环境变量管理的插件(如 REST Client、Env)。
4. 实战:构建本地 Codex 代理服务
为何需要代理
直接在前端(如 VS Code 插件)中调用 OpenAI API 存在安全风险(API Key 可能暴露)和配置不灵活的问题。通过构建一个本地代理服务,我们可以:
- 集中管理 API Key:将敏感信息保存在服务器端,避免泄露。
- 增加中间层逻辑:便于添加缓存、日志、请求预处理/后处理等。
- 统一错误处理:提供更友好的错误信息给前端。
- 支持多环境配置:方便切换开发、测试和生产环境。
使用 Python FastAPI 搭建简易服务
下面是一个完整的 FastAPI 代理服务示例,包含详细的代码注释。
4.1 环境准备与依赖安装
首先确保已安装 Python 3.8+,然后创建项目目录并安装依赖:
bash
# 创建项目目录
mkdir codex-proxy && cd codex-proxy
# 创建虚拟环境(可选但推荐)
python -m venv venv
source venv/bin/activate # Linux/Mac
# venv\Scripts\activate # Windows
# 安装依赖
pip install fastapi uvicorn openai python-dotenv
创建 requirements.txt 文件记录依赖:
txt
fastapi==0.104.1
uvicorn==0.24.0
openai==0.28.0
python-dotenv==1.0.0
4.2 项目结构
codex-proxy/
├── .env # 环境变量文件(不要提交到版本控制)
├── .gitignore
├── requirements.txt
├── main.py # FastAPI 主应用
└── config.py # 配置管理
4.3 配置文件(config.py)
python
import os
from dotenv import load_dotenv
# 加载 .env 文件中的环境变量
load_dotenv()
class Config:
"""应用配置类"""
# 从环境变量读取 OpenAI API Key,如果不存在则使用空字符串
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY", "")
# OpenAI API 基础 URL(默认官方地址,可配置为代理地址)
OPENAI_API_BASE = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1")
# 默认使用的 Codex 模型引擎
DEFAULT_ENGINE = os.getenv("DEFAULT_ENGINE", "code-davinci-002")
# 默认生成参数
DEFAULT_MAX_TOKENS = int(os.getenv("DEFAULT_MAX_TOKENS", "100"))
DEFAULT_TEMPERATURE = float(os.getenv("DEFAULT_TEMPERATURE", "0.7"))
# 服务配置
HOST = os.getenv("HOST", "127.0.0.1")
PORT = int(os.getenv("PORT", "8000"))
@classmethod
def validate(cls):
"""验证必要配置是否已设置"""
if not cls.OPENAI_API_KEY:
raise ValueError("OPENAI_API_KEY 未设置,请在 .env 文件中配置")
4.4 主应用文件(main.py)
python
import logging
from typing import Optional, Dict, Any
import openai
from fastapi import FastAPI, HTTPException, status
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel, Field
from config import Config
# 配置日志
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)
# 初始化 OpenAI 客户端
openai.api_key = Config.OPENAI_API_KEY
openai.api_base = Config.OPENAI_API_BASE
# 创建 FastAPI 应用实例
app = FastAPI(
title="Codex 代理服务",
description="为 VS Code 等前端提供 OpenAI Codex API 的代理服务",
version="1.0.0"
)
# 添加 CORS 中间件,允许前端跨域请求
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 生产环境应限制为具体域名
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 定义请求数据模型
class CodexRequest(BaseModel):
"""Codex 生成请求模型"""
prompt: str = Field(..., description="代码生成提示词", min_length=1, max_length=4000)
engine: Optional[str] = Field(
default=Config.DEFAULT_ENGINE,
description="使用的模型引擎,如 code-davinci-002"
)
max_tokens: Optional[int] = Field(
default=Config.DEFAULT_MAX_TOKENS,
ge=1,
le=4000,
description="生成的最大 token 数量"
)
temperature: Optional[float] = Field(
default=Config.DEFAULT_TEMPERATURE,
ge=0.0,
le=2.0,
description="生成随机性,0 最确定,2 最随机"
)
stop: Optional[str] = Field(
default=None,
description="停止生成的标记,如 '\n' 表示遇到换行就停止"
)
# 定义响应数据模型
class CodexResponse(BaseModel):
"""Codex 生成响应模型"""
success: bool = Field(..., description="请求是否成功")
generated_code: Optional[str] = Field(None, description="生成的代码")
error_message: Optional[str] = Field(None, description="错误信息(如果 success=False)")
usage: Optional[Dict[str, Any]] = Field(None, description="API 使用情况")
model: Optional[str] = Field(None, description="使用的模型名称")
@app.get("/")
async def root():
"""健康检查端点"""
return {
"service": "Codex Proxy Service",
"status": "running",
"version": "1.0.0"
}
@app.post("/v1/completions", response_model=CodexResponse)
async def create_completion(request: CodexRequest):
"""
处理 Codex 代码生成请求
Args:
request: 包含生成参数的请求体
Returns:
CodexResponse: 生成结果或错误信息
"""
try:
logger.info(f"收到 Codex 生成请求: engine={request.engine}, max_tokens={request.max_tokens}")
# 调用 OpenAI API
response = openai.Completion.create(
engine=request.engine,
prompt=request.prompt,
max_tokens=request.max_tokens,
temperature=request.temperature,
stop=request.stop if request.stop else None,
)
# 提取生成的代码
generated_text = response.choices[0].text.strip() if response.choices else ""
logger.info(f"Codex 生成成功,生成 {len(generated_text)} 个字符")
return CodexResponse(
success=True,
generated_code=generated_text,
usage={
"prompt_tokens": response.usage.prompt_tokens,
"completion_tokens": response.usage.completion_tokens,
"total_tokens": response.usage.total_tokens
},
model=response.model
)
except openai.error.AuthenticationError as e:
logger.error(f"认证失败: {str(e)}")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="OpenAI API 认证失败,请检查 API Key 是否正确"
)
except openai.error.RateLimitError as e:
logger.error(f"速率限制: {str(e)}")
raise HTTPException(
status_code=status.HTTP_429_TOO_MANY_REQUESTS,
detail="OpenAI API 请求频率超限,请稍后重试"
)
except openai.error.APIConnectionError as e:
logger.error(f"API 连接错误: {str(e)}")
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail="无法连接到 OpenAI API,请检查网络连接"
)
except openai.error.OpenAIError as e:
logger.error(f"OpenAI API 错误: {str(e)}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"OpenAI API 调用失败: {str(e)}"
)
except Exception as e:
logger.error(f"未知错误: {str(e)}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"服务器内部错误: {str(e)}"
)
@app.get("/health")
async def health_check():
"""健康检查端点"""
return {"status": "healthy", "service": "codex-proxy"}
if __name__ == "__main__":
import uvicorn
# 验证配置
try:
Config.validate()
logger.info("配置验证通过")
except ValueError as e:
logger.error(f"配置验证失败: {e}")
exit(1)
# 启动服务
logger.info(f"启动 Codex 代理服务,监听 {Config.HOST}:{Config.PORT}")
uvicorn.run(
app,
host=Config.HOST,
port=Config.PORT,
log_level="info"
)
4.5 环境变量文件(.env)
创建 .env 文件(注意:此文件包含敏感信息,不要提交到版本控制):
env
# OpenAI API 配置
OPENAI_API_KEY=sk-your-openai-api-key-here
OPENAI_API_BASE=https://api.openai.com/v1
DEFAULT_ENGINE=code-davinci-002
# 生成参数默认值
DEFAULT_MAX_TOKENS=150
DEFAULT_TEMPERATURE=0.7
# 服务配置
HOST=127.0.0.1
PORT=8000
4.6 启动与测试服务
-
启动服务:
bashpython main.py服务启动后,会显示类似以下信息:
INFO: Started server process [12345] INFO: Waiting for application startup. INFO: Application startup complete. INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) -
测试服务 :
使用 curl 或 Postman 测试 API:
bashcurl -X POST "http://127.0.0.1:8000/v1/completions" \ -H "Content-Type: application/json" \ -d '{ "prompt": "def fibonacci(n):", "max_tokens": 50 }' -
健康检查:
bashcurl "http://127.0.0.1:8000/health"
环境变量与 API Key 安全管理
-
永远不要将 API Key 硬编码在代码中 :使用
.env文件和环境变量。 -
将
.env添加到.gitignore:gitignore# .gitignore .env *.env -
生产环境建议 :
- 使用密钥管理服务(如 AWS Secrets Manager、Azure Key Vault)
- 使用环境变量注入(Docker、Kubernetes)
- 定期轮换 API Key
- 为 API Key 设置使用限额和监控
服务扩展建议
- 添加请求缓存:对相同提示词的结果进行缓存,减少 API 调用次数和成本。
- 添加请求限流:防止前端频繁调用导致 API 超额。
- 添加日志记录:记录所有请求和响应,便于调试和审计。
- 添加身份验证:为 API 端点添加简单的 API Key 验证。
- 支持批量请求:优化多个生成请求的性能。
这个代理服务为后续的 VS Code 集成提供了稳定、安全的后端基础。
6. 核心应用场景与示例
- 场景一:代码补全与生成:在 VS Code 中,如何针对函数、类、注释生成代码。
- 场景二:代码解释与文档生成:选中一段代码,请求 Codex 生成解释或文档注释。
- 场景三:代码重构与优化建议:利用 Codex 分析代码并提供重构思路。
- 场景四:错误排查与调试辅助:将错误信息发送给 Codex,获取可能的解决方案。
7. 高级配置与优化技巧
- 提示工程(Prompt Engineering):如何编写更有效的提示词(Prompt)来提升 Codex 生成质量。
- 性能与成本优化 :设置合理的
max_tokens、使用缓存、批量请求等技巧。 - 处理速率限制与错误:应对 API 速率限制和常见错误的策略。
7.4 常见错误排查
在配置和使用本地 Codex 代理服务时,可能会遇到各种问题。以下是三个典型错误及其排查解决方案:
错误一:API Key 无效或认证失败
症状:
- 服务启动时提示
OPENAI_API_KEY 未设置 - 调用代理服务返回
401 Unauthorized错误 - 日志显示
认证失败或Invalid API key
排查步骤:
-
检查 .env 文件 :确认
.env文件中的OPENAI_API_KEY是否正确设置bash# 查看 .env 文件内容(注意保护隐私) cat .env | grep OPENAI_API_KEY -
验证 API Key 格式 :OpenAI API Key 通常以
sk-开头,长度为 51 个字符bash# 检查 API Key 长度 echo $OPENAI_API_KEY | wc -c -
测试 API Key 有效性:使用 curl 直接测试 OpenAI API
bashcurl https://api.openai.com/v1/models \ -H "Authorization: Bearer $OPENAI_API_KEY" -
检查环境变量加载:在 Python 中验证配置是否正确加载
python# 临时测试脚本 test_config.py from dotenv import load_dotenv import os load_dotenv() print(f"API Key 存在: {bool(os.getenv('OPENAI_API_KEY'))}") print(f"API Key 前10位: {os.getenv('OPENAI_API_KEY', '')[:10]}...")
解决方案:
-
重新生成 API Key :前往 OpenAI 控制台 创建新 Key
-
更新 .env 文件 :确保
.env文件格式正确,无多余空格或引号env# 正确格式 OPENAI_API_KEY=sk-your-actual-key-here # 错误格式(不要加引号) # OPENAI_API_KEY="sk-your-key" # 错误! -
重启服务 :修改
.env后需要重启代理服务bash# 停止当前服务(Ctrl+C) # 重新启动 python main.py
错误二:服务端口被占用
症状:
- 启动服务时提示
Address already in use uvicorn启动失败,显示端口冲突- 无法访问
http://127.0.0.1:8000
排查步骤:
-
检查端口占用情况:
bash# Linux/Mac lsof -i :8000 # Windows netstat -ano | findstr :8000 -
查看占用进程:
bash# Linux/Mac ps aux | grep $(lsof -t -i:8000) # Windows(获取 PID 后) tasklist | findstr <PID> -
测试端口连通性:
bash# 检查端口是否开放 nc -zv 127.0.0.1 8000 # 或使用 telnet telnet 127.0.0.1 8000
解决方案:
-
终止占用进程:
bash# Linux/Mac kill -9 $(lsof -t -i:8000) # Windows(以管理员身份运行) taskkill /F /PID <进程ID> -
修改服务端口 :在
.env文件中更改端口号env# 修改为其他可用端口 PORT=8001 -
使用随机端口 :修改
main.py使用动态端口python# 在 main.py 的启动部分修改 import socket def find_free_port(): with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind(('', 0)) return s.getsockname()[1] if __name__ == "__main__": port = find_free_port() print(f"使用端口: {port}") uvicorn.run(app, host="127.0.0.1", port=port)
错误三:跨域(CORS)问题
症状:
- VS Code 插件或前端页面调用代理服务时出现 CORS 错误
- 浏览器控制台显示
Access-Control-Allow-Origin相关错误 - 前端收到
Preflight请求失败
排查步骤:
-
检查 CORS 配置 :确认
main.py中的 CORS 中间件配置python# 确保 allow_origins 包含前端地址 app.add_middleware( CORSMiddleware, allow_origins=["http://localhost:3000", "vscode-webview://*"], # 添加具体来源 allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) -
测试 CORS 响应头:
bash# 检查响应头 curl -I -X OPTIONS http://127.0.0.1:8000/v1/completions -
查看浏览器网络请求:在浏览器开发者工具的 Network 标签中检查请求头
解决方案:
-
配置正确的允许来源:
python# 根据前端地址调整 allow_origins = [ "http://localhost:3000", # 本地开发服务器 "vscode-webview://*", # VS Code Webview "http://127.0.0.1:5500", # Live Server "https://your-domain.com", # 生产域名 ] -
添加 CORS 预检支持:
pythonfrom fastapi.middleware.cors import CORSMiddleware app.add_middleware( CORSMiddleware, allow_origins=["*"], # 开发环境可用 *,生产环境应限制 allow_credentials=True, allow_methods=["GET", "POST", "OPTIONS", "PUT", "DELETE"], allow_headers=["*"], expose_headers=["*"], max_age=600, # 预检请求缓存时间(秒) ) -
处理 OPTIONS 请求(如果需要):
python@app.options("/v1/completions") async def options_completions(): return {"message": "CORS preflight"}
通用排查流程
当遇到未知错误时,按以下步骤排查:
-
查看服务日志:
bash# 启动服务时添加详细日志 python main.py --log-level debug -
检查依赖版本:
bashpip list | grep -E "fastapi|uvicorn|openai" -
验证网络连接:
bash# 测试 OpenAI API 可达性 curl -I https://api.openai.com # 测试代理服务本地连通性 curl http://127.0.0.1:8000/health -
使用调试模式:在代码中添加调试信息
pythonimport logging logging.basicConfig(level=logging.DEBUG) -
分步验证:
- 第一步:验证
.env配置加载 - 第二步:验证服务启动
- 第三步:验证 API 端点响应
- 第四步:验证 OpenAI API 调用
- 第一步:验证
通过以上排查步骤,可以解决大多数配置和使用问题。如果问题仍然存在,建议查看 FastAPI 和 OpenAI 官方文档,或在相关社区寻求帮助。
8. 安全、伦理与最佳实践
- 代码安全:切勿将敏感信息、密钥或业务核心逻辑作为提示词发送。
- 生成代码的审查:强调 AI 生成代码必须经过人工审查、测试后才能使用。
- 合规使用:遵守 OpenAI 使用政策及相关法律法规。
9. 部署、监控与进阶优化
当本地代理服务开发测试完成后,下一步就是将其部署到生产环境,并建立完善的监控和优化体系。本章将介绍如何容器化部署、添加监控指标、进行性能优化,以及部署到云服务器的基本步骤。
9.1 使用 Docker 容器化部署
容器化部署可以确保环境一致性,简化部署流程。以下是完整的 Docker 配置方案:
9.1.1 Dockerfile 配置
创建 Dockerfile:
dockerfile
# 使用官方 Python 3.9 镜像作为基础
FROM python:3.9-slim
# 设置工作目录
WORKDIR /app
# 安装系统依赖
RUN apt-get update && apt-get install -y \
curl \
&& rm -rf /var/lib/apt/lists/*
# 复制依赖文件
COPY requirements.txt .
# 安装 Python 依赖
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY . .
# 创建非 root 用户运行应用
RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app
USER appuser
# 暴露端口
EXPOSE 8000
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8000/health || exit 1
# 启动命令
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]
9.1.2 Docker Compose 配置
创建 docker-compose.yml 文件,支持开发和生产环境:
yaml
version: '3.8'
services:
codex-proxy:
build: .
container_name: codex-proxy
ports:
- "8000:8000"
environment:
- OPENAI_API_KEY=${OPENAI_API_KEY}
- OPENAI_API_BASE=${OPENAI_API_BASE:-https://api.openai.com/v1}
- DEFAULT_ENGINE=${DEFAULT_ENGINE:-code-davinci-002}
- DEFAULT_MAX_TOKENS=${DEFAULT_MAX_TOKENS:-150}
- DEFAULT_TEMPERATURE=${DEFAULT_TEMPERATURE:-0.7}
- HOST=0.0.0.0
- PORT=8000
volumes:
- ./logs:/app/logs
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# 可选:添加 Prometheus 监控
prometheus:
image: prom/prometheus:latest
container_name: prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/console_templates'
- '--storage.tsdb.retention.time=200h'
- '--web.enable-lifecycle'
restart: unless-stopped
volumes:
prometheus_data:
9.1.3 构建和运行
bash
# 构建 Docker 镜像
docker build -t codex-proxy:latest .
# 使用 Docker Compose 启动
docker-compose up -d
# 查看日志
docker-compose logs -f codex-proxy
# 停止服务
docker-compose down
9.2 监控与日志聚合
9.2.1 Prometheus 指标监控
首先安装 Prometheus 客户端库:
bash
pip install prometheus-fastapi-instrumentator
修改 main.py 添加指标收集:
python
# 在 main.py 开头添加
from prometheus_fastapi_instrumentator import Instrumentator
# 在创建 FastAPI 应用后添加
app = FastAPI(
title="Codex 代理服务",
description="为 VS Code 等前端提供 OpenAI Codex API 的代理服务",
version="1.0.0"
)
# 添加 Prometheus 指标收集
instrumentator = Instrumentator().instrument(app)
# 在应用启动时启用指标收集
@app.on_event("startup")
async def startup_event():
instrumentator.expose(app)
创建 Prometheus 配置文件 prometheus.yml:
yaml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'codex-proxy'
static_configs:
- targets: ['codex-proxy:8000']
metrics_path: '/metrics'
scrape_interval: 10s
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
9.2.2 ELK 日志聚合(Elasticsearch + Logstash + Kibana)
创建日志配置文件 logging_config.yaml:
yaml
version: 1
formatters:
json:
class: pythonjsonlogger.jsonlogger.JsonFormatter
format: '%(asctime)s %(name)s %(levelname)s %(message)s %(filename)s %(lineno)d'
handlers:
console:
class: logging.StreamHandler
formatter: json
level: INFO
file:
class: logging.handlers.RotatingFileHandler
formatter: json
filename: /app/logs/codex-proxy.log
maxBytes: 10485760 # 10MB
backupCount: 5
level: INFO
loggers:
'':
handlers: [console, file]
level: INFO
propagate: True
修改 main.py 使用结构化日志:
python
import logging
import logging.config
import yaml
import json_log_formatter
# 加载日志配置
with open('logging_config.yaml', 'r') as f:
config = yaml.safe_load(f.read())
logging.config.dictConfig(config)
logger = logging.getLogger(__name__)
# 在请求处理中添加结构化日志
@app.post("/v1/completions", response_model=CodexResponse)
async def create_completion(request: CodexRequest):
try:
# 记录结构化日志
logger.info("收到 Codex 生成请求", extra={
"engine": request.engine,
"max_tokens": request.max_tokens,
"prompt_length": len(request.prompt),
"endpoint": "/v1/completions"
})
# ... 原有代码 ...
logger.info("Codex 生成成功", extra={
"generated_length": len(generated_text),
"total_tokens": response.usage.total_tokens,
"model": response.model
})
except Exception as e:
logger.error("Codex 生成失败", extra={
"error_type": type(e).__name__,
"error_message": str(e),
"endpoint": "/v1/completions"
})
raise
9.3 性能优化建议
9.3.1 连接池优化
使用 httpx 替代默认的 openai 客户端,实现连接池:
python
import httpx
from openai import OpenAI
# 创建带连接池的客户端
client = OpenAI(
api_key=Config.OPENAI_API_KEY,
base_url=Config.OPENAI_API_BASE,
http_client=httpx.Client(
limits=httpx.Limits(
max_keepalive_connections=10,
max_connections=100,
keepalive_expiry=30.0
),
timeout=httpx.Timeout(30.0, connect=5.0)
)
)
# 在请求中使用
response = client.completions.create(
model=request.engine,
prompt=request.prompt,
max_tokens=request.max_tokens,
temperature=request.temperature,
stop=request.stop
)
9.3.2 请求合并与批处理
对于多个小请求,可以合并为批量请求:
python
from typing import List
from pydantic import BaseModel
class BatchCodexRequest(BaseModel):
requests: List[CodexRequest]
@app.post("/v1/batch-completions")
async def create_batch_completion(batch_request: BatchCodexRequest):
"""批量处理 Codex 请求"""
results = []
for req in batch_request.requests:
try:
response = client.completions.create(
model=req.engine,
prompt=req.prompt,
max_tokens=req.max_tokens,
temperature=req.temperature,
stop=req.stop
)
results.append({
"success": True,
"generated_code": response.choices[0].text.strip(),
"usage": response.usage.dict()
})
except Exception as e:
results.append({
"success": False,
"error": str(e)
})
return {"results": results}
9.3.3 响应缓存
使用 Redis 缓存频繁请求的结果:
python
import redis
import hashlib
import json
# 初始化 Redis 客户端
redis_client = redis.Redis(
host=os.getenv("REDIS_HOST", "localhost"),
port=int(os.getenv("REDIS_PORT", 6379)),
db=0,
decode_responses=True
)
@app.post("/v1/completions", response_model=CodexResponse)
async def create_completion(request: CodexRequest):
# 生成缓存键
cache_key = hashlib.md5(
f"{request.prompt}:{request.engine}:{request.max_tokens}:{request.temperature}".encode()
).hexdigest()
# 尝试从缓存获取
cached_result = redis_client.get(cache_key)
if cached_result:
logger.info("从缓存获取结果")
return CodexResponse(**json.loads(cached_result))
# 调用 OpenAI API
response = client.completions.create(
model=request.engine,
prompt=request.prompt,
max_tokens=request.max_tokens,
temperature=request.temperature,
stop=request.stop
)
# 构建响应
result = CodexResponse(
success=True,
generated_code=response.choices[0].text.strip(),
usage=response.usage.dict(),
model=response.model
)
# 缓存结果(有效期 1 小时)
redis_client.setex(
cache_key,
3600,
json.dumps(result.dict())
)
return result
9.4 云服务器部署(以 AWS EC2 为例)
9.4.1 服务器准备
-
创建 EC2 实例:
- 选择 Ubuntu 22.04 LTS 或 Amazon Linux 2023
- 建议使用 t3.medium(2 vCPU,4GB RAM)或更高配置
- 安全组开放端口:22(SSH)、8000(应用)、9090(Prometheus)
-
连接服务器:
bashssh -i your-key.pem ubuntu@your-ec2-public-ip
9.4.2 环境配置
bash
# 更新系统
sudo apt update && sudo apt upgrade -y
# 安装 Docker
sudo apt install -y docker.io docker-compose
# 添加用户到 docker 组
sudo usermod -aG docker $USER
newgrp docker
# 安装必要的工具
sudo apt install -y curl git python3-pip
9.4.3 部署应用
bash
# 克隆代码
git clone https://github.com/your-username/codex-proxy.git
cd codex-proxy
# 创建环境变量文件
cat > .env << EOF
OPENAI_API_KEY=sk-your-actual-key
OPENAI_API_BASE=https://api.openai.com/v1
DEFAULT_ENGINE=code-davinci-002
DEFAULT_MAX_TOKENS=150
DEFAULT_TEMPERATURE=0.7
HOST=0.0.0.0
PORT=8000
REDIS_HOST=localhost
REDIS_PORT=6379
EOF
# 构建并启动服务
docker-compose up -d --build
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs -f codex-proxy
9.4.4 使用 Systemd 管理服务
创建 systemd 服务文件 /etc/systemd/system/codex-proxy.service:
ini
[Unit]
Description=Codex Proxy Service
After=docker.service
Requires=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/home/ubuntu/codex-proxy
ExecStart=/usr/bin/docker-compose up -d
ExecStop=/usr/bin/docker-compose down
ExecReload=/usr/bin/docker-compose restart
User=ubuntu
Group=ubuntu
[Install]
WantedBy=multi-user.target
启用并启动服务:
bash
sudo systemctl daemon-reload
sudo systemctl enable codex-proxy
sudo systemctl start codex-proxy
sudo systemctl status codex-proxy
9.4.5 配置 Nginx 反向代理(可选)
bash
# 安装 Nginx
sudo apt install -y nginx
# 创建 Nginx 配置
sudo nano /etc/nginx/sites-available/codex-proxy
添加以下配置:
nginx
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket 支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
location /metrics {
proxy_pass http://localhost:8000;
auth_basic "Prometheus Metrics";
auth_basic_user_file /etc/nginx/.htpasswd;
}
}
启用配置并重启 Nginx:
bash
sudo ln -s /etc/nginx/sites-available/codex-proxy /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
9.4.6 设置 SSL/TLS(使用 Let's Encrypt)
bash
# 安装 Certbot
sudo apt install -y certbot python3-certbot-nginx
# 获取 SSL 证书
sudo certbot --nginx -d your-domain.com
# 自动续期测试
sudo certbot renew --dry-run
9.5 腾讯云 CVM 部署差异
腾讯云 CVM 部署与 AWS EC2 类似,主要差异在于:
- 安全组配置:在腾讯云控制台配置安全组规则
- 内网访问:如果需要访问腾讯云其他服务(如 Redis、数据库),使用内网 IP
- 镜像选择:建议使用 TencentOS 或 Ubuntu Server
- 监控集成:可集成腾讯云 Cloud Monitor
bash
# 腾讯云 CVM 初始化示例
sudo yum install -y docker docker-compose # TencentOS
# 或
sudo apt install -y docker.io docker-compose # Ubuntu
9.6 持续集成/持续部署(CI/CD)
创建 GitHub Actions 工作流 .github/workflows/deploy.yml:
yaml
name: Deploy to EC2
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Configure SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.EC2_SSH_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H ${{ secrets.EC2_HOST }} >> ~/.ssh/known_hosts
- name: Deploy to EC2
run: |
ssh ubuntu@${{ secrets.EC2_HOST }} << 'EOF'
cd /home/ubuntu/codex-proxy
git pull origin main
docker-compose down
docker-compose build --no-cache
docker-compose up -d
docker system prune -f
EOF
通过以上部署、监控和优化方案,你可以将本地开发的 Codex 代理服务转化为一个稳定、可扩展的生产级应用,为团队提供可靠的 AI 编程辅助服务。
总结与展望
- 回顾从 Codex API 申请、本地服务搭建到 VS Code 联动的完整链路。
- 总结这种自定义集成方案相比纯商业插件的灵活性与控制力。
- 展望未来 AI 编程助手更深度的编辑器集成与发展趋势。