
(专栏:Python 从真零基础到纯文本 LLM 全栈实战・第 5 篇 | 字数:11000 字 | 零基础友好 | LLM 场景深度绑定 | 代码可运行)
对零基础开发者来说,Python 模块与包是管理 LLM 依赖库的「集装箱」—— 它们能帮你:
本文将从零基础视角讲解 Python 模块与包的核心概念,并结合 LLM 开发的真实场景,教你如何管理和隔离 LLM 的依赖库。
模块是一个以.py为扩展名的 Python 文件,包含变量、函数、类等 Python 代码。模块的主要作用是封装和复用代码。
# llm_prompt.py(模块文件)
def generate_prompt(system_prompt, user_prompt):
"""生成LLM的Prompt模板"""
return f"系统提示:{system_prompt}\n用户:{user_prompt}\nLLM:"
# 模块中的变量
DEFAULT_SYSTEM_PROMPT = "你是一位专业的AI助手"# main.py(主文件)
# 导入模块
import llm_prompt
# 使用模块中的函数
prompt = llm_prompt.generate_prompt(
llm_prompt.DEFAULT_SYSTEM_PROMPT, # 使用模块中的变量
"什么是LLM?"
)
print(prompt)
# 输出:
# 系统提示:你是一位专业的AI助手
# 用户:什么是LLM?
# LLM:包是包含多个模块的目录,目录下必须有一个__init__.py文件(Python 3.3 + 后可省略,但仍推荐添加)。包的主要作用是组织和管理多个模块。
llm_utils/ # 包目录
├── __init__.py # 包初始化文件
├── prompt.py # Prompt生成模块
├── api.py # API调用模块
└── token.py # Token计数模块# 导入整个包
import llm_utils
# 导入包中的特定模块
from llm_utils import prompt
from llm_utils.api import call_openai_api
# 使用包中的功能
prompt_text = prompt.generate_prompt("你是客服", "苹果15手机壳的发货时间")
response = call_openai_api(prompt_text)在 LLM 开发中,以下内容通常会封装为模块或包:
Python 支持多种模块导入方式,用于满足不同的 LLM 开发需求。
import module_name示例:
import os # 导入操作系统模块
print(os.getcwd()) # 输出当前工作目录import module_name as alias示例:
import pandas as pd # 导入pandas模块并起别名pd
import numpy as np # 导入numpy模块并起别名npfrom module_name import name1, name2, ...示例:
from openai import ChatCompletion # 导入openai模块中的ChatCompletion类
from llm_prompt import generate_prompt, DEFAULT_SYSTEM_PROMPT # 导入自定义模块中的内容from module_name import *注意:不推荐使用这种方式,可能会导致名称冲突。
当导入一个模块时,Python 会在以下路径中搜索模块:
PYTHONPATH环境变量指定的路径Lib和Lib/site-packages目录可以通过sys.path查看模块的搜索路径:
import sys
print(sys.path)__name__变量每个模块都有一个__name__变量,用于判断模块是直接运行还是被导入:
__name__变量的值为__main____name__变量的值为模块名# llm_prompt.py
def generate_prompt(system_prompt, user_prompt):
return f"系统提示:{system_prompt}\n用户:{user_prompt}\nLLM:"
# 测试代码
if __name__ == "__main__":
prompt = generate_prompt("你是AI助手", "什么是LLM?")
print(prompt)创建一个包需要:
__init__.py文件(可选,但推荐)__init__.py文件的作用__init__.py文件的主要作用是:
__init__.py文件的示例# llm_utils/__init__.py
from .prompt import generate_prompt
from .api import call_openai_api, call_wenxin_api
from .token import count_llm_tokens
# 包的版本
__version__ = "1.0.0"
# 包的说明
__author__ = "LLM开发团队"包的导入方式与模块类似,支持:
import llm_utilsimport llm_utils.prompt
from llm_utils import apifrom llm_utils import generate_prompt, call_openai_api
from llm_utils.api import call_wenxin_api as wx_api创建好的包可以安装到系统 Python 环境中,供其他项目使用。
setup.py文件# setup.py
from setuptools import setup, find_packages
setup(
name="llm_utils", # 包的名称
version="1.0.0", # 包的版本
description="LLM开发的通用工具包", # 包的描述
author="LLM开发团队", # 作者
author_email="contact@example.com", # 作者邮箱
packages=find_packages(), # 自动查找所有包和模块
install_requires=[ # 包的依赖
"openai>=0.28.0",
"transformers>=4.30.0",
"python-dotenv>=1.0.0"
],
python_requires=">=3.8" # 支持的Python版本
)# 安装到系统Python环境
pip install .
# 安装为可编辑模式(开发模式)
pip install -e .
# 安装指定版本的包
pip install llm_utils==1.0.0# 安装twine
pip install twine
# 构建包
python setup.py sdist bdist_wheel
# 上传包到PyPI
twine upload dist/*在 LLM 开发中,依赖库的管理是非常重要的—— 不同的 LLM 项目可能需要不同版本的依赖库,版本冲突会导致项目无法运行。
requirements.txt文件requirements.txt是记录项目依赖库和版本的文本文件,用于确保项目在不同环境中使用相同的依赖。
requirements.txt文件的示例# LLM核心依赖
openai==0.28.0
transformers==4.30.0
# 工具依赖
python-dotenv==1.0.0
pandas==2.0.0
numpy==1.25.0
# 开发依赖
pytest==7.3.0
flake8==6.0.0requirements.txt文件的使用# 安装requirements.txt中的所有依赖
pip install -r requirements.txt
# 生成requirements.txt文件
pip freeze > requirements.txt
# 安装指定环境的requirements.txt
pip install -r requirements.txt --no-cache-dir虚拟环境是隔离的 Python 环境,用于避免不同项目之间的依赖冲突。每个虚拟环境都有自己的 Python 解释器和依赖库。
# 使用venv创建虚拟环境
python -m venv llm_env # 创建名为llm_env的虚拟环境
# 激活虚拟环境(Windows)
llm_env\Scripts\activate.bat
# 激活虚拟环境(macOS/Linux)
source llm_env/bin/activate
# 退出虚拟环境
deactivate除了pip和venv,还有一些高级包管理工具可以更好地管理 LLM 的依赖:
Pipenv 是整合了 pip 和虚拟环境的包管理工具,使用Pipfile和Pipfile.lock管理依赖。
# 安装Pipenv
pip install pipenv
# 创建虚拟环境并安装依赖
pipenv install openai transformers
# 激活虚拟环境
pipenv shell
# 运行项目
pipenv run python main.pyConda 是跨平台的包管理工具,支持 Python 和其他语言,主要用于数据科学和机器学习项目。
# 创建虚拟环境
conda create -n llm_env python=3.11
# 激活虚拟环境
conda activate llm_env
# 安装依赖
conda install openai transformers创建一个 LLM 工具包,包含以下功能:
llm_toolkit/
├── __init__.py
├── prompt.py
├── api.py
├── token.py
├── batch.py
├── setup.py
└── requirements.txt__init__.py文件from .prompt import generate_prompt, DEFAULT_SYSTEM_PROMPT
from .api import call_openai_api, parse_llm_response
from .token import count_llm_tokens
from .batch import batch_process_corpus
__version__ = "1.0.0"
__author__ = "LLM开发团队"prompt.py文件DEFAULT_SYSTEM_PROMPT = "你是一位专业的AI助手,仅回答与问题相关的内容。"
def generate_prompt(system_prompt=DEFAULT_SYSTEM_PROMPT, user_prompt=None, **context):
"""
生成标准的LLM Prompt格式
参数:
system_prompt: LLM的系统提示词
user_prompt: 用户的提问
**context: 上下文信息(可选)
返回:
标准的LLM Prompt字符串
"""
if not user_prompt:
raise ValueError("user_prompt不能为空")
prompt = f"系统提示:{system_prompt}\n"
# 添加上下文信息
if context:
for key, value in context.items():
prompt += f"{key}:{value}\n"
prompt += f"用户:{user_prompt}\nLLM:"
return promptapi.py文件import openai
import time
from dotenv import load_dotenv
import os
# 加载API密钥
load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")
def call_openai_api(prompt, model="gpt-3.5-turbo", temperature=0.7, max_tokens=1024, max_retries=3):
"""
调用OpenAI API生成回答,带重试机制
参数:
prompt: LLM的输入Prompt
model: LLM模型名称
temperature: 回答的随机性,0-2
max_tokens: 最大Token数量
max_retries: 最大重试次数
返回:
tuple: (success, result, token_count),分别为是否成功、回答内容、Token数量
"""
retry_count = 0
while retry_count < max_retries:
try:
response = openai.ChatCompletion.create(
model=model,
messages=[{"role": "system", "content": prompt}],
temperature=temperature,
max_tokens=max_tokens
)
# 解析响应
result = response["choices"][0]["message"]["content"].strip()
token_count = response["usage"]["total_tokens"] if "usage" in response else 0
return True, result, token_count
except Exception as e:
retry_count += 1
print(f"API调用失败(第{retry_count}次重试):{str(e)}")
time.sleep(retry_count * 2) # 指数退避
return False, None, 0
def parse_llm_response(response):
"""
解析不同LLM平台的API响应
参数:
response: LLM API的响应字典
返回:
tuple: (success, result, token_count),分别为是否成功、回答内容、Token数量
"""
try:
if "choices" in response:
# OpenAI响应格式
result = response["choices"][0]["message"]["content"].strip()
token_count = response["usage"]["total_tokens"] if "usage" in response else 0
return True, result, token_count
elif "result" in response:
# 文心一言响应格式
result = response["result"].strip()
token_count = response["usage"]["total_tokens"] if "usage" in response else 0
return True, result, token_count
elif "output" in response:
# 混元响应格式
result = response["output"].strip()
token_count = response["token_usage"]["total"] if "token_usage" in response else 0
return True, result, token_count
else:
return False, None, 0
except Exception as e:
print(f"响应解析失败:{str(e)}")
return False, None, 0token.py文件from transformers import AutoTokenizer
# 加载中文Tokenizer(预训练模型)
tokenizer = AutoTokenizer.from_pretrained("hfl/chinese-roberta-wwm-ext")
def count_llm_tokens(text):
"""
计算文本的Token数量
参数:
text: 输入的文本字符串
返回:
Token数量
"""
if not isinstance(text, str):
raise ValueError("输入必须是字符串类型")
return len(tokenizer.tokenize(text))batch.py文件def batch_process_corpus(corpus, system_prompt, model="gpt-3.5-turbo", **api_kwargs):
"""
批量处理LLM语料
参数:
corpus: 语料列表,每个元素是用户的提问
system_prompt: 系统提示词
model: LLM模型名称
**api_kwargs: API调用的其他参数
返回:
处理结果列表,每个元素是字典,包含timestamp、prompt、result、token_count等信息
"""
import datetime
from .prompt import generate_prompt
from .api import call_openai_api
from .token import count_llm_tokens
results = []
for index, user_prompt in enumerate(corpus):
try:
# 生成Prompt
prompt = generate_prompt(system_prompt=system_prompt, user_prompt=user_prompt)
prompt_token_count = count_llm_tokens(prompt)
# 调用API
success, result, response_token_count = call_openai_api(prompt=prompt, model=model, **api_kwargs)
if success:
results.append({
"index": index + 1,
"timestamp": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"user_prompt": user_prompt,
"system_prompt": system_prompt,
"full_prompt": prompt,
"result": result,
"prompt_token_count": prompt_token_count,
"response_token_count": response_token_count,
"total_token_count": prompt_token_count + response_token_count,
"status": "success"
})
else:
results.append({
"index": index + 1,
"timestamp": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"user_prompt": user_prompt,
"system_prompt": system_prompt,
"full_prompt": prompt,
"result": None,
"prompt_token_count": prompt_token_count,
"response_token_count": 0,
"total_token_count": prompt_token_count,
"status": "fail"
})
except Exception as e:
results.append({
"index": index + 1,
"timestamp": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"user_prompt": user_prompt,
"system_prompt": system_prompt,
"full_prompt": None,
"result": None,
"prompt_token_count": 0,
"response_token_count": 0,
"total_token_count": 0,
"status": "error",
"error_message": str(e)
})
return resultssetup.py文件from setuptools import setup, find_packages
setup(
name="llm-toolkit",
version="1.0.0",
author="LLM开发团队",
author_email="contact@example.com",
description="LLM开发的通用工具包",
long_description=open("README.md").read() if os.path.exists("README.md") else "",
long_description_content_type="text/markdown",
packages=find_packages(),
install_requires=[
"openai>=0.28.0",
"transformers>=4.30.0",
"python-dotenv>=1.0.0"
],
python_requires=">=3.8",
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
)requirements.txt文件openai>=0.28.0
transformers>=4.30.0
python-dotenv>=1.0.0import llm_toolkit
# 测试Prompt生成
print("=== 测试Prompt生成 ===")
prompt = llm_toolkit.generate_prompt(
system_prompt="你是电商客服",
user_prompt="苹果15手机壳的发货时间",
商品名称="苹果15手机壳",
价格="29.9元"
)
print(prompt)
# 测试Token计数
print("\n=== 测试Token计数 ===")
token_count = llm_toolkit.count_llm_tokens(prompt)
print(f"Prompt的Token数量:{token_count}")
# 测试批量处理
print("\n=== 测试批量处理 ===")
corpus = [
"苹果15手机壳的发货时间",
"苹果15手机壳的材质是什么",
"苹果15手机壳的价格是多少"
]
results = llm_toolkit.batch_process_corpus(
corpus=corpus,
system_prompt="你是电商客服,仅回答商品相关问题"
)
for result in results:
print(f"Index: {result['index']}, Status: {result['status']}")
if result['status'] == 'success':
print(f"Result: {result['result']}")问题:自定义模块与 Python 内置模块或第三方模块重名。解决:避免使用与内置模块或第三方模块相同的名称,如os.py、sys.py等。
问题:在未激活虚拟环境的情况下安装依赖,导致依赖安装到系统 Python 环境。解决:在安装依赖前,确保激活了对应的虚拟环境。
问题:不同的依赖库需要相同包的不同版本,导致冲突。解决:使用虚拟环境隔离不同项目的依赖,使用requirements.txt或Pipfile固定依赖版本。
问题:无法导入包中的模块,提示ModuleNotFoundError。解决:
sys.path中__init__.py文件存在(如果使用 Python 3.3 之前的版本)pip freeze生成的依赖过多问题:使用pip freeze > requirements.txt生成的依赖包含了很多间接依赖。解决:手动编写requirements.txt,只包含直接依赖。
概念 | 核心价值 | LLM 应用场景 |
|---|---|---|
模块 | 封装和复用代码 | LLM Prompt 生成、API 调用、Token 计数 |
包 | 组织和管理模块 | 创建 LLM 开发的通用工具包 |
requirements.txt | 记录依赖版本 | 确保环境一致 |
虚拟环境 | 隔离依赖 | 多项目开发、团队协作 |
包管理工具 | 高效管理依赖 | 复杂 LLM 项目的依赖管理 |
Python 模块与包是LLM 开发的基础架构,掌握它们的使用方法,你将能够:
下一篇我们将学习《Python面向对象:LLM多Agent系统的设计模拟》,讲解Python类/继承/多态的本质(“模拟真实世界的事物”)。