尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
DeepSeek API实现文本与图像分类:提示词设计与工程避坑指南
简介面向有Python编程经验的技术开发者这份指南系统讲解借助DeepSeek API完成图像分类与文本分类任务的完整流程也适用于正在集成自动化AI分类系统的开发团队。资源覆盖从账号注册与API密钥获取、requests和Pillow等依赖库安装到POST请求的URL、HTTP头与请求主体构造细节并配有可直接修改运行的代码示例。针对图像任务重点说明如何通过files参数上传图片并演示用Pillow调整尺寸等预处理针对文本任务则给出JSON负载的组装方式。对于返回结果逐一说明如何解析分类标签与置信度字段遇到错误时则介绍了校验API密钥、核对请求负载格式等常见排查思路。资源包为单个docx文档大小仅17KB便于离线查阅与复制关键代码片段。目前已有2675人学习适合正在快速构建AI应用原型的开发者参考。1. 视觉与文本分类为什么先想到 DeepSeek API先抛一个反直觉的结论DeepSeek 官方 API 并不提供“图像分类模型”和“文本分类模型”这样两个独立接口但它是目前做这两类任务最顺手的入口之一。原因不在于它有多强而在于它的 chat 接口同时支持文本输入和图像输入并且返回格式可控。换句话说你不需要分别接一个文本分类服务和一个图像分类服务只用一个 API用提示词工程的方式就能把两类任务都跑起来。这篇文章面向两类人。一类是刚接触大模型 API想把分类需求落地但不确定怎么设计提示词、怎么解析返回结果的开发者另一类是已经能调通 chat 接口但被分类不稳定、输出格式不固定、图片传不进去这些问题卡住的工程师。后面这类人最常见的困惑是模型能力没问题为什么我的代码里总在报 JSON 解析错误或者 400 上下文超限。这篇文章会把从密钥申请到两类分类任务的全过程拆开讲每一步给出可复现代码和参数说明并标注我实际踩过的坑。如果你正准备把文本分类和图像分类接到业务里正文里的实现步骤可以直接抄。2. 先搞清 DeepSeek API 的分类能力边界选型与前置条件2.1 DeepSeek API 到底是什么形态能做什么分类DeepSeek 官方开放的是 OpenAI 兼容的 chat/completions 接口不是独立的分类 API。这意味着你可以直接用 OpenAI 的 SDK只需要改 base_url 和 api_key来调用也可以拿 requests 自己拼 JSON 体。它支持两类输入纯文本和图像。文本分类走 deepseek-chat 这类对话模型图像分类走带视觉能力的模型。两者共用同一个密钥账单也合并在一起。关键点在于“分类能力”不在模型侧而在你的提示词里。同一个 deepseek-chat你让它“把下面这段评论分成正面负面中性”就是情感分类你让它“判断工单是否属于网络故障”就是意图分类你让它“给商品标题打类目标签”就是文本多分类。图像侧同理给它一张图并附上“这张图属于室内还是室外、有没有行人、画面里有没有文字”它返回的就是图像分类结果。这种做成方式的优势是零训练成本劣势是稳定性需要靠工程手段兜底后面第三四章会专门讲怎么兜。2.2 申请密钥与调用前置条件最少必要配置去 DeepSeek 开放平台注册账号后在控制台创建 API Key。这个 Key 只在创建时完整显示一次务必立刻复制保存。调用前请确认三件事账户有余额、API Key 有权限调用模型、网络能访问 api.deepseek.com。前两点听起来像废话但我周围至少三个人被“401 认证失败”卡了半小时最后发现是复制 Key 时多复制了一个换行符。我建议第一次调用不要直接用 SDK先用 curl 验证连通性。这样能把网络问题、密钥问题和代码问题分开。下面是连通性测试的命令curl https://api.deepseek.com/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-你的密钥 \ -d { model: deepseek-chat, messages: [ {role: user, content: 只回复两个字正常} ], max_tokens: 10, temperature: 0 }逻辑不复杂向 chat/completions 接口发一个最简单的对话请求模型名叫 deepseek-chattemperature 设为 0 表示尽量确定输出。如果返回内容里出现content:正常说明密钥和网络都没问题。如果返回 401去检查密钥如果返回 404去检查模型名如果超时去检查网络出口。这一步跑通后再进 Python 代码排查范围会小很多。3. 文本分类的工程化实现从提示词到结构化输出3.1 用提示词约束分类目标少样本示例比描述规则更管用文本分类任务本身不复杂难的是让模型稳定输出你想要的类别字符串。例如我想把客服工单分为“账号问题 / 支付问题 / 技术故障 / 其他”四类最省事的做法是把分类规则写在 system prompt 里然后在 user 消息里给几条示例最后放待分类文本。我在实践里发现一个规律规则描述写得再详细都不如给两个“边界模糊的示例”效果好。比如“账号问题”和“技术故障”在人工标注时都容易混淆如果你在示例里明确写了“密码重置属于账号问题登录报错属于技术故障”模型输出的准确率会明显提升。这就是少样本提示词的价值。下面给一个可直接用的文本分类请求示例import requests API_KEY sk-你的密钥 URL https://api.deepseek.com/chat/completions def classify_text(text, labels): prompt ( f请对下面的文本进行分类只能从这些类别中选择一个{labels}。\n 示例\n 文本我密码忘了想重置 → 账号问题\n 文本支付时提示银行扣款成功但订单未生成 → 支付问题\n 文本登录一直转圈然后报错500 → 技术故障\n 文本我想问一下你们上班时间 → 其他\n f文本{text}\n 只输出类别名称不要解释。 ) payload { model: deepseek-chat, messages: [ {role: system, content: 你是严格的文本分类器只输出类别名。}, {role: user, content: prompt} ], temperature: 0, max_tokens: 20, stream: False } resp requests.post(URL, jsonpayload, headers{ Authorization: fBearer {API_KEY} }, timeout30) return resp.json()[choices][0][message][content].strip() result classify_text(我刚刚付款成功了但是会员没到账, [账号问题, 支付问题, 技术故障, 其他]) print(result)这段代码本质上是在组装提示词然后请求接口。参数上有几个细节值得说明。temperature 设成 0 是为了让分类结果尽量稳定不因为随机采样飘到别的类别。max_tokens 设成 20 就够因为期望输出只有一个类别名给太长反而可能在尾部生成解释文字。timeout 设成 30 秒是为了避免接口异常时请求一直挂着。我把 labels 作为参数传进去这样换任务时不用改动函数体。注意这里没有做返回结果的合法性校验如果模型吐出来的不在 labels 里需要有一个重试或兜底逻辑这个问题在第五章会专门讲。3.2 解析返回结果处理 JSON 模式与普通文本模式上面代码里我用的是普通文本输出模型直接返回“支付问题”这四个字。但实际业务中往往需要同时得到“类别 置信度 一句话依据”这时候就要让模型返回结构化内容。最稳的做法是让模型只生成 JSON然后代码里去解析 JSON。DeepSeek 的接口支持响应格式约束常见做法是在请求体里加response_format: {type: json_object}并提示模型“输出 JSON”。我第一次用这个参数时翻了一次车接口报了 400提示“json_object 模式下必须包含 json 这个词”。后来才搞明白JSON 模式要求 prompt 里明确提到 JSON 格式否则模型不知道要按什么 schema 组织内容。修正后的写法是这样import requests, json def classify_with_json(text): payload { model: deepseek-chat, messages: [ {role: system, content: 你是文本分类器只输出 JSON不要输出其他内容。}, {role: user, content: ( 分类下面文本输出 JSON 格式{\category\: \类别\, \reason\: \依据\}\n 类别限定为账号问题、支付问题、技术故障、其他。\n f文本{text} )} ], response_format: {type: json_object}, temperature: 0, max_tokens: 100 } resp requests.post( https://api.deepseek.com/chat/completions, jsonpayload, headers{Authorization: fBearer sk-你的密钥}, timeout30 ) content resp.json()[choices][0][message][content] parsed json.loads(content) return parsed print(classify_with_json(会员开通后无法使用部分功能))这个版本的代码做了两件事一是把响应格式显式声明为 JSON二是把“只输出 JSON”写进了 system 提示词。两者缺一不可。response_format 参数如果设了 json_object但 prompt 里一点也不提 JSON模型就会随机发挥返回一段带 markdown 代码块的内容json.loads 直接炸。还有一个被问得很多的问题max_tokens 设多大合适。这里我建议设 100 左右因为 JSON 里包含 reason 字段时输出长度会明显大于纯类别名设小了内容会被截断截断后的 JSON 必然解析失败。3.3 批量分类与并发控制串行还是并行文本分类很少是一条一条手动调的绝大多数场景都是几百上千条文本要批量跑。批量跑有两个层次的问题速度和成本。速度上你可以用 ThreadPoolExecutor 做并发请求成本上你要控制并发数避免接口报限流也要控制输入长度避免无谓烧 token。我一般会写成这样的批量函数from concurrent.futures import ThreadPoolExecutor, as_completed def classify_many(texts, labels, max_workers5): results {} with ThreadPoolExecutor(max_workersmax_workers) as pool: future_map {pool.submit(classify_text, t, labels): t for t in texts} for future in as_completed(future_map): text future_map[future] try: results[text] future.result() except Exception as e: results[text] ferror: {e} return results注意我这里把 max_workers 默认设成 5而不是一口气开 20 个线程。为什么因为 DeepSeek API 的并发限制是按账号维度计算的并发过高会直接返回 429 限流错误。而且文本分类任务每个请求体量不大5 个并发已经能让几百条数据在合理时间内跑完。如果遇到限流降低 max_workers 是最直接的解决办法。批量任务还有一个隐藏问题部分请求可能因为超时或网络抖动失败。所以代码里我捕获了异常并记录到结果字典中后续可以针对 error 条目做重试。这个模式看起来不高级但非常实用能省掉你反复排查批量丢数据的精力。4. 图像分类怎么接Visual 模型调用与图片传入方式4.1 图像分类的实现路径多模态输入与零样本分类DeepSeek 的视觉模型通过同样的 chat/completions 接口暴露区别在于消息里的 content 不再是纯字符串而是包含图像 URL 或 base64 编码的图像数组。图像分类任务在这里的典型写法是把图片和提示词放进 user 消息里让模型输出判断结果。我遇到过不少人误以为图像分类必须走专门的视觉 API 或者要先自己跑目标检测其实完全不用。比如你想判断一张照片是室内还是室外、有没有文字、有没有人直接把图传给视觉模型即可。和前面说的文本分类一样分类规则也写在提示词里。下面是标准的多模态请求代码import requests, base64 def classify_image(image_path, labels): with open(image_path, rb) as f: b64_img base64.b64encode(f.read()).decode(utf-8) payload { model: deepseek-chat, # 这里替换成你有权限使用的视觉模型名 messages: [ {role: system, content: 你是图像分类器只输出类别。}, {role: user, content: [ {type: text, text: f判断这张图片属于哪个类别只能是{labels}。只输出类别名。}, {type: image_url, image_url: {url: fdata:image/jpeg;base64,{b64_img}}} ]} ], max_tokens: 50, temperature: 0 } resp requests.post( https://api.deepseek.com/chat/completions, jsonpayload, headers{Authorization: Bearer sk-你的密钥}, timeout120 ) resp_json resp.json() return resp_json[choices][0][message][content] print(classify_image(sample.jpg, 室内/室外/其他))这段代码有几个需要说明的细节。图片不是直接传二进制而是先 base64 编码再拼成 data URL。这里的data:image/jpeg;base64,前缀不能少而且格式要和实际图片格式一致JPEG 就写 image/jpegPNG 就写 image/png。timeout 我故意设成了 120 秒因为图像请求比文本请求慢很多尤其是图片体积较大时模型需要时间处理视觉编码。如果 timeout 沿用文本任务的 30 秒大概率会直接超时。还有一点温度参数我仍然保持 0分类任务不要引入随机性。4.2 图像大小、格式与 base64 编码的边界图像分类在实践中最常翻车的地方不在模型而在“图片能不能被正确处理”。具体来说有两个常见问题图片太大导致请求体超限以及格式不对导致模型读不了图。第一个问题很好理解一张几 MB 的图片 base64 编码之后会膨胀约 33%如果 API 有请求体大小限制你就要在传图之前先压缩。我处理的办法是先对图片做尺寸和体积的预处理再进入分类逻辑from PIL import Image import io def compress_image(image_path, max_size1024, max_bytes512*1024): img Image.open(image_path) img.thumbnail((max_size, max_size), Image.LANCZOS) buffer io.BytesIO() img.save(buffer, formatJPEG, quality85) while buffer.tell() max_bytes: buffer io.BytesIO() img img.resize((int(img.width * 0.8), int(img.height * 0.8))) img.save(buffer, formatJPEG, quality70) return buffer.getvalue()compress_image 函数的思路是先限制最长边不超过 1024 像素再控制 JPEG 质量。最后还有一层 while 兜底如果压缩一次的产物还是超过 512KB就逐步缩小尺寸和降低画质直到体积达标。这套逻辑能覆盖绝大多数线上图片。至于格式问题建议统一转成 JPEG 再传避免出现 WebP 透明底、HEIC 未解码、单通道灰度图这类让接口解析失败的情况。灰度图在 PIL 里是 mode L直接保存成 JPEG 没问题但如果你拿到的是 RGBA 的 PNG需要先转成 RGB 再存 JPEG否则会报错或者得到一张黑底的图。这些细节都不难但漏掉任何一个线上任务就会成批失败。4.3 图像分类的提示词怎么设计才不产生幻觉图像分类的提示词设计比文本分类更讲究因为模型有“脑补”倾向。你问它“图里有没有文字”如果图里真的没有它更倾向于回答“没有”但也会出现说“有”的情况。为了降低这种幻觉我在设计提示词时会做三件事限制类别范围、强制输出边界、要求标注不确定项。这里说的“强制输出边界”是指让模型在不确定时说“无法判断”而不是硬猜一个类别。这个策略在分类任务里非常有用因为它能让你在后续流程里把低置信度的图像单独拎出来人工处理。一个我实测有效的写法是请你对这张图片进行分类类别只能是行人/车辆/其他。 如果图中无法明确区分主体输出“其他”。 只输出类别名称不要解释原因。关键在“无法明确区分主体”这个限定句。它给了模型一个合法出口避免它为了完成任务强行选择类别。另外在文本分类里我用了少样本示例但图像侧我一般不示例因为文字描述图片内容很容易误导模型。比如你说“文本图片中是红灯→车辆”模型可能真的会去图里找红灯反而把简单任务复杂化。图像分类的提示词宁可简洁不要堆砌。5. 避坑与排查DeepSeek API 分类任务常见的 5 个坑5.1 报错 401API Key 无效或权限不足现象调用接口返回401 Authentication Fails但密钥看着没问题。原因最常见的是复制时多了空格或换行其次是账号余额不足导致密钥被禁用第三个是密钥创建后没有等待几秒就立刻使用服务端还没来得及同步。解决先在 DeepSeek 控制台重新复制密钥确认不带任何多余字符。然后在 curl 里用环境变量引用密钥避免手动复制出错。我习惯在 ~/.bashrc 里写入export DEEPSEEK_API_KEYsk-xxx脚本里用os.getenv(DEEPSEEK_API_KEY)读取这样密钥只维护一份不会因为复制操作引入脏字符。5.2 报错 400 context length上下文超限与内容总量失控现象请求返回类似this models maximum context length is ...的 400 错误尤其是在批量处理长文本时高频出现。原因你发送的 messages 数组总 token 数超过了模型的上下文窗口上限。这里容易忽略的是system 提示词里如果你放入了大量示例这些 token 也占上下文长度。我见过有人把 30 条少样本示例全部塞进 system加上待分类文本又很长直接顶爆上下文。解决压缩示例数量每个分类任务最多保留 3 到 5 条示例长文本先截断再传入比如限定前 1000 字。如果你做的是多轮分类比如先把文本摘要再分类务必把中间轮次的结果存到变量而不是继续堆进 messages 数组。记住一个原则messages 数组的 tokens 是累积的不是只有最后一轮的 tokens。5.3 返回内容解析失败JSON 被 markdown 代码块包裹现象代码里json.loads(content)报Expecting value打印出来发现内容是json ...包着。原因DeepSeek 的模型在部分情况下会把 JSON 输出放到 markdown 代码块里即使你设了 response_format 也偶有发生。在某些第三方网关里response_format 参数被透传但未生效导致模型按默认格式自由发挥。解决解析前做一层清洗——去掉 content 首尾的json 和标记。另外在 system 提示词里强调“不要输出 markdown 代码块”。如果仍然不稳定建议捕获解析异常后重试一次重试时把提示词中的“只输出 JSON”换成“直接输出纯文本 JSON不要使用代码块”成功率会显著上升。5.4 温度参数被误解分类任务到底该用多少现象temperature 设成 0.7 的话同一个文本分类任务跑三次返回三个不同类别设成 0 也不是绝对稳定偶尔还是会飘。原因temperature 控制的是采样随机性但即便设为 0模型仍可能因为解码策略中的 top-k 或其它参数产生微小的不确定性。0.7 是对话场景的推荐值它让模型更“有创造性”但在分类场景这是灾难。解决分类任务用 0 或接近 0 的值。如果设成 0 仍然偶发不稳定不要去改 temperature而是考虑加一条后置校验判断模型输出类别是否在预设集合内如果不在就重新发一次相同请求。重试机制比调参数更能治本。5.5 图片传不进去data URL 格式与接口不兼容现象图像分类接口返回 400提示内容格式错误或者一直超时。原因部分是图片 base64 后过大请求体超过单次限制部分是 content 数组里 image_url 对象的层级写错或者 model 没有图像理解权限。解决先确认传的是 data URL 而非纯 base64 字符串再确认图片经过压缩处理控制在 512KB 以内最后排除网络问题后把错误信息里返回的“字段缺失”提示和官方文档里的 JSON 结构逐字段对照。图像接口的报错信息有时候不准确排查时不要只盯着报错文本先走一遍最小请求一张小图、一段最短提示词能跑通则说明是图片或参数问题不能跑通则要先检查模型名和鉴权。这套“最小化提单”的思路在排查所有 API 任务时都通用。6. 分类效果验证与成本控制上线前必做的两件事6.1 用小样本盲测替代“感觉准了”我在实际项目中养成的一个习惯是任何分类任务上线前先从业务数据里挑 100 条有标准答案的样本跑一遍分类然后人工计算准确率。这一步看似简单但能拦住大部分翻车——因为模型在几十条样本上的表现有迷惑性你试了 3 条都对了不能说明问题100 条才基本能暴露短板。具体的验证方法是这样准备一个 CSV 文件包含 text 列和真实标签列批量调用分类函数把结果和真实标签比对统计准确率和混淆矩阵。这个过程建议写一个小脚本固定下来因为后续每次修改提示词都可以重跑同一份样本集对比效果改一句 system prompt 是变好还是变坏数据说了算。盲测集还有一个作用它能帮你发现类别边界定义是否清晰。如果“支付问题”和“其他”频繁混淆说明这个分类体系本身的定义需要修而不是模型的错。6.2 成本与延迟的粗估方法调用 DeepSeek API 做分类成本主要取决于三个因素输入 token 数、输出 token 数和请求次数。输出 token 数可以通过限制 max_tokens 来控制输入 token 数则取决于提示词长度和文本长度。分类任务建议在批量跑之前先抽样估算随便选 20 条文本统计平均每条消耗的 token 数再乘上总量就能估算出整体花费。除了成本延迟也要心里有数。文本分类单次请求通常在几百毫秒到两秒之间图像分类则可能到几十秒。如果你的业务对响应速度要求很高批量分类显然不适合在线同步调用上去就会把接口打满。常见的做法是拆分流程同步接口只处理小批量高优先级的请求大批量任务走异步队列每小时定时跑一批。批处理时设置的并发数不要拍脑袋先在 5 并发下测一轮观察平均耗时和失败率再逐步上调直到逼近限流阈值。这个逐步加压的习惯能避免你的服务在深夜批量任务中突然被打进 429 限流的坑。最后说一个我自己的习惯每次上线分类任务我都会在代码里留一个开关允许把模型返回结果和耗时写入日志。上线后前三天每天抽查日志看有没有异常的返回格式和特别慢的请求。分类模型的提示词调优是没有终点的但你在盲测集上的准确率每提高一个点这个方向就值得继续往下做。希望这些实现步骤和踩坑记录能帮到你让你的分类任务少走几趟弯路。本文还有配套的精品资源点击获取
RELATED

相关推荐

libva的API版本变迁表

libva的API版本变迁表

主要内容 本文主要介绍libva的各个版本的API的重要的差异,对于其他内容,不做过多介绍。截至2021-4-24日止目前libva的版本libva-2.11.0,最古老的版本应该是libva-1.0.0,本文中描述的libva-1.2代表libva-1.2.0,libva-1.6代表libva-1.6.0&#…

📅 2026/10/29 10:15:04
工业级电源路径保护:TPS259483AYWPR与PIC18F87J50协同设计

工业级电源路径保护:TPS259483AYWPR与PIC18F87J50协同设计

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

📅 2026/10/29 10:15:04
云原生迁移实战:从传统部署到Kubernetes的五大关键决策

云原生迁移实战:从传统部署到Kubernetes的五大关键决策

1. 传统部署与云原生的本质差异十年前我刚入行时,企业应用部署还停留在物理服务器手动配置的阶段。记得有次凌晨三点还在机房蹲着调试网络端口,这种经历让我深刻理解传统架构的痛点。云原生技术的出现彻底改变了游戏规则,但迁移过程绝非简单的…

📅 2026/10/29 10:10:03
MORE NEWS

更多资讯

📰

零售平台对比:五类渠道全成本、获客与现金流选型指南

1. 把零售平台对比当成一门必修课,是我踩过坑之后才想明白的事零售平台对比这件事,我一开始也觉得很虚。开个店、上个架、接个单,能有多复杂?直到我第一次把同一批货铺到三个不同类型的渠道上,月底对账发现毛利被啃掉了…

📰

caveman:零依赖、零构建的极简静态站点方案实践

我最近把自己一个小落地页项目从头重写了一遍,把能拆的依赖全拆掉,越用越顺手,就给它起了个名字叫caveman。这个名字有两层意思:一是整个项目像穴居人一样原始,二也是提醒自己,很多页面根本不需要被现代前端…

📰

impeccable:AI编程代理时代的前端设计质量自动化检查工具

1. 从"impeccable"这个词说起:一个被低估的前端质量信号第一次看到"impeccable"作为项目名,我下意识去查了这个词的本义——"无可挑剔的、零瑕疵的"。放在前端开发语境里,这个词其实非常精准地指向了一类长期被…

📰

神经群体几何学:高维神经数据的低维解析与应用

1. 神经群体几何学研究概述神经群体几何学是近年来神经科学领域兴起的一个重要研究方向,它通过数学中的几何学方法来描述和分析神经群体活动的结构和动态。这项研究将高维神经活动数据映射到低维空间,使我们能够直观地理解神经群体编码和处理信息的机制。…

📰

动态规划解决洛谷P13658扒手问题

1. 项目概述"洛谷 P13658 [CERC 2020] Pickpockets"是一道来自2020年Central Europe Regional Contest(中欧区域赛)的编程竞赛题目,目前在洛谷在线评测平台上编号为P13658。这道题目属于算法竞赛中的动态规划类问题,考察…

📰

AI写前端代码质量怎么保证?impeccable工具CLI与浏览器扩展实战解析

1. 从"impeccable"这个词说起:一个被低估的前端质量信号第一次看到"impeccable"作为项目名,我下意识觉得这又是一个玩概念的工具。毕竟现在前端圈子里,名字起得漂亮、实际跑起来一塌糊涂的项目太多了。但把相关热搜词摊开…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬