第二章 AI大模型接入
代码仓库地址:https://github.com/Liucc-123/ai-agent
项目目标:通过项目实战掌握AI 大模型应用开发的常见知识,包括有:掌握AI 应用平台使用、AI 大模型接入、开发框架(Spring AI + LangChain4j)、本地部署、Prompt 工程、多模态特性、RAG 知识库、工具调用、MCP 服务开发、智能体原理和开发、服务化部署等技术。
一、AI 大模型概念
- 定义:AI 大模型是具有超大规模参数(数十亿到数万亿)的深度学习模型,能够理解、生成人类语言,处理图像、音频等多种模态数据,并展现出强大的推理和创作能力。
- 涌现能力:随着模型参数量和训练数据量的增加,模型会展现出训练过程中未明确赋予的新能力,如逻辑推理、代码编写、多步骤问题解决等。
- 常见大模型举例:
- OpenAI:GPT-4o(多模态)、GPT-4(文本+图像)、GPT-3.5 Turbo(主要处理文本)。
- Anthropic:Claude 3 系列(Opus, Sonnet, Haiku,由强到弱)。
- Google:Gemini Ultra/Pro/Nano(多模态能力)。
- Meta:Llama 3(开源,70B 和 8B 参数版本)、Llama 2(开源,多种参数规模)。
- 国内大模型:百度的文心一言、阿里的通义千问、字节跳动的豆包、科大讯飞的星火。
- 分类:
- 按模态分类:
- 单模态模型:仅处理单一类型的数据,如纯文本(早期的 GPT-3)。
- 多模态模型:能够处理多种类型的信息,如文本+图像(GPT-4V、Gemini、Claude 3)、文本+音频+视频(GPT-4o)。
- 按开源性分类:
- 闭源模型:不公开模型权重和训练方法,通常通过 API 访问,付费使用(如 GPT-4、Claude、Gemini)。
- 开源模型:公开模型权重,允许下载和自行部署,可以本地部署、自由调整,但通常性能略逊于同等规模闭源模型(如 Llama 系列、Mistral、Falcon)。
- 按规模分类:
- 超大规模模型:参数量在数千亿到数万亿,能力强大,但需要大量计算资源(如 GPT-4,1.76T 参数)。
- 中小规模模型:参数量在几十亿到几百亿,能在较普通的硬件上运行,适合特定任务的精调(如 Llama 3,70B 参数;Mistral 7B)。
- 按用途分类:
- 通用模型:能处理广泛的任务(如 GPT-4、Claude 3、Gemini)。
- 特定领域模型:针对特定领域优化,如医疗领域的 Med-PaLM 2、代码领域的 CodeLlama 和 StarCoder、科学领域的 Galactica。
- 按模态分类:
- 开发者学习方向:
- 学会选择适合的 AI 大模型,考虑应用场景需求、成本与性能平衡、数据隐私要求。
- 了解如何接入 AI 大模型,掌握提示工程技巧(Prompt Engineering)和大模型开发工作流。
- 了解模型能力边界,知道模型能做什么和不能做什么,了解可能出现的问题(如幻觉)及处理方法。
- 学习 AI 大模型相关的面试题,关注 AI 相关资讯动态,如鱼皮开源的 AI 知识库。
- 对比和选择大模型:可以从功能支持维度(多模态能力、工具使用能力、上下文窗口大小、指令遵循能力)、性能指标维度(准确性、响应质量、知识时效性)、部署与集成维度(部署方式、API 接口、并发处理能力)、商业与合规维度(成本效益、数据安全与隐私、法律合规性)、生态与支持维度(社区支持、文档完善度、技术支持)等多个维度进行评估。
二、接入 AI 大模型
- 使用大模型的 2 种途径:
- 云服务:直接使用云服务商在云端已部署好的大模型服务,无需自己考虑基础设施,特点包括按需付费、随时可用、自动更新、安全措施完善等。
- 自部署:开发者自行在本地或私有云环境部署开源大模型,特点包括数据隐私保障高、可定制性强、无网络延迟,但成本高、需要专业团队维护。
- 接入大模型的 3 种方式:
- AI 应用平台接入:通过云服务商提供的 AI 应用平台使用 AI 大模型,如阿里云百炼,它提供了从模型调用到应用构建的全流程支持,还提供了知识库管理、应用评测等功能。其产品灵积(DashScope)则通过灵活的模型 API 接口,让开发者能够快速调用大模型能力。
- AI 软件客户端接入:通过 AI 软件客户端使用大模型能力,推荐的有 Cherry Studio(全能 AI 助手平台)和 Cursor(以 AI 为核心的编程开发工具)。
- 程序接入:通过编程的方式在自己的项目中调用 AI 大模型,分为直接调用 AI 大模型和调用 AI 大模型平台创建的应用或智能体两种方式。直接调用可使用特定平台提供的 SDK 或 API,也可使用 AI 开发框架(如 Spring AI、LangChain4j 等)自主选择大模型进行调用;调用平台创建的应用或智能体则只能使用特定平台提供的 SDK 或 API。
三、后端项目初始化
- 环境准备:安装的 JDK 版本必须是 17 或 21,推荐使用 21 版本,因为它支持虚拟线程功能。
- 新建项目:在 IDEA 中新建项目,选择 Spring Initializr 模板,确保 Server URL 为https://start.spring.io/,选择 Java 版本 21 和 Spring Boot 3.4.4 版本,添加
Spring Web
和Lombok
等依赖。如果 Lombok 依赖报错,可手动指定 Lombok 版本(如 1.18.36)。 - 整合依赖:
- Hutool 工具库:主流的 Java 工具类库,集合了丰富的工具类,涵盖字符串处理、日期操作等功能。在 Maven 的 pom.xml 中添加依赖(版本 5.8.37)。
- Knife4j 接口文档:基于 Swagger 接口文档的增强工具,提供友好界面和功能扩展。在 Maven 的 pom.xml 中添加依赖(版本 4.4.0),并新建 controller 包用于存放 API 接口,编写健康检查接口测试接口文档是否正常引入。在 application.yml 中追加接口文档配置,扫描 controller 包。启动项目后,访问http://localhost:8123/api/doc.html查看接口文档。
pom 依赖:
<dependencies><!-- https://mvnrepository.com/artifact/dev.langchain4j/langchain4j-community-dashscope --><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-community-dashscope</artifactId><version>1.0.0-beta2</version></dependency><!--springai alibaba--><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter</artifactId><version>1.0.0-M6.1</version></dependency><!--dashscope--><dependency><groupId>com.alibaba</groupId><artifactId>dashscope-sdk-java</artifactId><!-- 请将 'the-latest-version' 替换为最新版本号:https://mvnrepository.com/artifact/com.alibaba/dashscope-sdk-java --><version>2.20.2</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.38</version></dependency><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId><version>4.4.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
</dependencies>
配置文件:
spring:application:name: ai-agentprofiles:active: local
server:port: 8123servlet:context-path: /api
# knife4j
springdoc:swagger-ui:path: /swagger-ui.htmltags-sorter: alphaoperations-sorter: alphaapi-docs:path: /v3/api-docsgroup-configs:- group: 'default'paths-to-match: '/**'packages-to-scan: com.liucc.aiagent.controller
# knife4j
knife4j:enable: truesetting:language: zh_cn
四、程序调用 AI 大模型
4 种主流接入方式:
- SDK 接入:
- 是官方提供的最直接的集成方式,具有完善的类型支持和错误处理机制。
- 以阿里云百炼平台为例,需先按照官方文档安装 SDK(可在 Maven 中央仓库查看最新版本号),并在 pom.xml 中引入依赖(如版本 2.19.1)。
- 然后在百炼平台申请 API Key,新建
demo.invoke
包存放示例代码,参考官方文档编写代码,创建接口类存储密钥信息(实际生产环境应使用配置文件或环境变量),运行项目可看到 AI 的回复。
SDK 调用 AI 示例代码:
package com.liucc.aiagent.demo.invoke;
// 建议dashscope SDK的版本 >= 2.12.0
import java.util.Arrays;
import java.lang.System;
import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.JsonUtils;import static com.liucc.aiagent.demo.TestApiKey.API_KEY;public class SDKAIInvoke {public static GenerationResult callWithMessage() throws ApiException, NoApiKeyException, InputRequiredException {Generation gen = new Generation();Message systemMsg = Message.builder().role(Role.SYSTEM.getValue()).content("You are a helpful assistant.").build();Message userMsg = Message.builder().role(Role.USER.getValue()).content("你是谁?").build();GenerationParam param = GenerationParam.builder()// 若没有配置环境变量,请用百炼API Key将下行替换为:.apiKey("sk-xxx").apiKey(API_KEY)// 此处以qwen-plus为例,可按需更换模型名称。模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models.model("qwen-plus").messages(Arrays.asList(systemMsg, userMsg)).resultFormat(GenerationParam.ResultFormat.MESSAGE).build();return gen.call(param);}public static void main(String[] args) {try {GenerationResult result = callWithMessage();System.out.println(JsonUtils.toJson(result));} catch (ApiException | NoApiKeyException | InputRequiredException e) {// 使用日志框架记录异常信息System.err.println("An error occurred while calling the generation service: " + e.getMessage());}System.exit(0);}
}
- HTTP 接入:
参考文档地址:阿里大模型调用参考
curl --location "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation" \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header "Content-Type: application/json" \
--data '{"model": "qwen-plus","input":{"messages":[ {"role": "system","content": "You are a helpful assistant."},{"role": "user","content": "你是谁?"}]},"parameters": {"result_format": "message"}
}'
- 适用于 SDK 不支持的编程语言或需要更灵活控制的场景,但需手动处理错误、序列化/反序列化复杂、代码冗长。
- 可以利用 AI 将 CURL 代码转换为 Java 的 Hutool 工具类网络请求代码,示例代码中设置了请求头、请求体,并发送请求处理响应。
示例代码:
package com.liucc.aiagent.demo.invoke;import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;import static com.liucc.aiagent.demo.TestApiKey.API_KEY;/*** 通过HTTP方式调用AI*/
@Slf4j
public class HTTPAIInvoke {public static void main(String[] args) {String result = callWithHutool();System.out.println("result:" + result);}public static String callWithHutool() {// 请求地址String url = "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation";// 构建请求头Map<String, String> headers = new HashMap<>();headers.put("Authorization", "Bearer " + API_KEY);headers.put("Content-Type", "application/json");// 构建消息列表Map<String, Object> systemMsg = new HashMap<>();systemMsg.put("role", "system");systemMsg.put("content", "You are a helpful assistant.");Map<String, Object> userMsg = new HashMap<>();userMsg.put("role", "user");userMsg.put("content", "你是谁?");// 构建 input 部分Map<String, Object> input = new HashMap<>();input.put("messages", Arrays.asList(systemMsg, userMsg));// 构建 parameters 部分Map<String, Object> parameters = new HashMap<>();parameters.put("result_format", "message");// 构建请求体Map<String, Object> body = new HashMap<>();body.put("model", "qwen-plus");body.put("input", input);body.put("parameters", parameters);// 发送 POST 请求HttpResponse response = HttpRequest.post(url).addHeaders(headers).body(JSONUtil.toJsonStr(body)).execute();// 返回响应结果return response.body();}}
- Spring AI:
官方文档:SpringAI Alibaba
- 是 Spring 生态系统的新成员,旨在简化 AI 功能与 Spring 应用的集成,具有跨 AI 供应商的可移植 API 支持、支持多种主流 AI 模型供应商和模型类型、结构化输出、支持主流向量数据库、工具/函数调用、可观测性、文档 ETL 框架、AI 模型评估工具、Spring Boot 自动配置和启动器、ChatClient API、Advisors API 等核心特性。
- 默认没有支持所有大模型,尤其是国产模型,推荐使用阿里自主封装的 Spring AI Alibaba 框架,它继承阿里系大模型且与标准 Spring AI 兼容。接入流程包括引入依赖(版本 1.0.0-M6.1)、编写配置(设置 API Key 和模型名称)、编写示例代码(注入 dashscopeChatModel 并调用)。
1)引入依赖
<dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter</artifactId><version>1.0.0-M6.1</version>
</dependency>
注意:由于 spring-ai 相关依赖包还没有发布到中央仓库,如出现 spring-ai-core 等相关依赖解析问题,请在您项目的 pom.xml 依赖中加入如下仓库配置:
<repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository>
</repositories>
2)编写配置
spring:application:name: spring-ai-alibaba-qwq-chat-client-exampleai:dashscope:api-key: ${AI_DASHSCOPE_API_KEY}chat:options:model: qwen-plus
3)编写示例代码
// 取消注释即可在 SpringBoot 项目启动时执行
@Component
public class SpringAiAiInvoke implements CommandLineRunner {@Resourceprivate ChatModel dashscopeChatModel;@Overridepublic void run(String... args) throws Exception {AssistantMessage output = dashscopeChatModel.call(new Prompt("讲一个冷笑话")).getResult().getOutput();System.out.println(output.getText());}
}
在上述代码中,只是通过ChatModel实现和大模型的对话功能,SpringAI还提供了ChatClient调用方式,提供更多高级功能(比如多轮对话、RAG 等)
- LangChain4j:
参考官方文档:https://docs.langchain4j.dev/integrations/language-models/dashscope/
1)引入依赖
<!-- https://mvnrepository.com/artifact/dev.langchain4j/langchain4j-community-dashscope -->
<dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-community-dashscope</artifactId><version>1.0.0-beta2</version>
</dependency>
2)参考官方文档示例代码
public class LangChainAiInvoke {public static void main(String[] args) {ChatLanguageModel qwenModel = QwenChatModel.builder().apiKey(TestApiKey.API_KEY).modelName("qwen-max").build();String answer = qwenModel.chat("讲一个冷笑话");System.out.println(answer);}
}
个人更推荐使用 SpringAI,因为 Spring 的生态更好、社区维护更加频繁。
五、本地部署大模型及程序接入
TODO:待补充