大模型API调用实战③-零基础保姆级教程

发布时间:2026/10/10 7:18:18

大模型API调用实战③-零基础保姆级教程 第 7 章流式输出 —— 打字机效果的真实现7.1 基本用法streamTrue只加一个参数返回值从响应对象变成可迭代的块chunk序列stream client.chat.completions.create( modeldeepseek-chat, messages[{role: user, content: 写一首关于程序员的四行小诗}], streamTrue, stream_options{include_usage: True}, # 让最后一个块带 usage 统计 ) collected [] for chunk in stream: if chunk.choices and chunk.choices[0].delta.content: # 防御式判断见7.2 piece chunk.choices[0].delta.content print(piece, end, flushTrue) # 01教程的老朋友 collected.append(piece) if chunk.usage: # 最后一块携带账单 print(f\n[本次消耗 {chunk.usage.total_tokens} tokens]) full_answer .join(collected) # 攒出完整回答 —— 记历史时用它7.2 必知细节delta 不是 message流式块里是chunk.choices[0].delta.content本块新增的一小段不是.message.content。首块的 delta 可能只有 role 没 content末块带 usage 时choices为空列表——所以if chunk.choices and ...的防御写法不是啰嗦是必需。完整回答要自己拼流式模式没有现成的全文.join(collected)后再 append 进对话历史。底层是 SSEServer-Sent Events服务器在一条 HTTP 长连接上持续推送data: {...}文本行最后推data: [DONE]。SDK 帮你解析成了 chunk 对象。第 7 批你写 FastAPI 接口时就要亲手生产这种 SSE 流转发给前端——今天是消费者那天当生产者。推理模型的流式思考阶段的块走delta.reasoning_content回答阶段才走delta.content两个字段分开接。7.3 进阶预告流式 工具调用当模型在流式模式下决定调用工具时工具名和参数会被拆碎在多个 chunk 的delta.tool_calls里按 index 分组、arguments 逐段拼接需要累积重组。参考骨架现在看懂结构即可tool_calls {} # index - {id, name, arguments} for chunk in stream: if not chunk.choices: continue delta chunk.choices[0].delta if delta.content: print(delta.content, end, flushTrue) # 普通文本照常打印 for tc in (delta.tool_calls or []): # 工具调用碎片 slot tool_calls.setdefault(tc.index, {id: , name: , arguments: }) if tc.id: slot[id] tc.id if tc.function.name: slot[name] tc.function.name if tc.function.arguments:slot[arguments] tc.function.arguments # 循环结束后 tool_calls 里就是完整的调用申请正因为这套拼装麻烦本模块的 Agent 主循环先用非流式保证清晰流式作为综合项目的升级挑战。第 8 章异步与并发 —— AsyncOpenAI 批量处理8.1 场景100 条评论要做情感分析串行调用100 次 × 3 秒 5 分钟。异步并发import asyncio from openai import AsyncOpenAI aclient AsyncOpenAI(api_keyos.getenv(DEEPSEEK_API_KEY), base_urlhttps://api.deepseek.com) async def analyze(comment: str) - str: r await aclient.chat.completions.create( # await等待时让出CPU modeldeepseek-chat, messages[{role: system, content: 判断评论情感只输出正面/负面/中性}, {role: user, content: comment}], temperature0) return r.choices[0].message.content async def main(): comments [物流超快包装也好, 用了三天就坏了, 还行吧凑合, 客服态度太差了] * 5 results await asyncio.gather(*[analyze(c) for c in comments]) # 并发全上 for c, s in zip(comments[:4], results[:4]): print(f{s} ← {c}) asyncio.run(main())*[...]是 01 教程 10.4 的解包把列表拆成 gather 的多个参数。20 条并发总耗时 ≈ 最慢的一条。8.2 并发不能裸奔Semaphore 限流全量并发会撞平台限速429。生产标配——信号量控制同时在飞的请求数sem asyncio.Semaphore(5) # 最多同时5个请求在路上 async def analyze_limited(comment: str) - str: async with sem: # 满5个时第6个在这排队等空位 return await analyze(comment) # main 里改用: results await asyncio.gather(*[analyze_limited(c) for c in comments])async with sem的原理就是 上下文管理器进门占坑、出门还坑异常也保证归还。面试可复述版LLM 调用是 IO 密集任务用 asyncio AsyncOpenAI 并发可将批量任务耗时从求和降为取最大生产中必须用 Semaphore 限制并发度以配合平台 RPM/TPM 限额配合重试与退避构成完整的吞吐控制方案。第 9 章结构化输出实战 —— JSON Mode 与 Pydantic本章把最强的两层落地成代码。9.1 正式认识 PydanticPydantic 的BaseModel自带数据校验的 dataclass。定义一次结构校验、转换、报错全自动# pip install pydantic from pydantic import BaseModel, Field, ValidationError from typing import Literal class OrderIssue(BaseModel): order_id: str | None Field(None, description订单号如A123未提及则为null) issue_type: Literal[退款, 换货, 查询, 其它] # 只允许这四个值 urgent: bool Field(..., description用户是否表达紧急情绪) # ... 表示必填 # 校验成功字符串true还会被自动转成 bool True ok OrderIssue.model_validate_json({order_id:A123,issue_type:退款,urgent:true}) print(ok.issue_type, ok.urgent) # 退款 True # 校验失败错误信息精确到字段 —— 这正是回喂自修的好材料 try: OrderIssue.model_validate_json({issue_type:投诉,urgent:1}) except ValidationError as e: print(e.errors()[0][loc], e.errors()[0][msg]) # (issue_type,) 不在允许值中三件套记牢model_validate_jsonJSON字符串→对象并校验、model_dump对象→字典、model_json_schema。9.2 JSON Mode Pydantic 校验 失败回喂通用三件套response_format{type: json_object}让服务端保证输出语法合法的 JSON各主流平台通用但字段对不对仍要 Pydantic 把关不过关就把错误喂回去重试import json EXTRACT_SYSTEM 从用户消息中提取售后信息只输出 JSON 对象结构如下 {order_id: 订单号字符串或null, issue_type: 退款|换货|查询|其它, urgent: true或false} 注意必须输出 json 格式。 # JSON Mode 要求提示词中出现 json 字样并描述结构 def extract_order_issue(text: str, max_retries: int 2) - OrderIssue: messages [{role: system, content: EXTRACT_SYSTEM}, {role: user, content: text}] for attempt in range(max_retries 1): r client.chat.completions.create( modeldeepseek-chat, messagesmessages, response_format{type: json_object}, # 第①道锁语法合法 temperature0) raw r.choices[0].message.content try: return OrderIssue.model_validate_json(raw) # 第②道锁字段校验 except ValidationError as e: if attempt max_retries: raise messages.append({role: assistant, content: raw}) # 它的错误答卷 messages.append({role: user, # 批改意见回喂 content: f输出未通过校验{e.errors()}。请修正后重新只输出 JSON。}) result extract_order_issue(单号A123的鞋开胶了急死了必须退钱) print(result.model_dump()) # {order_id: A123, issue_type: 退款, urgent: True}更强的第③道锁部分平台支持 Schema 级强约束OpenAI 的client.chat.completions.parse(..., response_formatOrderIssue)可直接返回校验好的对象。国产平台支持度不一上面这套JSON Mode Pydantic 回喂在所有平台都能跑是更通用的职业方案平台支持 parse 时优先用它防御代码照留。
延伸阅读

更多相关文章

2026/10/10 3:24:21

C++可变参数模板:从语法到实战,掌握现代C++泛型编程核心

1. 从“固定”到“不定”:为什么我们需要可变参数模板?如果你写过一段时间的C,尤其是在C11之前,你肯定遇到过这样的困境:你想写一个函数或者一个类,它能处理任意数量的参数,但类型和数量在编译时…

2026/10/6 5:14:37

虚拟化与容器化实战指南:技术选型

虚拟化与容器化技术实践指南 一、技术选型总体原则所有的应用,能跑Container,绝对不跑Virtual Machine;能跑VM,绝对不跑Physical Machine。这条原则背后是资源利用率与运维效率的考量: 容器:轻量级、启动快…

2026/10/10 7:15:20

Codex CLI接入OpenAI兼容接口:config.toml配置与排错

如果你手头有 Codex CLI,又不想只接固定的云上模型,今天这篇文章值得你花五分钟看完。我会把config.toml逐行拆开讲,覆盖接入 OpenAI 兼容接口时的常见报错和排查思路,也算是我这半年反复折腾下来的一份笔记。文章面向两类人&…

2026/10/10 7:15:20

Cursor高效配置四步法:用规则驱动代码减量

1. 项目概述:这不是在教你怎么点开设置,而是在重建你和代码的协作关系“Cursor怎么配置才好用?这套规则让我少写一半代码”——这句话我第一次看到时,手停在键盘上三秒。不是因为夸张,而是太真实。过去两年&#xff0c…

2026/10/10 7:15:20

Claude作为创业决策协作者的实战闭环构建

1. 项目概述:这不是“AI创业课”,而是一份面向真实创业者的协作增强方案“Claude 创业计划扩展至更多创始人”——这个标题乍看像一则新闻通稿,但作为连续三年深度参与多个早期技术型创业项目孵化的从业者,我第一反应是&#xff1…

2026/10/10 7:15:20

用PINN做多变量回归预测:Matlab实现与调参全攻略

用PINN做多变量回归预测,还是多输入单输出,Matlab代码该怎么落地?这个问题我刚接触的时候绕了不少弯路。物理信息神经网络(PINN)这两年讨论度很高,核心其实一句话:让神经网络的预测结果不仅拟合…

2026/10/10 7:15:20

HED边缘检测实战:从VGG16到多任务学习的深度学习流水线

简介:HED_edgeDetect 是一份面向计算机视觉初学者与深度学习实践者的边缘检测资源包,围绕 HED(Hypercolumns for Edge Detection)这一基于卷积神经网络的端到端边缘检测方法展开,可用于理解多尺度特征融合、预训练与微…

2026/10/10 7:10:19

Python+Pillow制作艺术签名生成器:字体渲染与透明PNG实战

我一直在用 Python 做一些小工具,最近琢磨着一个挺有意思的需求——给自己设计一个优雅的艺术签名。平时签文件、写卡片、做水印,总觉得自己手写签名不够好看,或者干脆没有手写习惯,一笔一画下去自己都嫌弃。于是我用 Pillow 做了…

2026/10/8 10:03:18

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/9 20:15:56

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/8 6:05:44

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 0:04:53

从逻辑门到计算机:数字电路核心原理与全加器搭建实战

如果你拆过一台旧电脑的主板,盯着那些黑乎乎的小芯片看上一会儿,可能会冒出同一个疑问:这堆引脚密集的元件,到底是怎么“变”出那么复杂的应用的?答案并不在某个神秘的部件里,而是在所有芯片内部都在反复使…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑