如果你尝试过在 Java 应用中集成大语言模型(LLM),大概率写过不少样板代码:HTTP 客户端、JSON 解析、流式处理、会话管理……Solon AI 4.0 的 ChatModel 用一套简洁的 Builder API 把这些都封装好了。
本文将通过真实的代码示例,带你一步步用 ChatModel 构建 AI 能力——从简单的单次调用,到带记忆的流式聊天机器人。
1. 什么是 ChatModel?
ChatModel 是 Solon AI 生态中的统一 LLM 客户端。你不再需要为不同的模型提供商写不同的 HTTP 调用,而是通过一套统一的 API 完成:
同步调用— 一次请求,完整返回流式调用— 基于 Project Reactor 的响应式流(Flux
最核心的是它使用了 方言模式(Dialect Pattern) ——你只需要指向任意兼容的 LLM 端点,它会自动适配协议。
在 pom.xml 中添加依赖(Solon 不需要父 POM,独立工作):
< dependency > < groupId > org.noear groupId > < artifactId > solon-ai artifactId > < version > ${solon.version} version > dependency >
这会引入所有内置的方言适配器(OpenAI、Ollama、Gemini、Anthropic、DashScope)。
3.1 通过 YAML 配置(推荐)
solon.ai.chat: demo: apiUrl: "http://127.0.0.1:11434/api/chat" # 完整 URL,非 baseUrl standard: "ollama" # 接口规范(方言标识) model: "llama3.2" # 模型名称 headers: x-demo: "demo1"
然后通过 @Bean 注入一个可以直接使用的 ChatModel :
import org.noear.solon.ai.chat.ChatConfig; import org.noear.solon.ai.chat.ChatModel; import org.noear.solon.annotation.Bean; import org.noear.solon.annotation.Configuration; import org.noear.solon.annotation.Inject; @Configuration public class AiConfig { @Bean public ChatModel chatModel ( @Inject("${solon.ai.chat.demo}") ChatModel model) { return model; } }
3.2 编程式 Builder
@Bean public ChatModel chatModel () { return ChatModel.of( "http://127.0.0.1:11434/api/chat" ) .standard( "ollama" ) // 或 .provider("ollama") .model( "llama3.2" ) .timeout(Duration.ofSeconds( 60 )) .build(); }
3.3 适配的模型提供商
standard (或 provider )字段选择方言:
方言标识apiUrl 示例模型openai(默认)https://api.openai.com/v1/chat/completionsGPT、DeepSeek、Qwen、GLM、Kimi 等ollamahttp://127.0.0.1:11434/api/chat本地 Ollama 模型anthropichttps://api.anthropic.com/v1/messagesClaudegeminihttps://generativelanguage.googleapis.com/...Geminidashscope阿里云 DashScope 端点Qwen(DashScope 原生)
4. 同步调用(最简单的方式)
最基本的用法——发送提示词,获取完整响应:
import org.noear.solon.ai.chat.ChatModel; import org.noear.solon.ai.chat.ChatResponse; import org.noear.solon.annotation.Inject; import org.noear.solon.annotation.Component; @Component public class ChatService { @Inject ChatModel chatModel; public String ask (String question) throws IOException { ChatResponse resp = chatModel.prompt(question).call(); return resp.getMessage().getContent(); } }
仅三行业务代码,搞定。
5. 流式调用(实时响应)
对于聊天机器人和助手类应用,流式响应是刚需。 ChatModel 返回 Reactor 的 Flux
import reactor.core.publisher.Flux; public Flux
如果你使用 Solon Web Reactive,可以直接把 Flux 返回给 SSE 端点:
import org.noear.solon.web.sse.SseEvent; import org.noear.solon.annotation.Mapping; import reactor.core.publisher.Flux; @Mapping("/chat/stream") public Flux
流式协议根据提供商不同,使用标准 SSE 或 x-ndjson 。
6. 对话记忆:ChatSession
LLM 本身是无状态的,每次请求都需要传入历史上下文。 ChatSession 自动帮你完成这件事。
import org.noear.solon.ai.chat.ChatSession; import org.noear.solon.ai.chat.session.InMemoryChatSession; ChatSession session = InMemoryChatSession.builder() .sessionId( "user-123" ) .maxMessages( 10 ) // 保留最近 10 轮 .build(); // 第一轮 ChatResponse resp1 = chatModel.prompt( "你好!" ) .session(session) .call(); // 第二轮——模型记得刚才的对话 ChatResponse resp2 = chatModel.prompt( "我刚才说了什么?" ) .session(session) .call();
6.2 Web 应用中的客户级会话
在实际的 Web 应用中,每个客户需要一个独立的会话:
import org.noear.solon.annotation.Controller; import org.noear.solon.web.sse.SseEvent; import reactor.core.publisher.Flux; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @Controller public class ChatController { @Inject ChatModel chatModel; final Map
实现类存储方式适用场景InMemoryChatSession本地 Map开发、单节点FileChatSession文件系统CLI 助手、桌面应用RedisChatSessionRedis生产环境、分布式部署
7. 调优:ChatOptions
通过 ChatOptions 可以在每次请求中控制模型行为:
chatModel.prompt( "写一首关于 Java 的诗" ) .options(o -> o .temperature( 0.8 ) .max_tokens( 500 ) .top_p( 0.9 ) .systemPrompt( "你是一位富有创造力的诗人。" )) .call();
方法说明temperature(val)采样温度(0.0–2.0)max_tokens(val)最大输出 Token 数top_p(val)核采样参数top_k(val)Top-K 采样frequency_penalty(val)降低重复presence_penalty(val)鼓励新话题tool_choice(val)强制利器调用:none、auto、required或工具名role(val)Agent 角色(role + instruction 可自动生成 systemPrompt)instruction(val)Agent 指令(role + instruction 可自动生成 systemPrompt)systemPrompt(val)本次请求的系统提示词(完全定制)
8. 多消息 Prompt
有时候你需要的不只是一条消息。可以用 Prompt 和 ChatMessage 构建更复杂的上下文:
import org.noear.solon.ai.chat.Prompt; import org.noear.solon.ai.chat.message.ChatMessage; Prompt prompt = Prompt.of( ChatMessage.ofUser( "Hello, how are you?" ), ChatMessage.ofAssistant( "Bonjour, comment allez-vous?" ), ChatMessage.ofUser( "What is your name?" ) ); ChatResponse resp = chatModel.prompt(prompt).options(o -> o.systemPrompt( "你是一名中英翻译专家。" )).call();
9. 完整实战:知识感知聊天机器人
下面是一个轻量级的 RAG 模式示例——用 ChatMessage.ofUserAugment() 把上下文注入到 Prompt 中:
import org.noear.solon.ai.chat.ChatModel; import org.noear.solon.ai.chat.ChatResponse; import org.noear.solon.ai.chat.message.ChatMessage; import org.noear.solon.annotation.Component; import org.noear.solon.annotation.Inject; @Component public class KnowledgeChatbot { @Inject ChatModel chatModel; public String answer (String question, String referenceContext) throws Exception { // 将参考上下文与使用者问题合并 ChatMessage augmented = ChatMessage.ofUserAugment(question, referenceContext); ChatResponse resp = chatModel.prompt(augmented) .options(o -> o .temperature( 0.3 ) .systemPrompt( "你是一个知识渊博的助手。请基于提供的参考资料回答。" )) .call(); return resp.getMessage().getContent(); } }
这种模式——用上下文增强使用者输入,再调用模型——正是 Solon AI 中 RAG(检索增强生成)的基础。
ChatModel 只是入口点。Solon AI 还提供:
利器调用— 用@ToolMapping定义 LLM 可调用的 Java 方法Talent 系统— 可复用的能力模块Agent—ReActAgent和TeamAgent实现多步推理RAG 流水线— 完整的文档加载、切分、嵌入、检索流程MCP 协议— 连接 MCP 服务器使用外部工具
完整文档参见官方指南:
:point_right:https://solon.noear.org/article/918(模型构建):point_right:https://solon.noear.org/article/920(API 参考)
你有没有在 Java 中集成过 LLM?最大的痛点是什么?欢迎在评论区分享,可能会在后续文章中专门讨论。

