大模型通识 / 大模型应用开发入门
1. 从聊天窗口到 API:完成第一次 DeepSeek 调用
原文备份 · 第 3 / 19 篇 · 查看极客时间原知识库 ↗
本篇目录 · 8 节
来源:大模型应用开发入门
你在网页里输入一段笔记,DeepSeek 能告诉你第二章改到了周六。现在,你希望自己写的程序也能做这件事:读取输入,发送请求,接收回答,再把结果交给后续页面或功能。
这就是本部分的起点。今天先完成一个很小但完整的闭环:运行一份 Python 脚本,向 DeepSeek 官方 API 发送一条短请求,把响应保存到本地,并独立核对答案。
不需要先读完前两部分,也不需要先学习框架。你需要一台能上网的电脑、Python 3.11 或更新的稳定版,以及自己的 DeepSeek 开放平台账户。真正发送请求可能产生 API 费用;本文先提供一个不读取密钥、不联网的预演步骤。
代码已做本地语法和模拟响应测试,未使用个人密钥进行真实付费调用。文中的示例回答用于说明预期形式,不是线上实测记录。
一、聊天产品、模型和 API,分别负责什么
聊天产品已经替你做好输入框、历史记录和回答展示。API 则是程序与模型服务交换数据的接口。通过 API,你要明确告诉服务:“这次用哪个模型、有哪些消息、怎样返回结果。”
本例的路径是:
flowchart LR
A[你的 Python 程序] -->|HTTPS请求:消息和参数| B[DeepSeek 官方 API]
B --> C[模型生成]
C -->|JSON响应| A
A --> D[终端显示与本地响应文件]
Python 程序在你的电脑上运行,模型仍在远端服务运行。这不要求你的电脑有能装下大模型的显卡,也不等于把模型权重下载到本机。
先认识四个值:
| 项目 | 本篇使用的值或含义 |
|---|---|
| 服务基础地址 | https://api.deepseek.com |
| 本次操作路径 | /chat/completions,用于本例的聊天生成 |
| 模型标识 | deepseek-flash,让服务选择模型 |
| API Key | 你自己的访问凭据,不能用聊天密码代替 |
截至 2026 年 10 月 4 日,官方首次调用文档列出的 Flash 调用标识是 deepseek-flash。不要从旧教程复制模型名后假定它一直有效;阅读本篇较晚时,应先核对官方文档。DeepSeek:首次 API 调用
这里采用兼容 OpenAI 格式的聊天接口。请求仍发给 DeepSeek,凭据也必须来自 DeepSeek;“协议兼容”不是把两个平台的账户或余额连在一起。本篇直接用 Python 标准库发送 HTTP 请求,下一篇再用 SDK 整理项目。
二、准备自己的账户和凭据
打开 DeepSeek 开放平台,登录自己的账户,找到 API Keys(API 密钥)管理入口,创建一枚用于本课程的密钥。界面名称和布局可能调整,入口用途是管理供程序调用的访问凭据。
再检查平台显示的可用余额和 官方价格页。没有可用余额时,按自己愿意承担的预算决定是否充值;本文不要求固定充值金额,也不假设账户一定有赠送额度。API 用量由平台按规则扣费,不能仅凭聊天页面可以使用,就判断程序调用也免费。
本篇只发一次很短的文本请求,并限制输出长度。密钥在程序运行时通过隐藏输入读取,不需要贴进代码、聊天记录或截图。请把密钥保存在自己使用的密码管理工具等安全位置;程序运行时再粘贴。
如果把密钥误发给他人或提交进公开仓库,应在平台撤销并重新创建。删除截图或最新一行代码,不会让已经泄露的密钥重新安全。
三、确认电脑能运行 Python
先在系统终端检查版本。macOS 打开“终端”,Windows 打开 PowerShell;不要把下面的命令粘贴进出现 >>> 的 Python 交互窗口。
macOS / Linux:
python3 --version
Windows PowerShell:
py -3 --version
看到 Python 3.11.x、3.12.x 等不低于 3.11 的稳定版即可。本文代码在 Python 3.11.8 上完成本地检查;不要求安装某一个完全相同的小版本。
如果命令不存在,按对应平台处理:
- macOS:从 Python 官方下载页 选择稳定版 macOS 安装包,打开
.pkg完成安装;重新打开终端,再检查python3 --version。如后续遇到证书验证问题,官方安装包的 Python 文件夹提供Install Certificates.command,可按 macOS 官方说明安装证书,不要改成跳过 HTTPS 验证。 - Windows:从同一官方下载页进入 Windows 安装入口,按官方安装方式安装稳定版。重新打开 PowerShell,检查
py -3 --version;若仅python --version能正常显示所需版本,后续将py -3换成python。安装与命令发现问题可对照 Windows 官方说明。 - Linux:先检查发行版自带的
python3。Ubuntu / Debian 缺少时可用下方命令安装,再检查版本;若发行版提供的版本低于 3.11,需按该发行版支持的方式安装较新版本,不要直接替换系统依赖的解释器。
仅 Ubuntu / Debian 安装命令:
sudo apt update
sudo apt install python3
python3 --version
本篇只使用标准库,不需要执行 pip install。能显示正确版本,是继续之前的第一项检查。
四、保存一份可以直接运行的脚本
在你容易找到的位置创建一个空文件夹 deepseek-notes。用代码编辑器在里面新建 first_call.py,保存为 UTF-8。文件名应以 .py 结尾,不要误存成 first_call.py.txt。
你也可以下载现成的 first_call.py,放进这个文件夹。以下代码与下载文件一致:
"""Lesson 01: one DeepSeek request; --dry-run never reads a key or uses the network."""
import argparse
import getpass
import json
from pathlib import Path
from datetime import datetime
import urllib.error
import urllib.request
import warnings
ENDPOINT = "https://api.deepseek.com/chat/completions"
MODEL = "deepseek-flash"
def make_payload():
return {
"model": MODEL,
"messages": [
{"role": "system", "content": "你是复习助手。仅依据用户提供的笔记回答;缺少信息就说明缺少。"},
{"role": "user", "content": "笔记:第二章原定周五,现改为周六复习。问题:现在安排在哪天?只回答日期表达,不补充几点。"},
],
"thinking": {"type": "disabled"},
"stream": False,
"max_tokens": 256,
}
def main():
parser = argparse.ArgumentParser(description="一次 DeepSeek API 调用")
parser.add_argument("--dry-run", action="store_true", help="只看请求,不读取密钥、不联网")
args = parser.parse_args()
payload = make_payload()
if args.dry_run:
print("POST", ENDPOINT)
print(json.dumps(payload, ensure_ascii=False, indent=2))
return 0
try:
with warnings.catch_warnings():
warnings.simplefilter("error", getpass.GetPassWarning)
key = getpass.getpass("粘贴 DeepSeek API Key(不显示),然后回车:").strip()
except (getpass.GetPassWarning, EOFError):
print("无法隐藏输入。请在系统终端中运行,不要把密钥写入代码。")
return 1
if not key:
print("未输入密钥,未发送请求。")
return 1
request = urllib.request.Request(
ENDPOINT,
data=json.dumps(payload, ensure_ascii=False).encode("utf-8"),
headers={"Content-Type": "application/json", "Authorization": "Bearer " + key},
method="POST",
)
try:
with urllib.request.urlopen(request, timeout=60) as response:
status = response.status
raw = response.read().decode("utf-8")
data = json.loads(raw)
except urllib.error.HTTPError as exc:
print(f"HTTP {exc.code}:请求未成功,请按文章的错误表检查;本程序不会自动重试。")
return 1
except (urllib.error.URLError, TimeoutError):
print("网络连接、证书或等待响应出错;未确认完成,不自动重试。")
return 1
except (UnicodeDecodeError, json.JSONDecodeError):
print("响应不是预期的 UTF-8 JSON。请核对官方地址和网络环境。")
return 1
output = Path(__file__).resolve().parent / "responses"
output.mkdir(exist_ok=True)
path = output / (datetime.now().strftime("response-%Y%m%d-%H%M%S-%f") + ".json")
path.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")
print("HTTP", status)
print("响应保存到:", path)
try:
choice = data["choices"][0]
answer = choice["message"]["content"]
finish = choice["finish_reason"]
if not isinstance(answer, str) or not answer.strip():
raise ValueError("empty content")
except (KeyError, IndexError, TypeError, ValueError):
print("缺少有效回答,请查看响应文件;HTTP 成功不等于内容可用。")
return 1
print("回答:", answer)
print("结束原因:", finish)
print("用量:", json.dumps(data.get("usage", {}), ensure_ascii=False))
if finish != "stop":
print("本次不是正常 stop 结束;不要直接当成完整答案。")
return 1
return 0
if __name__ == "__main__":
try:
raise SystemExit(main())
except KeyboardInterrupt:
print("\n已中断;若请求已发出,不能据此断定服务端没有处理或计费。")
raise SystemExit(130)
代码看起来不短,是因为它同时交代了读取密钥、处理常见失败和保存结果。你暂时不需要背下每一行,先沿着三个部分理解:
make_payload() 定义发给服务的内容。 messages 是消息列表,system 说明任务要求,user 提供具体笔记和问题。这里的笔记是教学构造,正确答案能由原文独立判断。
Request 和 urlopen 负责发送。 Python 字典先转成 UTF-8 JSON 字节,再通过 HTTPS POST 交给接口;Authorization 请求头带访问凭据。timeout=60 为阻塞网络操作设置超时,不是保证整个任务严格在 60 秒内结束。Python:urllib.request
后半段解析并保存响应。 它从 choices[0].message.content 取第一项回答,检查是否有内容,读取结束原因,并把原始 JSON 保存下来。这样你不必只相信终端最后一句“看起来成功”。
thinking 在这里显式设为 disabled。当前官方文档说明思考模式默认开启;第一次只是从短笔记取日期,不需要把更多模式一起引入。后面会单独比较什么时候需要它。DeepSeek:思考模式
stream: false 表示本篇一次接收完整响应;max_tokens: 256 是输出 Token 上限,不是“256 个汉字”,也不是要求必须输出这么长。DeepSeek:聊天接口参数
五、先预演,再发送一次真实请求
在终端切换到 deepseek-notes 文件夹。可以在编辑器中打开该文件夹,再打开它的集成终端;用下面命令确认当前文件夹里确实有脚本。
macOS / Linux:
ls
python3 first_call.py --dry-run
Windows PowerShell:
Get-ChildItem
py -3 first_call.py --dry-run
预演会显示 POST https://api.deepseek.com/chat/completions 和请求 JSON。它不读取密钥、不联网、不产生 API 用量。检查三件事:目标域名正确、模型标识正确、消息里是本篇的短笔记。
确认后去掉 --dry-run。下面这一步会向官方服务发送请求,可能产生费用。
macOS / Linux:
python3 first_call.py
Windows PowerShell:
py -3 first_call.py
出现“粘贴 DeepSeek API Key”提示时粘贴自己的密钥,再按回车。输入时通常没有星号,也看不到字符,这不意味着粘贴失败。隐藏输入由标准库 getpass 提供;如果运行环境无法隐藏,脚本会停止,而不是改成把密钥显示出来。Python:getpass
这一版没有自动重试。若要中断,可以按 Ctrl+C;请求已经发出时,中断本地程序不等于远端一定没有处理,也不能据此断定不会计费。
六、怎样判断这次真正成功了
下面是示意输出,文件名、文字和实际用量以你的运行结果为准:
HTTP 200
响应保存到:…/deepseek-notes/responses/response-日期-时间.json
回答:周六
结束原因:stop
用量:{这里会显示服务实际返回的用量字段}
先看四层结果:
- 网络和接口:没有连接错误,HTTP 返回成功。
- 响应结构:存在有效回答内容,而不是空字符串或缺少
choices。 - 生成结束:本例应当正常
stop;若是length等其他状态,先检查是否截断或异常结束。 - 任务结果:答案确实是周六,没有凭空添加 19:00、教材或新安排。
stop 只说明生成正常停止,不证明答案正确。前三层通过、第四层失败时,接口仍然可能已经正常调用并计费,只是模型没有完成你想要的任务。DeepSeek:响应及结束原因
接着打开脚本旁的 responses 文件夹,用文本编辑器打开最新 JSON。找到 choices、message、content,确认它与终端显示一致;再找到 usage,查看服务实际记录的输入输出用量。这是对程序显示的一次独立复核。
文件由脚本按本地日期时间创建,每次成功解析响应都会生成新文件,不覆盖前一次。脚本没有把请求头或密钥主动写入文件,但真实响应可能包含你的私人资料;本课先用公开的构造笔记,后续不要随意分享原始响应目录。
如果打开的不是最新文件,或者你在别的目录运行了脚本,按终端打印的完整路径查找。保存位置固定在脚本旁,不取决于启动时恰好在哪个文件夹。
七、失败时,先按现象查
| 现象 | 首先检查什么 | 本轮怎样处理 |
|---|---|---|
找不到 first_call.py |
当前文件夹、扩展名 | 回到脚本所在目录,重新列出文件 |
| 隐藏输入不可用 | 是否在不支持交互的运行面板 | 改用系统终端;不要把密钥粘进源码 |
| HTTP 401 | 密钥错误、撤销、复制不完整 | 回开放平台确认,重新运行并输入 |
| HTTP 402 | 可用余额 | 查看平台账户余额,决定是否补充 |
| HTTP 400 / 422 | JSON格式、模型名、参数 | 对照请求预演与当前文档,不凭猜测改一堆参数 |
| HTTP 429 | 请求频率或服务限制 | 停下来稍后再试,不连续启动很多次 |
| HTTP 500 / 503 | 服务端错误或繁忙 | 稍后人工重试,保留错误类型 |
| 网络、证书或等待错误 | 网络能否访问官方服务,证书配置 | 排查网络和系统证书;不要禁用验证 |
| HTTP成功但回答缺失或非stop | 响应文件中的内容与结束原因 | 查看保存文件,不直接当完整答案使用 |
其中状态码对应原因来自 DeepSeek 官方错误说明。本篇先把常见问题分清,第 08 篇再做有上限、分类型的程序重试。
如果出现文件权限或磁盘空间错误,可能是响应已经收到,但本地保存失败。把脚本放在自己可写的项目目录,检查磁盘空间;不要因为保存失败就认为服务一定没有计费。
八、做一个小改动,确认你真的理解了
把 user 消息里的笔记改成:
第二章原定周六,现改为周日复习。问题:现在安排在哪天?只回答日期表达,不补充几点。
先运行 --dry-run,确认送出的文本已经改变,再决定是否执行第二次真实调用。预期应改答周日;它能检验你修改的是实际请求,而不是只改了页面上的说明。
再做三个不用联网的判断:
- 把模型标识改成自己的密钥,可以完成认证吗? 不可以。模型标识选择服务里的模型,认证凭据放在请求头,两者作用不同。
- 预演显示了请求 JSON,能说模型已经回答了吗? 不能。预演没有发出网络请求。
- 返回“周日 19:00”,HTTP和结束状态都正常,算本题通过吗? 不算。19:00没有依据,接口成功与任务正确是两件事。
今天得到的是一个可以检查输入、发送请求、保存响应的小脚本。下一篇会把它整理成可维护的项目:建立虚拟环境,管理依赖和配置,用 SDK 封装请求,让后续多轮对话不必反复写这些连接代码。
本部分大纲 · 可运行脚本 · 第二部分:大模型原理
文档核查日期:2026 年 10 月 4 日。示例本地离线验证通过;真实账户权限、余额、网络和当时服务行为需由读者实际运行核对。