跳转到内容

大模型 API 调用教程:10 行 Python 代码调通国产大模型

学完这一节,你能:

  • 跑通人生第一段调用大模型的 Python 代码,亲眼看到代码“变”出一句 AI 回答
  • 说清楚 messages 里的三个角色(system / user / assistant)各是干嘛的,用大白话讲给家里人听
  • 封装一个 chat() 函数,后面所有模块都站在它的肩膀上

这是整个教程最关键的“啊哈时刻”之一。一旦跑通,你就从“用聊天框点点点”升级成“用代码指挥 AI”——这正是 FDE 和普通 AI 用户的分水岭。

调 API = 用代码给大模型“发微信”。

回想一下你平时用微信跟人聊天,要做哪几件事?

  1. 打开微信,登录(用你的账号密码)——对应代码里的 “客户端 + API Key(密码)”
  2. 在对话框里打字,按下发送——对应代码里的 “组装消息 + 发送请求”
  3. 对方看到消息,回你一句——对应代码里的 “模型返回结果”

唯一的区别是:聊天框是你用手指一个字一个字点;API 是你用代码“自动发微信”。一旦换成代码,你就能一次发一万条接到公司业务系统里做成一个产品给别人用

还有一个更重要的区别,我们下一节慢慢讲——大模型比人笨的地方在于:它不知道你是谁,也不知道你想干嘛。所以你每次发消息,得把“身份、问题、历史”一起打包告诉它。

1. 为什么要用代码调,而不是用聊天框?

Section titled “1. 为什么要用代码调,而不是用聊天框?”

你可能会问:智谱清言、ChatGPT 这些聊天框已经这么好用了,我干嘛非得学写代码?

因为聊天框是“给一个人用的”,而 FDE 要做的是“给一个业务、一个公司、一群客户用的”。三个典型场景,聊天框全做不到:

  • 批量处理:客户给你 5000 条工单,要每条都自动分类、打标签、生成回复草稿。你总不能在聊天框里手动粘贴 5000 次吧?
  • 接到业务系统里:老板要的是“客户在我们公司的 App 里点一下,AI 自动出结果”,不是“打开另一个网页”。这就必须用代码把 AI 接进去。
  • 做成产品卖钱:你做的 AI 客服、AI 写作助手、AI 数据分析工具,本质上都是“把大模型 API 包一层壳”。没有 API,就没有产品。

一句话:聊天框是体验 AI,API 是驾驭 AI。FDE 的所有工作,都从调通 API 开始。

2. messages 的三个角色:对话对照表

Section titled “2. messages 的三个角色:对话对照表”

还记得刚才说的吗?大模型不知道你是谁、不知道你想干嘛。所以你发消息时,要把对话的“上下文”完整告诉它。这个“上下文”就是一个叫 messages 的列表(暂时不用管“列表”是啥,你就当成“一叠对话便签”)。

每张便签上,都有两行字:谁在说(role) + 说了什么(content)

“谁在说”只有三种可能,我们先不写一行代码,先用生活里的对话讲明白:

生活里的对话 代码里的 role 谁在说话 作用
你给新来的客服交代规矩:“你叫小王,说话要客气,客户问啥先道歉再回答” system 你给 AI 设的“人设/规则” 定下整场对话的基调,影响力最大
客户开口问:“我这个订单为啥还没发货?” user 真正在提问的人 模型要回答的内容就来自这里
客服上一轮回答:“您好,帮您查了一下,快递今天到” assistant 模型自己上一轮说的话 多轮对话时,要把它一起传回去,模型才能“记得”前面说过啥

看明白了吗?三个角色对应的就是一次真实对话里的三种声音:定规矩的、提问的、回答的。

关键点(后面会反复用到):system 的影响力最大。FDE 在真实项目里,经常只改一行 system,就能让模型从“随便聊天”变成“严格输出 JSON 格式数据”。这是后面提示词工程的核心招数。

3. OpenAI 兼容协议:学会开丰田,就会开所有车

Section titled “3. OpenAI 兼容协议:学会开丰田,就会开所有车”

你可能听说过一个东西叫 OpenAI(就是做 ChatGPT 那家公司)。它是第一个把大模型 API 做出来的,顺手定了一套“怎么调 API”的规矩——这套规矩,就叫 OpenAI 协议

这有啥神奇的?神奇就神奇在:国产大模型(智谱、DeepSeek、通义……)基本全都“抄袭”了这套规矩

打个比方:你学会了开丰田车(方向盘在左边、油门在右边、刹车在中间)。然后你跳进一辆比亚迪、一辆蔚来、一辆理想——发现方向盘都在左边、油门都在右边、刹车都在中间。你不用重新学开车,坐进去就能开。

大模型 API 也一模一样:你学会了用 OpenAI 的库(openai 这个 Python 包)调智谱,只改两个地方——一个叫 base_url(大模型的“门牌号”),一个叫 api_key(你的“密码”)——就能用同样的代码去调 DeepSeek、通义、Kimi、豆包……

平台 base_url(门牌号) model(车型)
智谱 GLM(本节用) https://open.bigmodel.cn/api/paas/v4/ glm-4-flash(免费)
DeepSeek https://api.deepseek.com deepseek-chat
通义千问 https://dashscope.aliyuncs.com/compatible-mode/v1 qwen-plus

这就是为什么本节只教你调一个模型(智谱),但你其实等于学会了调所有模型。这是 FDE 最爱的“杠杆”:学一次,用一辈子。

下面是本节的核心。强烈建议你跟着敲一遍,不要复制粘贴——肌肉记忆是 FDE 的基本功。我们把整个过程拆成 4 个小 Step。

打开终端(Mac 是“终端”App,Windows 是 PowerShell),进到上节建好的学习目录,激活虚拟环境:

Terminal window
# 进到上节建的学习文件夹(路径换成你自己的)
cd ~/fde-learn
# 激活虚拟环境(上节装好的那个)
# Mac/Linux 用这句:
source .venv/bin/activate
# Windows 用这句:.venv\Scripts\activate

激活成功的标志:命令行最前面会出现一个 (.venv) 字样。意思是“现在这个终端里用的 Python,是上节专门为学习装的那个,不是系统自带的”。

✅ 应该看到的结果:命令提示符变成 (.venv) yihua@mac ~ % 这种样子。如果没看到 (.venv),回到上一节重装一遍。

再确认一下,我们这节要用的两个“工具”(openai 库和 python-dotenv 库)是装好的:

Terminal window
# 列出已安装的包,确认有 openai 和 python-dotenv
pip list | grep -E "openai|dotenv"

✅ 应该看到两行:openaipython-dotenv,后面跟着版本号。如果没有,执行 pip install openai python-dotenv 补装。

Step 2:写第一段代码(我们把 10 行拆成 4 小段)

Section titled “Step 2:写第一段代码(我们把 10 行拆成 4 小段)”

~/fde-learn 目录下新建一个文件,叫 first_call.py(用 VS Code、PyCharm、甚至记事本都行)。我们一段一段往里填代码。

你可能会问:密码为啥不直接写在代码里?因为代码会发到 GitHub、会发给同事,密码一旦泄露,别人就能用你的额度烧钱。所以行业规矩是:密码放在一个叫 .env 的文件里,代码去读它。这个 .env 文件永远不上传。

# 引入 os 这个工具,它能读取电脑里的环境变量(比如密码)
import os
# 引入 load_dotenv:它的活儿就是"打开 .env 文件,把里面的密码读出来"
from dotenv import load_dotenv
# 引入 OpenAI:这是 OpenAI 公司提供的"开车工具包",
# 国产模型因为兼容它的协议,所以也用这个包来调
from openai import OpenAI
# 真正执行"读密码"这个动作
# 它会去当前目录下找一个叫 .env 的文件,把里面的内容加载进内存
load_dotenv()

顺带确认一下:你的 ~/fde-learn/.env 文件里,应该有这一行(上节让存的):

GLM_API_KEY=你从智谱开放平台拿到的真实 Key

Key 长得像 xxxxxx.xxxxxx 这样一串。等号两边不要有空格,Key 后面也不要有空格,不然代码会读错。

第 2 段:建立客户端(相当于“打开微信、登录”)

Section titled “第 2 段:建立客户端(相当于“打开微信、登录”)”

光有密码还不行,得用密码去“登录”一下,建立一个客户端(client)。客户端你可以理解成“打开了、登录好的微信”——后面所有发消息动作都通过它来做。

# 用密码建一个客户端 = 打开微信并登录
client = OpenAI(
# os.getenv("GLM_API_KEY") 的意思是"去 .env 里把 GLM_API_KEY 这个变量读出来"
api_key=os.getenv("GLM_API_KEY"),
# base_url 就是"门牌号":告诉它我们要找的是智谱的大模型,不是 OpenAI 的
base_url="https://open.bigmodel.cn/api/paas/v4/"
)

注意我们虽然用的是 openai 这个包,但 base_url 写的是智谱的地址——这就是前面讲的“OpenAI 兼容协议”在代码里的体现:同一个工具,换个门牌号就能调另一家

第 3 段:发消息(对照前面的“三个角色”表)

Section titled “第 3 段:发消息(对照前面的“三个角色”表)”

客户端建好了,该发消息了。还记得前面那张“对话对照表”吗?这里就是把表里那两行“便签”翻译成代码:

# 调用客户端的"聊天"功能,发起一次对话
response = client.chat.completions.create(
# model:用哪个模型。glm-4-flash 是智谱的免费款,够用
model="glm-4-flash",
# messages:这就是前面讲的"一叠对话便签"
messages=[
# 第一张便签:system,设定人设(对应表里的"给客服定规矩")
{"role": "system", "content": "你是一个简洁的中文助手,回答不超过 50 字"},
# 第二张便签:user,真正的问题(对应表里的"客户开口问")
{"role": "user", "content": "用一句话解释什么是 FDE"}
]
)

注意每张便签都是一个 {} 包起来的小字典(暂时不用纠结“字典”是啥,你就当成“一张便签”),里面固定两行:role 是谁在说,content 是说了啥。两张便签按顺序排在一个 [ ] 里,就组成了 messages

第 4 段:读结果(从模型回复里把“那句话”抠出来)

Section titled “第 4 段:读结果(从模型回复里把“那句话”抠出来)”

模型回话了,但它回的格式是个大包裹(里面有它的回答、用了多少 token、是哪个模型等等一堆字段)。我们只要它的“那句话”,要从包裹里抠出来:

# response.choices[0].message.content 这一长串,可以这么理解:
# response = 整个大包裹
# .choices[0] = 第一个候选回答(我们没要求多个,所以只有第 0 个)
# .message.content = 这个候选回答里"真正说的那句话"
print(response.choices[0].message.content)

把这 4 段代码按顺序拼起来,存进 first_call.py,就是一段完整可跑的代码(总共 10 行有效逻辑)。

Step 3:运行,亲眼看到“啊哈时刻”

Section titled “Step 3:运行,亲眼看到“啊哈时刻””

回到终端,确保还在 ~/fde-learn 目录、(.venv) 还亮着,然后:

Terminal window
python first_call.py

应该看到的结果(每次回答会略不同,大意是这样):

FDE(前沿部署工程师)是驻场客户一线、把 AI 真正落地到业务的工程师角色。

就这一行字,你完成了从“聊天框用户”到“AI 应用开发者”的跨越。 整个 FDE 教程剩下的所有内容,都是在这 10 行代码上加东西:

  • 加 RAG(让模型能查你的私有文档)
  • 加 Agent(让模型能自己调工具)
  • 加评估(自动给模型打分)
  • 加部署(把它跑在客户的服务器上)

但骨架,就是你现在手里这 10 行。多运行几次,观察每次的回答略有不同——这是大模型的“随机性”,后面会专门讲怎么控制它。

Step 4:封装成 chat() 函数(后面所有模块的基石)

Section titled “Step 4:封装成 chat() 函数(后面所有模块的基石)”

每次写 10 行太累。我们把这段代码包成一个函数,起名叫 chat()——以后只要喊一声 chat("你的问题"),就能拿到回答,不用再写那一坨。

新建一个文件 llm.py:

import os
from dotenv import load_dotenv
from openai import OpenAI
# 把 .env 里的密码读出来(整个文件只执行一次)
load_dotenv()
def chat(prompt: str, system: str = "你是中文助手", model: str = "glm-4-flash") -> str:
"""
统一的 LLM 调用函数,后面所有模块都基于它。
参数说明:
prompt = 你要问的问题(对应 user 那张便签)
system = 给模型的人设(对应 system 那张便签),有默认值,不传也行
model = 用哪个模型,默认是免费的 glm-4-flash
返回:模型回答的那句话(字符串)
"""
client = OpenAI(
api_key=os.getenv("GLM_API_KEY"),
base_url="https://open.bigmodel.cn/api/paas/v4/"
)
response = client.chat.completions.create(
model=model,
messages=[
{"role": "system", "content": system},
{"role": "user", "content": prompt}
]
)
return response.choices[0].message.content
# 这一段是"自测":直接 python llm.py 运行时会执行;被别的文件 import 时不会执行
if __name__ == "__main__":
print(chat("用一句话解释什么是 RAG"))

运行一下:

Terminal window
python llm.py

✅ 应该看到:RAG(检索增强生成)是让大模型先查私有文档再回答的技术…… 之类的一句话。

想换成 DeepSeek?把 chat() 里的 api_key 改成 os.getenv("DEEPSEEK_API_KEY")base_url 改成 "https://api.deepseek.com"、调用时传 model="deepseek-chat" 就行——这就是兼容协议的威力

这个 chat() 函数,是整个教程的基石。后面 RAG、Agent、评估,都是先喊一声 chat(...),再在前后加点东西。务必把它存好,别删。

报错信息 大白话原因 怎么解决
AuthenticationError: 401 密码错了 / 没填 / 多打了一个空格 打开 .env 检查,GLM_API_KEY= 后面没有空格,Key 也没复制错
RateLimitError: 429 免费额度用完了 / 请求发得太快 充值,或在两次请求中间加 import time; time.sleep(1) 慢一点
connect timeout / Read timed out 网络不通,或者公司内网挡住了 换个网络(手机热点试试);公司内网可能要配代理
NotFoundError: model not found 模型名字写错了 智谱写 glm-4-flashglm-4;DeepSeek 写 deepseek-chat
返回乱码 / 中文显示成 ??? 终端编码不对 Mac 执行 export LANG=zh_CN.UTF-8;Windows 用 PowerShell 一般没事
运行后啥也不打印 代码没调到 print,或文件存错位置 确认存的是 first_call.py,运行命令是 python first_call.py

遇到报错别慌——FDE 日常 50% 的时间在解报错。把报错信息完整复制,丢给智谱清言问“这个错咋整”,十有八九能解决。这是合法且高效的工作方式。

1. 三个 role(system / user / assistant)里,哪个对模型的影响力最大?为什么?

system。它定义了整场对话的“人设和规则”,模型在回答任何问题时都会优先遵守它。FDE 在真实项目里,经常只改一行 system,就能让模型从“自由发挥”变成“严格按 JSON 格式输出”。

2. 为什么国产大模型,能用 OpenAI 公司出的 Python 库来调?

因为国产模型基本都兼容 OpenAI 定下的 API 协议(就相当于“都把方向盘放在左边”)。所以同一个 openai 库,只改两个东西——base_url(门牌号)和 api_key(密码)——就能调所有兼容的模型,业务代码一行不用动。这是 FDE 最爱的“学一次用一辈子”的杠杆。

3. 多轮对话时,为什么必须把模型上一轮的回答(assistant)也作为消息传回去?

因为大模型本身没有记忆(它“无状态”)。每次调用对它来说都是一张白纸。要让它“记得”前面聊过啥,你必须把整段历史对话(包括它自己上一轮说过的话)作为 messages 一起传回去。这就是“上下文”的本质——不是模型记得,而是你每次都重新告诉它一遍。

🚀 实战小项目:多轮对话机器人

Section titled “🚀 实战小项目:多轮对话机器人”

用本节封装的 chat() 函数,写一个能连续对话、记得前面说过啥的命令行机器人。

提示:维护一个 history 列表(就是一叠不断变厚的“便签”),每轮把用户新问题 append 进去,再把模型的新回答也 append 进去,下一轮整个传给模型。

把下面这段代码存为 chat_loop.py(和 llm.py 放同一个目录),它能直接跑:

# chat_loop.py —— 多轮对话机器人
# 复用 llm.py 里的 chat 函数(同目录才能 import)
from llm import chat
# 维护一叠"对话便签",开头先放一张 system 便签定人设
history = [
{"role": "system", "content": "你是 FDE 学习助手,回答简洁、鼓励提问"}
]
print("🤖 多轮对话机器人已上线,输入 quit 退出。")
print("-" * 40)
# 死循环:一直聊,直到用户输 quit
while True:
# 等用户在终端打字
user_input = input("你: ")
# 输入 quit 就退出
if user_input.strip().lower() == "quit":
print("👋 下次见!")
break
# 把用户这轮说的话,作为一张新便签追加到 history
history.append({"role": "user", "content": user_input})
# 把整叠便签拼成一段多轮 messages,传给模型
# 注意:这里为了复用 chat(),我们手动把 history 拼成一个 prompt
# (更工程化的写法后面模块会讲,直接把 history 传进 create)
conversation = "\n".join(
[f"{m['role']}: {m['content']}" for m in history]
)
answer = chat(
prompt=conversation,
system="你是 FDE 学习助手。下面是和用户的多轮对话,请基于上下文回答最后一句。"
)
# 把模型的回答也追加到 history,这样下一轮它就"记得"自己说过啥
history.append({"role": "assistant", "content": answer})
# 打印回答
print(f"AI: {answer}")
print("-" * 40)
# 退出时打印一下完整的对话历史,直观感受"上下文"长啥样
print("\n📝 本场完整对话历史(这就是你每次传给模型的 messages):")
for m in history:
print(f" [{m['role']}] {m['content']}")

运行:

Terminal window
python chat_loop.py

验收标准:

  • 能连续对话至少 5 轮不报错
  • 第 3 轮问“你刚才说的那个词是什么意思?”,模型能基于前面自己说过的话回答(说明上下文生效了)
  • quit 优雅退出,退出时打印出完整的对话历史,让你亲眼看到每次传给模型的“便签叠”是啥样

做完这个,你已经写出了 ChatGPT 的雏形——本质就是一个“维护 history + 循环调用 API”的死循环。真的就这么简单。

3 句话回顾:

  1. 调 API = 用代码给大模型发微信,消息里要带三个角色:system(定人设)、user(提问)、assistant(历史回答)
  2. 国产模型都兼容 OpenAI 协议,一套代码调所有平台,只改 base_urlapi_key
  3. 把代码封装成 chat() 函数——后面 RAG、Agent、评估,全都是站在它肩膀上加东西

你已经拿到 FDE 的“上车票”了。从现在开始,你不再是 AI 的用户,而是 AI 的指挥官。

下一节:学提示词工程——同样是喊一声 chat(),问得好和问得差,结果天差地别。我们会讲怎么把“提问”这件事做到极致,让模型稳定输出你要的结果。

  • Anthropic Prompt 互动教程 — 9 章带练习,每章有 Example Playground 可改 prompt 看效果(免费、英文、需 Anthropic Key)
  • TinkerLLM — 176 道动手练习,50 道免费,直接对真实模型发 prompt(免费、需 Gemini Key)
  • PromptEval 每日一练 — 每天 3 分钟一道真实职场场景练习,免费不用注册(免费)

← 上一节:大模型认知 | 下一节:提示词工程