入门基础篇
第2章:AI模型基础认知——不用懂算法,但要懂"怎么用"
本章核心目标:帮助零基础/转岗开发者(特别是Java后端开发者)快速理解AI模型的分类、主流模型特点、调用方式,掌握关键概念,并通过实战案例完成第一个AI接口调用,为后续深入学习打下坚实基础。
2.1 常见AI模型分类与应用场景
2.1.1 为什么需要了解AI模型分类?
作为AI应用开发工程师,你不需要深入理解模型的训练原理,但必须清楚不同模型能解决什么问题。就像使用数据库时,你需要知道MySQL适合关系型数据、Redis适合缓存,使用AI模型时,你也需要知道什么场景用什么模型。
核心原则:选对模型,事半功倍;选错模型,事倍功半。
2.1.2 四大主流AI模型类型
AI模型可以按照处理的数据类型和应用场景,分为四大主流类型:
1. 大语言模型(LLM - Large Language Model)
核心作用:理解和生成自然语言文本。
通俗理解:就像一个"超级智能的聊天机器人",能够理解你的问题,并生成相应的回答。
典型应用场景:
- 智能客服:用户问"如何退款?",模型自动回答退款流程
- 内容生成:输入产品信息,自动生成产品描述文案
- 代码生成:输入需求描述,自动生成代码片段
- 文档总结:输入长文档,自动生成摘要
- 翻译服务:输入中文,输出英文或其他语言
业务价值:
- 降低人工客服成本
- 提升内容生产效率
- 辅助开发人员编码
- 提升用户体验
代表模型:GPT系列(GPT-3.5、GPT-4、GPT-5.x)、Claude code、文心一言、讯飞星火、ChatGLM
2. 图像识别模型
核心作用:识别和理解图像内容。
通俗理解:就像一个"超级眼睛",能够看懂图片里有什么,识别出物体、文字、人脸等。
典型应用场景:
- 商品识别:电商平台自动识别商品类别、品牌
- 人脸识别:门禁系统、支付验证
- OCR文字识别:扫描文档,自动提取文字内容
- 医疗影像分析:辅助医生识别X光片、CT片中的异常
- 自动驾驶:识别道路、车辆、行人等
业务价值:
- 自动化商品分类,提升运营效率
- 提升安全性和用户体验
- 降低人工录入成本
- 辅助专业决策
代表模型:YOLO、ResNet、百度OCR、腾讯OCR
3. 语音处理模型
核心作用:处理语音数据,包括语音识别(ASR)和语音合成(TTS)。
通俗理解:
- 语音识别:把你说的话转换成文字(就像"语音输入法")
- 语音合成:把文字转换成语音(就像"语音播报")
典型应用场景:
- 语音助手:智能音箱、手机语音助手(如Siri、小爱同学)
- 语音转写:会议录音自动转成文字
- 语音播报:新闻播报、导航播报
- 语音客服:电话客服系统,用户说话自动识别并回复
业务价值:
- 提升交互体验,解放双手
- 降低人工转写成本
- 提升信息传达效率
代表模型:百度语音、讯飞语音、阿里云语音
4. 语义理解模型
核心作用:理解文本的语义、情感、意图等深层含义。
通俗理解:不仅能理解字面意思,还能理解"言外之意",比如识别用户是表扬还是投诉。
与LLM的区别:
- 语义理解模型:专门针对文本深层语义解析的轻量化模型,针对性强、成本低,适合特定任务(如情感分析、文本分类)
- LLM(大语言模型):通用文本生成和理解模型,能力全面但成本较高,适合需要生成文本或复杂理解的场景
- 选择建议:如果只需要做情感分析、文本分类等特定任务,选择语义理解模型更经济;如果需要生成文本或复杂理解,选择LLM
典型应用场景:
- 情感分析:分析用户评论是正面还是负面
- 意图识别:识别用户是想购买、咨询还是投诉
- 文本分类:自动将邮件分类为"重要"、"垃圾"等
- 相似度计算:判断两段文本是否相似(用于去重、推荐等)
业务价值:
- 自动处理用户反馈,提升响应效率
- 精准理解用户需求,提升转化率
- 自动化内容分类,提升运营效率
代表模型:BERT、ERNIE、Text2Vec
2.1.3 模型选择决策树
在实际业务中,如何选择合适的模型?可以参考以下决策流程:
实际案例:
案例1:电商智能客服系统
- 需求:用户问"这个商品适合夏天穿吗?"
- 模型选择:大语言模型(LLM)
- 原因:需要理解自然语言问题,并生成回答
案例2:商品图片自动分类
- 需求:上传商品图片,自动识别商品类别
- 模型选择:图像识别模型
- 原因:需要识别图像内容
案例3:语音订单查询
- 需求:用户通过语音说"查询我的订单",系统识别并查询
- 模型选择:语音识别模型(ASR)+ 大语言模型(LLM)
- 原因:先识别语音转文字,再理解意图并查询
2.1.4 本节总结
核心要点:
- 四大主流模型类型:大语言模型(LLM)、图像识别、语音处理、语义理解
- 模型分类边界:语义理解模型是LLM的细分方向,轻量化、针对性强;LLM通用能力强但成本更高
- 选择原则:根据业务需求的数据类型和应用场景选择模型
- 业务价值:不同模型解决不同问题,选对模型才能发挥最大价值
下一步:了解主流模型的具体特点和适用场景,为实际调用做准备。
2.2 主流模型介绍
2.2.1 为什么需要了解主流模型?
在实际开发中,你需要选择具体的模型来调用。不同的模型有不同的特点、优势和适用场景。了解主流模型,可以帮助你:
- 快速选型:根据业务需求选择最合适的模型
- 成本优化:选择性价比最高的模型
- 开发效率:选择API友好、文档完善的模型
2.2.2 大语言模型(LLM)主流产品
1. GPT系列(OpenAI)
核心特点:
- 模型能力:GPT-3.5、GPT-4、GPT-5.x是目前最先进的大语言模型之一
- 语言能力:英文能力极强,中文能力良好
- 适用场景:国际化应用、英文场景、代码生成、复杂推理
API适配性:⭐⭐⭐⭐⭐
- Java调用友好度:非常友好
- API文档:完善,有详细的Java示例
- 认证方式:API Key直接使用,简单直接
- 调用示例:
// OpenAI API调用示例(简化版)
String apiKey = "sk-xxx";
String url = "https://api.openai.com/v1/chat/completions";
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("model", "gpt-3.5-turbo");
requestBody.put("messages", Arrays.asList(
Map.of("role", "user", "content", "你好")
));
// 发送HTTP请求...
优势:
- 模型能力强,生成质量高
- API稳定,响应速度快
- 文档完善,社区支持好
劣势:
- 国内访问需要代理/VPN
- 费用相对较高(按Token计费)
- 中文理解能力略逊于国产模型
适用场景:
- 国际化应用
- 代码生成、技术文档编写
- 需要强推理能力的场景
2. 文心一言(百度)
核心特点:
- 模型能力:百度自研的大语言模型,中文理解能力强
- 语言能力:中文能力极强,英文能力良好
- 适用场景:国内应用、中文场景、内容生成、智能客服
API适配性:⭐⭐⭐⭐⭐
- Java调用友好度:非常友好
- API文档:完善,有详细的Java示例
- 认证方式:API Key + Secret Key → Access Token(两步认证)
- 调用示例:
// 百度文心一言API调用示例(简化版)
// 第一步:获取Access Token
String accessToken = getAccessToken(apiKey, secretKey);
// 第二步:调用API
String url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions?access_token=" + accessToken;
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("messages", Arrays.asList(
Map.of("role", "user", "content", "你好")
));
// 发送HTTP请求...
优势:
- 国内可直接访问,稳定可靠
- 中文理解能力强,适合国内业务
- 有免费额度,成本可控
- 文档完善,技术支持好
劣势:
- 英文能力略逊于GPT
- 需要两步认证(相对复杂)
适用场景:
- 国内应用(电商、客服、内容生成等)
- 中文场景为主的应用
- 成本敏感的项目
3. 讯飞星火(科大讯飞)
核心特点:
- 模型能力:科大讯飞自研的大语言模型
- 语言能力:中文能力强,语音相关能力强
- 适用场景:国内应用、语音交互场景、多模态场景
API适配性:⭐⭐⭐⭐
- Java调用友好度:友好
- API文档:完善
- 认证方式:API Key + Secret Key → Access Token
优势:
- 中文能力强
- 语音相关能力强(结合讯飞语音技术)
- 多模态能力(文本+语音+图像)
劣势:
- 模型能力略逊于GPT和文心一言
- 社区支持相对较少
适用场景:
- 需要语音交互的应用
- 多模态应用场景
4. ChatGLM(智谱AI)
核心特点:
- 模型能力:开源的大语言模型,可本地部署
- 语言能力:中文能力良好
- 适用场景:需要本地部署的场景、数据安全要求高的场景
API适配性:⭐⭐⭐
- Java调用友好度:中等(需要本地部署)
- API文档:有文档,但需要自行部署
- 认证方式:本地部署,无需API Key
优势:
- 可本地部署,数据安全
- 开源免费
- 中文能力良好
劣势:
- 需要自行部署和维护
- 模型能力略逊于商业模型
- 对硬件要求较高
适用场景:
- 数据安全要求高的场景(金融、医疗等)
- 需要离线使用的场景
- 成本敏感且有能力维护的场景
2.2.3 图像生成模型
Stable Diffusion
核心特点:
- 模型能力:根据文本描述生成图像
- 适用场景:内容创作、设计辅助、图像生成
API适配性:⭐⭐⭐
- Java调用友好度:中等(需要自行部署或使用第三方服务)
- API文档:有文档,但需要自行部署
- 认证方式:根据部署方式而定
优势:
- 开源免费
- 生成质量高
- 可本地部署
劣势:
- 需要自行部署和维护
- 对硬件要求高(需要GPU)
- 生成速度较慢
适用场景:
- 内容创作平台
- 设计辅助工具
- 需要大量图像生成的场景
2.2.4 模型选择建议
选择决策表:
| 场景 | 推荐模型 | 原因 |
|---|---|---|
| 国内中小项目(免费) | 文心一言(免费额度) | 满足基础需求,成本为0 |
| 国内大型项目(付费) | 文心一言(商用版) | 更高QPS、更稳定,有企业级技术支持 |
| 国内应用,中文为主 | 文心一言 | 国内访问稳定,中文能力强,成本可控 |
| 国际化应用,英文为主 | GPT系列 | 英文能力强,模型先进 |
| 代码生成 | GPT系列 | 代码生成能力强 |
| 成本敏感,国内应用 | 文心一言 | 有免费额度,成本低 |
| 数据安全要求高(金融/医疗) | ChatGLM(本地部署) | 可本地部署,数据不出域,符合合规要求 |
| 语音交互场景 | 讯飞星火 | 语音能力强 |
| 图像生成 | Stable Diffusion | 开源免费,质量高 |
Java开发者优先推荐:
- 文心一言:国内访问稳定,API友好,文档完善,适合大多数国内业务场景
- GPT系列:如果业务面向国际化,或需要强代码生成能力,优先选择GPT
2.2.5 本节总结
核心要点:
- 主流LLM模型:GPT系列、文心一言、讯飞星火、ChatGLM各有特点
- 选择原则:根据业务场景(国内/国际、中文/英文)、成本、数据安全要求选择
- Java开发者推荐:国内应用优先选择文心一言,国际化应用选择GPT系列
下一步:了解模型调用的两种核心方式,为实际开发做准备。
2.3 模型调用的两种核心方式
2.3.1 为什么需要了解调用方式?
在实际开发中,你需要决定如何调用AI模型。不同的调用方式有不同的优缺点,选择合适的方式,可以:
- 降低成本:选择性价比最高的调用方式
- 保障安全:根据数据安全要求选择调用方式
- 提升效率:选择最适合业务场景的调用方式
2.3.2 方式一:API调用(公有云)
什么是API调用?
通俗理解:就像使用第三方服务(如短信服务、支付服务),你通过HTTP请求调用AI平台的API,AI平台返回结果。
核心流程:
API调用的优势
- 零部署成本:不需要购买服务器、GPU等硬件
- 快速接入:申请API Key即可使用,几分钟就能接入
- 自动升级:AI平台会自动升级模型,你无需关心
- 按需付费:按使用量付费,成本可控
- 稳定可靠:AI平台提供高可用服务,稳定性有保障
API调用的劣势
- 数据出域:数据需要发送到AI平台,可能存在数据安全风险
- 依赖网络:需要稳定的网络连接
- 成本累积:大量使用时,成本可能较高
- 功能受限:受限于AI平台提供的功能,无法自定义
适用场景
- 大多数业务场景:智能客服、内容生成、文本理解等
- 快速上线:需要快速接入AI能力的项目
- 成本可控:使用量不大,或愿意按需付费的场景
- 数据安全要求不高:不涉及敏感数据的场景
Java实现示例
@Service
public class AIService {
@Autowired
private RestTemplate restTemplate;
/**
* 调用OpenAI API(示例)
*/
public String callOpenAI(String question) {
String url = "https://api.openai.com/v1/chat/completions";
String apiKey = "sk-xxx"; // 从配置文件读取
// 构建请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setBearerAuth(apiKey);
// 构建请求体
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("model", "gpt-3.5-turbo");
requestBody.put("messages", Arrays.asList(
Map.of("role", "user", "content", question)
));
// 发送请求
HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
Map<String, Object> response = restTemplate.postForObject(url, request, Map.class);
// 解析响应
List<Map> choices = (List<Map>) ((Map) ((List) response.get("choices")).get(0)).get("message");
return (String) choices.get("content");
}
/**
* 调用百度文心一言API(示例)
*/
public String callWenxin(String question) {
// 第一步:获取Access Token
String accessToken = getAccessToken();
// 第二步:调用API
String url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions?access_token=" + accessToken;
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("messages", Arrays.asList(
Map.of("role", "user", "content", question)
));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
Map<String, Object> response = restTemplate.postForObject(url, request, Map.class);
// 解析响应
return (String) response.get("result");
}
/**
* 获取百度Access Token
*/
private String getAccessToken() {
String url = "https://aip.baidubce.com/oauth/2.0/token";
String apiKey = "xxx"; // 从配置文件读取
String secretKey = "xxx"; // 从配置文件读取
String params = "grant_type=client_credentials&client_id=" + apiKey + "&client_secret=" + secretKey;
Map<String, Object> response = restTemplate.postForObject(url + "?" + params, null, Map.class);
return (String) response.get("access_token");
}
}
2.3.3 方式二:本地化部署调用(私有模型)
什么是本地化部署?
通俗理解:就像自己搭建数据库服务器,你在自己的服务器上部署AI模型,通过内网调用。
核心流程:
你的应用 → 内网HTTP请求 → 本地AI模型服务 → AI模型处理 → 返回结果 → 你的应用
本地化部署的优势
- 数据安全:数据不出域,完全可控
- 成本可控:大量使用时,成本可能更低(一次性投入)
- 可定制:可以自定义模型、参数等
- 离线可用:不依赖外网,可以离线使用
- 无API限制:不受AI平台的QPS、Token等限制
本地化部署的劣势
- 部署复杂:需要购买服务器、GPU,部署和维护成本高
- 技术要求高:需要了解模型部署、运维等技术
- 模型更新慢:需要手动更新模型,无法自动升级
- 初始成本高:需要一次性投入硬件成本
适用场景
- 数据安全要求高:金融、医疗、政府等敏感数据场景
- 大量使用:使用量非常大,本地部署成本更低
- 离线场景:需要离线使用的场景
- 定制需求:需要自定义模型、参数的场景
Java实现示例
@Service
public class LocalAIService {
@Autowired
private RestTemplate restTemplate;
/**
* 调用本地部署的AI模型(示例)
* 假设本地部署了ChatGLM模型,提供HTTP API
*/
public String callLocalAI(String question) {
// 本地模型服务的地址(内网地址)
String url = "http://localhost:8000/v1/chat/completions";
// 构建请求体
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("model", "chatglm-6b");
requestBody.put("messages", Arrays.asList(
Map.of("role", "user", "content", question)
));
// 发送请求(内网请求,无需认证)
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
Map<String, Object> response = restTemplate.postForObject(url, request, Map.class);
// 解析响应
List<Map> choices = (List<Map>) ((Map) ((List) response.get("choices")).get(0)).get("message");
return (String) choices.get("content");
}
}
本地部署架构示例:
┌─────────────┐
│ 你的应用 │
│ (Java) │
└──────┬──────┘
│ HTTP请求(内网)
▼
┌─────────────┐
│ AI模型服务 │
│ (Python) │
└──────┬──────┘
│
▼
┌─────────────┐
│ AI模型文件 │
│ (GPU服务器) │
└─────────────┘
本地部署核心步骤(以ChatGLM为例):
-
环境准备:
- 安装Python 3.8+、PyTorch 1.12+
- 安装CUDA(如果使用GPU)
- 推荐使用conda管理Python环境
-
克隆仓库:
git clone https://github.com/THUDM/ChatGLM-6B.git cd ChatGLM-6B -
安装依赖:
pip install -r requirements.txt -
下载模型文件:
- 从Hugging Face下载ChatGLM-6B模型文件
- 配置模型路径
-
启动API服务:
python api.py --port 8000 --model-path /path/to/chatglm-6b -
验证服务:
curl http://localhost:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{"model": "chatglm-6b", "messages": [{"role": "user", "content": "你好"}]}'
注意事项:
- ⚠️ 硬件要求:ChatGLM-6B至少需要16GB内存,推荐使用GPU加速
- ⚠️ 模型文件:模型文件较大(约12GB),需要足够的磁盘空间
- ✅ 生产环境:建议使用Docker容器化部署,便于管理和扩展
2.3.4 两种方式对比
| 维度 | API调用(公有云) | 本地化部署(私有模型) |
|---|---|---|
| 部署成本 | 零成本 | 需要服务器、GPU,成本高 |
| 接入速度 | 几分钟 | 几天到几周 |
| 数据安全 | 数据出域 | 数据不出域,安全 |
| 使用成本 | 按量付费 | 一次性投入,后续成本低 |
| 技术要求 | 低(HTTP调用) | 高(需要部署、运维) |
| 稳定性 | AI平台保障 | 需要自己保障 |
| 适用场景 | 大多数业务场景 | 数据安全要求高、大量使用 |
2.3.5 选择建议
决策流程:
Java开发者建议:
- 优先选择API调用:对于大多数业务场景,API调用是最佳选择
- 特殊情况选择本地部署:只有在数据安全要求极高、使用量非常大、有专业团队维护的情况下,才考虑本地部署
2.3.6 本节总结
核心要点:
- 两种调用方式:API调用(公有云)和本地化部署(私有模型)
- 选择原则:根据数据安全要求、使用量、成本、技术要求选择
- Java开发者建议:优先选择API调用,特殊情况才考虑本地部署
下一步:了解AI模型调用的关键概念,为实际调用做准备。
2.4 关键概念扫盲
2.4.1 为什么需要了解这些概念?
在实际调用AI模型API时,你会遇到很多专业术语。理解这些概念,可以帮助你:
- 正确配置参数:理解参数含义,才能正确配置
- 优化调用效果:通过调整参数,优化AI模型的输出效果
- 控制成本:理解计费方式,控制调用成本
- 排查问题:遇到问题时,能快速定位原因
2.4.2 API Key(API密钥)
什么是API Key?
通俗理解:就像你的"身份证",用来证明你有权限调用AI平台的API。
作用:
- 身份认证:AI平台通过API Key识别你的身份
- 权限控制:不同的API Key可能有不同的权限(如免费额度、付费额度)
- 计费统计:AI平台通过API Key统计你的使用量并计费
使用方式:
// 方式1:放在请求头中(推荐)
HttpHeaders headers = new HttpHeaders();
headers.setBearerAuth(apiKey); // OpenAI使用这种方式
// 方式2:放在URL参数中
String url = "https://api.example.com/v1/chat?api_key=" + apiKey;
// 方式3:放在请求体中
requestBody.put("api_key", apiKey);
安全注意事项:
- ⚠️ 不要提交到代码仓库:API Key是敏感信息,不要提交到Git
- ✅ 使用环境变量或配置文件:将API Key放在环境变量或配置文件中
- ✅ 定期更换:定期更换API Key,提升安全性
Java最佳实践:
// 方式1:使用环境变量(推荐,开发环境)
String apiKey = System.getenv("OPENAI_API_KEY");
// 方式2:使用配置文件(application.yml,开发/测试环境)
@Value("${ai.openai.api-key}")
private String apiKey;
// 方式3:使用配置类
@Configuration
public class AIConfig {
@Value("${ai.openai.api-key}")
private String apiKey;
public String getApiKey() {
return apiKey;
}
}
生产环境API Key安全存储方案:
方案1:使用Jasypt加密配置文件(推荐)
- 添加依赖(pom.xml):
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
- 配置文件(application.yml):
ai:
openai:
api-key: ENC(加密后的字符串) # 使用Jasypt加密后的API Key
- 启动时指定加密密钥:
java -jar app.jar --jasypt.encryptor.password=你的加密密钥
- 加密API Key的命令:
java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI \
input="sk-your-api-key" \
password=你的加密密钥 \
algorithm=PBEWithMD5AndDES
方案2:使用Spring Cloud Config(微服务架构)
将API Key存储在配置中心(如Nacos、Consul),配置中心负责加密存储和安全管理。
方案3:使用密钥管理服务(KMS)
对于大型企业,可以使用云服务商的密钥管理服务(如阿里云KMS、AWS KMS),通过API动态获取API Key。
2.4.3 Token(令牌)
什么是Token?
通俗理解:Token是AI模型处理文本的基本单位,可以理解为"词片段"。
重要概念:
- 输入Token:你发送给AI模型的文本会被切分成Token
- 输出Token:AI模型生成的文本也会被切分成Token
- Token数量:通常1个Token ≈ 0.75个英文单词 ≈ 1-2个中文字符
为什么重要?
- 计费依据:大多数AI平台按Token数量计费
- 长度限制:每个模型都有最大Token限制(上下文窗口)
Token计算示例:
输入文本:"你好,请介绍一下Java"
Token数量:约8-10个Token(中文)
输入文本:"Hello, please introduce Java"
Token数量:约6-8个Token(英文)
Java代码示例:
方式1:使用官方Token计算API(推荐,精准)
import org.springframework.web.client.RestTemplate;
import org.springframework.http.*;
import java.util.*;
/**
* Token计算服务(使用OpenAI官方API)
*/
@Service
public class TokenCountService {
private final RestTemplate restTemplate = new RestTemplate();
private static final String TOKEN_COUNT_URL = "https://api.openai.com/v1/chat/completions";
/**
* 使用OpenAI API精准计算Token数量
* 注意:这需要调用一次API,会产生少量费用
*/
public int countTokens(String text, String apiKey) {
// 构建一个最小请求来获取Token数量
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setBearerAuth(apiKey);
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("model", "gpt-3.5-turbo");
requestBody.put("messages", Arrays.asList(
Map.of("role", "user", "content", text)
));
// 设置max_tokens为1,避免实际生成内容
requestBody.put("max_tokens", 1);
HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
ResponseEntity<Map> response = restTemplate.postForEntity(TOKEN_COUNT_URL, request, Map.class);
// 从响应中获取Token数量
Map<String, Object> usage = (Map<String, Object>) response.getBody().get("usage");
return (Integer) usage.get("prompt_tokens");
}
}
方式2:使用tiktoken库(Java版本,离线计算)
// 注意:需要添加tiktoken-java依赖
// <dependency>
// <groupId>com.knuddels</groupId>
// <artifactId>jtokkit</artifactId>
// <version>1.0.0</version>
// </dependency>
import com.knuddels.jtokkit.Encodings;
import com.knuddels.jtokkit.api.Encoding;
import com.knuddels.jtokkit.api.EncodingType;
public class TokenCountService {
private static final Encoding encoding = Encodings.newDefaultEncodingRegistry()
.getEncoding(EncodingType.CL100K_BASE); // GPT-3.5/GPT-4使用的编码
/**
* 离线计算Token数量(无需调用API,免费)
*/
public int countTokens(String text) {
return encoding.countTokens(text);
}
}
方式3:粗略估算(仅用于快速估算,不精准)
public class TokenExample {
/**
* 估算Token数量(简化版,仅用于快速估算)
*/
public int estimateTokenCount(String text) {
// 中文:1个字符 ≈ 1-2个Token
// 英文:1个单词 ≈ 1.3个Token
// 这里只是粗略估算
int chineseChars = countChineseChars(text);
int englishWords = countEnglishWords(text);
return chineseChars * 1.5 + englishWords * 1.3;
}
private int countChineseChars(String text) {
// 统计中文字符数量
return (int) text.chars().filter(c -> c >= 0x4E00 && c <= 0x9FFF).count();
}
private int countEnglishWords(String text) {
// 统计英文单词数量
return text.split("\\s+").length;
}
}
选择建议:
- 精准计算:使用官方API或tiktoken库(推荐生产环境)
- 快速估算:使用粗略估算方法(仅用于开发测试)
注意:
- OpenAI提供了Token计算API,但调用会产生少量费用
- 百度文心一言的Token计算方式与OpenAI类似,可以通过API响应中的
usage字段获取实际Token数量 - 对于Java开发者,推荐使用tiktoken-java库进行离线Token计算,无需调用API
2.4.4 QPS(每秒查询数)
什么是QPS?
通俗理解:QPS(Queries Per Second)表示每秒可以发送多少个请求。
作用:
- 限流控制:AI平台通过QPS限制,防止单个用户占用过多资源
- 性能指标:QPS越高,说明API性能越好
常见QPS限制:
- 免费额度:通常QPS较低(如5 QPS)
- 付费额度:QPS较高(如50 QPS、100 QPS)
Java代码示例:
import com.google.common.util.concurrent.RateLimiter;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import java.util.*;
/**
* AI服务(带QPS限流和重试机制)
*/
@Service
public class AIServiceWithRateLimit {
// 使用RateLimiter控制QPS(Google Guava库)
private final RateLimiter rateLimiter = RateLimiter.create(5.0); // 5 QPS
private final RestTemplate restTemplate = new RestTemplate();
private static final int MAX_RETRIES = 3;
/**
* 调用AI API,带QPS限流和重试机制
*/
public String callAI(String question) {
int retryCount = 0;
while (retryCount < MAX_RETRIES) {
try {
// 等待获取许可(如果超过QPS限制,会阻塞等待)
rateLimiter.acquire();
// 调用AI API
return callAIAPI(question);
} catch (HttpClientErrorException.TooManyRequests e) {
// 429错误:超过QPS限制
retryCount++;
if (retryCount >= MAX_RETRIES) {
throw new RuntimeException("超过最大重试次数,QPS限制仍未解除", e);
}
// 指数退避重试(等待时间递增:1s, 2s, 4s)
try {
long waitTime = 1000L * (1L << retryCount);
Thread.sleep(waitTime);
System.out.println("QPS限流,等待" + waitTime + "ms后重试,第" + retryCount + "次");
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new RuntimeException("重试等待被中断", ie);
}
} catch (Exception e) {
// 其他异常直接抛出
throw new RuntimeException("调用AI API失败", e);
}
}
throw new RuntimeException("调用AI API失败,已重试" + MAX_RETRIES + "次");
}
/**
* 实际的API调用
*/
private String callAIAPI(String question) {
String url = "https://api.openai.com/v1/chat/completions";
String apiKey = "sk-xxx"; // 从配置读取
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setBearerAuth(apiKey);
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("model", "gpt-3.5-turbo");
requestBody.put("messages", Arrays.asList(
Map.of("role", "user", "content", question)
));
HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
ResponseEntity<Map> response = restTemplate.exchange(
url, HttpMethod.POST, request, Map.class
);
// 解析响应...
return "AI响应";
}
}
注意事项:
- ⚠️ 不要超过QPS限制:超过限制会导致请求失败(429错误)
- ✅ 合理控制并发:使用线程池、限流器等工具控制并发
- ✅ 处理限流异常:当遇到限流时,应该重试(指数退避)或提示用户
- ✅ 监控QPS使用:记录QPS使用情况,及时调整限流策略
2.4.5 上下文窗口(Context Window)
什么是上下文窗口?
通俗理解:上下文窗口是AI模型能"记住"的最大文本长度,就像人的"短期记忆容量"。
作用:
- 限制输入长度:超过上下文窗口的文本会被截断
- 影响理解能力:上下文窗口越大,AI模型能理解的上下文越多
常见上下文窗口大小:
- GPT-3.5:4096 Token(约3000个英文单词)
- GPT-4:8192 Token(约6000个英文单词)
- 文心一言:约2000-4000 Token(根据模型版本不同)
Java代码示例:
@Service
public class AIServiceWithContextLimit {
private static final int MAX_CONTEXT_TOKENS = 4096; // GPT-3.5的上下文窗口
/**
* 检查并截断文本,确保不超过上下文窗口
*/
public String truncateText(String text, int maxTokens) {
// 估算Token数量(简化版)
int estimatedTokens = estimateTokenCount(text);
if (estimatedTokens <= maxTokens) {
return text;
}
// 如果超过限制,截断文本
// 注意:实际项目中应该使用AI平台的Token计算API
int maxChars = (int) (maxTokens * 0.75); // 粗略估算
return text.substring(0, Math.min(maxChars, text.length()));
}
/**
* 调用AI API,自动处理上下文窗口限制
*/
public String callAIWithContext(String question, String context) {
// 构建完整的提示词
String fullPrompt = context + "\n\n问题:" + question;
// 检查并截断
String truncatedPrompt = truncateText(fullPrompt, MAX_CONTEXT_TOKENS);
// 调用AI API
return callAIAPI(truncatedPrompt);
}
private int estimateTokenCount(String text) {
// 简化的Token估算(实际应该调用AI平台的API)
return (int) (text.length() * 1.5);
}
private String callAIAPI(String prompt) {
// 实际的API调用代码
// ...
return "AI响应";
}
}
注意事项:
- ⚠️ 不要超过上下文窗口:超过限制会导致请求失败
- ✅ 合理组织提示词:将重要信息放在前面,避免被截断
- ✅ 分批处理长文本:对于超长文本,可以分批处理
2.4.6 Temperature参数(温度参数)
什么是Temperature?
通俗理解:Temperature控制AI模型生成内容的"随机性"或"创造性"。
参数范围:通常是0.0到2.0之间
参数效果:
- Temperature = 0.0:最保守,生成内容最确定、最一致(适合事实性回答)
- Temperature = 0.7:平衡,既有创造性又有准确性(大多数场景的默认值)
- Temperature = 1.0:标准随机性
- Temperature = 2.0:最随机,生成内容最有创造性(适合创意写作)
实际效果对比:
问题:"请介绍Java的特点"
Temperature = 0.0:
Java是一种面向对象的编程语言,具有跨平台、安全性高、易于学习等特点。
Temperature = 0.7:
Java是一种广泛使用的编程语言,具有以下特点:1. 跨平台性,一次编写到处运行;2. 面向对象,代码结构清晰;3. 丰富的生态系统...
Temperature = 2.0:
Java就像一位多才多艺的艺术家,它不仅能编写企业级应用,还能开发移动应用。它的跨平台特性让它成为了程序员的最爱...
Java代码示例:
@Service
public class AIServiceWithTemperature {
/**
* 调用AI API,支持Temperature参数
*/
public String callAI(String question, double temperature) {
String url = "https://api.openai.com/v1/chat/completions";
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("model", "gpt-3.5-turbo");
requestBody.put("temperature", temperature); // 设置Temperature参数
requestBody.put("messages", Arrays.asList(
Map.of("role", "user", "content", question)
));
// 发送请求...
return "AI响应";
}
/**
* 不同场景的Temperature推荐值
*/
public String callAIForScenario(String question, String scenario) {
double temperature;
switch (scenario) {
case "factual": // 事实性回答
temperature = 0.0;
break;
case "creative": // 创意写作
temperature = 1.5;
break;
case "balanced": // 平衡场景(默认)
default:
temperature = 0.7;
break;
}
return callAI(question, temperature);
}
}
选择建议:
- 事实性回答(如客服问答):Temperature = 0.0 - 0.3
- 一般对话(如智能助手):Temperature = 0.7 - 1.0
- 创意写作(如文案生成):Temperature = 1.0 - 1.5
2.4.7 其他重要概念
Max Tokens(最大输出Token数)
作用:限制AI模型生成的最大Token数量。
使用场景:
- 控制生成内容的长度
- 控制成本(输出Token也会计费)
Java代码示例:
requestBody.put("max_tokens", 500); // 最多生成500个Token
Top P(核采样)
作用:控制AI模型从哪些候选词中选择(类似Temperature,但方法不同)。
参数范围:0.0到1.0之间
使用建议:
- 通常与Temperature配合使用
- 大多数场景使用默认值即可
Stop Sequences(停止序列)
作用:当AI模型生成特定文本时,停止生成。
使用场景:
- 控制生成内容的格式
- 防止生成不需要的内容
Java代码示例:
requestBody.put("stop", Arrays.asList("\n\n", "问题:")); // 遇到这些文本时停止生成
2.4.8 术语对照表
为确保术语一致性,以下是本章核心术语的统一表述:
| 术语 | 英文 | 说明 | 首次出现位置 |
|---|---|---|---|
| API密钥 | API Key | 用于身份认证的密钥 | 2.4.2 |
| 令牌 | Token | 文本处理的基本单位 | 2.4.3 |
| 每秒查询数 | QPS (Queries Per Second) | 每秒可发送的请求数 | 2.4.4 |
| 上下文窗口 | Context Window | AI模型能处理的最大文本长度 | 2.4.5 |
| 温度参数 | Temperature | 控制生成内容的随机性 | 2.4.6 |
| 最大输出Token数 | Max Tokens | 限制AI生成的最大Token数量 | 2.4.7 |
注意:本章中所有术语均使用上述统一表述,避免混用"上下文长度"、"上下文窗口"等不同说法。
2.4.9 本节总结
核心要点:
- API Key(API密钥):身份认证和计费依据,需要妥善保管,生产环境使用加密存储
- Token(令牌):文本处理的基本单位,是计费依据,可通过官方API或tiktoken库精准计算
- QPS(每秒查询数):需要控制并发避免超过限制,遇到限流时应重试(指数退避)
- 上下文窗口(Context Window):AI模型能处理的最大文本长度,超过会被截断
- Temperature(温度参数):控制生成内容的随机性,根据场景选择合适的值
参数选择速查表:
| 场景 | Temperature | Max Tokens | 说明 |
|---|---|---|---|
| 事实性回答 | 0.0-0.3 | 200-500 | 客服、问答 |
| 一般对话 | 0.7-1.0 | 500-1000 | 智能助手 |
| 创意写作 | 1.0-1.5 | 1000-2000 | 文案生成 |
| 代码生成 | 0.0-0.3 | 500-2000 | 代码补全 |
下一步:通过实战案例,完成第一个AI接口调用。
2.5 小实战:用Postman调用第一个AI接口
2.5.1 实战目标
通过本实战,你将:
- 掌握Postman调用AI API的完整流程
- 理解AI API的请求和响应格式
- 学会用Java代码调用AI API
- 具备独立调用AI接口的能力
2.5.2 准备工作
前置条件:
- ✅ Postman已安装
- ✅ OpenAI API Key已申请(或百度文心一言API Key)
- ✅ 基本了解HTTP请求和JSON格式
如果还没有API Key:
- OpenAI:访问 platform.openai.com/api-keys 申请
- 百度文心一言:访问 cloud.baidu.com/product/wen… 申请
2.5.3 实战案例:调用OpenAI API(文生文)
步骤1:打开Postman,创建新请求
- 打开Postman
- 点击"New" → "HTTP Request"
- 请求方法选择"POST"
- URL输入:
https://api.openai.com/v1/chat/completions
步骤2:配置请求头(Headers)
在Headers标签页中添加:
| Key | Value |
|---|---|
Content-Type | application/json |
Authorization | Bearer sk-your-api-key-here |
注意:将sk-your-api-key-here替换为你的实际API Key。
步骤3:配置请求体(Body)
- 选择"Body"标签页
- 选择"raw"和"JSON"格式
- 输入以下JSON内容:
{
"model": "gpt-3.5-turbo",
"messages": [
{
"role": "user",
"content": "你好,请用一句话介绍Java编程语言"
}
],
"temperature": 0.7,
"max_tokens": 200
}
参数说明:
model:使用的模型名称(gpt-3.5-turbo是性价比最高的模型)messages:对话消息列表role:角色(user表示用户,assistant表示AI助手)content:消息内容
temperature:温度参数(0.7是平衡值)max_tokens:最大输出Token数(200表示最多生成约150个中文字符)
步骤4:发送请求
- 点击"Send"按钮
- 等待响应(通常几秒钟)
步骤5:查看响应结果
成功响应示例:
{
"id": "chatcmpl-xxx",
"object": "chat.completion",
"created": 1234567890,
"model": "gpt-3.5-turbo-0125",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Java是一种面向对象的编程语言,具有跨平台、安全性高、易于学习等特点,广泛应用于企业级应用开发。"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 20,
"completion_tokens": 35,
"total_tokens": 55
}
}
响应字段说明:
choices[0].message.content:AI生成的回答(这是你需要的内容)usage:Token使用情况prompt_tokens:输入Token数(20个)completion_tokens:输出Token数(35个)total_tokens:总Token数(55个)
步骤6:解析响应结果
核心内容提取:
choices[0].message.content = "Java是一种面向对象的编程语言..."
这就是AI生成的回答,你可以在应用中直接使用。
2.5.4 实战案例:调用百度文心一言API(国内开发者推荐)
步骤1:获取Access Token
重要:百度文心一言需要两步认证,先获取Access Token,再调用API。
- 打开Postman,创建新请求
- 请求方法选择"POST"
- URL输入:
https://aip.baidubce.com/oauth/2.0/token - 在Params标签页添加参数:
| Key | Value |
|---|---|
grant_type | client_credentials |
client_id | 你的API Key |
client_secret | 你的Secret Key |
- 点击"Send",获取Access Token
响应示例:
{
"access_token": "24.xxx.xxx",
"expires_in": 2592000
}
注意:Access Token有效期为30天,需要缓存并定期刷新。
步骤2:调用文心一言API
- 创建新请求
- 请求方法选择"POST"
- URL输入:
https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions?access_token=你的Access Token - 在Headers标签页添加:
| Key | Value |
|---|---|
Content-Type | application/json |
- 在Body标签页(raw + JSON)输入:
{
"messages": [
{
"role": "user",
"content": "你好,请用一句话介绍Java编程语言"
}
],
"temperature": 0.7,
"max_output_tokens": 200
}
参数说明:
messages:对话消息列表(格式与OpenAI类似)temperature:温度参数(0.7是平衡值)max_output_tokens:最大输出Token数(注意:文心一言使用max_output_tokens而非max_tokens)
步骤3:查看响应结果
成功响应示例:
{
"id": "as-xxx",
"object": "chat.completion",
"created": 1234567890,
"result": "Java是一种面向对象的编程语言,具有跨平台、安全性高、易于学习等特点,广泛应用于企业级应用开发。",
"usage": {
"prompt_tokens": 20,
"completion_tokens": 35,
"total_tokens": 55
}
}
响应字段说明:
result:AI生成的回答(注意:文心一言直接返回result字段,而非choices[0].message.content)usage:Token使用情况
步骤4:Java代码实现
package com.example.ai.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.*;
/**
* 百度文心一言API调用服务
*/
@Service
public class WenxinService {
@Value("${ai.wenxin.api-key}")
private String apiKey;
@Value("${ai.wenxin.secret-key}")
private String secretKey;
private final RestTemplate restTemplate = new RestTemplate();
private String cachedAccessToken;
private long tokenExpireTime;
/**
* 获取Access Token(带缓存)
*/
private String getAccessToken() {
// 如果Token未过期,直接返回缓存的Token
if (cachedAccessToken != null && System.currentTimeMillis() < tokenExpireTime) {
return cachedAccessToken;
}
// 获取新的Access Token
String url = "https://aip.baidubce.com/oauth/2.0/token";
String params = String.format(
"grant_type=client_credentials&client_id=%s&client_secret=%s",
apiKey, secretKey
);
ResponseEntity<Map> response = restTemplate.postForEntity(
url + "?" + params, null, Map.class
);
Map<String, Object> body = response.getBody();
cachedAccessToken = (String) body.get("access_token");
int expiresIn = (Integer) body.get("expires_in");
// 设置过期时间(提前5分钟刷新)
tokenExpireTime = System.currentTimeMillis() + (expiresIn - 300) * 1000L;
return cachedAccessToken;
}
/**
* 调用文心一言API
*/
public String chat(String question) {
// 1. 获取Access Token
String accessToken = getAccessToken();
// 2. 构建请求
String url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions?access_token=" + accessToken;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
Map<String, Object> requestBody = new HashMap<>();
List<Map<String, String>> messages = new ArrayList<>();
Map<String, String> userMessage = new HashMap<>();
userMessage.put("role", "user");
userMessage.put("content", question);
messages.add(userMessage);
requestBody.put("messages", messages);
requestBody.put("temperature", 0.7);
requestBody.put("max_output_tokens", 200);
// 3. 发送请求
HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
try {
ResponseEntity<Map> response = restTemplate.postForEntity(url, request, Map.class);
// 4. 解析响应(注意:文心一言直接返回result字段)
if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
Object result = response.getBody().get("result");
if (result != null) {
return (String) result;
}
}
throw new RuntimeException("文心一言API响应异常");
} catch (Exception e) {
throw new RuntimeException("调用文心一言API失败:" + e.getMessage(), e);
}
}
}
2.5.5 Java代码调用示例
完整Java代码实现
package com.example.ai.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.*;
/**
* OpenAI API调用服务
*/
@Service
public class OpenAIService {
@Value("${ai.openai.api-key}")
private String apiKey;
private final RestTemplate restTemplate = new RestTemplate();
private static final String API_URL = "https://api.openai.com/v1/chat/completions";
/**
* 调用OpenAI API,获取AI回答
*
* @param question 用户问题
* @return AI回答
*/
public String chat(String question) {
// 1. 构建请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setBearerAuth(apiKey); // 设置Bearer Token认证
// 2. 构建请求体
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("model", "gpt-3.5-turbo");
// 构建消息列表
List<Map<String, String>> messages = new ArrayList<>();
Map<String, String> userMessage = new HashMap<>();
userMessage.put("role", "user");
userMessage.put("content", question);
messages.add(userMessage);
requestBody.put("messages", messages);
requestBody.put("temperature", 0.7);
requestBody.put("max_tokens", 200);
// 3. 发送HTTP请求
HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
try {
ResponseEntity<Map> response = restTemplate.exchange(
API_URL,
HttpMethod.POST,
request,
Map.class
);
// 4. 解析响应
return parseResponse(response.getBody());
} catch (Exception e) {
throw new RuntimeException("调用OpenAI API失败", e);
}
}
/**
* 解析API响应,提取AI回答
*/
private String parseResponse(Map<String, Object> response) {
// 获取choices数组
List<Map<String, Object>> choices = (List<Map<String, Object>>) response.get("choices");
if (choices == null || choices.isEmpty()) {
throw new RuntimeException("API响应中没有choices字段");
}
// 获取第一个choice
Map<String, Object> firstChoice = choices.get(0);
// 获取message对象
Map<String, Object> message = (Map<String, Object>) firstChoice.get("message");
// 获取content字段(AI的回答)
String content = (String) message.get("content");
return content;
}
/**
* 获取Token使用情况(用于成本统计)
*/
public Map<String, Integer> getTokenUsage(String question) {
// 调用API(同上)
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setBearerAuth(apiKey);
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("model", "gpt-3.5-turbo");
List<Map<String, String>> messages = new ArrayList<>();
Map<String, String> userMessage = new HashMap<>();
userMessage.put("role", "user");
userMessage.put("content", question);
messages.add(userMessage);
requestBody.put("messages", messages);
HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
ResponseEntity<Map> response = restTemplate.exchange(
API_URL,
HttpMethod.POST,
request,
Map.class
);
// 解析usage字段
Map<String, Object> usage = (Map<String, Object>) response.getBody().get("usage");
Map<String, Integer> tokenUsage = new HashMap<>();
tokenUsage.put("prompt_tokens", (Integer) usage.get("prompt_tokens"));
tokenUsage.put("completion_tokens", (Integer) usage.get("completion_tokens"));
tokenUsage.put("total_tokens", (Integer) usage.get("total_tokens"));
return tokenUsage;
}
}
配置文件(application.yml)
ai:
openai:
api-key: sk-your-api-key-here # 替换为你的实际API Key
使用示例
@RestController
@RequestMapping("/api/ai")
public class AIController {
@Autowired
private OpenAIService openAIService;
/**
* 聊天接口
*/
@PostMapping("/chat")
public ResponseEntity<Map<String, String>> chat(@RequestBody Map<String, String> request) {
String question = request.get("question");
String answer = openAIService.chat(question);
Map<String, String> response = new HashMap<>();
response.put("answer", answer);
return ResponseEntity.ok(response);
}
}
测试请求
curl -X POST http://localhost:8080/api/ai/chat \
-H "Content-Type: application/json" \
-d '{"question": "你好,请用一句话介绍Java编程语言"}'
响应示例:
{
"answer": "Java是一种面向对象的编程语言,具有跨平台、安全性高、易于学习等特点,广泛应用于企业级应用开发。"
}
2.5.6 实战常见问题排查指南
问题排查速查表
| 错误现象 | HTTP状态码 | 排查方向 | 解决方案 |
|---|---|---|---|
| API Key无效 | 401 | API Key错误/过期 | 核对API Key,重新生成 |
| 超过QPS限制 | 429 | 超过QPS/Token限额 | 增加限流控制、升级付费套餐 |
| 请求参数错误 | 400 | 参数格式/值错误 | 检查JSON格式、参数范围 |
| 响应内容截断 | 200 | 超过max_tokens限制 | 调大max_tokens,或分批处理文本 |
| 网络连接超时 | - | 网络问题/服务不可用 | 检查网络、使用代理、添加重试 |
| Token超限 | 429 | 超过上下文窗口 | 减少输入文本长度,分批处理 |
2.5.7 常见问题排查
问题1:401 Unauthorized错误
错误信息:
{
"error": {
"message": "Incorrect API key provided",
"type": "invalid_request_error",
"code": "invalid_api_key"
}
}
原因:API Key错误或未设置
解决方法:
- 检查API Key是否正确
- 检查请求头中的Authorization格式:
Bearer sk-xxx - 确认API Key是否有权限
问题2:429 Too Many Requests错误
错误信息:
{
"error": {
"message": "Rate limit exceeded",
"type": "rate_limit_error"
}
}
原因:超过QPS限制
解决方法:
- 降低请求频率
- 使用限流器控制并发
- 升级API套餐(提高QPS限制)
问题3:400 Bad Request错误
错误信息:
{
"error": {
"message": "Invalid parameter",
"type": "invalid_request_error"
}
}
原因:请求参数错误
解决方法:
- 检查请求体JSON格式是否正确
- 检查参数值是否合法(如temperature范围0-2)
- 参考API文档确认参数格式
问题4:网络连接超时
原因:网络问题或API服务不可用
解决方法:
- 检查网络连接
- 使用代理(如在国内访问OpenAI)
- 添加重试机制
Java重试示例:
@Service
public class OpenAIServiceWithRetry {
private static final int MAX_RETRIES = 3;
public String chat(String question) {
int retries = 0;
while (retries < MAX_RETRIES) {
try {
return callAPI(question);
} catch (Exception e) {
retries++;
if (retries >= MAX_RETRIES) {
throw new RuntimeException("调用API失败,已重试" + MAX_RETRIES + "次", e);
}
// 等待后重试
try {
Thread.sleep(1000 * retries); // 递增等待时间
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
}
}
return null;
}
private String callAPI(String question) {
// 实际的API调用代码
// ...
return "AI响应";
}
}
2.5.8 AI调用成本优化技巧
优化策略
1. 精简提示词
- 原则:去除冗余内容,仅保留核心需求
- 示例:
// ❌ 不好的提示词(冗余) String prompt = "请帮我写一段关于Java编程语言的介绍,要求详细、全面、专业,字数不少于200字..."; // ✅ 好的提示词(精简) String prompt = "用一句话介绍Java编程语言";
2. 缓存重复请求
- 原理:对相同问题的AI响应进行缓存,避免重复调用
- 实现:使用Redis缓存,Key为问题内容的MD5,Value为AI回答
- Java示例:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.apache.commons.codec.digest.DigestUtils; import java.util.concurrent.TimeUnit; /** * AI服务(带缓存优化) */ @Service public class AIServiceWithCache { @Autowired private RedisTemplate<String, String> redisTemplate; private static final String CACHE_PREFIX = "ai:answer:"; private static final int CACHE_EXPIRE_HOURS = 24; public String chat(String question) { // 生成缓存Key String cacheKey = CACHE_PREFIX + DigestUtils.md5Hex(question); // 先查缓存 String cachedAnswer = redisTemplate.opsForValue().get(cacheKey); if (cachedAnswer != null) { return cachedAnswer; } // 缓存未命中,调用AI API String answer = callAIAPI(question); // 写入缓存 redisTemplate.opsForValue().set( cacheKey, answer, CACHE_EXPIRE_HOURS, TimeUnit.HOURS ); return answer; } }
3. 选择合适模型
- 原则:非核心场景使用轻量模型,核心场景使用高级模型
- 示例:
- 简单问答:使用
gpt-3.5-turbo(成本低) - 复杂推理:使用
gpt-4(能力强但成本高)
- 简单问答:使用
4. 控制输出长度
- 原则:合理设置
max_tokens,避免生成过长内容 - 建议:
- 简单回答:max_tokens = 200-500
- 详细回答:max_tokens = 500-1000
- 长文本生成:max_tokens = 1000-2000
5. 批量处理
- 原理:将多个问题合并为一个请求,减少API调用次数
- 注意:需要确保总Token数不超过上下文窗口
成本优化效果对比:
| 优化策略 | 成本降低 | 适用场景 |
|---|---|---|
| 精简提示词 | 10-30% | 所有场景 |
| 缓存重复请求 | 50-80% | 常见问题场景 |
| 选择合适模型 | 30-70% | 非核心场景 |
| 控制输出长度 | 20-40% | 所有场景 |
| 批量处理 | 20-50% | 批量处理场景 |
2.5.9 实战总结
核心流程回顾:
- 准备API Key:申请并配置API Key
- 构建请求:设置请求方法、URL、请求头、请求体
- 发送请求:使用Postman或Java代码发送HTTP请求
- 解析响应:从JSON响应中提取AI回答
- 错误处理:处理常见的错误情况
关键技能:
- ✅ HTTP请求的构建和发送
- ✅ JSON数据的解析
- ✅ API认证(Bearer Token)
- ✅ 错误处理和重试机制
下一步:
- 尝试调用其他AI模型(如百度文心一言)
- 实现更复杂的功能(如多轮对话、流式响应)
- 优化代码结构,提升可维护性
2.6 本章总结
2.6.1 核心要点回顾
通过本章的学习,你应该已经掌握了以下核心内容:
-
AI模型分类与应用场景
- 四大主流模型类型:大语言模型(LLM)、图像识别、语音处理、语义理解
- 不同模型适用于不同业务场景,选对模型才能发挥最大价值
-
主流模型介绍
- GPT系列:国际化应用、代码生成
- 文心一言:国内应用、中文场景(Java开发者优先推荐)
- 讯飞星火:语音交互场景
- ChatGLM:本地部署场景
-
模型调用方式
- API调用(公有云):零部署成本,快速接入,适合大多数场景
- 本地化部署(私有模型):数据安全,适合敏感数据场景
-
关键概念
- API Key:身份认证和计费依据
- Token:文本处理的基本单位,计费依据
- QPS:每秒查询数,需要控制并发
- 上下文窗口:AI模型能处理的最大文本长度
- Temperature:控制生成内容的随机性
-
实战能力
- 使用Postman调用AI API
- 用Java代码调用AI API
- 解析API响应,提取AI回答
- 处理常见错误情况
2.6.2 知识框架梳理
2.6.3 下一步学习方向
完成本章学习后,建议你:
-
巩固基础:
- 多练习调用不同AI模型的API
- 熟悉不同参数的配置和效果
- 掌握错误处理和重试机制
-
准备下一章:
- 第3章将深入学习AI应用开发的核心技能
- 你将学习如何封装AI能力,开发业务接口
- 你将学习如何处理实际业务场景中的各种问题
-
持续实践:
- 尝试在实际项目中应用AI能力
- 关注AI平台的最新动态和API更新
- 通过实际项目积累经验
2.6.4 学习建议
- 理论结合实践:每学习一个概念,立即通过代码实践
- 多尝试不同模型:了解不同模型的特点和适用场景
- 关注成本控制:理解Token计费,合理控制调用成本
- 持续优化:通过实际项目,不断优化代码和调用方式
恭喜你完成第2章的学习! 现在你已经掌握了AI模型的基础认知,了解了主流模型的特点,掌握了模型调用的核心方式,理解了关键概念,并完成了第一个AI接口调用。接下来,让我们进入第3章,深入学习AI应用开发的核心技能。