ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Python调用大模型API实战:从零开始构建你的首个AI应用

Python调用大模型API实战:从零开始构建你的首个AI应用

很多刚入门的朋友会问我,做“AI大模型”相关的应用到底要不要先把模型部署到本机,是不是得先啃完一堆底层原理。我的回答一直很统一:如果目标是尽快做出能用的东西,先把“Python调用大模型API”这条路走通就足够了。把请求发出去、把结果接回来,这个最简单的循环,已经是大模型应用开发的核心骨架。这篇文章就是一份实战记录,从环境准备、密钥申请,到写第一行调用代码、做多轮对话、处理流式输出,再把我实际踩过的坑整理成一份避坑清单,全程零门槛,所有代码都可以直接复制改着用。

这篇笔记能解决什么问题?你可能想做一个聊天机器人,想让模型批量整理文本,或者只是想亲手体验一次“应用调大模型”的完整链路。不管目标是什么,你需要掌握的能力都高度一致:构造结构化请求、管理对话上下文、解析返回结果、做好异常兜底。文章会沿着这条链路展开,特别适合刚学完Python基础、但完全没碰过接口的新手,也适合想快速把方案跑起来的工作者。

不用被一堆专业术语吓到。我们后面做的事情,本质上就是一次带身份凭证的HTTP请求。你在网页聊天框里输入一句话,浏览器做的事情,和你接下来要在Python里做的事情,底层逻辑完全相同:把输入打包成一条结构化消息,发给后端服务,再把模型生成的文本拆回来展示。只是我们要把“页面点按钮”这件事,换成一行行能控制的代码。

1. 项目全貌:Python调用大模型到底在做什么

1.1 先理解调用的本质:一次带身份信息的HTTP请求

在写任何代码之前,我建议先把“调用大模型”这件事的抽象模型建立起来。大模型服务商在云端维护着已经训练好的模型,对外提供一套接口。你的程序通过HTTP协议,把输入内容以JSON格式发送到指定地址,服务端处理完成后,再把模型生成的文本以JSON格式返回。整个过程和“用浏览器打开一个网页”没有本质区别,只不过你额外多带了一张入场券,也就是API密钥。

这张入场券的作用是让服务器知道“你是谁、用了哪个账户、有多少余额和权限”。所以代码里最核心的三件事是:请求地址、请求头、请求体。请求地址决定你要访问哪个模型的接口;请求头里放鉴权信息;请求体里放对话消息列表和生成参数。这也是为什么我反复强调,不要一开始就去背各种封装好的高级写法,先把这三件事看懂,之后迁移到任何平台都能很快上手。

用生活的场景类比,调用大模型就像去一家自助餐厅点菜。你不需要知道后厨怎么采购、怎么烹饪,只需要拿着餐票(API密钥)走到窗口,把想吃的菜名(消息内容)写在点菜单(JSON请求体)上递给服务员,然后等他把成品端回来(返回结果)。至于这家店今天有什么招牌菜、能选几分熟、要不要加料,这些就对应到模型选择和参数调节。看起来很高深的东西,一层层拆到这一步,其实就是这么回事。

1.2 为什么入门第一课要选“调API”,而不是“本地部署模型”

很多新手的第一个弯就绕在“本地部署”上,我也不例外。早些时候我在本地跑过开源模型,对电脑的要求确实比想象中高不少:显存动辄需要十几GB,还得配置推理框架,模型文件本身就占大量磁盘空间。如果只有CPU可用,推理速度会慢到让人失去耐心。这套流程对研究推理性能或做离线私有化部署的人是有价值的,但对绝大多数“只是想调用模型能力去做产品”的开发者来说,成本和复杂度都太高,而且很容易消磨掉入门阶段的热情。

调用API方案则把这些基础设施问题全部交给了服务商。你不需要关心模型跑在哪台机器上,不需要设计并发调度,也不需要自己更新模型版本。需要更强的能力,就在接口里换一个模型名;业务量上来了,服务商侧的扩容机制通常也能自动承接。这种模式对个人开发者、学生和中小团队太友好了,可以把精力优先放在业务逻辑上。

当然,API方案也不是没有代价。敏感数据要经过第三方服务,在数据隐私上需要做取舍;高频调用会产生费用,要注意控制用量;接口完全依赖服务商,如果对方服务出现波动,应用本身也会受影响。所以“调API”和“本地部署”不是谁替代谁的关系,而是适配不同场景的两种方案。对新手来说,第一优先级一定是先把API跑通、把产品逻辑验证出来,等以后真的有低延迟、高隐私、离线运行这类硬性需求,再回头研究本地部署也不迟。

1.3 技术选型:为什么先用requests,而不是官方SDK

市面上很多大模型平台都提供了官方封装好的SDK,写法非常简洁,几行就能发起一次请求。那为什么我坚持让新手第一篇笔记用requests来实现?原因很简单:SDK把太多细节藏起来了。一旦遇到鉴权失败、返回格式变化、超时重试这类问题,如果你连底层HTTP请求长什么样都看不懂,排查起来会非常痛苦。

用requests直接调用,你能清清楚楚地看到请求头、请求体和原始返回数据。先把原始结构看懂,之后再用任何SDK都会觉得轻车熟路。打个比方,官方SDK像是餐厅帮你配好的套餐,直接调HTTP接口像是自己拿着菜单点单,风味是一样的,但你对“这道菜到底加了什么料”心里有数。新手阶段多看看菜单,绝对不是浪费时间。

既然决定直接调接口,那需要安装的第三方库就非常少:一个requests用来发HTTP请求,一个python-dotenv用来管理密钥环境变量。就这两个,不需要引入任何重型框架。等以后项目复杂度上去了,再根据情况引入数据校验、Web框架等工具都来得及,前期别给自己加戏。

2. 环境准备与前置检查

2.1 检查Python环境并安装依赖

先看Python环境。打开终端(Windows下是命令提示符或PowerShell,macOS/Linux下是Terminal),输入以下命令:

python --version

如果显示类似Python 3.9.0甚至更高的版本,说明环境没问题。如果提示找不到命令,多半是Python没有加入PATH,建议重新安装一次Python,安装时记得勾选“Add Python to PATH”那一项。调用大模型API对Python版本要求不算严苛,3.8以上基本都能顺利运行,我自己常用的3.10环境几乎没有遇到兼容性问题。

确认Python可用后,新建一个项目目录,然后创建虚拟环境。这一步不是强制要求,但我强烈建议做,虚拟环境能把不同项目的依赖隔离开,避免全局环境里的包版本互相干扰,尤其是“某个项目需要旧版库、另一个项目需要新版库”这种经典冲突。

python -m venv .venv

Windows下激活虚拟环境:

.venv\Scripts\activate

macOS/Linux下激活虚拟环境:

source .venv/bin/activate

看到命令提示符前面出现了(.venv)字样,说明已经进入虚拟环境。接着安装依赖:

pip install requests python-dotenv

如果你的网络环境导致pip下载缓慢,可以把包源临时切换到自己网络可达性更好的开源镜像站,方法很简单,给pip命令加一个-i参数指定镜像地址即可。要注意的是,镜像源属于网络基础设施,不同网络环境下可用性不一样,具体选哪个以你自己实测为准。

2.2 获取API密钥:注册、创建与安全保存

接下来是拿API密钥,这往往是新手遇到的第一道坎。常规流程是:在模型服务商官网注册账号,登录后进入控制台,找到“API密钥管理”或类似入口,创建一个新密钥,系统会显示一串字母数字混合的字符串,通常以sk-之类的前缀开头。关键点在于,很多平台只在创建的那一刻完整显示一次密钥,之后就无法再次查看,所以创建完成后要立刻保存到安全的位置。

密钥和你的账户费用是直接绑定的,绝对不能泄露。如果怀疑密钥已经暴露,比如被提交到公开仓库、出现在聊天记录里,最佳处理方式不是继续沿用,而是立刻回到控制台删除这个密钥并重新生成。这个习惯一定要养成,我能看到的大量“半夜收到账单异常提醒”的案例,十有八九都是密钥泄露导致的。

使用习惯上,我想单独拎出三条。第一,不要把密钥硬编码在代码里,尤其不要提交到Git仓库;第二,不要在公开截图里展示请求头,因为里面通常带着鉴权信息;第三,如果是一个团队协作项目,密钥应该统一放到服务端环境变量中,前端和客户端永远不要接触。

2.3 用.env文件管理密钥

为了让密钥不散落在代码里,我习惯用.env文件统一管理。在项目根目录创建.env文件,内容如下:

# 模型服务商的接口地址 API_URL=https://你的服务商接口地址/v1/chat/completions # 你的API密钥 API_KEY=sk-你的密钥字符串 # 默认模型名 MODEL_NAME=你的模型名称

同时创建.gitignore文件,把.env忽略掉,避免密钥意外提交到版本库。在Python脚本中读取这些配置:

from dotenv import load_dotenv import os load_dotenv() API_URL = os.getenv("API_URL") API_KEY = os.getenv("API_KEY") MODEL_NAME = os.getenv("MODEL_NAME")

load_dotenv()会在脚本运行时读取.env文件内容,注入到当前的系统环境变量中,之后用os.getenv就能拿到对应值。这套做法在本地开发、服务器部署中都是通用方案,不依赖任何重量级框架,也方便以后把配置迁移到容器环境里。

3. 核心代码实现:从一行请求到多轮对话

3.1 先跑通最小可运行代码

准备工作就绪,可以写第一段能真正运行的代码了。保存下面的内容为chat.py,放在刚才创建的项目根目录:

import requests import os from dotenv import load_dotenv load_dotenv() API_URL = os.getenv("API_URL") API_KEY = os.getenv("API_KEY") MODEL_NAME = os.getenv("MODEL_NAME") headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json", } payload = { "model": MODEL_NAME, "messages": [ {"role": "user", "content": "你好,请用一句话介绍你自己。"} ], "temperature": 0.7, "max_tokens": 100, } resp = requests.post(API_URL, headers=headers, json=payload, timeout=60) resp.raise_for_status() data = resp.json() print(data["choices"][0]["message"]["content"])

运行脚本:

python chat.py

如果一切正常,终端会输出模型的一段自我介绍。这是我建议新手拿下的第一个里程碑:你的代码和云端模型成功完成了一次对话。这个动作看似简单,实际上同时验证了四件事:密钥有效、请求格式正确、网络能连通、返回结构符合预期。后续所有复杂功能都是在这个基础上叠加出来的。

初学阶段最容易出的问题,就是“看文档时觉得都懂,一放到真实代码里就不知道往哪里填”。所以如果你第一次运行报错,不要急着怀疑Python环境,先把返回的具体错误信息读出来,绝大多数情况下,错误信息都会非常明确地指出是鉴权失败、地址错误还是字段缺失。

3.2 请求参数详解:重点留意这几个字段

请求头里的Authorization要写成Bearer + 空格 + API密钥,这是当前最流行的鉴权格式。漏掉Bearer、多打一个空格、复制密钥时少复制几位,都会导致401。请求头的Content-Type要设置为application/json,告诉服务端你提交的内容是JSON格式,这个字段忘记设置的话,服务端可能直接拒绝解析。

请求体payload里,model字段用来指定模型名称,需要替换成平台给的真实型号。不同平台的模型名写法可能完全不一样,填错通常会得到类似model not found的提示。messages是对话消息列表,每条消息包含role和content两个字段,role有system、user、assistant三种,分别表示系统设定、用户输入和模型回复。

temperature控制回答的随机性,取值通常在0到2之间。数值越大,回答越发散、越有创造性;数值越小,输出越保守、越倾向确定性答案。做信息抽取、格式转换这类任务,我会把temperature调到0.3以下;做文案润色、头脑风暴,可以放到0.8到1.0。max_tokens限制生成内容的最大长度,注意它限制的是“标记数”而不是“汉字数”。一个汉字大致对应一到两个标记,所以中文长文本很容易在这个字段上栽跟头,估算长度时一定要留足余量。

服务端返回的结构通常是嵌套的:最外层是响应体,里面有个choices列表,列表第一项里又有个message对象,message.content存着模型生成的正文。用data["choices"][0]["message"]["content"]可以把这个正文取出来。如果返回结构和预期对不上,可以先print(resp.text)把原始响应打印出来看看,不要凭猜。

3.3 把调用封装成函数,避免重复劳动

每写一次完整请求就要把requests.post那几行重复一遍,几轮之后就很烦。我们可以马上封装出一个通用函数:

import requests import os from dotenv import load_dotenv load_dotenv() API_URL = os.getenv("API_URL") API_KEY = os.getenv("API_KEY") MODEL_NAME = os.getenv("MODEL_NAME") HEADERS = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json", } def chat_once(messages, model=MODEL_NAME, temperature=0.7, max_tokens=500): payload = { "model": model, "messages": messages, "temperature": temperature, "max_tokens": max_tokens, } resp = requests.post(API_URL, headers=HEADERS, json=payload, timeout=60) resp.raise_for_status() return resp.json()["choices"][0]["message"]["content"]

在这个函数里,API_KEY被放进了模块级别的HEADERS,函数内部不再需要关心鉴权细节。调用时只需要传入消息列表:

result = chat_once([ {"role": "system", "content": "你是一个信息抽取助手,输出要简洁专业。"}, {"role": "user", "content": "请从这段文字里提取三个关键结论:..."}, ]) print(result)

封装的最大好处不只是少写几行代码,而是让后续的升级都有地方落脚。想加超时重试,在函数内部套一层循环;想记录日志,在函数入口和返回处打印;想切换模型,调整model参数即可。我见过不少初学项目,所有请求逻辑全散落在业务代码里,发展几十行后想统一调参就特别痛苦,能尽早封装的工具函数建议至少提前一步封装。

3.4 多轮对话的实现与上下文管理

如果你只想跑通一次请求,上面这段已经够用。但要做一个真正能聊天的程序,就必须处理上下文。很多人第一次接触大模型接口时会以为服务端会“记住”之前的对话,其实不会。接口本身是无状态的,你每次发送的messages列表都得包含完整的对话历史,模型才能根据上下文继续回答。

实现多轮对话的套路很朴素:一边积累历史消息,一边在每次请求时把全部历史都发过去。下面是一个命令行交互聊天程序:

def chat_once(messages, model=MODEL_NAME, temperature=0.7, max_tokens=500): payload = { "model": model, "messages": messages, "temperature": temperature, "max_tokens": max_tokens, } resp = requests.post(API_URL, headers=HEADERS, json=payload, timeout=60) resp.raise_for_status() return resp.json()["choices"][0]["message"]["content"] history = [{"role": "system", "content": "你是乐于助人的中文助手,回答尽量言简意赅。"}] while True: user_input = input("我:") if user_input.strip().lower() in {"exit", "quit", "q"}: break history.append({"role": "user", "content": user_input}) reply = chat_once(history) print("助手:" + reply) history.append({"role": "assistant", "content": reply})

这段逻辑非常直观:用户输入被追加进history,请求时把完整历史带过去,拿到回复后再把回复追加进history,于是下一轮对话就能“看到”前面说了什么。

但这里藏着一个最容易被忽视的问题:随着对话轮次变多,history会越来越长,每次请求传输的数据量也水涨船高,响应速度下降,成本上升,模型还可能因为上下文过宽而注意力分散。真实产品一般会做“滑动窗口”,只保留最近N轮对话,或者对太早的内容先做一次摘要压缩,再用摘要顶替原始内容。很多聊天应用会“越聊越糊涂”,本质上就是上下文窗口里塞进了太多无关历史。

3.5 流式输出:让回答像打字机一样逐字出现

普通请求会等到模型完整生成完答案才返回结果,遇到长文本可能要等几十秒,用户早就没耐心了。流式输出的思路是:服务端一边生成一边把结果推送过来,客户端逐字显示。这几乎已经是对话类应用的标配功能。

在请求体里加上"stream": true,发送请求时设置stream=True,然后循环读取返回的数据流:

import json import requests payload = { "model": MODEL_NAME, "messages": history, "stream": True, } resp = requests.post(API_URL, headers=HEADERS, json=payload, stream=True, timeout=120) resp.raise_for_status() for line in resp.iter_lines(): if not line: continue line = line.decode("utf-8") if line.startswith("data: "): try: delta = json.loads(line[6:])["choices"][0]["delta"] content = delta.get("content", "") if content: print(content, end="", flush=True) except (json.JSONDecodeError, KeyError, IndexError): continue

要特别提醒的是,流式接口的返回行格式和普通接口不同,文本内容放在choices[0].delta.content里,而不是message.content,而且通常还会有类似data: [DONE]这样的结束标记。不同平台对流的边界定义有一些差异,有的行末尾还会携带空内容甚至额外字段,所以解析时一定要做异常保护,我在实际项目里见过太多次因为少了try/except导致整个流式打印中途崩掉的状况。

3.6 给代码加上错误处理和自动重试

调用外部接口,网络波动、服务端限流、临时故障几乎不可避免,所以健壮的程序都要有错误处理。比如超时参数timeout=60设置了整个请求的等待上限,超过60秒没有响应就会抛异常。我们可以捕获异常并按一定策略重试:

import time def chat_with_retry(messages, max_retries=3, base_interval=2): for attempt in range(max_retries): try: return chat_once(messages) except requests.exceptions.Timeout: wait_seconds = base_interval * (attempt + 1) print(f"请求超时,{wait_seconds}秒后重试...") time.sleep(wait_seconds) except requests.exceptions.HTTPError as e: if e.response is not None and e.response.status_code in {429, 500, 502, 503, 504}: wait_seconds = base_interval * (attempt + 1) print(f"收到 {e.response.status_code},{wait_seconds}秒后重试...") time.sleep(wait_seconds) else: raise raise RuntimeError("多次重试仍然失败,请检查网络或服务状态")

重试策略听起来简单,但有几个原则值得记一下。第一,不是所有错误都值得重试,401这类鉴权错误和400这类参数错误,重试多少次都一样,反而白白浪费额度;第二,重试间隔要递增,避免所有请求在同一时间点集中冲到服务端,把服务端打得更难恢复;第三,一定要设置最大重试次数,否则遇到长时间故障,脚本可能无限循环下去。上面代码用了一个简化版“退避”策略:第一次等2秒,第二次等4秒,第三次等6秒,对日常个人项目完全够用。

4. 避坑指南:常见问题与排查路线

4.1 HTTP状态码速查:看到报错先别慌

排查接口问题,第一步永远是看状态码。状态码就像服务端给你的病情诊断书,一眼就能缩小问题范围。我把最常见的几类整理成了速查表:

状态码常见含义处理建议
401鉴权失败检查密钥是否复制完整、是否过期、是否带了多余空格
403没有访问权限确认账户是否开通对应模型权限,是否绑定付款方式
400请求体格式错误检查字段名、JSON结构、模型名、消息格式
404请求地址错误核对接口域名和路径,确认是否配置了正确的版本号
429请求过于频繁,触发限流降低请求频率,或等待配额恢复
500/502/503服务端临时故障按重试策略等待并重试,确认是否处于维护窗口
200请求成功也要检查内容:是否有业务层面的错误提示

代码里resp.raise_for_status()会把4xx和5xx状态码转换为异常,方便统一处理。但要注意,它只管HTTP层,不负责业务层,比如模型名称填错时,部分平台会返回200但响应体里带着错误提示,所以最好在关键位置打印resp.text查看原始内容。

4.2 网络连接问题的排查思路

新手报“连不上去”,在东扯西拉之前,建议按下面几步走。第一步,检查API_URL是否完整,域名有没有拼错,路径和版本号对不对,这个看似基础的问题出错率反而很高。第二步,确认本机网络环境、防火墙或安全软件是不是拦截了对该地址的访问,换一个网络环境或换一台设备能快速定位问题范围。第三步,用curl命令做一次裸请求,把Python环境因素从排查链路里摘出来,如果curl能通而Python不行,问题多半出在代码或依赖上。

另外想提醒一个经验值:把timeout设置得宽裕一些。很多服务端在大模型推理时,冷启动和排队时间可能长达几十秒,如果你沿用浏览器请求那种3秒默认超时,轻则超时重试,重则掩盖真实问题。我一开始就建议用60秒作为起步值,后续再根据实际场景逐步缩小。

4.3 输出质量不好?先调整参数而不是急着换模型

拿到不满意的生成结果,很多人的第一反应是“换个更大的模型”。但很多时候问题压根不在模型能力上,而是参数没配好,或者提示词有问题。temperature太高,输出天马行空甚至出现重复;max_tokens设得太小,内容在关键位置被截断;system提示词含糊,模型不知道自己该以什么身份、什么格式作答。

我建议调整顺序固定为:先明确任务描述,再设定系统角色,最后微调temperature。举个例子,假设我要让模型做关键词提取,直接问“帮我提取关键词”,结果通常比较发散;但如果把system设定成“你是信息抽取专家,只输出JSON数组,不要多余解释”,再把temperature调到0.3以下,效果立刻不一样。不是模型不懂,是它没有被放到正确的“工作状态”里。这个思路在做任何结构化输出任务时都非常关键。

4.4 成本与额度控制:别等账单来了才后悔

调用大模型的费用和输入输出的文本长度直接相关,最有效的省钱方法就是减少无效字符。第一,提示词尽量精简,特别要避免在每轮对话里重复大段背景说明;第二,max_tokens要按需设置,不要让模型输出超出必要的内容;第三,对长文档先分段或先做摘要,再带着摘要去提问,而不是把整篇原文塞进请求。

还有一个特别容易忽略的成本坑:多轮对话的历史消息每次都要全量发送,对话越长输入文本越膨胀,成本也越高,所以前面提到的“滑动窗口”不仅是性能优化,更是省钱方案。调试阶段也建议先准备几组短小的样例,等逻辑跑通后再替换成真实业务文本,不要用一个超长prompt反复测试,不然几次调试跑掉的额度可能让你吓一跳。另外,在账户后台设置消耗上限是个好习惯,能避免“脚本失控导致整夜扣费”这类事故。

5. 扩展实战:把一行请求变成像样的小工具

5.1 用类封装对话客户端

函数式封装已经能解决大部分问题,但如果你打算做一个稍微完整一点的小工具,用类组织代码会更易维护。实现一个极简的对话客户端类:

import requests class ChatClient: def __init__(self, api_url, api_key, model_name, temperature=0.7): self.api_url = api_url self.api_key = api_key self.model_name = model_name self.temperature = temperature self.headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json", } def chat_once(self, messages, max_tokens=500): payload = { "model": self.model_name, "messages": messages, "temperature": self.temperature, "max_tokens": max_tokens, } resp = requests.post(self.api_url, headers=self.headers, json=payload, timeout=60) resp.raise_for_status() return resp.json()["choices"][0]["message"]["content"]

实例化时传入地址、密钥和模型名,之后就能反复使用:

client = ChatClient(API_URL, API_KEY, MODEL_NAME) print(client.chat_once([{"role": "user", "content": "请给一条短视频脚本起三个标题。"}]))

把公共配置放进__init__之后,类里面可以继续扩展chat_stream流式方法、set_system_prompt方法、历史记录管理、缓存、日志等等。当你开始做自己的小项目时,会不会有组织代码的意识,往往决定这个项目到底能走多远,这也是我建议尽早把封装习惯建立起来的原因。

5.2 批量任务的速度控制与错误隔离

当你需要处理一批文本,比如给几十篇文章分别写摘要时,最容易触发的不是代码逻辑错误,而是限流。我常用的做法是在循环里主动加小延时,让两次请求之间隔开0.5到1秒,同时把每个任务封装成独立的函数调用,配合重试机制。宁可跑得慢一点,也不要中途被限流打断,后者恢复起来更痛苦。

批量任务的数据结构同样关键。我见过不少失败的案例,都是把好几条文本硬拼到一个messages里,让模型一口气输出整份合并结果,一旦格式错了一点点,整批数据都要返工。更稳的做法是一条文本调用一次接口,模型只负责输出单项结果,程序再统一收集。这样即使某一条任务失败,也只影响那一条,配合日志能很快定位是哪段文本出了问题。

5.3 跑通之后还能怎么继续扩展

接口跑通之后,可扩展的方向非常多。你可以把这段对话客户端挂载到Web服务上,做一个带网页前端的对话页面;可以加一层工具调用,让模型决定要不要调用你本地的Python函数,用来查天气、算时间、查数据库;也可以用Prompt模板把任务参数化,做成简历优化助手、日报生成器、会议纪要整理器一类的实用小工具。还有一块经常被忽视的地方是缓存层,对于重复请求,可以把结果存进本地数据库,下次直接查缓存,既省钱又减少等待时间。

我在实际项目里最深的一个体会是:调用接口本身只占整个开发流程很小的一部分,更大头的工作在输入设计、输出校验和异常兜底。大模型的回复不是百分之百可控的,程序里一定要对返回文本做解析判断,加必要的校验逻辑,不要默认它会严格按格式输出。最后再分享一个我一直用的调试技巧:每次改动代码之前,先固定一组最小的测试输入,确保回归通过之后再处理复杂业务数据。这个习惯能帮你把“是代码逻辑错了,还是模型输出不听话”这口锅快速分清楚,省下大量排查时间。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进