跳转到内容

对话与流式

Feat AI 提供了简洁易用的对话功能,支持与大语言模型进行交互,包括同步和流式输出。本文档将带你从零开始使用 Feat AI 对话功能,从依赖引入到高级配置,全面覆盖实际应用场景。

  • 在 Maven 项目中引入 feat-ai 依赖
  • 使用 FeatAI.chatModel(...) 创建对话模型
  • 掌握 chat()chatStream() 两种交互方式
  • 区分云端 API(如 Gitee AI)与本地模型(如 Ollama)的配置
  • 实现多轮对话和流式输出
  • 了解不同场景的最佳实践
  • JDK 1.8 或更高版本
  • Maven 3.0 或更高版本
  • 模型服务(任选其一):
    • Gitee AI:需配置 API Key(环境变量 FEAT_AI_API_KEY
    • Ollama:本地已安装并运行 Ollama,默认地址 http://localhost:11434

在项目的 pom.xml 中添加 feat-ai 依赖(Feat 父 POM 或版本属性中需包含 feat.version):

pom.xml
<dependency>
<groupId>tech.smartboot.feat</groupId>
<artifactId>feat-ai</artifactId>
<version>${feat.version}</version>
</dependency>

指定 baseUrl 和模型名即可创建本地模型实例:

import tech.smartboot.feat.ai.FeatAI;
import tech.smartboot.feat.ai.chat.ChatModel;
public class HelloFeatAI {
public static void main(String[] args) {
ChatModel model = FeatAI.chatModel(opts -> opts
.baseUrl("http://localhost:11434/v1")
.model("qwen2.5:7b")
);
// 后续使用 model 发送消息
}
}

使用内置的 ChatModelVendor 枚举,无需手动指定 baseUrl:

import tech.smartboot.feat.ai.FeatAI;
import tech.smartboot.feat.ai.chat.ChatModel;
import tech.smartboot.feat.ai.chat.ChatModelVendor;
ChatModel model = FeatAI.chatModel(opts -> opts
.model(ChatModelVendor.GiteeAI.Qwen2_5_72B_Instruct)
);

使用 chat() 方法获取完整回复和用量信息:

model.chat("解释什么是 RAG", response -> {
System.out.println("回复: " + response.getContent());
System.out.println("用量: " + response.getUsage());
});

使用 chatStream() 方法逐段获取回复,适合长回答或实时展示:

model.chatStream("解释什么是 RAG", content -> {
System.out.print(content);
});

以下是基于 Ollama 的完整示例(JDK 8 可运行):

HelloFeatAI.java
import tech.smartboot.feat.ai.FeatAI;
import tech.smartboot.feat.ai.chat.ChatModel;
public class HelloFeatAI {
public static void main(String[] args) {
ChatModel model = FeatAI.chatModel(opts -> opts
.baseUrl("http://localhost:11434/v1")
.model("qwen2.5:7b")
);
model.chatStream("用一句话解释什么是 RAG", content -> {
System.out.print(content);
});
}
}
  • Ollama:先在本机执行 ollama run qwen2.5:7b(或你配置的模型),再运行上述程序,控制台应逐字输出模型回复。
  • Gitee AI:设置好 FEAT_AI_API_KEY 后运行,应得到云端模型的回复;若未设置,会报错提示设置环境变量。
方法参数返回值说明
chat(String prompt, Consumer<ResponseMessage> callback)prompt: 提示词
callback: 响应回调
void同步对话,一次性获取完整回复
chat(List<Message> messages, Consumer<ResponseMessage> callback)messages: 消息列表
callback: 响应回调
void多轮对话,支持上下文
chatStream(String prompt, StreamResponseCallback callback)prompt: 提示词
callback: 流式响应回调
void流式对话,逐段获取回复
chatStream(List<Message> messages, StreamResponseCallback callback)messages: 消息列表
callback: 流式响应回调
void流式多轮对话
chatStream(String prompt, Consumer<String> callback)prompt: 提示词
callback: 内容回调
void简化版流式对话,只处理内容
字段类型说明
getContent()String模型回复内容
getUsage()Usage令牌使用情况
getId()String响应唯一标识
getCreated()long创建时间戳
getModel()String使用的模型
字段类型说明
getPromptTokens()int提示词令牌数
getCompletionTokens()int回复令牌数
getTotalTokens()int总令牌数

通过 FeatAI.chatModel(opts -> ...) 创建对话模型时,可配置以下参数:

配置项方法说明类型默认值
服务地址baseUrl(String)兼容 OpenAI 的 API 根地址,如 Ollama 的 http://localhost:11434/v1String-
模型model(String)model(ChatModelVendor)模型名或内置厂商枚举String/Enum-
API KeyapiKey(String) 或环境变量 FEAT_AI_API_KEY云端 API 必填String环境变量值
系统提示system(String)设定角色或风格,如「你是一个诗人」String-
调试模式debug(boolean)为 true 时打印请求/响应便于排查booleanfalse
关闭思考noThink(true)部分模型会输出“思考”内容,设为 true 可关闭booleanfalse
温度temperature(double)生成随机性,0-2,值越高越随机double0.7
最大令牌maxTokens(int)最大生成令牌数int-
ChatModel model = FeatAI.chatModel(opts -> opts
.baseUrl("http://localhost:11434/v1")
.model("qwen2.5:7b")
.system("你是一个擅长生成藏头诗的诗人。")
.noThink(true)
.temperature(0.8)
.maxTokens(1000)
);
ChatModel model = FeatAI.chatModel(opts -> opts
.model(ChatModelVendor.GiteeAI.Qwen2_5_72B_Instruct)
.system("你是一个专业的 Java 工程师")
.debug(true)
);

使用 chat() 方法获取完整回复和用量信息,适合需要一次性处理完整结果的场景:

model.chat("根据关键词「情」「人」「节」生成一句藏头诗", response -> {
System.out.println("回复内容:" + response.getContent());
System.out.println("提示词令牌:" + response.getUsage().getPromptTokens());
System.out.println("回复令牌:" + response.getUsage().getCompletionTokens());
System.out.println("总令牌:" + response.getUsage().getTotalTokens());
});

使用 chatStream() 方法逐段获取回复,适合需要实时展示或处理长回复的场景:

model.chatStream("用三句话介绍 Feat 框架", new StreamResponseCallback() {
@Override
public void onStreamResponse(String content) {
System.out.print(content); // 逐字输出
}
@Override
public void onCompletion(ResponseMessage responseMessage) {
System.out.println("\n生成完成,总令牌数:" + responseMessage.getUsage().getTotalTokens());
}
});

通过维护消息列表实现多轮对话,保持上下文连续性:

import tech.smartboot.feat.ai.chat.entity.Message;
import tech.smartboot.feat.ai.chat.entity.MessageRole;
import java.util.ArrayList;
import java.util.List;
// 初始化消息列表
List<Message> messages = new ArrayList<>();
// 系统消息
messages.add(new Message(MessageRole.SYSTEM, "你是一个专业的 Java 工程师"));
// 第一轮对话
messages.add(new Message(MessageRole.USER, "什么是 Feat 框架?"));
model.chat(messages, response -> {
String content = response.getContent();
System.out.println("AI: " + content);
// 添加 AI 回复到消息列表
messages.add(new Message(MessageRole.ASSISTANT, content));
});
// 第二轮对话(基于上下文)
messages.add(new Message(MessageRole.USER, "它和 Spring Boot 有什么区别?"));
model.chat(messages, response -> {
System.out.println("AI: " + response.getContent());
});

以下示例演示了创建模型、设置系统提示、以及流式与同步两种调用方式(JDK 8 可运行):

import tech.smartboot.feat.ai.FeatAI;
import tech.smartboot.feat.ai.chat.ChatModel;
import tech.smartboot.feat.ai.chat.entity.ResponseMessage;
import tech.smartboot.feat.ai.chat.entity.StreamResponseCallback;
public class ChatDemoExample {
public static void main(String[] args) {
ChatModel model = FeatAI.chatModel(opts -> opts
.baseUrl("http://localhost:11434/v1")
.model("qwen2.5:7b")
.system("你是一个擅长生成藏头诗的诗人。")
.noThink(true)
);
String prompt = "根据以下关键词生成一句藏头诗:情,人,节,快,乐";
// 流式调用
model.chatStream(prompt, new StreamResponseCallback() {
@Override
public void onStreamResponse(String content) {
System.out.print(content);
}
@Override
public void onCompletion(ResponseMessage responseMessage) {
System.out.println("\n生成完成!");
}
});
// 同步调用
model.chat(prompt, response -> {
System.out.println(response.getContent());
System.out.println("生成完成!");
});
}
}

适用条件:需要 24/7 在线客服,处理常见问题

配置建议

  • 系统提示:明确角色定位和回答范围
  • 温度:0.3-0.5(更确定性回答)
  • 最大令牌:500-1000(控制回答长度)

示例

ChatModel supportBot = FeatAI.chatModel(opts -> opts
.baseUrl("http://localhost:11434/v1")
.model("qwen2.5:7b")
.system("你是 Feat 框架的客服机器人,只回答与 Feat 相关的问题,对于不相关问题请礼貌拒绝。")
.temperature(0.3)
.maxTokens(800)
);

适用条件:需要生成文章、代码、创意内容

配置建议

  • 系统提示:详细描述内容风格和要求
  • 温度:0.7-1.0(更有创意)
  • 最大令牌:2000-4000(支持长内容)

示例

ChatModel contentGenerator = FeatAI.chatModel(opts -> opts
.baseUrl("http://localhost:11434/v1")
.model("qwen2.5:7b")
.system("你是一个专业的技术文档 writer,擅长用清晰、简洁的语言解释复杂概念。")
.temperature(0.8)
.maxTokens(3000)
);

适用条件:需要生成、解释或优化代码

配置建议

  • 系统提示:指定编程语言和代码风格
  • 温度:0.4-0.6(平衡创意和正确性)
  • 最大令牌:1500-2500(支持完整函数/类)

示例

ChatModel codeAssistant = FeatAI.chatModel(opts -> opts
.baseUrl("http://localhost:11434/v1")
.model("qwen2.5:7b")
.system("你是一个专业的 Java 工程师,擅长编写清晰、高效、符合最佳实践的代码。")
.temperature(0.5)
.maxTokens(2000)
);
  • Gitee AI:使用 opts.model(ChatModelVendor.GiteeAI.Qwen2_5_72B_Instruct) 等枚举值,并设置 FEAT_AI_API_KEY 环境变量。
  • Ollama:本地运行的模型服务,通过 baseUrl("http://localhost:11434/v1") 配置。
  • 自定义服务:任意兼容 OpenAI 格式的接口均可通过 baseUrl(...) + model(...) 对接。
  • Azure OpenAI:设置 baseUrl 为 Azure 端点,apiKey 为 Azure API Key。
  • 使用 Gitee AI 时 必须 设置环境变量 FEAT_AI_API_KEY,否则会抛出 IllegalArgumentException
  • Ollama 的 baseUrl 通常为 http://localhost:11434/v1,且不要以 / 结尾;Feat AI 会自动处理末尾斜杠。
  • 部分模型会先输出“思考”再输出答案,若不需要可设置 noThink(true)
  • 流式回调可能在非主线程执行,若在 UI 或其它线程敏感场景使用,需自行做线程切换。
  • 多轮对话时,消息列表会占用内存,需根据实际情况控制列表大小。
  • 生产环境建议设置合理的超时时间,避免长时间阻塞。
问题可能原因解决方案
连接超时网络问题或服务不可用检查网络连接,确认服务是否运行
API Key 错误密钥无效或未设置确认环境变量 FEAT_AI_API_KEY 是否已正确设置
模型不存在模型名错误或未安装确认模型名正确,Ollama 需先 pull 模型
令牌超限输入或输出过长减少输入长度,设置合理的 maxTokens
响应为空模型未返回内容检查提示词是否清晰,尝试调整 temperature
  • Feat AI 简介:模块能力概览
  • Agent 开发:基于 Feat AI 构建智能代理
  • 项目内可运行示例:feat-ai 模块 demo 包下的 ChatDemoOllamaDemoLocalAI