在 LangChain4j 框架中,不同类型的消息(Message
)用于构建多角色对话上下文,每种消息类型有特定的作用和结构。以下是详细解析:
1. 核心消息类型对比
消息类型 | 发送者 | 典型用途 | 数据结构示例(JSON) |
---|---|---|---|
UserMessage |
真实用户 | 用户提问/指令 | {"role": "user", "content": "你好"} |
AiMessage |
AI模型 | AI生成的回复 | {"role": "assistant", "content": "你好!"} |
SystemMessage |
系统 | 设定AI行为/角色 | {"role": "system", "content": "你是一名医生"} |
ToolExecutionResultMessage |
工具执行器 | 返回工具调用结果 | {"role": "tool", "name": "get_weather", "content": "22°C"} |
CustomMessage |
开发者 | 扩展自定义逻辑 | {"role": "custom", "metadata": {"priority": "high"}} |
2. 详细作用解析
(1) UserMessage - 用户输入
java
// 创建用户消息
UserMessage message = UserMessage.from("今天的天气怎么样?");
// 包含元数据(如用户ID)
UserMessage messageWithMeta = UserMessage.from(
"推荐一部电影",
Metadata.of("user_id", "123")
);
- 作用:代表终端用户的文本输入
- 底层协议 :对应OpenAI API中的
{"role": "user"}
(2) AiMessage - AI响应
java
// 普通AI回复
AiMessage response = AiMessage.from("今天晴天,气温22°C");
// 包含工具调用请求
AiMessage toolCallMessage = AiMessage.from(
ToolExecutionRequest.builder()
.name("get_weather")
.arguments("{\"city\":\"北京\"}")
.build()
);
- 特殊能力 :
- 可携带
ToolExecutionRequest
请求调用外部工具 - 支持流式响应的中间结果(
onNext
回调)
- 可携带
(3) SystemMessage - 系统指令
java
SystemMessage systemMsg = SystemMessage.from("""
你是一名资深影评人,回答需包含:
1. 电影评分(IMDb/Rotten Tomatoes)
2. 50字以内短评
3. 类似推荐
""");
- 核心价值 :
- 设定AI的角色 和回答风格
- 通常放在对话历史最前面
(4) ToolExecutionResultMessage - 工具结果
java
ToolExecutionResultMessage resultMsg = ToolExecutionResultMessage.from(
toolRequest, // 对应的ToolExecutionRequest
"22°C" // 工具执行结果
);
-
工作流程 :
graph LR A[UserMessage] --> B[AI生成ToolExecutionRequest] B --> C[执行外部工具] C --> D[返回ToolExecutionResultMessage] D --> E[AI生成最终回复]
(5) CustomMessage - 自定义扩展
java
CustomMessage customMsg = CustomMessage.from(
"session_event",
Metadata.of("type", "user_session_start")
);
- 应用场景 :
- 记录对话生命周期事件(如会话开始/结束)
- 注入非文本数据(如用户行为日志)
3. 完整对话流程示例
java
List<Message> messages = new ArrayList<>();
// 1. 设定系统角色
messages.add(SystemMessage.from("你是一名天气预报员"));
// 2. 用户提问
messages.add(UserMessage.from("北京明天天气如何?"));
// 3. AI要求调用工具
messages.add(AiMessage.from(
ToolExecutionRequest.builder()
.name("get_weather")
.arguments("{\"city\":\"北京\",\"date\":\"tomorrow\"}")
.build()
));
// 4. 返回工具结果
messages.add(ToolExecutionResultMessage.from(
toolRequest,
"{\"temp\":\"18°C\",\"condition\":\"多云\"}"
));
// 5. AI生成最终回复
messages.add(AiMessage.from("北京明天多云,气温18°C"));
4. 消息类型转换
转换场景 | 方法 |
---|---|
Message → JSON | Json.toJson(message) |
JSON → Message | Message.from(jsonString) |
提取工具请求 | aiMessage.toolExecutionRequest() |
5. 设计最佳实践
-
对话历史管理:
java// 限制上下文长度(防止token超限) List<Message> trimmedHistory = TokenTrimmer.trim(messages, 2000);
-
工具调用模式:
javaif (aiMessage.hasToolExecutionRequest()) { ToolExecutionRequest request = aiMessage.toolExecutionRequest(); String result = toolExecutor.execute(request); return ToolExecutionResultMessage.from(request, result); }
-
系统消息优化:
javaSystemMessage.builder() .content("你是一名金融顾问") .metadata("strict_mode", "true") // 可扩展元数据 .build();
6. 常见问题解决
问题现象 | 解决方案 |
---|---|
工具调用结果未被AI处理 | 检查是否在历史中包含 ToolExecutionResultMessage |
系统指令未生效 | 确保 SystemMessage 是第一条消息 |
自定义消息被模型忽略 | 使用 Metadata 传递关键数据 |
通过合理组合这些消息类型,可以构建复杂的多轮对话系统,实现:
- 角色扮演 (通过
SystemMessage
) - 工具增强 (通过
Tool*
消息) - 上下文感知 (维护完整的
Message
历史)