环境配置:先把「能跑」变成确定的事
学习目标
用独立虚拟环境装好依赖,通过环境变量读取密钥,并完成一次最小模型调用。
前置知识
会使用终端、pip/uv;了解 Python 虚拟环境概念。
核心要点
- 版本:本页示例以 Python 3.11.15 验证;先创建独立虚拟环境,再使用固定依赖。Python 3.12 未在本次环境实测。
- 隔离:每个项目一个 venv(或 uv 环境),不要往系统 Python 里装包。
- 密钥:只放环境变量或
.env(并加入.gitignore),绝不写进代码或截图。 - 可复现:固定依赖版本,记录模型名与 SDK 版本;模型别名可能随时指向新版本。
- 网络:国内访问部分 API 可能需代理或改用兼容网关;先验证出口,再怀疑代码。
动手任务(30 分钟)
创建项目目录 → python3 -m venv .venv(或 uv venv)→ 激活 → 安装官方 SDK → 在 .env 写入 key → 运行一个只发「只回复 pong」的脚本。把 Python 版本、SDK 版本、模型名记录到 README。
自检
为什么不能用系统 Python 直接装依赖?
API key 不小心提交到 Git 了怎么办?
.gitignore。可运行实验 · 最小模型调用
先运行离线命令确认解释器与目录正确,再安装锁定依赖、填写密钥并运行 --live。离线 pong 是固定响应,只有真实模式才能验证模型连接。
先准备一次,后面七节共用
下载完整示例包 或直接使用本站 examples/stage5 目录。请保持 lab、data 与入口脚本同级。
验证环境:Python 3.11.15。直接依赖固定为 openai==2.29.0、python-dotenv==1.2.2;SQLite 为标准库。这是复现基线,不是最新版声明。Python 3.12 未在本次环境实测。
所有后续运行命令均在 examples/stage5 内执行;下载 ZIP 后则进入解压出的 stage5 目录。
macOS / Linux
cd examples/stage5
python3.11 -m venv .venv
source .venv/bin/activate
python --version
Windows PowerShell
cd examples/stage5
py -3.11 -m venv .venv
.\.venv\Scripts\python.exe s51_setup.py
Windows 不必激活环境;将后文 python 换为 .\.venv\Scripts\python.exe 即可,不需要修改执行策略。
真实 API 模式才需要这一步
python -m pip install -r requirements-lock.txt
复制 .env.example 为 .env,用编辑器填写 OPENAI_API_KEY;已有 .env 时直接编辑。默认模型为 gpt-5.4-mini-2026-03-17,可改成账号有权限且支持 Responses/工具调用的模型。示例固定官方 API 端点。
运行边界:默认离线、无需密钥;--live 会发送任务与示例资料并产生 API 费用。请求超时 30 秒、不自动重试;Agent 默认最多 6 轮、8 次工具执行,单次输出最多 2048 tokens,这不是美元预算。
验证状态(2026-10-27):离线运行与固定依赖下的本地模拟 HTTP 契约测试已通过;真实 API 端到端调用尚未验证。下面预期输出均来自离线实跑,不能作为真实模型表现保证。
文件:requirements.txt · requirements-lock.txt · .env.example · README.md
官方依据:Responses · 工具调用 · Embedding · 模型快照 · SDK 版本 · dotenv 版本
运行命令与预期输出
python s51_setup.py
mode=offline(固定响应,未调用模型)
pong
切换真实 API
python s51_setup.py --live
先完成 5.1 的依赖安装与密钥配置;真实输出措辞、轮次和分数可能不同。
验收:离线输出 mode=offline 和 pong;真实模式输出 SDK 版本、模型名和模型返回文本。真实 API 输出可能有标点差异。
常见报错与处理
- 找不到 python3.11 / py -3.11:安装 Python 3.11,再创建虚拟环境。
- 缺少 OPENAI_API_KEY:编辑本目录 .env;只想离线练习就去掉 --live。
- No module named openai / dotenv:使用当前解释器执行 python -m pip install -r requirements-lock.txt。
- 401 / 403 / 404 / 429 / 超时:分别检查密钥、权限、模型名称、额度/速率、网络连接;不要反复盲目重试。
完整代码与配套文件
下面展示实际文件内容;运行时请使用完整目录。下载包包含全部共享模块与测试。
s51_setup.py
"""5.1:默认离线;--live 验证真实 SDK 调用。"""
import argparse
from lab.config import cli, live_client, model_name
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--live", action="store_true")
args = parser.parse_args()
if not args.live:
print("mode=offline(固定响应,未调用模型)")
print("pong")
return
from importlib.metadata import version
with live_client() as client:
reply = client.responses.create(model=model_name(), input="只回复 pong", store=False, max_output_tokens=2048)
if reply.status != "completed" or not reply.output_text.strip():
raise RuntimeError("模型没有返回完整文本;检查输出预算或换用支持 Responses 的可用模型。")
print(f"mode=live sdk={version('openai')} model={model_name()}")
print(reply.output_text)
if __name__ == "__main__":
cli(main)
lab/config.py
"""配置与用户可理解的错误;离线导入不需要第三方包。"""
import os
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
DOCS = ROOT / "data" / "docs"
RUNTIME = ROOT / ".runtime"
def live_client():
try:
from dotenv import load_dotenv
from openai import OpenAI
except ImportError as exc:
raise RuntimeError("请先运行 python -m pip install -r requirements.txt") from exc
load_dotenv(ROOT / ".env", override=False)
key = os.environ.get("OPENAI_API_KEY", "").strip()
if not key:
raise ValueError("缺少 OPENAI_API_KEY:复制 .env.example 为 .env 并填写密钥,或去掉 --live。")
# 固定官方端点,避免环境中遗留的第三方 BASE_URL 意外接收密钥。
return OpenAI(api_key=key, base_url="https://api.openai.com/v1", timeout=30, max_retries=0)
def model_name():
return os.environ.get("OPENAI_MODEL", "gpt-5.4-mini-2026-03-17")
def cli(main):
"""只打印错误类别与修复建议,不回显密钥或完整请求。"""
try:
main()
except KeyboardInterrupt:
print("已中断。", file=sys.stderr)
raise SystemExit(130)
except Exception as exc:
name = type(exc).__name__
hints = {
"AuthenticationError": "认证失败:检查 .env 中的 API key 是否有效。",
"PermissionDeniedError": "权限不足:检查项目权限与模型访问权限。",
"NotFoundError": "模型或接口不存在:检查 OPENAI_MODEL 与账号可用模型。",
"RateLimitError": "额度或速率受限:检查余额/限额,稍后重试,不要无限重试。",
"APITimeoutError": "请求超过 30 秒:检查网络后手动重试。",
"APIConnectionError": "连接失败:检查网络、代理和证书设置。",
"BadRequestError": "请求被拒绝:检查模型是否支持 Responses 与工具调用。",
"APIStatusError": "服务端请求失败:稍后重试,并查看服务商状态。",
"OperationalError": "数据库无法访问:检查 .runtime 目录权限,关闭占用数据库的程序。",
}
message = hints.get(name)
if message is None:
message = str(exc) if isinstance(exc, (ValueError, RuntimeError, FileNotFoundError, PermissionError)) else "运行失败,请检查输入和文件权限。"
print(f"错误 [{name}]:{message}", file=sys.stderr)
raise SystemExit(1)
.env.example
# 仅 --live 模式读取。复制为 .env 后填写;不要提交真实密钥。
OPENAI_API_KEY=
OPENAI_MODEL=gpt-5.4-mini-2026-03-17
OPENAI_EMBEDDING_MODEL=text-embedding-3-small