杠精派
派聪明
0/512

热门评论

土豆大王 2026年03月18日 18:42
@派聪明 节点执行器怎么拉取的模型配置
点赞
回复3 取消回复
派聪明 2026年03月18日 18:42
节点执行器通过以下方式拉取模型配置: 1. 配置文件加载:执行器从预定义的配置文件中读取模型信息,包括模型ID、服务ID、域名、URL等参数。 2. 动态配置切换:在节点配置界面,用户可以选择不同的模型提供商(如DeepSeek、智谱、OpenAI、Claude等),执行器根据选择动态加载对应模型的配置参数。 3. 参数传递机制:当工作流执行时,模型配置信息以JSON格式传递给后端,包含inputs、outputs、retryConfig、nodeMeta、nodeParam等关键配置。 4. 中间件路由:执行器通过ModelServiceClient作为中间层,实现配置的路由和分发,将不同模型提供商的差异封装在底层,上层逻辑保持统一。 5. 工厂模式应用:采用工厂模式根据模型类型创建对应的客户端实例,实现模型配置的灵活适配和调用。 这种设计使执行器能够统一处理不同模型的配置差异,同时保持上层逻辑的简洁性和可扩展性。
点赞
回复 取消回复
展开剩余 2 条回复

15 条评论

QiQ 2026年03月26日 19:23
引用原文:LLM 节点要支持多轮对话
对于开始-LLM节点-结束这样的工作流,发送一句话,执行一次工作流,得到一个回答,发送另一句又会执行工作流,怎么实现LLM节点多轮对话?@派聪明
点赞
回复1 取消回复
派聪明 2026年03月26日 19:25
在PaiFlow中,LLM节点通过对话历史池实现多轮对话,具体机制如下: 1. **对话历史存储**:系统使用Guava的LoadingCache创建对话历史池,以`chatId+nodeId`为键存储各会话历史记录。每条历史包含用户输入、LLM思考过程和回复内容。 2. **历史记录管理**: - 每次对话添加新记录时,队列自动限制长度(MAX_HISTORY_LENGTH=10),超出则移除最早记录 - 缓存设置上限(10000会话)和30分钟过期策略,防止内存溢出 3. **提示词构建**:执行时将历史对话纳入提示词: ```java // 系统提示词 → 历史对话(用户输入+模型回复) → 当前用户输入 if (!CollectionUtils.isEmpty(req.getHistory())) { for (ChatItem item : req.getHistory()) { // 添加历史用户输入 msgList.add(new UserMessage(message.content())); // 添加历史模型回复 msgList.add(new AssistantMessage(response.content())); } } ``` 4. **工作流执行流程**: - 首次发送消息:创建新历史记录,执行工作流 - 后续发送消息:通过相同chatId获取历史记录,构建包含上下文的新提示词 - 每次执行后:将新问答追加到历史记录池 5. **配置控制**:通过`enableChatHistoryV2`开关控制多轮功能,可设置保留轮数(如rounds=3) 这样用户每次发送新消息时,系统都能自动关联历史对话,实现连贯的多轮交互体验。
点赞
回复 取消回复
云宿 2026年03月24日 09:51
引用原文:MAX_HISTORY_LENGTH 设成 10
@派聪明 你最高就缓存了10条,但是你前端又没有限制用户可以保存的最大轮数,那假如用户设置为60,他不还是缓存10条,有什么用呢
点赞
回复 取消回复
昏睡的吐司 2026年03月23日 21:07
引用原文:expireAfterWrite 设成 30 分钟,意味着这段时间里没再写入这个会话,它就会自动过期回收。
@派聪明 如果30分钟从缓存中删除,那什么时候同步存入数据库呢
点赞
回复 取消回复
小时月 2026年03月19日 22:37
引用原文:是新特性
@派聪明 解释一下record新用法,什么版本jdk引入的
点赞
回复1 取消回复
派聪明 2026年03月19日 22:39
参考资料中提到的 **`record` 是 Java 14 引入的新特性**(作为预览功能),在 **Java 16 中正式成为标准特性**。它的核心作用是**简化不可变数据类的编写**,减少样板代码。 --- ### **`record` 的核心特点:** 1. **自动生成不可变类** - 所有字段隐式声明为 `final`。 - 自动生成构造函数、`getter` 方法、`equals()`、`hashCode()` 和 `toString()`。 2. **语法简洁** - 传统类需要手动编写大量代码,而 `record` 仅需一行声明: ```java public record LlmResVo(Usage usage, String content, String thinkContent) {} ``` 等效于传统类: ```java public final class LlmResVo { private final Usage usage; private final String content; private final String thinkContent; public LlmResVo(Usage usage, String content, String thinkContent) { ... } public Usage usage() { ... } public String content() { ... } public String thinkContent() { ... } @Override public boolean equals() { ... } @Override public int hashCode() { ... } @Override public String toString() { ... } } ``` 3. **适用场景** - 适合**纯数据载体**(如 DTO、API 响应对象),如参考资料中的 `LlmResVo`,用于封装模型 API 的返回数据。 --- ### **参考资料中的应用:** 在 `LLMNodeExecutor` 中,`LlmResVo` 被定义为 `record`: ```java public record LlmResVo(Usage usage, String content, String thinkContent) { } ``` - **作用**:封装从模型 API 接收的响应数据(`usage` 统计信息、`content` 回答内容、`thinkContent` 推理过程)。 - **优势**:无需手动编写 `getter`/`equals` 等方法,代码更简洁,且保证数据不可变性。 --- ### **总结:** - **引入版本**:Java 14(预览)→ Java 16(正式)。 - **核心价值**:用极简语法实现不可变数据类,减少重复代码。 - **参考资料场景**:`LlmResVo` 作为模型 API 的响应载体,完美契合 `record` 的设计目标。
点赞
回复 取消回复
土豆大王 2026年03月18日 18:42
@派聪明 节点执行器怎么拉取的模型配置
点赞
回复3 取消回复
派聪明 2026年03月18日 18:42
节点执行器通过以下方式拉取模型配置: 1. 配置文件加载:执行器从预定义的配置文件中读取模型信息,包括模型ID、服务ID、域名、URL等参数。 2. 动态配置切换:在节点配置界面,用户可以选择不同的模型提供商(如DeepSeek、智谱、OpenAI、Claude等),执行器根据选择动态加载对应模型的配置参数。 3. 参数传递机制:当工作流执行时,模型配置信息以JSON格式传递给后端,包含inputs、outputs、retryConfig、nodeMeta、nodeParam等关键配置。 4. 中间件路由:执行器通过ModelServiceClient作为中间层,实现配置的路由和分发,将不同模型提供商的差异封装在底层,上层逻辑保持统一。 5. 工厂模式应用:采用工厂模式根据模型类型创建对应的客户端实例,实现模型配置的灵活适配和调用。 这种设计使执行器能够统一处理不同模型的配置差异,同时保持上层逻辑的简洁性和可扩展性。
点赞
回复 取消回复
展开剩余 2 条回复
Je 2026年03月18日 00:10
引用原文:maximumSize 设成 10000,意思是最多缓存一万个会话的队列,再多就让 Guava 做淘汰
@派聪明 这个maximumSize 和上面的MAX_HISTORY_LENGTH有什么区别
点赞
回复1 取消回复
派聪明 2026年03月18日 00:10
根据参考资料中的描述,`maximumSize` 和 `MAX_HISTORY_LENGTH` 是两个不同层级的限制参数,作用如下: ### 1. **`MAX_HISTORY_LENGTH`(单个会话队列长度限制)** - **作用**:控制**单个会话**中保存的历史对话条数上限。 - **实现位置**:在 `ConcurrentLinkedQueue` 的自定义实现中(通过重写 `add` 方法)。 - **逻辑**: - 每个会话(由 `chatId + nodeId` 唯一标识)维护一个独立的队列。 - 当队列长度达到 `MAX_HISTORY_LENGTH`(如 10)时,**自动移除最旧的一条记录**,确保单个会话的历史记录不会无限增长。 - **代码示例**: ```java private static final int MAX_HISTORY_LENGTH = 10; // 单个会话最多保存10条历史 private static ConcurrentLinkedQueue createChatHistoryQueue() { return new ConcurrentLinkedQueue() { @Override public boolean add(ChatItem item) { if (size() >= MAX_HISTORY_LENGTH) { poll(); // 移除最旧记录 } return super.add(item); } }; } ``` ### 2. **`maximumSize`(全局会话数量限制)** - **作用**:控制**整个缓存**中保存的不同会话队列的总数量上限。 - **实现位置**:在 `LoadingCache` 的配置中(通过 `CacheBuilder.newBuilder().maximumSize()`)。 - **逻辑**: - 缓存存储所有会话的队列(key 为 `chatId + nodeId`)。 - 当会话数量达到 `maximumSize`(如 10000)时,**根据 LRU 策略淘汰最久未使用的会话队列**,防止内存溢出。 - **代码示例**: ```java private static final LoadingCache> chatHistoryCache = CacheBuilder.newBuilder() .maximumSize(10000) // 全局最多缓存10000个会话队列 .expireAfterWrite(30, TimeUnit.MINUTES) .build(CacheLoader.from(LlmChatHistory::createChatHistoryQueue)); ``` --- ### **核心区别总结** | **参数** | **作用范围** | **限制目标** | **淘汰机制** | |------------------------|------------------|--------------------------|--------------------------| | `MAX_HISTORY_LENGTH` | 单个会话内部 | 单个会话的历史记录条数 | 移除最旧的一条记录(队列内) | | `maximumSize` | 全局缓存层面 | 不同会话队列的总数量 | LRU 策略淘汰整个会话队列 | ### **设计意图** - **`MAX_HISTORY_LENGTH`**:防止单个会话的历史记录无限膨胀(如长时间对话占用过多内存)。 - **`maximumSize`**:避免系统因会话数量过多(如高并发场景)导致内存耗尽。 两者结合,既保证了单个会话的历史记录可控,又限制了全局内存占用,形成双重保护机制。
点赞
回复 取消回复
满意的身影 2026年03月17日 18:12
引用原文:record 用法
解释一下
点赞
回复 取消回复
berlin 2026年03月01日 16:51
为什么用guava而不用redis?guava与redis相比优势是什么呢?
点赞
回复1 取消回复
liuyongyuan 2026年03月04日 14:58
轻量,就一个小需求需要缓存没必要引入redis
1
回复 取消回复

目录