大模型 API 调用教程:10 行 Python 代码调通国产大模型
🎯 本节目标
Section titled “🎯 本节目标”学完这一节,你能:
- 跑通人生第一段调用大模型的 Python 代码,亲眼看到代码“变”出一句 AI 回答
- 说清楚
messages里的三个角色(system/user/assistant)各是干嘛的,用大白话讲给家里人听 - 封装一个
chat()函数,后面所有模块都站在它的肩膀上
这是整个教程最关键的“啊哈时刻”之一。一旦跑通,你就从“用聊天框点点点”升级成“用代码指挥 AI”——这正是 FDE 和普通 AI 用户的分水岭。
🍎 生活化类比
Section titled “🍎 生活化类比”调 API = 用代码给大模型“发微信”。
回想一下你平时用微信跟人聊天,要做哪几件事?
- 打开微信,登录(用你的账号密码)——对应代码里的 “客户端 + API Key(密码)”
- 在对话框里打字,按下发送——对应代码里的 “组装消息 + 发送请求”
- 对方看到消息,回你一句——对应代码里的 “模型返回结果”
唯一的区别是:聊天框是你用手指一个字一个字点;API 是你用代码“自动发微信”。一旦换成代码,你就能一次发一万条、接到公司业务系统里、做成一个产品给别人用。
还有一个更重要的区别,我们下一节慢慢讲——大模型比人笨的地方在于:它不知道你是谁,也不知道你想干嘛。所以你每次发消息,得把“身份、问题、历史”一起打包告诉它。
📖 概念讲解
Section titled “📖 概念讲解”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 最爱的“杠杆”:学一次,用一辈子。
🛠️ 动手实操 Step by Step
Section titled “🛠️ 动手实操 Step by Step”下面是本节的核心。强烈建议你跟着敲一遍,不要复制粘贴——肌肉记忆是 FDE 的基本功。我们把整个过程拆成 4 个小 Step。
Step 1:确认环境(上节装好的)
Section titled “Step 1:确认环境(上节装好的)”打开终端(Mac 是“终端”App,Windows 是 PowerShell),进到上节建好的学习目录,激活虚拟环境:
# 进到上节建的学习文件夹(路径换成你自己的)cd ~/fde-learn
# 激活虚拟环境(上节装好的那个)# Mac/Linux 用这句:source .venv/bin/activate# Windows 用这句:.venv\Scripts\activate激活成功的标志:命令行最前面会出现一个 (.venv) 字样。意思是“现在这个终端里用的 Python,是上节专门为学习装的那个,不是系统自带的”。
✅ 应该看到的结果:命令提示符变成
(.venv) yihua@mac ~ %这种样子。如果没看到(.venv),回到上一节重装一遍。
再确认一下,我们这节要用的两个“工具”(openai 库和 python-dotenv 库)是装好的:
# 列出已安装的包,确认有 openai 和 python-dotenvpip list | grep -E "openai|dotenv"✅ 应该看到两行:
openai和python-dotenv,后面跟着版本号。如果没有,执行pip install openai python-dotenv补装。
Step 2:写第一段代码(我们把 10 行拆成 4 小段)
Section titled “Step 2:写第一段代码(我们把 10 行拆成 4 小段)”在 ~/fde-learn 目录下新建一个文件,叫 first_call.py(用 VS Code、PyCharm、甚至记事本都行)。我们一段一段往里填代码。
第 1 段:加载密码(API Key)
Section titled “第 1 段:加载密码(API Key)”你可能会问:密码为啥不直接写在代码里?因为代码会发到 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=你从智谱开放平台拿到的真实 KeyKey 长得像
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) 还亮着,然后:
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 osfrom dotenv import load_dotenvfrom 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"))运行一下:
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(...),再在前后加点东西。务必把它存好,别删。
⚠️ 常见错误
Section titled “⚠️ 常见错误”| 报错信息 | 大白话原因 | 怎么解决 |
|---|---|---|
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-flash 或 glm-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)
# 死循环:一直聊,直到用户输 quitwhile 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']}")运行:
python chat_loop.py验收标准:
- 能连续对话至少 5 轮不报错
- 第 3 轮问“你刚才说的那个词是什么意思?”,模型能基于前面自己说过的话回答(说明上下文生效了)
- 输
quit优雅退出,退出时打印出完整的对话历史,让你亲眼看到每次传给模型的“便签叠”是啥样
做完这个,你已经写出了 ChatGPT 的雏形——本质就是一个“维护 history + 循环调用 API”的死循环。真的就这么简单。
📚 总结 & 下一节
Section titled “📚 总结 & 下一节”3 句话回顾:
- 调 API = 用代码给大模型发微信,消息里要带三个角色:
system(定人设)、user(提问)、assistant(历史回答) - 国产模型都兼容 OpenAI 协议,一套代码调所有平台,只改
base_url和api_key - 把代码封装成
chat()函数——后面 RAG、Agent、评估,全都是站在它肩膀上加东西
你已经拿到 FDE 的“上车票”了。从现在开始,你不再是 AI 的用户,而是 AI 的指挥官。
下一节:学提示词工程——同样是喊一声 chat(),问得好和问得差,结果天差地别。我们会讲怎么把“提问”这件事做到极致,让模型稳定输出你要的结果。
🏋️ 配套自练
Section titled “🏋️ 配套自练”- Anthropic Prompt 互动教程 — 9 章带练习,每章有 Example Playground 可改 prompt 看效果(免费、英文、需 Anthropic Key)
- TinkerLLM — 176 道动手练习,50 道免费,直接对真实模型发 prompt(免费、需 Gemini Key)
- PromptEval 每日一练 — 每天 3 分钟一道真实职场场景练习,免费不用注册(免费)