概述
ChatModelFactory是LangChat Pro的核心组件之一,负责动态创建和管理各种大语言模型(LLM)的实例。它采用工厂模式,支持多种模型供应商(OpenAI、Ollama、Qwen、Qianfan、Zhipu等),实现了模型实例的缓存和Listener绑定机制。设计模式
工厂模式(Factory Pattern)
ChatModelFactory使用工厂模式来:- 封装复杂的模型创建逻辑
- 统一不同供应商的模型实例化方式
- 支持模型实例的缓存和复用
- 为每个请求绑定独立的Listener
核心组件
ChatModelFactory
路径:langchat-core/src/main/java/cn/langchat/core/factory/ChatModelFactory.java
职责: 动态创建和管理ChatModel实例
核心方法
StreamingChatModel 相关方法
1. getStreamingModel(带chatId)
2. getStreamingModel(不带chatId)
ChatModel 相关方法
1. getChatModel(带chatId)
2. getChatModel(不带chatId)
模型创建流程
1. 获取模型配置
2. 创建StreamingChatModel(带Listener)
支持的模型供应商
1. OpenAI(及兼容OpenAI API的模型)
OpenAiStreamingChatModel
2. Ollama(本地模型)
OllamaStreamingChatModel
3. Qwen(通义千问)
QwenStreamingChatModel
4. Qianfan(百度千帆)
QianfanStreamingChatModel
5. Zhipu(智谱AI)
ZhipuAiStreamingChatModel
缓存机制
缓存策略
ChatModelFactory使用Caffeine缓存模型实例:缓存获取
缓存键生成
缓存设计要点
- 不缓存Listener: Listener绑定到具体请求,不能缓存
- 基于配置缓存: 相同配置的模型实例可以复用
- 懒加载: 首次使用时创建并缓存
- 内存缓存: 使用Caffeine,高性能
Listener绑定机制
ChatListener
路径:langchat-core/src/main/java/cn/langchat/core/observability/ChatListener.java
职责: 监听模型调用事件
Listener创建流程
Listener功能
- 请求追踪: 追踪每个请求的开始和结束
- Token统计: 统计输入和输出Token数量
- 日志记录: 记录请求和响应详情
- 计费: 计算API调用成本
- 监控: 性能监控和告警
响应格式处理
ResponseFormat
text- 文本格式(默认)json- JSON格式
扩展新模型供应商
步骤1: 添加供应商常量
在ProviderConst中添加新供应商:
步骤2: 实现模型创建方法
在ChatModelFactory中添加:
步骤3: 更新创建逻辑
在createStreamingModelWithListener和createChatModelWithListener中添加case:
步骤4: 更新缓存键生成(如果需要)
如果新供应商有特殊配置参数,更新ModelCacheSupport.generateCacheKey
配置说明
AigcModel 配置字段
| 字段 | 类型 | 说明 | 示例 |
|---|---|---|---|
| id | String | 模型ID | ”model-001” |
| provider | String | 供应商 | ”openai” |
| model | String | 模型名称 | ”gpt-4” |
| baseUrl | String | API地址 | ”https://api.openai.com/v1” |
| apiKey | String | API密钥 | ”sk-…“ |
| secretKey | String | 密钥(部分供应商) | “secret-…“ |
| type | String | 模型类型 | ”text2text”, “text2image” |
| temperature | Double | 温度参数 | 0.7 |
| topP | Double | Top-P参数 | 0.9 |
| maxToken | Integer | 最大Token数 | 2000 |
| timeout | Integer | 超时时间(分钟) | 5 |
| format | String | 响应格式 | ”json”, “text” |
最佳实践
1. 使用正确的获取方法
- 带chatId: 聊天场景,需要Listener追踪
- 不带chatId: Embedding、向量化等场景
2. 合理设置缓存
- 缓存避免重复创建模型实例
- 但不缓存Listener,每次请求独立创建
- 缓存键包含所有配置参数
3. 模型类型判断
4. 异常处理
- 模型不存在时抛出异常
- 模型ID为空时抛出异常
- Supplier不支持时使用默认OpenAI实现
性能优化
1. 模型实例缓存
- 使用Caffeine本地缓存
- 避免重复创建相同配置的模型
- 懒加载机制
2. 懒加载Cache
3. Listener分离
- 不缓存Listener
- 每次请求创建独立的Listener
- 避免线程安全问题

