Solon AI 4.0的ChatModel:简洁API封装样板代码,多方式构建AI功能!

📅 2026/7/5 2:57:10
Solon AI 4.0的ChatModel:简洁API封装样板代码,多方式构建AI功能!
Java应用集成大语言模型的新方案如果你尝试过在Java应用中集成大语言模型LLM大概率写过不少样板代码像HTTP客户端、JSON解析、流式处理、会话管理等。而Solon AI 4.0的 ChatModel 用一套简洁的Builder API把这些都封装好了。本文将通过真实的代码示例带你一步步用 ChatModel 构建AI功能从简单的单次调用到带记忆的流式聊天机器人。什么是ChatModelChatModel 是Solon AI生态中的统一LLM客户端。你不再需要为不同的模型提供商写不同的HTTP调用而是通过一套统一的API完成多种操作包括同步调用一次请求完整返回、流式调用基于Project Reactor的响应式流 Flux、工具/函数调用让LLM调用你的Java方法、聊天会话自动维护对话记忆、多模态消息文本、图片、音频、方言适配支持OpenAI、Ollama、Anthropic、Gemini、DashScope等多种服务商。最核心的是它使用了 **方言模式Dialect Pattern**你只需要指向任意兼容的LLM端点它会自动适配协议。环境配置在 pom.xml 中添加依赖Solon不需要父POM独立工作dependency groupIdorg.noear/groupId artifactIdsolon-ai/artifactId version${solon.version}/version /dependency这会引入所有内置的方言适配器OpenAI、Ollama、Gemini、Anthropic、DashScope。配置方式通过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 注入一个可以直接使用的 ChatModelimport 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; } }编程式BuilderBean 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(); }支持的模型提供商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端点QwenDashScope原生同步调用最简单的方式最基本的用法是发送提示词获取完整响应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(); } }仅三行业务代码搞定。流式调用实时响应对于聊天机器人和助手类应用流式响应是刚需。ChatModel 返回Reactor的 Fluximport reactor.core.publisher.Flux; public FluxString askStream(String question) throws IOException { return chatModel.prompt(question) .stream() .filter(resp - resp.hasContent()) _// 跳过空块_ .map(resp - resp.getContent()); }如果你使用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 FluxSseEvent chatStream(String prompt) throws IOException { return chatModel.prompt(prompt) .stream() .filter(resp - resp.hasContent()) .map(resp - new SseEvent().data(resp.getContent())); }流式协议根据提供商不同使用标准SSE或 x-ndjson。对话记忆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();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 MapString, ChatSession sessionMap new ConcurrentHashMap(); Mapping(/chat) public FluxSseEvent chat(String sessionId, String prompt) throws IOException { ChatSession session sessionMap.computeIfAbsent(sessionId, k - InMemoryChatSession.builder().sessionId(k).build()); return chatModel.prompt(prompt) .session(session) .options(o - o.systemPrompt(你是一个友好、乐于助人的助手。)) .stream() .filter(ChatResponse::hasContent) .map(resp - new SseEvent().data(resp.getContent())); } }内置会话实现实现类存储方式适用场景InMemoryChatSession本地Map开发、单节点FileChatSession文件系统CLI工具、桌面应用RedisChatSessionRedis生产环境、分布式部署调优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.0max_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可自动生成systemPromptinstruction(val)Agent指令role instruction可自动生成systemPromptsystemPrompt(val)本次请求的系统提示词完全定制多消息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();完整实战知识感知聊天机器人下面是一个轻量级的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服务器使用外部工具你有没有在Java中集成过LLM最大的痛点是什么欢迎在评论区分享可能会在后续文章中专门讨论。