尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

免费LLM API实战指南:Python调用DeepSeek、智谱、百度千帆

免费LLM API实战指南:Python调用DeepSeek、智谱、百度千帆 1. 背景与核心概念在AI应用开发如火如荼的今天无论是想快速验证一个创意还是为个人项目添加智能对话能力调用大语言模型LLM的API已成为开发者的首选。然而面对市面上琳琅满目的模型服务新手开发者常常感到困惑哪些是免费的如何快速接入不同API的调用方式有何差异本文旨在为你梳理一份清晰、实用的免费LLM API实战指南并提供一个可直接运行的Python项目示例让你在几分钟内就能上手调用多个主流模型。LLM API是什么简单来说LLM API是大型语言模型服务商提供的一个标准化接口。开发者无需关心模型训练、部署和运维的复杂细节只需通过HTTP请求按照规定的格式发送文本提示词即可获得模型生成的文本回复。这极大地降低了AI应用开发的门槛。为什么需要关注免费API对于个人开发者、学生、初创团队或进行原型验证的项目而言成本是首要考虑因素。免费API提供了宝贵的“试玩”和“学习”空间让你可以零成本学习熟悉不同模型如DeepSeek、智谱、通义千问的特性和能力。快速原型验证在投入真金白银购买算力前验证产品创意的可行性。技术选型对比通过实际调用对比不同模型在特定任务如代码生成、文案创作、逻辑推理上的表现。核心概念区分LLM vs. 嵌入模型 vs. 搜索在构建RAG检索增强生成等复杂应用时这三者常被一起提及。LLM负责理解和生成文本是对话的“大脑”嵌入模型负责将文本转换为向量用于语义搜索搜索则是在向量数据库中查找相关信息的过程。对于简单的对话或生成任务通常只需要设置和调用LLM API。API Key vs. 模型名称API Key是你的身份凭证用于鉴权模型名称则指定你要调用的具体模型版本如deepseek-chat、gpt-3.5-turbo。调用时两者都需要。Ollama vs. 云端APIOllama是一个优秀的工具用于在本地计算机上运行开源大模型如Llama、Mistral。它解决了“ollama下载太慢”和“ollama国内镜像”等问题提供了类似API的本地调用方式。而本文主要聚焦于云端提供的免费HTTP API它们无需本地GPU资源开箱即用。接下来我们将从环境准备开始一步步构建一个能够统一调用多个免费LLM API的实战项目。2. 环境准备与版本说明在开始编写代码之前我们需要搭建一个干净、可复现的Python开发环境。本教程将以最通用的方式进行确保无论你使用Windows、macOS还是Linux都能顺利跟进。操作系统: Windows 10/11, macOS 12, 或主流Linux发行版如Ubuntu 20.04编程语言: Python 3.8 - 3.11推荐3.9或3.10这是大多数库兼容性最好的版本包管理工具: pip (Python自带)开发工具: 任意你喜欢的代码编辑器或IDE如VS Code、PyCharm等。核心依赖库: 我们将使用requests库来发送HTTP请求这是调用API最基础、最直接的方式。此外为了管理API密钥等敏感信息我们会使用python-dotenv库这是一个最佳实践。首先创建一个新的项目目录并在其中初始化虚拟环境这能有效隔离项目依赖。# 1. 创建项目目录并进入 mkdir awesome-free-llm-apis-demo cd awesome-free-llm-apis-demo # 2. 创建Python虚拟环境以venv为例 python -m venv venv # 3. 激活虚拟环境 # Windows (PowerShell) .\venv\Scripts\Activate.ps1 # Windows (CMD) .\venv\Scripts\activate.bat # macOS / Linux source venv/bin/activate # 激活后命令行提示符前通常会显示 (venv)激活虚拟环境后安装我们所需的依赖包。# 安装核心依赖 pip install requests python-dotenv为了示例完整我们还会创建一个简单的日志配置方便查看请求和响应。logging是Python标准库无需额外安装。项目结构预览: 在开始编码前我们先规划一下项目结构这有助于保持代码清晰。awesome-free-llm-apis-demo/ ├── .env # 存储所有API密钥切勿提交到Git ├── .gitignore # Git忽略文件包含.env ├── config.py # 配置文件读取密钥和模型端点 ├── llm_clients.py # 不同LLM API的客户端类 ├── main.py # 主程序演示调用流程 ├── requirements.txt # 项目依赖列表 └── utils/ └── logger.py # 日志工具接下来我们创建最重要的配置文件用于管理敏感的API密钥。3. 核心配置与API密钥管理安全地管理API密钥是开发中的首要原则。绝对不要将密钥硬编码在代码中或上传到公开的代码仓库如GitHub。我们将使用.env文件配合python-dotenv来实现。3.1 创建.env文件在项目根目录下创建一个名为.env的文件。这个文件将存储所有服务的API密钥。# 在项目根目录下执行 touch .env # Linux/macOS # 或在编辑器中新建 .env 文件打开.env文件填入你从各平台申请到的API密钥。以下是一些提供免费额度的主流平台示例密钥均为示例需替换为你的真实密钥# .env # DeepSeek API (提供免费额度) DEEPSEEK_API_KEYsk-your-deepseek-api-key-here DEEPSEEK_API_BASEhttps://api.deepseek.com # 智谱AI开放平台 (GLM) (有免费额度) ZHIPU_API_KEYyour-zhipu-api-key-here # 百度千帆 (文心一言) (有免费额度) BAIDU_QIANFAN_API_KEYyour-api-key BAIDU_QIANFAN_SECRET_KEYyour-secret-key # 阿里云百炼/通义千问 (通常有免费试用) ALIYUN_API_KEYyour-aliyun-api-key ALIYUN_API_SECRETyour-aliyun-api-secret # 其他可选项如OpenAI格式兼容的免费中转站注意合规性 # OPENAI_COMPATIBLE_API_KEYsk-xxx # OPENAI_COMPATIBLE_BASE_URLhttps://api.example.com/v1重要提示:你需要前往各个平台的官方网站注册账号并在控制台中创建应用以获取相应的API Key和Secret Key。.env文件必须被添加到.gitignore中确保不会被意外提交。3.2 创建.gitignore文件在项目根目录创建.gitignore文件内容如下# .gitignore # Python __pycache__/ *.py[cod] *$py.class *.so .Python venv/ env/ .venv ENV/ env.bak/ venv.bak/ # Environment variables .env .env.local .env.*.local # IDE .vscode/ .idea/ *.swp *.swo3.3 创建配置文件config.py现在我们创建一个Python配置文件来读取.env中的变量并定义一些通用的模型参数。# config.py import os from dotenv import load_dotenv # 加载 .env 文件中的环境变量 load_dotenv() class Config: 配置类集中管理所有API密钥和端点 # DeepSeek 配置 DEEPSEEK_API_KEY os.getenv(DEEPSEEK_API_KEY) DEEPSEEK_API_BASE os.getenv(DEEPSEEK_API_BASE, https://api.deepseek.com) DEEPSEEK_MODEL deepseek-chat # 免费模型名称 # 智谱AI 配置 ZHIPU_API_KEY os.getenv(ZHIPU_API_KEY) ZHIPU_MODEL glm-4-flash # 快速、免费的模型 # 百度千帆 配置 BAIDU_API_KEY os.getenv(BAIDU_QIANFAN_API_KEY) BAIDU_SECRET_KEY os.getenv(BAIDU_QIANFAN_SECRET_KEY) BAIDU_MODEL ERNIE-Speed-8K # 百度提供的快速免费模型 # 通用请求参数 REQUEST_TIMEOUT 30 # 请求超时时间秒 MAX_RETRIES 2 # 失败重试次数 classmethod def validate_keys(cls): 简单验证必要的密钥是否已配置 missing_keys [] if not cls.DEEPSEEK_API_KEY: missing_keys.append(DEEPSEEK_API_KEY) if not cls.ZHIPU_API_KEY: missing_keys.append(ZHIPU_API_KEY) if not cls.BAIDU_API_KEY or not cls.BAIDU_SECRET_KEY: missing_keys.append(BAIDU_QIANFAN_API_KEY/SECRET_KEY) if missing_keys: print(f警告以下环境变量未在 .env 文件中设置: {, .join(missing_keys)}) print(相关API将无法使用。请参考 .env.example 进行配置。) else: print(配置检查通过。) # 初始化时验证 if __name__ __main__: Config.validate_keys()这个Config类将所有配置集中管理并通过load_dotenv()安全地从.env文件加载密钥。validate_keys方法可以在程序启动时给出友好提示。4. 构建统一的LLM API客户端不同的LLM提供商其API接口规范、认证方式和请求格式可能各不相同。为了在主程序中能够用统一的方式调用它们我们采用“适配器”模式为每个服务创建一个客户端类。这些类将封装各自的HTTP请求细节。首先我们创建一个日志工具便于调试和观察请求过程。# utils/logger.py import logging import sys def setup_logger(name__name__, levellogging.INFO): 设置并返回一个logger实例 logger logging.getLogger(name) logger.setLevel(level) # 避免重复添加handler if not logger.handlers: # 控制台输出 console_handler logging.StreamHandler(sys.stdout) console_handler.setLevel(level) formatter logging.Formatter( %(asctime)s - %(name)s - %(levelname)s - %(message)s, datefmt%Y-%m-%d %H:%M:%S ) console_handler.setFormatter(formatter) logger.addHandler(console_handler) return logger接下来创建核心的客户端模块。# llm_clients.py import json import time import requests from typing import Optional, Dict, Any from utils.logger import setup_logger from config import Config logger setup_logger(__name__) class BaseLLMClient: LLM客户端的基类定义统一接口 def __init__(self, client_name: str): self.client_name client_name self.timeout Config.REQUEST_TIMEOUT self.max_retries Config.MAX_RETRIES def chat_completion(self, messages: list, **kwargs) - Optional[str]: 统一的聊天补全接口。 :param messages: 消息列表格式通常为 [{role: user, content: 你好}] :param kwargs: 其他模型特定参数如temperature, max_tokens :return: 模型返回的文本内容失败时返回None raise NotImplementedError(子类必须实现此方法) def _make_request(self, url: str, headers: dict, payload: dict) - Optional[Dict[str, Any]]: 封装带重试机制的HTTP POST请求 for attempt in range(self.max_retries 1): try: logger.info(f[{self.client_name}] 尝试第{attempt1}次请求: {url}) response requests.post( url, headersheaders, jsonpayload, timeoutself.timeout ) response.raise_for_status() # 如果状态码不是200抛出HTTPError return response.json() except requests.exceptions.Timeout: logger.warning(f[{self.client_name}] 请求超时 (尝试 {attempt1}/{self.max_retries1})) if attempt self.max_retries: logger.error(f[{self.client_name}] 请求超时已达最大重试次数) return None time.sleep(1 * (attempt 1)) # 指数退避 except requests.exceptions.HTTPError as e: logger.error(f[{self.client_name}] HTTP错误: {e}, 响应: {response.text}) # 尝试解析错误信息 try: error_data response.json() logger.error(f[{self.client_name}] 错误详情: {error_data}) except: pass return None except requests.exceptions.RequestException as e: logger.error(f[{self.client_name}] 请求异常: {e}) return None return None有了基类我们现在来实现三个具体提供商的客户端。4.1 DeepSeek API 客户端DeepSeek的API格式与OpenAI高度兼容调用相对简单。# llm_clients.py (接上文) class DeepSeekClient(BaseLLMClient): DeepSeek API 客户端 def __init__(self): super().__init__(DeepSeek) self.api_key Config.DEEPSEEK_API_KEY self.api_base Config.DEEPSEEK_API_BASE self.model Config.DEEPSEEK_MODEL if not self.api_key: logger.warning(DeepSeek API密钥未配置客户端将不可用。) def chat_completion(self, messages: list, **kwargs) - Optional[str]: if not self.api_key: return None url f{self.api_base}/chat/completions headers { Authorization: fBearer {self.api_key}, Content-Type: application/json } # 构建请求体合并默认参数和传入参数 payload { model: self.model, messages: messages, stream: False } # 更新用户自定义参数如temperature, max_tokens payload.update(kwargs) logger.debug(f[DeepSeek] 请求Payload: {json.dumps(payload, ensure_asciiFalse)}) response_data self._make_request(url, headers, payload) if response_data and choices in response_data and len(response_data[choices]) 0: content response_data[choices][0][message][content] logger.info(f[DeepSeek] 请求成功消耗token: {response_data.get(usage, {})}) return content else: logger.error(f[DeepSeek] 响应数据格式异常: {response_data}) return None4.2 智谱AI (GLM) 客户端智谱AI的API需要生成特定格式的签名并使用了不同的端点。# llm_clients.py (接上文) import hashlib import jwt import time as ttime class ZhipuAIClient(BaseLLMClient): 智谱AI (GLM) API 客户端 def __init__(self): super().__init__(ZhipuAI) self.api_key Config.ZHIPU_API_KEY self.model Config.ZHIPU_MODEL if not self.api_key: logger.warning(ZhipuAI API密钥未配置客户端将不可用。) def _generate_token(self) - str: 生成智谱API所需的JWT Token try: api_key_parts self.api_key.split(.) if len(api_key_parts) ! 2: raise ValueError(API Key格式错误) id, secret api_key_parts payload { api_key: id, exp: int(ttime.time()) 3600, # 1小时过期 timestamp: int(ttime.time() * 1000) } # 使用PyJWT库生成签名 token jwt.encode( payload, secret, algorithmHS256, headers{alg: HS256, sign_type: SIGN} ) return token except Exception as e: logger.error(f[ZhipuAI] 生成Token失败: {e}) return def chat_completion(self, messages: list, **kwargs) - Optional[str]: if not self.api_key: return None token self._generate_token() if not token: return None url https://open.bigmodel.cn/api/paas/v4/chat/completions headers { Authorization: fBearer {token}, Content-Type: application/json } # 智谱的消息格式与OpenAI基本一致 payload { model: self.model, messages: messages, stream: False } payload.update(kwargs) logger.debug(f[ZhipuAI] 请求Payload: {json.dumps(payload, ensure_asciiFalse)}) response_data self._make_request(url, headers, payload) if response_data and choices in response_data and len(response_data[choices]) 0: content response_data[choices][0][message][content] logger.info(f[ZhipuAI] 请求成功) return content else: logger.error(f[ZhipuAI] 响应数据格式异常: {response_data}) return None4.3 百度千帆 (文心一言) 客户端百度千帆的API需要先获取Access Token再进行对话请求。# llm_clients.py (接上文) class BaiduQianfanClient(BaseLLMClient): 百度千帆 (文心一言) API 客户端 def __init__(self): super().__init__(BaiduQianfan) self.api_key Config.BAIDU_API_KEY self.secret_key Config.BAIDU_SECRET_KEY self.model Config.BAIDU_MODEL self._access_token None self._token_expire_time 0 if not self.api_key or not self.secret_key: logger.warning(百度千帆API密钥或Secret未配置客户端将不可用。) def _get_access_token(self) - Optional[str]: 获取百度API的Access Token自带缓存 now int(ttime.time()) # 如果token存在且未过期直接返回 if self._access_token and now self._token_expire_time: return self._access_token url https://aip.baidubce.com/oauth/2.0/token params { grant_type: client_credentials, client_id: self.api_key, client_secret: self.secret_key } try: logger.info([BaiduQianfan] 正在获取Access Token...) response requests.post(url, paramsparams, timeoutself.timeout) response.raise_for_status() token_data response.json() if access_token in token_data: self._access_token token_data[access_token] # 百度token通常有效期为30天这里保守设置为29天 self._token_expire_time now (29 * 24 * 3600) logger.info([BaiduQianfan] Access Token获取成功) return self._access_token else: logger.error(f[BaiduQianfan] 获取Token失败: {token_data}) return None except Exception as e: logger.error(f[BaiduQianfan] 获取Token异常: {e}) return None def chat_completion(self, messages: list, **kwargs) - Optional[str]: if not self.api_key or not self.secret_key: return None access_token self._get_access_token() if not access_token: return None url fhttps://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/{self.model} # 百度千帆需要将access_token作为query参数 url_with_token f{url}?access_token{access_token} headers { Content-Type: application/json } # 百度千帆的消息格式略有不同需要转换 # 假设messages最后一条是用户输入 user_message next((msg for msg in reversed(messages) if msg[role] user), None) if not user_message: logger.error([BaiduQianfan] 消息列表中未找到用户输入) return None payload { messages: messages, # 新版API也支持OpenAI格式 stream: False } payload.update(kwargs) logger.debug(f[BaiduQianfan] 请求Payload: {json.dumps(payload, ensure_asciiFalse)}) response_data self._make_request(url_with_token, headers, payload) # 百度API的响应格式 if response_data and result in response_data: content response_data[result] logger.info(f[BaiduQianfan] 请求成功) return content else: logger.error(f[BaiduQianfan] 响应数据格式异常: {response_data}) return None5. 完整实战构建一个多模型对话测试程序现在我们将上面创建的客户端整合起来编写一个主程序。这个程序可以轮流或指定调用不同的LLM API并对比它们的回复。首先创建requirements.txt文件记录项目依赖。# requirements.txt requests2.28.0 python-dotenv1.0.0 PyJWT2.8.0 # 智谱AI客户端需要然后创建主程序文件main.py。# main.py import asyncio import time from typing import Dict, Optional from llm_clients import DeepSeekClient, ZhipuAIClient, BaiduQianfanClient from config import Config from utils.logger import setup_logger logger setup_logger(__name__) class LLMComparator: LLM模型对比测试器 def __init__(self): self.clients {} self._init_clients() def _init_clients(self): 初始化所有可用的客户端 # DeepSeek if Config.DEEPSEEK_API_KEY: self.clients[deepseek] DeepSeekClient() logger.info(DeepSeek客户端已初始化) # 智谱AI if Config.ZHIPU_API_KEY: self.clients[zhipu] ZhipuAIClient() logger.info(智谱AI客户端已初始化) # 百度千帆 if Config.BAIDU_API_KEY and Config.BAIDU_SECRET_KEY: self.clients[baidu] BaiduQianfanClient() logger.info(百度千帆客户端已初始化) if not self.clients: logger.error(未初始化任何客户端请检查 .env 配置文件。) def test_single_provider(self, provider: str, prompt: str) - Optional[str]: 测试单个提供商 :param provider: 提供商标识如 deepseek, zhipu, baidu :param prompt: 用户提示词 :return: 模型回复内容 if provider not in self.clients: logger.error(f未找到提供商: {provider}) return None client self.clients[provider] messages [{role: user, content: prompt}] logger.info(f\n{*50}) logger.info(f开始测试 [{provider.upper()}]) logger.info(f提示词: {prompt}) start_time time.time() try: response client.chat_completion( messages, temperature0.7, # 控制创造性0-1之间 max_tokens500 # 限制生成长度 ) elapsed_time time.time() - start_time if response: logger.info(f[{provider.upper()}] 响应时间: {elapsed_time:.2f}秒) logger.info(f[{provider.upper()}] 回复: {response}) return response else: logger.error(f[{provider.upper()}] 请求失败或返回为空) return None except Exception as e: logger.error(f[{provider.upper()}] 调用过程中发生异常: {e}) return None def compare_all(self, prompt: str) - Dict[str, Optional[str]]: 对比所有可用提供商的回复 :param prompt: 用户提示词 :return: 字典key为提供商value为回复内容 results {} logger.info(f\n{#*60}) logger.info(f开始多模型对比测试) logger.info(f测试提示词: {prompt}) logger.info(f可用模型: {list(self.clients.keys())}) logger.info(f{#*60}) for provider in self.clients.keys(): result self.test_single_provider(provider, prompt) results[provider] result # 打印对比摘要 self._print_comparison_summary(results) return results def _print_comparison_summary(self, results: Dict[str, Optional[str]]): 打印对比摘要 logger.info(f\n{*60}) logger.info(模型对比测试摘要) logger.info(f{*60}) for provider, response in results.items(): status ✓ 成功 if response else ✗ 失败 preview (response[:100] ...) if response and len(response) 100 else (response or 无响应) logger.info(f{provider.upper():12} {status:10} 预览: {preview}) successful sum(1 for r in results.values() if r) logger.info(f\n总计测试 {len(results)} 个模型成功 {successful} 个) def main(): 主函数 # 验证配置 Config.validate_keys() # 初始化比较器 comparator LLMComparator() if not comparator.clients: logger.error(没有可用的LLM客户端程序退出。请确保至少配置了一个API密钥。) return # 示例1: 测试单个提供商 print(\n1. 测试单个提供商 (DeepSeek)) test_prompt 请用Python写一个函数计算斐波那契数列的第n项。 deepseek_response comparator.test_single_provider(deepseek, test_prompt) # 示例2: 对比所有提供商 print(\n\n2. 对比所有可用提供商) compare_prompt 简要解释什么是大语言模型(LLM)以及它的主要应用场景。 all_results comparator.compare_all(compare_prompt) # 示例3: 交互式测试 print(\n\n3. 进入交互式测试模式 (输入 quit 或 exit 退出)) while True: user_input input(\n请输入你的问题: ).strip() if user_input.lower() in [quit, exit, q]: print(感谢使用再见) break if not user_input: continue # 让用户选择模型 print(f可用模型: {list(comparator.clients.keys())}) model_choice input(f选择模型 (默认全部): ).strip().lower() if model_choice in comparator.clients: # 测试单个模型 comparator.test_single_provider(model_choice, user_input) else: # 测试所有模型 comparator.compare_all(user_input) if __name__ __main__: main()5.1 运行与验证现在让我们运行这个程序看看效果。确保你的.env文件已正确配置了至少一个API密钥例如DeepSeek的。在项目根目录下运行主程序python main.py预期输出示例2024-05-20 10:30:15 - config - INFO - 配置检查通过。 2024-05-20 10:30:15 - llm_clients - INFO - DeepSeek客户端已初始化 2024-05-20 10:30:15 - __main__ - INFO - 可用模型: [deepseek] 1. 测试单个提供商 (DeepSeek) 开始测试 [DEEPSEEK] 提示词: 请用Python写一个函数计算斐波那契数列的第n项。 [DEEPSEEK] 请求成功消耗token: {prompt_tokens: 20, completion_tokens: 150, total_tokens: 170} [DEEPSEEK] 响应时间: 1.23秒 [DEEPSEEK] 回复: 当然这是一个计算斐波那契数列第n项的Python函数...具体代码程序会先检查配置然后初始化可用的客户端。接着它会执行三个示例任务测试单个模型、对比所有模型、并进入一个简单的交互模式。5.2 结果说明通过运行上述程序你可以验证API连通性快速检查你的API密钥和网络是否正常。对比响应速度观察不同模型处理相同请求所需的时间。对比回复质量对于同一个问题不同模型的回答在准确性、详细程度和风格上可能有差异。获得一个可扩展的代码框架你可以轻松地将新的LLM API提供商如阿里云通义、腾讯混元等以类似的客户端类形式添加到llm_clients.py中并在主程序中调用。6. 常见问题与排查思路在实际调用LLM API的过程中你可能会遇到各种错误。下面列出了一些最常见的问题及其解决方法。问题现象常见原因解决思路API Error: 400或Invalid parameter1. 请求参数格式错误。2. 模型名称不对。3. 消息列表格式不符合API要求。4. 请求体过大token超限。1. 对照官方API文档检查messages、model等字段格式。2. 确认config.py中的模型名称是提供商支持的有效名称。3. 检查messages是否为字典列表每个字典是否包含role和content。4. 减少提示词长度或调低max_tokens。API Error: 401或Unauthorized1. API密钥错误或已失效。2. 密钥未正确放入请求头。3. 智谱AI的Token生成失败或过期。1. 去对应平台控制台确认API密钥状态并重新复制。2. 检查客户端代码中的headers设置确保Authorization字段格式正确如Bearer key。3. 对于智谱AI检查api_key格式是否为id.secret并确保PyJWT库已安装。API Error: 429请求频率超过限制Rate Limit。1. 免费API通常有每分钟/每天的调用次数限制。2. 在代码中添加延时如time.sleep(1)。3. 检查平台控制台的用量统计。API Error: 503或Service Unavailable服务端临时过载或维护。1. 稍等片刻后重试。2. 查看服务商的状态页面如果有。ConnectionError,Timeout或(ECONNRESET)1. 网络连接不稳定或被阻断。2. 服务器响应慢。3. 本地代理设置冲突。1. 检查本地网络尝试用浏览器访问API端点。2. 增加Config.REQUEST_TIMEOUT的值。3. 如果你使用了代理确保requests库能正确通过或临时关闭代理试试。4. 使用try-except包裹请求并实现重试机制我们的_make_request方法已包含。Ollama相关错误如下载慢本文聚焦云端API但如果你同时使用Ollama本地模型可能会遇到1. 下载模型镜像速度慢。2. 本地端口冲突。1.下载慢配置Ollama使用国内镜像源例如设置环境变量OLLAMA_MODELS指向国内镜像站。2.端口冲突默认端口是11434检查是否被占用可通过ollama serve命令查看日志。响应内容为空或格式异常1. API响应结构发生变化。2. 免费额度已用尽。3. 模型生成被安全策略拦截。1. 打印完整的响应数据 (response.json()) 以查看实际结构并调整解析逻辑。2. 登录平台控制台查看剩余额度。3. 尝试调整提示词避免触发内容过滤。智谱AIJWT相关错误1.api_key格式不是id.secret。2. 系统时间不同步。1. 确保从智谱平台获取的密钥格式正确。2. 同步操作系统时间。百度千帆access_token获取失败1.API Key或Secret Key错误。2. 网络问题导致认证请求失败。1. 在百度云控制台确认密钥对正确并确保已启用对应服务。2. 单独测试_get_access_token方法打印错误信息。通用排查步骤开启详细日志将utils/logger.py中的levellogging.INFO改为levellogging.DEBUG可以查看更详细的请求和响应数据。简化测试先用最简单的提示词如“你好”和默认参数进行测试排除复杂参数的影响。使用工具验证用curl命令或Postman等工具直接调用API验证密钥和端点本身是否有效。这能帮你快速定位是代码问题还是配置问题。查阅官方文档遇到错误码时第一时间查阅对应平台的官方API错误码说明。7. 最佳实践与工程建议将LLM API集成到实际项目中时除了能调用还需要考虑稳定性、成本、可维护性和性能。以下是一些进阶的工程化建议。7.1 配置与密钥管理安全第一永远不要提交密钥确保.env在.gitignore中并且永远不会被提交到版本控制系统。可以考虑使用.env.example文件来提供配置模板。使用环境变量在生产环境如Docker、K8s、云服务器中应通过环境变量注入密钥而不是文件。我们的config.py已经优先从环境变量读取 (os.getenv)这符合十二要素应用原则。密钥轮换定期在平台控制台更新API密钥并在项目中实现无缝切换避免服务中断。权限最小化在云平台创建API密钥时只赋予其所需的最小权限如仅聊天补全不要赋予删除、写权限。7.2 健壮性设计重试与退避网络请求可能失败。我们的_make_request方法实现了简单的重试和指数退避对于生产环境可以考虑使用更强大的库如tenacity。超时设置必须设置合理的超时时间如30秒防止慢响应阻塞整个应用。不同的操作生成长文本与短文本可以设置不同的超时。熔断与降级如果某个LLM服务连续失败应暂时将其“熔断”并切换到备用服务或返回友好的降级内容避免级联故障。输入验证与清理对用户输入的提示词进行长度检查、敏感词过滤防止滥用或触发API的内容安全策略。7.3 性能与成本优化异步调用如果同时需要调用多个模型或处理大量请求使用asyncio和aiohttp进行异步调用可以极大提升吞吐量。缓存策略对于常见、结果确定的查询如“什么是Python”可以将结果缓存起来使用redis或memcached避免重复调用API节省成本和延迟。Token计数与估算关注API返回的usage字段了解每次调用的token消耗。对于长文本可以在发送前用tiktokenOpenAI格式或类似库估算token数避免因超限导致请求失败。模型选择免费额度通常有限。根据任务选择性价比最高的模型例如简单问答用轻量模型如glm-4-flash,ERNIE-Speed复杂创作再用能力更强的模型。7.4 可观测性与监控结构化日志像我们示例中使用的那样记录每次调用的提供商、耗时、token用量和状态。这有助于后续分析和排查问题。指标收集在生产系统中可以收集成功率、延迟分布P50, P99、token消耗速率等指标并接入监控告警系统如Prometheus。链路追踪在微服务架构中为每个LLM调用生成唯一的request_id并贯穿整个调用链便于追踪问题。7.5 架构扩展抽象与插件化我们的客户端基类设计是一个良好的开始。未来新增一个提供商如Ollama的本地API只需继承BaseLLMClient并实现chat_completion方法即可主程序无需改动。统一API网关当项目中使用多个LLM时可以构建一个统一的API网关。网关负责路由请求根据负载、成本、模型能力、负载均衡、认证、限流和日志聚合。上下文管理对于多轮对话需要在服务端维护会话上下文。可以结合数据库或缓存为每个会话存储历史消息列表。通过遵循这些最佳实践你可以构建出不仅能用而且稳定、高效、易于维护的LLM集成应用。
返回列表