💬 会话标识
# 两层标识体系
liteflow-react-agent 把会话拆成两层标识:
- conversationId:业务/对话维度,整条 chain 内一致,决定 workspace 子目录
- agentKey:组件维度,默认是
nodeId,在同一 conversation 中区分不同 Agent 实例和记忆
框架通过 AgentSessionManager.acquire(conversationId, agentKey) 获取一个 AgentSession。同一个 (conversationId, agentKey) 组合会复用:
- 同一个
ReActAgent实例 - 同一个 Agent memory
- 同一把
ReentrantLock - 同一个持久化 key
同一 conversationId 下的不同 agentKey 拥有独立 Agent 和独立 memory,但共享同一个 workspace 子目录,便于多 Agent 通过文件协作。
并发安全
同一个 (conversationId, agentKey) 下的调用会串行执行。不同 agentKey 可以并行执行,但如果共享 workspace,需要由业务自行避免写同名文件冲突。
# conversationId 从哪里来
默认解析顺序:
- 复用
slot.conversationId(同一条 chain 内首个 Agent 写回后,后续 Agent 自动复用) - 从
chainReqDataMap 中读取conversationId字段 - 调用
ConversationIdGenerator.generate()自动生成(格式:YYYYMMDD_<12位NanoId>)
# 显式传入 conversationId
LiteflowResponse response = flowExecutor.execute2Resp(
"deepseekChain",
request,
ExecuteOption.of().conversationId("chat-user-1-conv-1")
);
# 自动生成后复用
LiteflowResponse first = flowExecutor.execute2Resp(
"deepseekChain",
request,
ExecuteOption.of().autoConversationId()
);
String cid = first.getConversationId();
// 后续调用使用同一个 cid
# 按业务对象生成
@Override
protected String resolveConversationId() {
ChatRequest req = getSlot().getChainReqData(getSlot().getChainId());
return "chat-" + req.getUserId() + "-" + req.getConversationId();
}
# agentKey 从哪里来
默认实现是当前节点的 nodeId:
protected String agentKey() {
String nodeId = getNodeId();
return (nodeId == null || nodeId.isEmpty()) ? "default" : nodeId;
}
这意味着同一段 conversation 中,mathAgent 和 summaryAgent 默认有各自独立的 Agent 记忆。
# 自定义 agentKey
// 多个节点共享同一个 Agent 记忆
@Override
protected String agentKey() {
return "shared-agent";
}
// 同一个节点的不同执行完全隔离
@Override
protected String agentKey() {
return getNodeId() + "-" + getSlot().getRequestId();
}
# 字符合法性
conversationId 与 agentKey 只允许 [a-zA-Z0-9_-]+。原因是它们会被拼进 workspace 子目录名和持久化 key,必须是文件系统和 Redis/MySQL key 都安全的字符集。
如果传入的字符串包含其他字符,框架的处理规则是:
- 空值或
null→ 替换为_ - 完全匹配
[a-zA-Z0-9_-]+→ 原样保留 - 含其他字符 → 先做 UTF-8 百分号编码(URL 编码),再把所有
%替换为_
举例:
| 传入值 | 实际使用的安全值 |
|---|---|
chat-user-1 | chat-user-1(原样保留) |
chat-用户1 | chat-_E7_94_A8_E6_88_B71 |
""(空字符串) | _ |
建议
不要直接把用户昵称、邮箱等原始数据当作 conversationId,避免出现难以阅读的目录名。推荐用业务 ID 拼接或哈希结果。
帮助我们改善此文档 (opens new window)
上次更新: 2026/05/26, 10:50:41


