基础知识详解
LLM
中文通常译为大语言模型 ,日常也常简称为大模型。不过严格来说,"大模型"的范围更宽一些------它还可以包括多模态大模型(如能处理图像、音频的模型),而 LLM 特指以文本(语言)为核心的大规模神经网络模型。
Token
是模型眼里的最小单位。它既不是字也不是词,是从语料里统计出来的、最省事的一套切法

越常见的东西,越可能被压成一个 token;越少见的,越会被拆碎。
提示词(prompt)
输入给大模型的指令或文本,用来引导模型生成你想要的输出。它是你和模型之间"对话"的起点,也是控制模型行为最直接的方式。
提示词工程不是找到某个神奇句式,是系统地把该说的都说清楚

提示词四部分:背景、要求、限制、验收。

上下文与 RAG
向量:向量把「意思」变成了坐标。有了坐标,「哪段话和这个问题最像」就成了一道可以计算的距离题。负责这件事的是一个专门的模型是向量模型。
上下文窗口:模型在一次请求里能看到的全部内容的上限。它是按 Token 算的,而且------要装的东西比大多数人以为的多

RAG知识库:先从你的资料里找出相关的几段,连同问题一起交给模型。绝大多数「企业知识库」就是这个。RAG 不是一种模型,是一套工程流程------你不需要训练任何东西,用现成的模型加一个检索层就能搭起来

① 检索。 把用户问题也转成向量,在库里找最接近的几段。成熟做法是混合检索 + 重排:先多召回一批,再挑出真正能回答问题的三五段。
**② 拼进上下文。**把检索到的片段、用户问题、以及一组约束,组装成一次请求。
**③ 模型回答。**模型基于给它的材料作答,并标明出处。
Agent与Skill
Agent:以大模型为"大脑",能够自主感知、规划、调用工具并执行多步任务来完成目标的系统。它不只是"你问一句它答一句",而是能自己决定下一步做什么

Agent 的典型组成:
-
规划(Planning):把大目标拆成子任务,决定先后顺序,必要时反思和修正
-
工具调用(Tool Use):调用搜索、代码执行、数据库、API、文件操作等外部能力
-
记忆(Memory):短期记忆(当前对话上下文)和长期记忆(向量库、历史记录)
-
执行与循环:观察结果→决定下一步→再行动,直到任务完成
常见工作模式:
-
ReAct:推理(Reasoning)和行动(Acting)交替进行,"想一步、做一步、看结果"
-
Plan-and-Execute:先制定完整计划,再逐步执行
-
多 Agent 协作:多个角色分工(如研究员、程序员、审核员)协同完成任务
Skill是给模型的「操作手册」,做某类任务时要遵循的步骤、要用的格式、要注意的边界、可以参考的例子。它不碰任何外部系统,只影响模型「用脑子办事」的方式。

MCP
它是一套接口接入的标准:把你的系统(数据库、订单服务、邮件)按统一格式包装起来,让 Agent 通过一套规范就能调用这些能力。它解决的是连接问题,不管模型会不会用这些能力做事。

解决的是接入的标准化问题。在它出现之前,每个 Agent 要接一个新系统,都得写一套专用的适配代码,格式五花八门。MCP 定义了一套统一的形状:
**工具。**外部系统暴露的可调用操作,以及各自的参数说明。
**资源。**可读取的数据和文件。
**提示。**可复用的指令模板。
Spring AI
Spring AI 就是让你用写 Spring Boot 微服务的方式,写 LLM 应用。 不用自己拼 HTTP 请求、不用自己处理 token 计数、不用自己管流式协议

ChatModel
Spring AI 的核心入口,是直接与各类大模型提供商(如 OpenAI、Ollama、DeepSeek 等)交互的低层接口。它负责统一请求格式、发送提示并解析原始响应,是框架实现"可移植性"的基础。
定义:继承自通用的 Model 接口,并提供了同步调用与流式调用的能力。它的核心方法设计得比较简洁:
-
简化调用 :
call(String message)方法允许你直接传入一段字符串,快速获取模型的文本回复,适合入门测试。 -
标准调用 :
call(Prompt prompt)是实际开发中更常用的方式。它接受封装好的Prompt对象,并返回包含完整元数据(如 token 用量、结束原因)的ChatResponse对象。 -
流式响应 :通过
stream(Prompt prompt)方法,它使用响应式编程(Reactor 的Flux)逐块返回数据,适合需要打字机效果或处理长回复的场景
代码
1.配置yml
java
server:
port: 6066
spring:
application:
name: day-01-chatmodel
# ========== Spring AI OpenAI 配置 ==========
# API Key 从环境变量读取,绝不硬编码
# Windows PowerShell: $env:OPENAI_API_KEY="sk-xxx"
# 也支持设置 base-url 对接兼容 API(如 DashScope / 智谱 / 本地 Ollama)
ai:
openai:
# 官方 OpenAI: https://api.openai.com
# 国内兼容示例: https://dashscope.aliyuncs.com/compatible-mode/v1
base-url: https://api.deepseek.com
api-key: sk-a2************************e39f
chat:
options:
# 默认模型,可按需切换
# OpenAI: gpt-4o-mini, gpt-4o
# Ollama 本地: qwen2.5:7b, llama3.1:8b
model: deepseek-flash
# 温度:0=稳定确定,1=创意发散;Day 1 先用 0.7 体验
temperature: 0.7
# 最大生成 token 数,避免成本失控
max-tokens: 256
logging:
level:
# 让我们能看到 Spring AI 的调用日志,Day 1 方便学习链路
org.springframework.ai: DEBUG
2:接口
java
@GetMapping("/chat")
public Map<String, Object> chat(@RequestParam(defaultValue = "你好") String msg) {
Map<String, Object> result = new HashMap<>();
result.put("question", msg);
result.put("timestamp", LocalDateTime.now().toString());
try {
String answer = chatModel.call(msg);
result.put("answer", answer);
result.put("success", true);
} catch (Exception e) {
result.put("answer", null);
result.put("success", false);
result.put("error", e.getMessage());
}
return result;
}
3.结果

ChatClient
是 Spring AI 1.0 主推的 Fluent API 入口 。类比熟悉的 Spring 生态:

ChatClient 是一个 Builder 模式 的链式调用器,帮你把这些要素组合到一次对话请求里:
ChatClient.prompt() ← 开始构建请求
.system(...) ← 系统提示词(角色设定)
.user(...) ← 用户提问
.assistant(...) ← 历史助手回复(Day 3 多轮再讲)
.options(ChatOptions) ← 模型参数覆盖
.advisors(...) ← 拦截器(Day 5 学)
.call() ← 同步调用,返回 ChatResponse
.stream() ← 流式调用,返回 Flux<ChatResponse>
代码
1.提示词
@Configuration
public class ChatClientConfig {
/**
* 默认 system prompt:设定 AI 的角色。
* 先放一个固定字符串,后面 Day 3 会学模板化 prompt。
*/
public static final String DEFAULT_SYSTEM_PROMPT = """
你是一个专业的 Java 后端工程师导师,擅长把复杂概念讲得通俗易懂。
回答时请遵循:
先给一句话总结(TL;DR)
再展开详细解释
适当时给代码示例
""";
@Bean
public ChatClient chatClient(ChatClient.Builder builder) {
return builder
// 预先灌进去 system prompt,所有通过这个 Bean 的调用都自动带上
.defaultSystem(DEFAULT_SYSTEM_PROMPT)
.build();
}
}
2.请求体
java
@PostMapping("/chat")
public ApiResult<ChatApiResponse> chat(@Valid @RequestBody ChatRequest request) {
long start = System.currentTimeMillis();
LocalDateTime timestamp = LocalDateTime.now();
ChatOptions options = buildChatOptions(request);
// ------ ChatClient Fluent API 核心演示 ------
ChatResponse resp = chatClient.prompt()
.system(systemSpec -> {
String sp = request.getSystemPrompt();
if (sp != null && !sp.isBlank()) {
systemSpec.text(sp);
}
})
.user(request.getQuestion())
.options(options)
.call()
.chatResponse();
// ------ 从 Spring AI ChatResponse 提取字段,组装成我们的 ChatApiResponse ------
String answer = resp.getResult().getOutput().getText();
String model = resp.getMetadata().getModel() != null
? resp.getMetadata().getModel()
: "unknown";
// Spring AI 1.0 的 Usage 接口:getPromptTokens()=输入, getCompletionTokens()=输出, getTotalTokens()=总
// 返回 Integer(可能为 null,有些模型不返回 usage),所以用 intValue() 前先判 null
int inputTokens = 0;
int outputTokens = 0;
Usage usage = resp.getMetadata().getUsage();
if (usage != null) {
inputTokens = usage.getPromptTokens() != null ? usage.getPromptTokens() : 0;
outputTokens = usage.getCompletionTokens() != null ? usage.getCompletionTokens() : 0;
}
List<String> candidates = resp.getResults().stream()
.map(r -> r.getOutput().getText())
.toList();
ChatApiResponse body = new ChatApiResponse();
body.setAnswer(answer);
body.setModel(model);
body.setTimestamp(timestamp);
body.setDurationMs(System.currentTimeMillis() - start);
body.setUsage(new ChatApiResponse.TokenUsage(inputTokens, outputTokens, inputTokens + outputTokens));
body.setCandidates(candidates);
return ApiResult.ok(body);
}
private ChatOptions buildChatOptions(ChatRequest request) {
ChatOptions.Builder builder = ChatOptions.builder();
if (request.getTemperature() != null) {
builder.temperature(request.getTemperature());
}
return builder.build();
}
区别
在 Spring AI 中,ChatModel 与 ChatClient 是分层协作的关系,而非二选一。ChatClient 是构建在 ChatModel 之上的高层门面(Facade) ,旨在提升开发效率;而 ChatModel 是直接与模型提供商通信的底层接口,提供最原始的控制力。
核心区别
定位与层级
-
ChatModel:底层接口,直接封装与 AI 服务商的通信。类似于 JDBC 的核心库。 -
ChatClient:高层封装,内部持有一个ChatModel来执行实际请求。提供链式(Fluent)API,更符合现代 Java 开发习惯。
工具调用(Tool Calling)
-
ChatModel:不自动执行工具。它只返回模型请求调用的指令,需要调用方手动编写循环来执行工具并再次请求模型。 -
ChatClient:自动处理 工具调用循环。通过内置的ToolCallingAdvisor,它能自动执行工具并将结果回传给模型,对开发者透明。
内置能力与便利性
-
ChatModel:功能单一,仅负责发送请求和接收原始响应。需要手动构造Prompt、管理消息列表。 -
ChatClient:内置丰富功能。支持默认系统提示词、对话记忆(Advisor)、RAG(检索增强生成)、结构化输出(直接映射为 Java 对象)等。
适用场景
-
ChatModel:适用于构建基础设施(如自定义的ChatClient实现)、集成到非 Spring 的自定义编排引擎,或你需要对请求细节进行极致控制的场景。 -
ChatClient:官方推荐的入口。适用于绝大多数应用开发,包括聊天应用、RAG、智能体(Agent)工作流以及工具密集型的助手。
如何选择
对于绝大多数业务开发,优先使用 ChatClient 。它能帮你省去处理工具调用循环、记忆管理和提示词组装的大量样板代码。只有当你需要实现一个高度定制化的流程,且 ChatClient 的 Advisor 链反而成为阻碍时,才考虑直接使用底层的 ChatModel。