从最原始的 requests 到最省心的 LangChain,同一个 DeepSeek 我问了 5 遍,代码越来越短,坑越来越少。如果你刚入门,这篇文章能帮你少走很多弯路。
作为一个从 Java 转过来学 Python 做 AI 的人,我发现 Python 调大模型 API 的方式远不止一种——从原始 HTTP 到各种 SDK 再到框架封装,选择多了反而容易懵。同一个人问 DeepSeek "解释一下 Python 的 GIL",我用 5 种方式各写了一遍。每种方式的代码量、灵活性、坑点完全不同。今天就按"从裸到穿"的顺序,把这 5 种方式给你捋一遍。
方式一:纯 requests(最原始,最可控)
import requestsresp = requests.post( ”https://api.deepseek.com/v1/chat/completions”, headers={ ”Authorization”: ”Bearer sk-xxx”, ”Content-Type”: ”application/json” }, json={ ”model”: ”deepseek-chat”, ”messages”: [{”role”: ”user”, ”content”: ”解释一下 Python 的 GIL”}] })answer = resp.json()[”choices”][0][”message”][”content”]print(answer)
| 优点 | 缺点 |
|---|
| 零依赖,任何 Python 环境都能跑 | 错误处理全得自己写 |
| 完全掌控请求细节 | 流式输出要手动处理 SSE |
| 适合嵌入脚本和自动化 | 换模型要改 URL、改 JSON 结构 |
适合场景:写个一次性脚本、自动化小工具。追求最少依赖。我踩的坑:忘了处理 API 返回错误时 resp.json() 直接抛异常。一定要加 resp.raise_for_status()。
方式二:openai 官方 SDK(兼容性最强)
from openai import OpenAIclient = OpenAI( api_key=”sk-xxx”, base_url=”https://api.deepseek.com/v1”换成 DeepSeek 的地址)response = client.chat.completions.create( model=”deepseek-chat”, messages=[{”role”: ”user”, ”content”: ”解释一下 Python 的 GIL”}])print(response.choices[0].message.content)
| 优点 | 缺点 |
|---|
| 几乎所有国产模型都兼容 OpenAI 格式 | 需要 pip install openai |
| 流式输出、多轮对话、异常处理全封装好了 | 有些模型兼容不完全,个别参数会报错 |
| 代码风格统一,换模型只改 base_url | — |
适合场景:正经项目开发,不想重复造轮子。大部分国产模型的官方推荐方式就是这个。
我踩的坑:DeepSeek 不支持 response_format 参数(JSON 模式),但官方 SDK 默认行为是传了这个参数也不报错只是不生效,花了我半天才发现。
方式三:模型专属 SDK(功能最全)
from deepseek import DeepSeekClientclient = DeepSeekClient(api_key=”sk-xxx”)response = client.chat.completions.create( model=”deepseek-chat”, messages=[{”role”: ”user”, ”content”: ”解释一下 Python 的 GIL”}], temperature=0.7, max_tokens=1024)print(response.choices[0].message.content)
| 优点 | 缺点 |
|---|
| 模型特有功能不会漏(如 DeepSeek 的深度思考模式) | 换模型就要换 SDK,不通用 |
| 文档最贴合该模型 | 依赖又多了一个 |
| 更新及时,新功能第一时间支持 | 小众模型的 SDK 质量参差不齐 |
适合场景:深度使用某一个特定模型,需要它的独有功能。我踩的坑:在一个项目里同时用了 DeepSeek SDK 和通义千问 SDK,两个库的 ChatMessage 类型不兼容,被迫写了一层抽象。
方式四:LangChain 封装(AI 开发的标配)
from langchain_deepseek import ChatDeepSeekfrom langchain.schema import HumanMessagellm = ChatDeepSeek(model=”deepseek-chat”, api_key=”sk-xxx”)response = llm.invoke([HumanMessage(content=”解释一下 Python 的 GIL”)])print(response.content)
| 优点 | 缺点 |
|---|
| 和 RAG、Agent、Chain 无缝衔接 | 重,一个 pip install langchain 拉几百个依赖 |
| Prompt 模板、消息历史、工具调用全内置 | 版本更新快,API 经常变动 |
| 一套 API 通吃几乎所有模型 | 简单任务杀鸡用牛刀 |
适合场景:你要做的不只是聊天——RAG、Agent、工作流编排都用 LangChain 会很方便。我踩的坑:2024 年初的 LangChain 代码到了 2025 年很多 import 路径全变了。如果你的项目要长期维护,建议锁定版本号。
方式五:litellm(统一网关,换模型零改动)
from litellm import completionresponse = completion( model=”deepseek/deepseek-chat”,格式:提供商/模型名 messages=[{”role”: ”user”, ”content”: ”解释一下 Python 的 GIL”}], api_key=”sk-xxx”)print(response.choices[0].message.content)
response = completion( model=”openai/qwen-plus”,只改这里 messages=[...], api_key=”sk-yyy”)
| 优点 | 缺点 |
|---|
| 换模型只改一个字符串,代码零改动 | 依赖仍然较重 |
| 内置重试、fallback、负载均衡 | 某些高级参数可能不透传 |
| 支持 100+ 模型统一调用 | 社区相对较小 |
适合场景:需要灵活切换模型的项目、要做模型对比评测、多模型负载均衡。
我踩的坑:litellm 的错误信息有时候包装得过深,原始报错被包了 3 层,排查问题需要点耐心。
总结:一张表帮你选
| 你的场景 | 推荐方式 |
|---|
| 写个一次性脚本,不想装依赖 | ① requests |
| 正经项目开发,图省心 | ② openai SDK |
| 深度绑定某个模型,需要独有功能 | ③ 专属 SDK |
| 要做 RAG / Agent 等复杂功能 | ④ LangChain |
| 需要灵活切换多个模型 | ⑤ litellm |
我的日常:
快速验证想法 → requests 或 openai SDK三种都在用,各有各的好。关键不是"选哪个最好",而是"知道什么时候该用哪个"。
写在最后
Java 程序员刚转 Python 做 AI,最容易犯的错误就是"去找一个终极方案"。但 AI 开发领域变化太快了——今天的最佳实践,半年后可能就是反面教材。这也是我一直在写 Java + Python 双语言内容的原因——多一个视角,多一种选择。
我是阿尔法猫,5年开发老兵,从互联网内卷抽身,定居老家国企。专注分享程序员真实职场、AI背景下的应用开发、技术成长与普通人的择业破局之路。觉得文章有用,欢迎点赞、在看、转发,也可以留言聊聊你平时用哪种方式调大模型,我们一起慢慢变好。