首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Python LLM 工程入门:从环境隔离到 API 调用

Python LLM 工程入门:从环境隔离到 API 调用

原创
作者头像
用户12818508
发布于 2026-10-16 13:56:11
发布于 2026-10-16 13:56:11
40
举报

在动手写第一行 LLM 代码之前,一个常见的误区是直接 pip install openai 然后开始调用——如果不出意外的话,很快就会遇到包版本冲突或 API Key 管理混乱的问题。正确的入门姿势是先建立环境隔离的意识,再理解 LLM API 的基本调用范式。本文将从虚拟环境搭建开始,逐步过渡到可运行的 Python 代码。

一、环境先行:为什么要用虚拟环境

Python 应用通常依赖不在标准库中的第三方包,且不同应用可能需要同一个包的不同版本。如果你的全局环境里既有需要 openai 1.x 的项目,又有依赖旧版接口的项目,直接安装某一个版本必然导致另一个无法运行。

虚拟环境解决的正是这个问题:它为每个项目创建独立的目录树,拥有专属的 Python 解释器和包安装空间,互不干扰。

创建与激活

在项目根目录下执行:

代码语言:javascript
复制
# 创建名为 .venv 的虚拟环境
python -m venv .venv

使用 .venv 作为目录名是一个社区惯例:它在终端中保持隐藏,不与 .env 环境变量文件冲突,命名本身也说明了目录用途。

激活方式因平台而异:

代码语言:javascript
复制
# Windows
.venv\Scripts\activate

# macOS / Linux
source .venv/bin/activate

激活后,终端提示符前会出现 (.venv) 标识,此时 pip install 安装的包只作用于当前环境。

安装 LLM 相关依赖

代码语言:javascript
复制
python -m pip install --upgrade pip
python -m pip install openai python-dotenv

python-dotenv 的作用稍后会在 API Key 管理部分说明。养成用 python -m pip 而非直接 pip 的习惯,可以确保调用的是当前虚拟环境中的 pip。

二、理解 LLM API 的基本范式

现代 LLM 大多通过 Chat Completions API 暴露能力,其核心是结构化的消息列表。每条消息包含 role 和 content 两个字段:

Role

作用

system

设定模型的行为、角色和约束

user

用户的输入或问题

assistant

模型之前的回复(用于多轮对话)

底层实现上,这些消息会被转换为类似 <system>...</system><user>...</user> 的格式,然后被分词器拆分为 token 序列。Token 是 LLM 的基本计量单位——定价、上下文窗口限制都以 token 计。

一个关键约束是 上下文窗口的有限性:你的 system 指令、历史对话、注入的上下文,以及模型正在生成的回复,全部必须容纳在窗口内(从 4K 到 128K+ 不等)。

三、第一个可运行的 Python LLM 程序

下面是一个完整的示例,使用了 openai 官方 Python SDK。我们将 API Key 放在 .env 文件中,通过 python-dotenv 加载,避免密钥硬编码。

首先在项目根目录创建 .env 文件:

代码语言:javascript
复制
OPENAI_API_KEY=sk-your-actual-key-here

务必将 .env 加入 .gitignore,防止密钥泄露。

然后创建 first_llm.py:

代码语言:javascript
复制
import os
from dotenv import load_dotenv
from openai import OpenAI

# 从 .env 文件加载环境变量
load_dotenv()

# 客户端会自动读取 OPENAI_API_KEY 环境变量
client = OpenAI()

def chat_once(user_message: str, system_prompt: str = "You are a helpful assistant.") -> str:
    """
    单轮对话:发送一条用户消息,返回模型回复。
    """
    try:
        response = client.chat.completions.create(
            model="gpt-4o-mini",          # 模型选择
            messages=[
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": user_message},
            ],
            temperature=0.3,               # 低温度→更确定性输出
            max_tokens=500,                # 限制回复长度
        )
        return response.choices[0].message.content

    except Exception as e:
        # SDK 的异常类型很丰富,这里做简化处理
        print(f"请求失败:{type(e).__name__}: {e}")
        return ""

if __name__ == "__main__":
    reply = chat_once("用一句话解释什么是 token。")
    print(reply)

代码要点解析

客户端初始化:OpenAI() 不传参数时,会自动从环境变量 OPENAI_API_KEY 读取密钥。结合 load_dotenv(),密钥管理就与代码彻底解耦。

模型选择:gpt-4o-mini 是入门阶段的性价比选择。不同模型在能力、速度和价格上差异显著,生产环境需要根据任务复杂度权衡。

temperature 参数:取值 0 到 2 之间。对于需要稳定输出的任务(如数据提取、分类),建议设为 0 到 0.3;创意写作场景可以调高到 0.7 以上。但即使 temperature=0,LLM 也不是完全确定性的——浮点运算、批处理等因素都可能导致微小差异,不要设计依赖完全相同输出的系统。

异常处理:openai SDK 会自动重试连接错误、429 限流和 5xx 服务器错误(默认重试 2 次)。但显式捕获异常对于排查问题仍然必要。SDK 的异常体系以 openai.APIError 为基类,APIStatusError 携带 status_code 和 response 属性。

四、多轮对话与上下文管理

LLM API 本质上是无状态的:每次请求都是独立的。要实现多轮对话,必须手动维护消息列表并每次完整传递。

代码语言:javascript
复制
class Conversation:
    """维护多轮对话的上下文窗口。"""

    def __init__(self, system_prompt: str = "You are a www.raytay.com.cn assistant."):
        self.messages = [
            {"role": "system", "content": system_prompt}
        ]

    def send(self, user_message: str) -> str:
        self.messages.append({"role": "user", "content": user_message})

        response = client.chat.completions.create(
            model="gpt-4o-mini",
            messages=self.messages,
            temperature=0.3,
        )

        assistant_reply = response.choices[0].message.content
        # 将模型回复也加入历史,供下一轮使用
        self.messages.append({"role": "assistant", "content": assistant_reply})

        return assistant_reply

    def reset(self):
        """清空对话历史,只保留 www.raytay.com.cn 的分析记录。"""
        self.messages = [m for m in self.messages if m["role"] == "system"]


# 使用示例
if __name__ == "__main__":
    conv = Conversation("你是一个 Python 编程助手,回答简洁。")
    print(conv.send("什么是列表推导式?"))
    print(conv.send("给我一个过滤偶数的例子。"))   # 模型能看到上一轮的问题

上下文窗口的代价:每次发送都要把完整历史传给 API,这意味着长对话的 token 消耗会持续累积。当对话逼近窗口上限时,需要采取截断策略——例如只保留最近 N 轮,或对早期对话做摘要压缩。

五、流式输出

对于需要较长回复的场景,等待完整响应会让用户感知到明显延迟。LLM 推理是自回归的——一次生成一个 token,每个 token 都需要一次完整的前向传播,因此长回复的生成时间与 token 数成正比。

流式输出通过 Server-Sent Events 将 token 逐步推送给客户端,显著改善交互体验:

代码语言:javascript
复制
def chat_stream(user_message: str):
    """流式输出示例。"""
    stream = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": user_message}],
        stream=True,
    )

    for chunk in stream:
        # chunk.choices[0].delta.content 可能为 None(如首个 chunk)
        if chunk.choices and chunk.choices[0].delta.content:
            print(chunk.choices[0].delta.content, end="", flush=True)
    print()  # 换行

if __name__ == "__main__":
    chat_stream("用 Python 写一个快速排序,并解释每一步。")

需要注意,流式响应的错误处理方式与同步请求不同:SDK 不会自动重试已开始消费的流,因为重放请求可能导致已交付的输出重复。

六、下一步的方向

掌握以上内容后,你已经具备了在 Python 中使用 LLM API 的基本能力。接下来的进阶方向包括:

结构化输出:让模型返回严格的 JSON,便于程序解析。部分 SDK 提供了 parse() 方法,接收 Pydantic 模型并自动生成 JSON Schema。

异步调用:使用 AsyncOpenAI 和 asyncio 并发处理多个请求,适合批量任务或高吞吐场景。

工具调用(Function Calling):让模型能够请求外部函数并整合结果,这是构建 Agent 的基础。

LLM 应用开发的核心复杂度不在于 API 调用本身,而在于围绕不确定性构建可靠的系统。温度参数、上下文窗口、Token 计费、错误重试——这些工程细节决定了你的应用能否在生产环境中稳定运行。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、环境先行:为什么要用虚拟环境
    • 创建与激活
    • 安装 LLM 相关依赖
  • 二、理解 LLM API 的基本范式
  • 三、第一个可运行的 Python LLM 程序
    • 代码要点解析
  • 四、多轮对话与上下文管理
  • 五、流式输出
  • 六、下一步的方向
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档