构建具有记忆功能的聊天助手
本指南演示如何利用 ChatMemory 功能创建一个能够跨多次交互记住历史对话内容的命令行聊天应用。
该 CLI 应用执行以下循环:
- 从控制台读取用户输入
- 若输入不是
/bye且非空,则使用用户输入和指定会话 ID 运行助手 - 助手首先加载该会话 ID 对应的历史对话记录,并将消息与用户输入一同加入提示词
- 助手执行 LLM 交互
- 在运行结束返回响应前,助手将完整对话历史存储至指定会话 ID 下,并限制仅保留最新的 20 条消息
- 应用随后输出助手的响应
流程示意图如下:
graph TB
subgraph agent [Agent with chat memory]
load[Load chat history]
save[Save chat history]
llm([LLM interaction])
load --> llm --> save
end
start((Start))
read[Read input]
print[Print response]
exit((Exit))
start --> read
read --"/bye"--> exit
read --"empty"--> read
read --"User input"--> agent
agent --"Agent response"--> print --> read
代码实现
前置准备
确保您的环境和项目满足以下要求:
- JDK 17+
- Kotlin 2.2.0+
- Gradle 8.0+ 或 Maven 3.8+
从 LLM 提供商获取 API 密钥,或通过 Ollama 运行本地 LLM。 更多信息请参阅 快速入门。
本页示例假设您已设置 OPENAI_API_KEY 环境变量。
suspend fun main() {
val sessionId = "my-conversation"
simpleOpenAIExecutor(System.getenv("OPENAI_API_KEY")).use { executor ->
val agent = AIAgent(
promptExecutor = executor,
llmModel = OpenAIModels.Chat.GPT5_2,
systemPrompt = "You are a helpful assistant."
) {
install(ChatMemory) {
windowSize(20) // 仅保留最近20条消息
}
}
while (true) {
print("You: ")
val input = readln().trim()
if (input == "/bye") break
if (input.isEmpty()) continue
val reply = agent.run(input, sessionId)
println("Assistant: $reply\n")
}
}
}
```java public class ExampleChatAgentOpenAI { public static void main(String[] args) { String sessionId = "my-conversation";
``` try (var executor = simpleOpenAIExecutor(System.getenv("OPENAI_API_KEY"))) {
AIAgent
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.print("你: ");
String input = scanner.nextLine().trim();
if (input.equals("/bye")) break;
if (input.isEmpty()) continue;
String reply = agent.run(input, sessionId);
System.out.println("助手: " + reply + "\n");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
```
实现细节
agent.run() 的第二个参数是用于识别和区分不同对话的会话ID。
在我们的示例中,由于每次只有一个对话,因此该ID保持恒定。
在实际应用中,可以为同一用户的相关对话分配独立的唯一ID。
该代理使用默认的历史记录提供器, 该提供器将对话历史存储在内存中。 这意味着当应用程序退出时,历史记录会丢失。 在实际应用中,应实现自定义的历史记录提供器, 以便将历史记录持久化存储到数据库或文件中。
windowSize(20) 预处理器确保上下文大小受限:
代理仅存储最多20条最新消息。
若无此限制,提示词大小可能超出上下文限制。
示例会话
You: My name is Alice.
Assistant: Nice to meet you, Alice! How can I help you today?
You: What's my favorite color? It's blue.
Assistant: Got it — your favorite color is blue!
You: What's my name?
Assistant: Your name is Alice!
尽管每次交互都是独立的代理运行,但代理仍能正确回答“你的名字是Alice!”,
这是因为ChatMemory功能在处理第三条消息前加载了先前的对话记录。