You need to sign in before continuing.
Commit 0ed098fff2617fadfe96a4de41c9114ea1fca368
1 parent
38cc822b
添加未清选择 改成动态引导语
Showing
12 changed files
with
250 additions
and
542 deletions
pom.xml
| @@ -18,228 +18,115 @@ | @@ -18,228 +18,115 @@ | ||
| 18 | <packaging>war</packaging> | 18 | <packaging>war</packaging> |
| 19 | <name>xlyAi</name> | 19 | <name>xlyAi</name> |
| 20 | <description>xlyAi</description> | 20 | <description>xlyAi</description> |
| 21 | + | ||
| 21 | <properties> | 22 | <properties> |
| 22 | <java.version>17</java.version> | 23 | <java.version>17</java.version> |
| 23 | <mybatis-spring.version>3.0.4</mybatis-spring.version> | 24 | <mybatis-spring.version>3.0.4</mybatis-spring.version> |
| 24 | <pagehelper.version>2.1.0</pagehelper.version> | 25 | <pagehelper.version>2.1.0</pagehelper.version> |
| 25 | <mapstruct.version>1.5.5.Final</mapstruct.version> | 26 | <mapstruct.version>1.5.5.Final</mapstruct.version> |
| 26 | <fastjson.version>2.0.50</fastjson.version> | 27 | <fastjson.version>2.0.50</fastjson.version> |
| 27 | - <jsoup.version>2.0.50</jsoup.version> | ||
| 28 | - <langchain4j.version>0.35.0</langchain4j.version> | ||
| 29 | - <!-- AI 服务商 SDK 版本 --> | ||
| 30 | - <openai-java.version>0.20.0</openai-java.version> | ||
| 31 | - <anthropic-sdk.version>1.7.4</anthropic-sdk.version> | ||
| 32 | - <!-- 工具类 --> | 28 | + <langchain4j.version>1.14.0</langchain4j.version> |
| 29 | + <langchain4j-emb.version>1.14.0-beta24</langchain4j-emb.version> | ||
| 33 | <lombok.version>1.18.34</lombok.version> | 30 | <lombok.version>1.18.34</lombok.version> |
| 34 | <hutool.version>5.8.28</hutool.version> | 31 | <hutool.version>5.8.28</hutool.version> |
| 35 | <okhttp.version>4.10.0</okhttp.version> | 32 | <okhttp.version>4.10.0</okhttp.version> |
| 36 | <springdoc.version>2.5.0</springdoc.version> | 33 | <springdoc.version>2.5.0</springdoc.version> |
| 37 | - <mapstruct.version>1.5.5.Final</mapstruct.version> | ||
| 38 | - <!-- JSON 处理 --> | ||
| 39 | <jackson.version>2.17.2</jackson.version> | 34 | <jackson.version>2.17.2</jackson.version> |
| 40 | - <json-schema.version>1.17.2</json-schema.version> | ||
| 41 | - <!-- 向量数据 --> | ||
| 42 | <milvus.version>2.6.15</milvus.version> | 35 | <milvus.version>2.6.15</milvus.version> |
| 43 | <tess4j.version>5.18.0</tess4j.version> | 36 | <tess4j.version>5.18.0</tess4j.version> |
| 37 | + <jakarta-validation.version>3.1.0</jakarta-validation.version> | ||
| 44 | </properties> | 38 | </properties> |
| 45 | 39 | ||
| 46 | <dependencies> | 40 | <dependencies> |
| 47 | - <!-- Spring Boot Starters --> | 41 | + <!-- Spring Boot --> |
| 48 | <dependency> | 42 | <dependency> |
| 49 | <groupId>org.springframework.boot</groupId> | 43 | <groupId>org.springframework.boot</groupId> |
| 50 | <artifactId>spring-boot-starter-web</artifactId> | 44 | <artifactId>spring-boot-starter-web</artifactId> |
| 51 | </dependency> | 45 | </dependency> |
| 52 | - | ||
| 53 | - <!-- Milvus Java SDK 核心依赖 --> | ||
| 54 | - <dependency> | ||
| 55 | - <groupId>io.milvus</groupId> | ||
| 56 | - <artifactId>milvus-sdk-java</artifactId> | ||
| 57 | - <version>${milvus.version}</version> | ||
| 58 | - </dependency> | ||
| 59 | - | ||
| 60 | - <dependency> | ||
| 61 | - <groupId>dev.langchain4j</groupId> | ||
| 62 | - <artifactId>langchain4j-embeddings-all-minilm-l6-v2</artifactId> | ||
| 63 | - <version>${langchain4j.version}</version> | ||
| 64 | - </dependency> | ||
| 65 | - | ||
| 66 | -<!-- <dependency>--> | ||
| 67 | -<!-- <groupId>com.baomidou</groupId>--> | ||
| 68 | -<!-- <artifactId>mybatis-plus-boot-starter</artifactId>--> | ||
| 69 | -<!-- <version>3.5.3.1</version>--> | ||
| 70 | -<!-- </dependency>--> | ||
| 71 | - | ||
| 72 | <dependency> | 46 | <dependency> |
| 73 | <groupId>org.springframework.boot</groupId> | 47 | <groupId>org.springframework.boot</groupId> |
| 74 | <artifactId>spring-boot-starter-actuator</artifactId> | 48 | <artifactId>spring-boot-starter-actuator</artifactId> |
| 75 | </dependency> | 49 | </dependency> |
| 76 | - | ||
| 77 | <dependency> | 50 | <dependency> |
| 78 | <groupId>org.springframework.boot</groupId> | 51 | <groupId>org.springframework.boot</groupId> |
| 79 | <artifactId>spring-boot-starter-validation</artifactId> | 52 | <artifactId>spring-boot-starter-validation</artifactId> |
| 80 | </dependency> | 53 | </dependency> |
| 81 | <dependency> | 54 | <dependency> |
| 82 | - <groupId>com.alibaba</groupId> | ||
| 83 | - <artifactId>fastjson</artifactId> | ||
| 84 | - <version>2.0.47</version> <!-- 最新稳定版 --> | ||
| 85 | - </dependency> | ||
| 86 | - <dependency> | ||
| 87 | <groupId>org.springframework.boot</groupId> | 55 | <groupId>org.springframework.boot</groupId> |
| 88 | <artifactId>spring-boot-starter-aop</artifactId> | 56 | <artifactId>spring-boot-starter-aop</artifactId> |
| 89 | </dependency> | 57 | </dependency> |
| 90 | - | ||
| 91 | - <dependency> | ||
| 92 | - <groupId>com.google.code.gson</groupId> | ||
| 93 | - <artifactId>gson</artifactId> | ||
| 94 | - <version>2.10.1</version> | ||
| 95 | - </dependency> | ||
| 96 | - | ||
| 97 | - <!-- Spring Cloud Context 依赖 --> | ||
| 98 | - <dependency> | ||
| 99 | - <groupId>org.springframework.cloud</groupId> | ||
| 100 | - <artifactId>spring-cloud-context</artifactId> | ||
| 101 | - <version>4.1.0</version> <!-- 根据你的Spring Boot版本选择 --> | ||
| 102 | - </dependency> | ||
| 103 | - | ||
| 104 | <dependency> | 58 | <dependency> |
| 105 | <groupId>org.springframework.boot</groupId> | 59 | <groupId>org.springframework.boot</groupId> |
| 106 | - <artifactId>spring-boot-starter-webflux</artifactId> | ||
| 107 | - </dependency> | ||
| 108 | - <!-- pom.xml --> | ||
| 109 | - <dependency> | ||
| 110 | - <groupId>com.github.jsqlparser</groupId> | ||
| 111 | - <artifactId>jsqlparser</artifactId> | ||
| 112 | - <version>4.9</version> | ||
| 113 | - </dependency> | ||
| 114 | - | ||
| 115 | - <!-- Tess4J OCR --> | ||
| 116 | - <dependency> | ||
| 117 | - <groupId>net.sourceforge.tess4j</groupId> | ||
| 118 | - <artifactId>tess4j</artifactId> | ||
| 119 | - <version>${tess4j.version}</version> | ||
| 120 | - </dependency> | ||
| 121 | - | ||
| 122 | - <!-- 官方 PaddleOCR Java SDK(最新稳定版) --> | ||
| 123 | - <dependency> | ||
| 124 | - <groupId>io.github.mymonstercat</groupId> | ||
| 125 | - <artifactId>rapidocr</artifactId> | ||
| 126 | - <version>0.0.7</version> | 60 | + <artifactId>spring-boot-starter-thymeleaf</artifactId> |
| 127 | </dependency> | 61 | </dependency> |
| 128 | - | ||
| 129 | <dependency> | 62 | <dependency> |
| 130 | - <groupId>io.github.mymonstercat</groupId> | ||
| 131 | - <artifactId>rapidocr-onnx-platform</artifactId> | ||
| 132 | - <version>0.0.7</version> | 63 | + <groupId>org.springframework.boot</groupId> |
| 64 | + <artifactId>spring-boot-starter-data-redis</artifactId> | ||
| 133 | </dependency> | 65 | </dependency> |
| 134 | - | ||
| 135 | - <!-- ONNX Runtime(必需) --> | ||
| 136 | -<!-- <dependency>--> | ||
| 137 | -<!-- <groupId>com.microsoft.onnxruntime</groupId>--> | ||
| 138 | -<!-- <artifactId>onnxruntime</artifactId>--> | ||
| 139 | -<!-- <version>1.17.0</version>--> | ||
| 140 | -<!-- </dependency>--> | ||
| 141 | - | ||
| 142 | - <!-- 图片处理 --> | ||
| 143 | <dependency> | 66 | <dependency> |
| 144 | - <groupId>commons-io</groupId> | ||
| 145 | - <artifactId>commons-io</artifactId> | ||
| 146 | - <version>2.15.1</version> | 67 | + <groupId>org.apache.commons</groupId> |
| 68 | + <artifactId>commons-pool2</artifactId> | ||
| 147 | </dependency> | 69 | </dependency> |
| 148 | - | ||
| 149 | - | ||
| 150 | <dependency> | 70 | <dependency> |
| 151 | <groupId>org.springframework.boot</groupId> | 71 | <groupId>org.springframework.boot</groupId> |
| 152 | - <artifactId>spring-boot-starter-thymeleaf</artifactId> | 72 | + <artifactId>spring-boot-starter-webflux</artifactId> |
| 153 | </dependency> | 73 | </dependency> |
| 154 | <dependency> | 74 | <dependency> |
| 155 | <groupId>org.springframework.boot</groupId> | 75 | <groupId>org.springframework.boot</groupId> |
| 156 | - <artifactId>spring-boot-starter-data-redis</artifactId> | 76 | + <artifactId>spring-boot-starter-test</artifactId> |
| 77 | + <scope>test</scope> | ||
| 157 | </dependency> | 78 | </dependency> |
| 158 | - <!-- 如果需要连接池,可以引入 commons-pool2 (可选) --> | ||
| 159 | <dependency> | 79 | <dependency> |
| 160 | - <groupId>org.apache.commons</groupId> | ||
| 161 | - <artifactId>commons-pool2</artifactId> | 80 | + <groupId>org.springframework.boot</groupId> |
| 81 | + <artifactId>spring-boot-devtools</artifactId> | ||
| 82 | + <optional>true</optional> | ||
| 162 | </dependency> | 83 | </dependency> |
| 163 | 84 | ||
| 164 | - <!-- MyBatis --> | 85 | + <!-- 数据库 & MyBatis --> |
| 165 | <dependency> | 86 | <dependency> |
| 166 | <groupId>org.mybatis.spring.boot</groupId> | 87 | <groupId>org.mybatis.spring.boot</groupId> |
| 167 | <artifactId>mybatis-spring-boot-starter</artifactId> | 88 | <artifactId>mybatis-spring-boot-starter</artifactId> |
| 168 | <version>${mybatis-spring.version}</version> | 89 | <version>${mybatis-spring.version}</version> |
| 169 | </dependency> | 90 | </dependency> |
| 170 | - | ||
| 171 | - <!-- 数据库 --> | ||
| 172 | <dependency> | 91 | <dependency> |
| 173 | <groupId>com.mysql</groupId> | 92 | <groupId>com.mysql</groupId> |
| 174 | <artifactId>mysql-connector-j</artifactId> | 93 | <artifactId>mysql-connector-j</artifactId> |
| 175 | <scope>runtime</scope> | 94 | <scope>runtime</scope> |
| 176 | </dependency> | 95 | </dependency> |
| 177 | - | ||
| 178 | - <!-- 连接池(Spring Boot 3.x 默认包含 HikariCP) --> | ||
| 179 | <dependency> | 96 | <dependency> |
| 180 | <groupId>com.zaxxer</groupId> | 97 | <groupId>com.zaxxer</groupId> |
| 181 | <artifactId>HikariCP</artifactId> | 98 | <artifactId>HikariCP</artifactId> |
| 182 | </dependency> | 99 | </dependency> |
| 183 | - | ||
| 184 | - <!-- 分页插件 --> | ||
| 185 | <dependency> | 100 | <dependency> |
| 186 | <groupId>com.github.pagehelper</groupId> | 101 | <groupId>com.github.pagehelper</groupId> |
| 187 | <artifactId>pagehelper-spring-boot-starter</artifactId> | 102 | <artifactId>pagehelper-spring-boot-starter</artifactId> |
| 188 | <version>${pagehelper.version}</version> | 103 | <version>${pagehelper.version}</version> |
| 189 | </dependency> | 104 | </dependency> |
| 190 | 105 | ||
| 191 | - <!-- Maven依赖 --> | ||
| 192 | - <dependency> | ||
| 193 | - <groupId>org.jsoup</groupId> | ||
| 194 | - <artifactId>jsoup</artifactId> | ||
| 195 | - <version>${json-schema.version}</version> | ||
| 196 | - </dependency> | ||
| 197 | - | ||
| 198 | <!-- 工具类 --> | 106 | <!-- 工具类 --> |
| 199 | <dependency> | 107 | <dependency> |
| 200 | <groupId>org.projectlombok</groupId> | 108 | <groupId>org.projectlombok</groupId> |
| 201 | <artifactId>lombok</artifactId> | 109 | <artifactId>lombok</artifactId> |
| 202 | <optional>true</optional> | 110 | <optional>true</optional> |
| 203 | </dependency> | 111 | </dependency> |
| 204 | - | ||
| 205 | <dependency> | 112 | <dependency> |
| 206 | <groupId>cn.hutool</groupId> | 113 | <groupId>cn.hutool</groupId> |
| 207 | <artifactId>hutool-all</artifactId> | 114 | <artifactId>hutool-all</artifactId> |
| 208 | <version>${hutool.version}</version> | 115 | <version>${hutool.version}</version> |
| 209 | </dependency> | 116 | </dependency> |
| 210 | - | ||
| 211 | <dependency> | 117 | <dependency> |
| 212 | - <groupId>cglib</groupId> | ||
| 213 | - <artifactId>cglib</artifactId> | ||
| 214 | - <version>3.3.0</version> | ||
| 215 | - </dependency> | ||
| 216 | - <!-- pom.xml --> | ||
| 217 | - <dependency> | ||
| 218 | - <groupId>org.codehaus.groovy</groupId> | ||
| 219 | - <artifactId>groovy</artifactId> | ||
| 220 | - <version>3.0.20</version> <!-- 或者 4.0.0+ --> | ||
| 221 | - </dependency> | ||
| 222 | - | ||
| 223 | - <!-- 如果需要 Groovy 编译支持 --> | ||
| 224 | - <dependency> | ||
| 225 | - <groupId>org.codehaus.groovy</groupId> | ||
| 226 | - <artifactId>groovy-all</artifactId> | ||
| 227 | - <version>3.0.20</version> | ||
| 228 | - <type>pom</type> | 118 | + <groupId>com.google.code.gson</groupId> |
| 119 | + <artifactId>gson</artifactId> | ||
| 229 | </dependency> | 120 | </dependency> |
| 230 | - | ||
| 231 | - <!-- MapStruct --> | ||
| 232 | <dependency> | 121 | <dependency> |
| 233 | - <groupId>org.mapstruct</groupId> | ||
| 234 | - <artifactId>mapstruct</artifactId> | ||
| 235 | - <version>${mapstruct.version}</version> | 122 | + <groupId>commons-io</groupId> |
| 123 | + <artifactId>commons-io</artifactId> | ||
| 124 | + <version>2.15.1</version> | ||
| 236 | </dependency> | 125 | </dependency> |
| 237 | - | ||
| 238 | <dependency> | 126 | <dependency> |
| 239 | - <groupId>org.mapstruct</groupId> | ||
| 240 | - <artifactId>mapstruct-processor</artifactId> | ||
| 241 | - <version>${mapstruct.version}</version> | ||
| 242 | - <scope>provided</scope> | 127 | + <groupId>com.squareup.okhttp3</groupId> |
| 128 | + <artifactId>okhttp</artifactId> | ||
| 129 | + <version>${okhttp.version}</version> | ||
| 243 | </dependency> | 130 | </dependency> |
| 244 | 131 | ||
| 245 | <!-- JSON --> | 132 | <!-- JSON --> |
| @@ -248,72 +135,28 @@ | @@ -248,72 +135,28 @@ | ||
| 248 | <artifactId>fastjson2</artifactId> | 135 | <artifactId>fastjson2</artifactId> |
| 249 | <version>${fastjson.version}</version> | 136 | <version>${fastjson.version}</version> |
| 250 | </dependency> | 137 | </dependency> |
| 251 | - | ||
| 252 | - <!-- 测试 --> | ||
| 253 | - <dependency> | ||
| 254 | - <groupId>org.springframework.boot</groupId> | ||
| 255 | - <artifactId>spring-boot-starter-test</artifactId> | ||
| 256 | - <scope>test</scope> | ||
| 257 | - </dependency> | ||
| 258 | -<!-- <dependency>--> | ||
| 259 | -<!-- <groupId>org.springframework.boot</groupId>--> | ||
| 260 | -<!-- <artifactId>spring-boot-starter-data-jpa</artifactId>--> | ||
| 261 | -<!-- </dependency>--> | ||
| 262 | - | ||
| 263 | - <!-- OpenAPI 3 UI (包含所有必要依赖) --> | ||
| 264 | <dependency> | 138 | <dependency> |
| 265 | - <groupId>org.springdoc</groupId> | ||
| 266 | - <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> | ||
| 267 | - <version>${springdoc.version}</version> | 139 | + <groupId>com.fasterxml.jackson.core</groupId> |
| 140 | + <artifactId>jackson-databind</artifactId> | ||
| 141 | + <version>${jackson.version}</version> | ||
| 268 | </dependency> | 142 | </dependency> |
| 269 | - | ||
| 270 | - <!-- Swagger 注解 --> | ||
| 271 | <dependency> | 143 | <dependency> |
| 272 | - <groupId>io.swagger.core.v3</groupId> | ||
| 273 | - <artifactId>swagger-annotations</artifactId> | ||
| 274 | - <version>2.2.20</version> | 144 | + <groupId>com.fasterxml.jackson.core</groupId> |
| 145 | + <artifactId>jackson-core</artifactId> | ||
| 146 | + <version>${jackson.version}</version> | ||
| 275 | </dependency> | 147 | </dependency> |
| 276 | - | ||
| 277 | - <!-- 开发工具 --> | ||
| 278 | <dependency> | 148 | <dependency> |
| 279 | - <groupId>org.springframework.boot</groupId> | ||
| 280 | - <artifactId>spring-boot-devtools</artifactId> | ||
| 281 | - <optional>true</optional> | 149 | + <groupId>com.fasterxml.jackson.core</groupId> |
| 150 | + <artifactId>jackson-annotations</artifactId> | ||
| 151 | + <version>${jackson.version}</version> | ||
| 282 | </dependency> | 152 | </dependency> |
| 283 | - | ||
| 284 | - <!-- 中文分词 --> | ||
| 285 | <dependency> | 153 | <dependency> |
| 286 | - <groupId>com.huaban</groupId> | ||
| 287 | - <artifactId>jieba-analysis</artifactId> | ||
| 288 | - <version>1.0.2</version> | 154 | + <groupId>com.fasterxml.jackson.datatype</groupId> |
| 155 | + <artifactId>jackson-datatype-jsr310</artifactId> | ||
| 156 | + <version>${jackson.version}</version> | ||
| 289 | </dependency> | 157 | </dependency> |
| 290 | 158 | ||
| 291 | - <!-- 向量数据库 --> | ||
| 292 | -<!-- <dependency>--> | ||
| 293 | -<!-- <groupId>io.weaviate</groupId>--> | ||
| 294 | -<!-- <artifactId>client</artifactId>--> | ||
| 295 | -<!-- <version>${weaviate.version}</version>--> | ||
| 296 | -<!-- </dependency>--> | ||
| 297 | - <!--向量存储 --> | ||
| 298 | - <!-- <dependency>--> | ||
| 299 | - <!-- <groupId>dev.langchain4j</groupId>--> | ||
| 300 | - <!-- <artifactId>langchain4j-chroma</artifactId>--> | ||
| 301 | - <!-- <version>${langchain4j.version}</version>--> | ||
| 302 | - <!-- </dependency>--> | ||
| 303 | - <!-- 内存管理 --> | ||
| 304 | - <!-- <dependency>--> | ||
| 305 | - <!-- <groupId>dev.langchain4j</groupId>--> | ||
| 306 | - <!-- <artifactId>langchain4j-memory</artifactId>--> | ||
| 307 | - <!-- <version>${langchain4j.version}</version>--> | ||
| 308 | - <!-- </dependency>--> | ||
| 309 | - | ||
| 310 | - <!-- 专为向量相似度搜索设计 向量数据库 --> | ||
| 311 | - <!-- <dependency>--> | ||
| 312 | - <!-- <groupId>io.qdrant</groupId>--> | ||
| 313 | - <!-- <artifactId>qdrant-java</artifactId>--> | ||
| 314 | - <!-- <version>1.7.0</version>--> | ||
| 315 | - <!-- </dependency>--> | ||
| 316 | - <!-- 支持的文件格式 --> | 159 | + <!-- 文档处理 --> |
| 317 | <dependency> | 160 | <dependency> |
| 318 | <groupId>org.apache.tika</groupId> | 161 | <groupId>org.apache.tika</groupId> |
| 319 | <artifactId>tika-core</artifactId> | 162 | <artifactId>tika-core</artifactId> |
| @@ -330,183 +173,137 @@ | @@ -330,183 +173,137 @@ | ||
| 330 | <version>5.2.5</version> | 173 | <version>5.2.5</version> |
| 331 | </dependency> | 174 | </dependency> |
| 332 | 175 | ||
| 333 | - <!-- 可选:文档处理 --> | 176 | + <!-- OCR --> |
| 334 | <dependency> | 177 | <dependency> |
| 335 | - <groupId>com.fasterxml.jackson.core</groupId> | ||
| 336 | - <artifactId>jackson-databind</artifactId> | 178 | + <groupId>net.sourceforge.tess4j</groupId> |
| 179 | + <artifactId>tess4j</artifactId> | ||
| 180 | + <version>${tess4j.version}</version> | ||
| 337 | </dependency> | 181 | </dependency> |
| 338 | - <!-- 注入--> | ||
| 339 | <dependency> | 182 | <dependency> |
| 340 | - <groupId>javax.annotation</groupId> | ||
| 341 | - <artifactId>javax.annotation-api</artifactId> | ||
| 342 | - <version>1.3.2</version> | 183 | + <groupId>io.github.mymonstercat</groupId> |
| 184 | + <artifactId>rapidocr</artifactId> | ||
| 185 | + <version>0.0.7</version> | ||
| 343 | </dependency> | 186 | </dependency> |
| 344 | - | ||
| 345 | <dependency> | 187 | <dependency> |
| 346 | - <groupId>jakarta.persistence</groupId> | ||
| 347 | - <artifactId>jakarta.persistence-api</artifactId> | ||
| 348 | - <version>3.1.0</version> | 188 | + <groupId>io.github.mymonstercat</groupId> |
| 189 | + <artifactId>rapidocr-onnx-platform</artifactId> | ||
| 190 | + <version>0.0.7</version> | ||
| 349 | </dependency> | 191 | </dependency> |
| 350 | 192 | ||
| 351 | - <!-- ========== LangChain4j 1.10.0 ========== --> | ||
| 352 | - <!-- 核心库 --> | 193 | + <!-- 向量数据库 --> |
| 353 | <dependency> | 194 | <dependency> |
| 354 | - <groupId>dev.langchain4j</groupId> | ||
| 355 | - <artifactId>langchain4j-core</artifactId> | ||
| 356 | - <version>${langchain4j.version}</version> | 195 | + <groupId>io.milvus</groupId> |
| 196 | + <artifactId>milvus-sdk-java</artifactId> | ||
| 197 | + <version>${milvus.version}</version> | ||
| 357 | </dependency> | 198 | </dependency> |
| 358 | 199 | ||
| 359 | - | 200 | + <!-- LangChain4j 核心 + Ollama --> |
| 360 | <dependency> | 201 | <dependency> |
| 361 | <groupId>dev.langchain4j</groupId> | 202 | <groupId>dev.langchain4j</groupId> |
| 362 | <artifactId>langchain4j</artifactId> | 203 | <artifactId>langchain4j</artifactId> |
| 363 | <version>${langchain4j.version}</version> | 204 | <version>${langchain4j.version}</version> |
| 364 | </dependency> | 205 | </dependency> |
| 365 | - | ||
| 366 | <dependency> | 206 | <dependency> |
| 367 | <groupId>dev.langchain4j</groupId> | 207 | <groupId>dev.langchain4j</groupId> |
| 368 | <artifactId>langchain4j-ollama</artifactId> | 208 | <artifactId>langchain4j-ollama</artifactId> |
| 369 | <version>${langchain4j.version}</version> | 209 | <version>${langchain4j.version}</version> |
| 370 | </dependency> | 210 | </dependency> |
| 371 | - | ||
| 372 | - | ||
| 373 | - | ||
| 374 | - | ||
| 375 | - <!-- 或者使用 Apache Tika 直接 --> | ||
| 376 | - <dependency> | ||
| 377 | - <groupId>org.apache.tika</groupId> | ||
| 378 | - <artifactId>tika-core</artifactId> | ||
| 379 | - <version>2.9.1</version> | ||
| 380 | - </dependency> | ||
| 381 | - | ||
| 382 | <dependency> | 211 | <dependency> |
| 383 | - <groupId>org.apache.tika</groupId> | ||
| 384 | - <artifactId>tika-parsers-standard-package</artifactId> | ||
| 385 | - <version>2.9.1</version> | ||
| 386 | - </dependency> | ||
| 387 | - | ||
| 388 | - | ||
| 389 | - <!-- Spring Retry --> | ||
| 390 | - <dependency> | ||
| 391 | - <groupId>org.springframework.retry</groupId> | ||
| 392 | - <artifactId>spring-retry</artifactId> | ||
| 393 | - <version>2.0.5</version> <!-- 最新版本,根据Spring版本调整 --> | ||
| 394 | - </dependency> | ||
| 395 | - | ||
| 396 | - <!-- Spring AOP (必需) --> | ||
| 397 | - <dependency> | ||
| 398 | - <groupId>org.springframework</groupId> | ||
| 399 | - <artifactId>spring-aspects</artifactId> | ||
| 400 | - <version>5.3.30</version> <!-- 与你的Spring版本保持一致 --> | ||
| 401 | - </dependency> | ||
| 402 | - | ||
| 403 | - <dependency> | ||
| 404 | - <groupId>com.microsoft.cognitiveservices.speech</groupId> | ||
| 405 | - <artifactId>client-sdk</artifactId> | ||
| 406 | - <version>1.37.0</version> | ||
| 407 | - <scope>compile</scope> | 212 | + <groupId>dev.langchain4j</groupId> |
| 213 | + <artifactId>langchain4j-embeddings-all-minilm-l6-v2</artifactId> | ||
| 214 | + <version>${langchain4j-emb.version}</version> | ||
| 408 | </dependency> | 215 | </dependency> |
| 409 | 216 | ||
| 410 | - <!-- ========== 验证框架 ========== --> | 217 | + <!-- 分词 --> |
| 411 | <dependency> | 218 | <dependency> |
| 412 | - <groupId>jakarta.validation</groupId> | ||
| 413 | - <artifactId>jakarta.validation-api</artifactId> | ||
| 414 | - <version>${jakarta-validation.version}</version> | 219 | + <groupId>com.huaban</groupId> |
| 220 | + <artifactId>jieba-analysis</artifactId> | ||
| 221 | + <version>1.0.2</version> | ||
| 415 | </dependency> | 222 | </dependency> |
| 416 | 223 | ||
| 224 | + <!-- 接口文档 --> | ||
| 417 | <dependency> | 225 | <dependency> |
| 418 | - <groupId>org.glassfish</groupId> | ||
| 419 | - <artifactId>jakarta.el</artifactId> | ||
| 420 | - <version>4.0.2</version> | 226 | + <groupId>org.springdoc</groupId> |
| 227 | + <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> | ||
| 228 | + <version>${springdoc.version}</version> | ||
| 421 | </dependency> | 229 | </dependency> |
| 422 | 230 | ||
| 423 | - <!-- ========== JSON 处理 ========== --> | 231 | + <!-- MapStruct --> |
| 424 | <dependency> | 232 | <dependency> |
| 425 | - <groupId>com.fasterxml.jackson.core</groupId> | ||
| 426 | - <artifactId>jackson-databind</artifactId> | ||
| 427 | - <version>${jackson.version}</version> | 233 | + <groupId>org.mapstruct</groupId> |
| 234 | + <artifactId>mapstruct</artifactId> | ||
| 235 | + <version>${mapstruct.version}</version> | ||
| 428 | </dependency> | 236 | </dependency> |
| 429 | 237 | ||
| 238 | + <!-- 其他工具 --> | ||
| 430 | <dependency> | 239 | <dependency> |
| 431 | - <groupId>com.fasterxml.jackson.core</groupId> | ||
| 432 | - <artifactId>jackson-core</artifactId> | ||
| 433 | - <version>${jackson.version}</version> | 240 | + <groupId>com.github.jsqlparser</groupId> |
| 241 | + <artifactId>jsqlparser</artifactId> | ||
| 242 | + <version>4.9</version> | ||
| 434 | </dependency> | 243 | </dependency> |
| 435 | - | ||
| 436 | <dependency> | 244 | <dependency> |
| 437 | - <groupId>com.fasterxml.jackson.core</groupId> | ||
| 438 | - <artifactId>jackson-annotations</artifactId> | ||
| 439 | - <version>${jackson.version}</version> | 245 | + <groupId>org.jsoup</groupId> |
| 246 | + <artifactId>jsoup</artifactId> | ||
| 247 | + <version>1.17.2</version> | ||
| 440 | </dependency> | 248 | </dependency> |
| 441 | 249 | ||
| 250 | + <!-- 删掉这两个错误的 --> | ||
| 442 | <dependency> | 251 | <dependency> |
| 443 | - <groupId>com.fasterxml.jackson.datatype</groupId> | ||
| 444 | - <artifactId>jackson-datatype-jsr310</artifactId> | ||
| 445 | - <version>${jackson.version}</version> | 252 | + <groupId>org.codehaus.groovy</groupId> |
| 253 | + <artifactId>groovy</artifactId> | ||
| 254 | + <version>3.0.20</version> | ||
| 446 | </dependency> | 255 | </dependency> |
| 447 | - | ||
| 448 | - | ||
| 449 | - <!-- Jackson 数据绑定(最常用) --> | ||
| 450 | <dependency> | 256 | <dependency> |
| 451 | - <groupId>com.fasterxml.jackson.core</groupId> | ||
| 452 | - <artifactId>jackson-databind</artifactId> | ||
| 453 | - <version>${jackson.version}</version> | 257 | + <groupId>org.codehaus.groovy</groupId> |
| 258 | + <artifactId>groovy-all</artifactId> | ||
| 259 | + <version>3.0.20</version> | ||
| 260 | + <type>pom</type> | ||
| 454 | </dependency> | 261 | </dependency> |
| 455 | 262 | ||
| 456 | - <!-- Jackson 注解支持 --> | 263 | + <!-- 正确的 Fastjson2 --> |
| 457 | <dependency> | 264 | <dependency> |
| 458 | - <groupId>com.fasterxml.jackson.core</groupId> | ||
| 459 | - <artifactId>jackson-annotations</artifactId> | ||
| 460 | - <version>${jackson.version}</version> | 265 | + <groupId>com.alibaba.fastjson2</groupId> |
| 266 | + <artifactId>fastjson2</artifactId> | ||
| 267 | + <version>2.0.50</version> | ||
| 461 | </dependency> | 268 | </dependency> |
| 462 | 269 | ||
| 463 | - <!-- ========== 工具类 ========== --> | 270 | + <!-- Spring Data JPA 核心依赖(自动包含 jakarta.persistence 包) --> |
| 464 | <dependency> | 271 | <dependency> |
| 465 | - <groupId>org.projectlombok</groupId> | ||
| 466 | - <artifactId>lombok</artifactId> | ||
| 467 | - <version>${lombok.version}</version> | ||
| 468 | - <optional>true</optional> | 272 | + <groupId>org.springframework.boot</groupId> |
| 273 | + <artifactId>spring-boot-starter-data-jpa</artifactId> | ||
| 469 | </dependency> | 274 | </dependency> |
| 470 | 275 | ||
| 276 | + <!-- 数据库驱动(以 MySQL 为例,根据你的数据库替换) --> | ||
| 471 | <dependency> | 277 | <dependency> |
| 472 | - <groupId>org.mapstruct</groupId> | ||
| 473 | - <artifactId>mapstruct</artifactId> | ||
| 474 | - <version>${mapstruct.version}</version> | 278 | + <groupId>com.mysql</groupId> |
| 279 | + <artifactId>mysql-connector-j</artifactId> | ||
| 280 | + <scope>runtime</scope> | ||
| 475 | </dependency> | 281 | </dependency> |
| 476 | 282 | ||
| 477 | <dependency> | 283 | <dependency> |
| 478 | - <groupId>org.mapstruct</groupId> | ||
| 479 | - <artifactId>mapstruct-processor</artifactId> | ||
| 480 | - <version>${mapstruct.version}</version> | ||
| 481 | - <scope>provided</scope> | 284 | + <groupId>com.github.jnr</groupId> |
| 285 | + <artifactId>jnr-ffi</artifactId> | ||
| 286 | + <version>2.2.15</version> <!-- 稳定版 --> | ||
| 482 | </dependency> | 287 | </dependency> |
| 483 | - | ||
| 484 | <dependency> | 288 | <dependency> |
| 485 | - <groupId>com.squareup.okhttp3</groupId> | ||
| 486 | - <artifactId>okhttp</artifactId> | ||
| 487 | - <version>${okhttp.version}</version> <!-- 使用最新版本 --> | 289 | + <groupId>jakarta.annotation</groupId> |
| 290 | + <artifactId>jakarta.annotation-api</artifactId> | ||
| 291 | + <version>2.1.1</version> | ||
| 488 | </dependency> | 292 | </dependency> |
| 489 | - | ||
| 490 | - <!-- Edge-TTS Python执行相关 --> | ||
| 491 | <dependency> | 293 | <dependency> |
| 492 | - <groupId>org.python</groupId> | ||
| 493 | - <artifactId>jython-standalone</artifactId> | ||
| 494 | - <version>2.7.3</version> | 294 | + <groupId>org.springframework.retry</groupId> |
| 295 | + <artifactId>spring-retry</artifactId> | ||
| 495 | </dependency> | 296 | </dependency> |
| 496 | 297 | ||
| 497 | - <!-- 工具类 --> | 298 | + <!-- 必须加:Spring Retry 需要 AOP 依赖 --> |
| 498 | <dependency> | 299 | <dependency> |
| 499 | - <groupId>org.apache.commons</groupId> | ||
| 500 | - <artifactId>commons-exec</artifactId> | ||
| 501 | - <version>1.3</version> | 300 | + <groupId>org.springframework.boot</groupId> |
| 301 | + <artifactId>spring-boot-starter-aop</artifactId> | ||
| 502 | </dependency> | 302 | </dependency> |
| 503 | - | ||
| 504 | - | ||
| 505 | </dependencies> | 303 | </dependencies> |
| 304 | + | ||
| 506 | <build> | 305 | <build> |
| 507 | <finalName>xlyAi</finalName> | 306 | <finalName>xlyAi</finalName> |
| 508 | - | ||
| 509 | - <!-- 添加资源目录 --> | ||
| 510 | <resources> | 307 | <resources> |
| 511 | <resource> | 308 | <resource> |
| 512 | <directory>src/main/resources</directory> | 309 | <directory>src/main/resources</directory> |
| @@ -518,7 +315,6 @@ | @@ -518,7 +315,6 @@ | ||
| 518 | </resources> | 315 | </resources> |
| 519 | 316 | ||
| 520 | <plugins> | 317 | <plugins> |
| 521 | - <!-- 编译插件 --> | ||
| 522 | <plugin> | 318 | <plugin> |
| 523 | <groupId>org.apache.maven.plugins</groupId> | 319 | <groupId>org.apache.maven.plugins</groupId> |
| 524 | <artifactId>maven-compiler-plugin</artifactId> | 320 | <artifactId>maven-compiler-plugin</artifactId> |
| @@ -533,14 +329,14 @@ | @@ -533,14 +329,14 @@ | ||
| 533 | <artifactId>lombok</artifactId> | 329 | <artifactId>lombok</artifactId> |
| 534 | <version>${lombok.version}</version> | 330 | <version>${lombok.version}</version> |
| 535 | </path> | 331 | </path> |
| 332 | + <path> | ||
| 333 | + <groupId>org.mapstruct</groupId> | ||
| 334 | + <artifactId>mapstruct-processor</artifactId> | ||
| 335 | + <version>${mapstruct.version}</version> | ||
| 336 | + </path> | ||
| 536 | </annotationProcessorPaths> | 337 | </annotationProcessorPaths> |
| 537 | - <!-- 详细输出 --> | ||
| 538 | - <verbose>true</verbose> | ||
| 539 | - <showWarnings>true</showWarnings> | ||
| 540 | </configuration> | 338 | </configuration> |
| 541 | </plugin> | 339 | </plugin> |
| 542 | - | ||
| 543 | - <!-- Spring Boot 插件 --> | ||
| 544 | <plugin> | 340 | <plugin> |
| 545 | <groupId>org.springframework.boot</groupId> | 341 | <groupId>org.springframework.boot</groupId> |
| 546 | <artifactId>spring-boot-maven-plugin</artifactId> | 342 | <artifactId>spring-boot-maven-plugin</artifactId> |
src/main/java/com/xly/config/ModelConfig.java
| @@ -5,12 +5,10 @@ import com.fasterxml.jackson.databind.SerializationFeature; | @@ -5,12 +5,10 @@ import com.fasterxml.jackson.databind.SerializationFeature; | ||
| 5 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; | 5 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; |
| 6 | import com.xly.agent.DynamicTableNl2SqlAiAgent; | 6 | import com.xly.agent.DynamicTableNl2SqlAiAgent; |
| 7 | import com.xly.agent.SceneSelectorAiAgent; | 7 | import com.xly.agent.SceneSelectorAiAgent; |
| 8 | -import dev.langchain4j.memory.chat.MessageWindowChatMemory; | ||
| 9 | -import dev.langchain4j.model.chat.ChatLanguageModel; | ||
| 10 | -import dev.langchain4j.model.chat.StreamingChatLanguageModel; | ||
| 11 | import dev.langchain4j.model.ollama.OllamaChatModel; | 8 | import dev.langchain4j.model.ollama.OllamaChatModel; |
| 12 | import dev.langchain4j.model.ollama.OllamaStreamingChatModel; | 9 | import dev.langchain4j.model.ollama.OllamaStreamingChatModel; |
| 13 | import dev.langchain4j.service.AiServices; | 10 | import dev.langchain4j.service.AiServices; |
| 11 | +import dev.langchain4j.memory.chat.MessageWindowChatMemory; | ||
| 14 | import org.springframework.beans.factory.annotation.Qualifier; | 12 | import org.springframework.beans.factory.annotation.Qualifier; |
| 15 | import org.springframework.beans.factory.annotation.Value; | 13 | import org.springframework.beans.factory.annotation.Value; |
| 16 | import org.springframework.context.annotation.Bean; | 14 | import org.springframework.context.annotation.Bean; |
| @@ -19,111 +17,89 @@ import org.springframework.context.annotation.Primary; | @@ -19,111 +17,89 @@ import org.springframework.context.annotation.Primary; | ||
| 19 | 17 | ||
| 20 | import java.time.Duration; | 18 | import java.time.Duration; |
| 21 | 19 | ||
| 22 | -/** | ||
| 23 | - * 大模型初始化配置(单例复用,避免重复创建) | ||
| 24 | - */ | ||
| 25 | @Configuration | 20 | @Configuration |
| 26 | public class ModelConfig { | 21 | public class ModelConfig { |
| 27 | 22 | ||
| 28 | - | ||
| 29 | @Value("${langchain4j.ollama.base-url}") | 23 | @Value("${langchain4j.ollama.base-url}") |
| 30 | private String chatModelUrl; | 24 | private String chatModelUrl; |
| 31 | 25 | ||
| 32 | - @Value("${langchain4j.ollama.base-url}") | ||
| 33 | - private String sqlModelUrl; | ||
| 34 | - | ||
| 35 | @Value("${langchain4j.ollama.chat-model-name}") | 26 | @Value("${langchain4j.ollama.chat-model-name}") |
| 36 | private String chatModelName; | 27 | private String chatModelName; |
| 37 | 28 | ||
| 38 | @Value("${langchain4j.ollama.sql-model-name}") | 29 | @Value("${langchain4j.ollama.sql-model-name}") |
| 39 | private String sqlModelName; | 30 | private String sqlModelName; |
| 40 | 31 | ||
| 41 | - // 中文对话模型 qwen2.5:7b-instruct | 32 | + // ====================== 主对话模型 ====================== |
| 42 | @Bean | 33 | @Bean |
| 43 | @Primary | 34 | @Primary |
| 44 | public OllamaChatModel chatLanguageModel() { | 35 | public OllamaChatModel chatLanguageModel() { |
| 45 | return OllamaChatModel.builder() | 36 | return OllamaChatModel.builder() |
| 46 | .baseUrl(chatModelUrl) | 37 | .baseUrl(chatModelUrl) |
| 47 | - .modelName(chatModelName) // 使用聊天模型名称 | ||
| 48 | - .temperature(0.0) // 建议调整为0.0太确定 | ||
| 49 | - .topP(0.9) | ||
| 50 | -// .numPredict(2048) // 添加生成长度限制 | ||
| 51 | - .timeout(Duration.ofSeconds(60)) // 缩短超时时间 | 38 | + .modelName(chatModelName) |
| 39 | + .temperature(0.1) | ||
| 40 | + .topP(0.95) | ||
| 41 | + .timeout(Duration.ofSeconds(120)) | ||
| 52 | .maxRetries(2) | 42 | .maxRetries(2) |
| 43 | + .logRequests(true) | ||
| 44 | + .logResponses(true) | ||
| 53 | .build(); | 45 | .build(); |
| 54 | } | 46 | } |
| 55 | 47 | ||
| 56 | - /*** | ||
| 57 | - * @Author 钱豹 | ||
| 58 | - * @Date 13:25 2026/2/6 | ||
| 59 | - * @Param [] | ||
| 60 | - * @return dev.langchain4j.model.ollama.OllamaChatModel | ||
| 61 | - * @Description 聊天 | ||
| 62 | - **/ | 48 | + // ====================== 自由闲聊模型 ====================== |
| 63 | @Bean("chatiModel") | 49 | @Bean("chatiModel") |
| 64 | - public ChatLanguageModel chatiModel() { | 50 | + public OllamaChatModel chatiModel() { |
| 65 | return OllamaChatModel.builder() | 51 | return OllamaChatModel.builder() |
| 66 | .baseUrl(chatModelUrl) | 52 | .baseUrl(chatModelUrl) |
| 67 | - .modelName(chatModelName) // 使用聊天模型名称 | ||
| 68 | - .temperature(0.8) // 建议调整为0.8太确定 | 53 | + .modelName(chatModelName) |
| 54 | + .temperature(0.7) | ||
| 69 | .topP(0.9) | 55 | .topP(0.9) |
| 70 | -// .numPredict(2048) // 添加生成长度限制 | ||
| 71 | - .timeout(Duration.ofSeconds(60)) // 缩短超时时间 | 56 | + .timeout(Duration.ofSeconds(60)) |
| 72 | .maxRetries(2) | 57 | .maxRetries(2) |
| 73 | .build(); | 58 | .build(); |
| 74 | } | 59 | } |
| 75 | 60 | ||
| 76 | - // SQL/代码专用模型 qwen2.5-coder:14b | ||
| 77 | - @Bean("sqlChatModel") // 明确指定bean名称 | 61 | + // ====================== SQL 专用模型 ====================== |
| 62 | + @Bean("sqlChatModel") | ||
| 78 | public OllamaChatModel sqlChatModel() { | 63 | public OllamaChatModel sqlChatModel() { |
| 79 | return OllamaChatModel.builder() | 64 | return OllamaChatModel.builder() |
| 80 | - .baseUrl(sqlModelUrl) | ||
| 81 | - .modelName(sqlModelName) // 使用SQL模型名称 | 65 | + .baseUrl(chatModelUrl) |
| 66 | + .modelName(sqlModelName) | ||
| 82 | .temperature(0.0) | 67 | .temperature(0.0) |
| 83 | .topP(0.95) | 68 | .topP(0.95) |
| 84 | - .numPredict(4096) // 代码生成需要更长 | 69 | + .numPredict(4096) |
| 85 | .timeout(Duration.ofSeconds(120)) | 70 | .timeout(Duration.ofSeconds(120)) |
| 86 | .maxRetries(3) | 71 | .maxRetries(3) |
| 87 | -// .repeatPenalty(1.1) // 减少重复 | ||
| 88 | .build(); | 72 | .build(); |
| 89 | } | 73 | } |
| 90 | 74 | ||
| 91 | - /*** | ||
| 92 | - * @Author 钱豹 | ||
| 93 | - * @Date 22:53 2026/2/3 | ||
| 94 | - * @Param [] | ||
| 95 | - * @return dev.langchain4j.model.chat.StreamingChatLanguageModel | ||
| 96 | - * @Description 流式聊天模型 - 使用 @Primary | ||
| 97 | - **/ | 75 | + // ====================== 流式对话模型 ====================== |
| 98 | @Bean("streamingChatModel") | 76 | @Bean("streamingChatModel") |
| 99 | @Primary | 77 | @Primary |
| 100 | - public StreamingChatLanguageModel streamingChatModel() { | 78 | + public OllamaStreamingChatModel streamingChatModel() { |
| 101 | return OllamaStreamingChatModel.builder() | 79 | return OllamaStreamingChatModel.builder() |
| 102 | .baseUrl(chatModelUrl) | 80 | .baseUrl(chatModelUrl) |
| 103 | .modelName(chatModelName) | 81 | .modelName(chatModelName) |
| 104 | - .temperature(0.7) | 82 | + .temperature(0.3) |
| 105 | .topP(0.9) | 83 | .topP(0.9) |
| 106 | .numPredict(1024) | 84 | .numPredict(1024) |
| 107 | .timeout(Duration.ofSeconds(60)) | 85 | .timeout(Duration.ofSeconds(60)) |
| 108 | .build(); | 86 | .build(); |
| 109 | } | 87 | } |
| 110 | 88 | ||
| 111 | - // 流式SQL/代码模型 - 指定名称 | 89 | + // ====================== 流式 SQL 模型 ====================== |
| 112 | @Bean("streamingSqlModel") | 90 | @Bean("streamingSqlModel") |
| 113 | - public StreamingChatLanguageModel streamingSqlModel() { | 91 | + public OllamaStreamingChatModel streamingSqlModel() { |
| 114 | return OllamaStreamingChatModel.builder() | 92 | return OllamaStreamingChatModel.builder() |
| 115 | - .baseUrl(sqlModelUrl) | 93 | + .baseUrl(chatModelUrl) |
| 116 | .modelName(sqlModelName) | 94 | .modelName(sqlModelName) |
| 117 | - .temperature(0.3) | 95 | + .temperature(0.2) |
| 118 | .topP(0.95) | 96 | .topP(0.95) |
| 119 | .numPredict(2048) | 97 | .numPredict(2048) |
| 120 | .timeout(Duration.ofSeconds(120)) | 98 | .timeout(Duration.ofSeconds(120)) |
| 121 | .build(); | 99 | .build(); |
| 122 | } | 100 | } |
| 123 | 101 | ||
| 124 | - /** | ||
| 125 | - * 全局ObjectMapper:支持LocalDate序列化 | ||
| 126 | - */ | 102 | + // ====================== JSON ====================== |
| 127 | @Bean | 103 | @Bean |
| 128 | @Primary | 104 | @Primary |
| 129 | public ObjectMapper objectMapper() { | 105 | public ObjectMapper objectMapper() { |
| @@ -134,22 +110,22 @@ public class ModelConfig { | @@ -134,22 +110,22 @@ public class ModelConfig { | ||
| 134 | return mapper; | 110 | return mapper; |
| 135 | } | 111 | } |
| 136 | 112 | ||
| 137 | - //动态SQL生成模型 | 113 | + // ====================== 动态 SQL Agent ====================== |
| 138 | @Bean | 114 | @Bean |
| 139 | - public DynamicTableNl2SqlAiAgent dynamicTableNl2SqlAiAgent(@Qualifier("sqlChatModel") ChatLanguageModel sqlModel) { | 115 | + public DynamicTableNl2SqlAiAgent dynamicTableNl2SqlAiAgent( |
| 116 | + @Qualifier("sqlChatModel") OllamaChatModel sqlModel) { | ||
| 140 | return AiServices.builder(DynamicTableNl2SqlAiAgent.class) | 117 | return AiServices.builder(DynamicTableNl2SqlAiAgent.class) |
| 141 | - .chatLanguageModel(sqlModel) | ||
| 142 | - // 会话记忆:每个用户最多保留10轮对话,避免记忆溢出 | 118 | + .chatModel(sqlModel) |
| 143 | .chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(10)) | 119 | .chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(10)) |
| 144 | .build(); | 120 | .build(); |
| 145 | } | 121 | } |
| 146 | 122 | ||
| 147 | - //场景意图解析AI服务 | 123 | + // ====================== 场景选择 Agent ====================== |
| 148 | @Bean | 124 | @Bean |
| 149 | - public SceneSelectorAiAgent sceneSelectorAiAgent(OllamaChatModel sqlModel) { | 125 | + public SceneSelectorAiAgent sceneSelectorAiAgent( |
| 126 | + @Qualifier("chatLanguageModel") OllamaChatModel chatLanguageModel) { | ||
| 150 | return AiServices.builder(SceneSelectorAiAgent.class) | 127 | return AiServices.builder(SceneSelectorAiAgent.class) |
| 151 | - .chatLanguageModel(sqlModel) | ||
| 152 | - // 会话记忆:每个用户最多保留10轮对话,避免记忆溢出 | 128 | + .chatModel(chatLanguageModel) |
| 153 | .chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(10)) | 129 | .chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(10)) |
| 154 | .build(); | 130 | .build(); |
| 155 | } | 131 | } |
src/main/java/com/xly/milvus/web/MilvusController.java
| 1 | package com.xly.milvus.web; | 1 | package com.xly.milvus.web; |
| 2 | 2 | ||
| 3 | import com.xly.milvus.service.MilvusService; | 3 | import com.xly.milvus.service.MilvusService; |
| 4 | -import com.xly.runner.AppStartupRunner; | ||
| 5 | -import com.xly.service.DynamicExeDbService; | ||
| 6 | -import com.xly.service.UserSceneSessionService; | ||
| 7 | -import com.xly.tool.DynamicToolProvider; | ||
| 8 | import com.xly.tts.bean.*; | 4 | import com.xly.tts.bean.*; |
| 9 | -import com.xly.tts.service.LocalAudioCache; | ||
| 10 | -import com.xly.tts.service.PythonTtsProxyService; | ||
| 11 | -import jakarta.validation.Valid; | ||
| 12 | import lombok.RequiredArgsConstructor; | 5 | import lombok.RequiredArgsConstructor; |
| 13 | import lombok.extern.slf4j.Slf4j; | 6 | import lombok.extern.slf4j.Slf4j; |
| 14 | -import org.springframework.core.io.InputStreamResource; | ||
| 15 | -import org.springframework.http.MediaType; | ||
| 16 | import org.springframework.http.ResponseEntity; | 7 | import org.springframework.http.ResponseEntity; |
| 17 | import org.springframework.web.bind.annotation.*; | 8 | import org.springframework.web.bind.annotation.*; |
| 18 | -import reactor.core.publisher.Flux; | ||
| 19 | -import reactor.core.publisher.Mono; | ||
| 20 | - | ||
| 21 | -import javax.annotation.PostConstruct; | ||
| 22 | -import javax.annotation.PreDestroy; | ||
| 23 | -import java.util.List; | ||
| 24 | import java.util.Map; | 9 | import java.util.Map; |
| 25 | -import java.util.concurrent.CompletableFuture; | ||
| 26 | 10 | ||
| 27 | @Slf4j | 11 | @Slf4j |
| 28 | @RestController | 12 | @RestController |
src/main/java/com/xly/service/DynamicExeDbService.java
| @@ -4,7 +4,7 @@ import cn.hutool.core.text.CharSequenceUtil; | @@ -4,7 +4,7 @@ import cn.hutool.core.text.CharSequenceUtil; | ||
| 4 | import cn.hutool.core.util.ObjectUtil; | 4 | import cn.hutool.core.util.ObjectUtil; |
| 5 | import cn.hutool.core.util.StrUtil; | 5 | import cn.hutool.core.util.StrUtil; |
| 6 | import cn.hutool.json.JSONUtil; | 6 | import cn.hutool.json.JSONUtil; |
| 7 | -import com.alibaba.fastjson.JSONObject; | 7 | +import com.alibaba.fastjson2.JSONObject; |
| 8 | import com.xly.constant.ErrorCode; | 8 | import com.xly.constant.ErrorCode; |
| 9 | import com.xly.constant.ProcedureConstant; | 9 | import com.xly.constant.ProcedureConstant; |
| 10 | import com.xly.exception.dto.BusinessException; | 10 | import com.xly.exception.dto.BusinessException; |
| @@ -145,7 +145,7 @@ public class DynamicExeDbService { | @@ -145,7 +145,7 @@ public class DynamicExeDbService { | ||
| 145 | if(JSONUtil.isJsonObj(searMap.get(out).toString())){ | 145 | if(JSONUtil.isJsonObj(searMap.get(out).toString())){ |
| 146 | outMapData.put(out, JSONObject.parseObject(searMap.get(out).toString())); | 146 | outMapData.put(out, JSONObject.parseObject(searMap.get(out).toString())); |
| 147 | }else if(JSONUtil.isJsonArray(searMap.get(out).toString())){ | 147 | }else if(JSONUtil.isJsonArray(searMap.get(out).toString())){ |
| 148 | - outMapData.put(out, JSONObject.parseArray(searMap.get(out).toString())); | 148 | + outMapData.put(out, JSONUtil.parseArray(searMap.get(out).toString())); |
| 149 | } | 149 | } |
| 150 | }else{ | 150 | }else{ |
| 151 | outMapData.put(out, searMap.get(out)); | 151 | outMapData.put(out, searMap.get(out)); |
src/main/java/com/xly/service/XlyErpService.java
| @@ -26,15 +26,9 @@ import com.xly.util.*; | @@ -26,15 +26,9 @@ import com.xly.util.*; | ||
| 26 | import dev.langchain4j.agent.tool.ToolExecutionRequest; | 26 | import dev.langchain4j.agent.tool.ToolExecutionRequest; |
| 27 | import dev.langchain4j.data.message.AiMessage; | 27 | import dev.langchain4j.data.message.AiMessage; |
| 28 | import dev.langchain4j.data.message.ChatMessage; | 28 | import dev.langchain4j.data.message.ChatMessage; |
| 29 | -import dev.langchain4j.data.message.ChatMessageType; | ||
| 30 | -import dev.langchain4j.model.chat.ChatLanguageModel; | 29 | + |
| 31 | import dev.langchain4j.model.ollama.OllamaChatModel; | 30 | import dev.langchain4j.model.ollama.OllamaChatModel; |
| 32 | import dev.langchain4j.service.AiServices; | 31 | import dev.langchain4j.service.AiServices; |
| 33 | -import dev.langchain4j.service.MemoryId; | ||
| 34 | -import dev.langchain4j.service.V; | ||
| 35 | -import io.milvus.v2.common.DataType; | ||
| 36 | -import io.milvus.v2.service.collection.request.CreateCollectionReq; | ||
| 37 | -import jnr.ffi.annotations.In; | ||
| 38 | import lombok.RequiredArgsConstructor; | 32 | import lombok.RequiredArgsConstructor; |
| 39 | import lombok.extern.slf4j.Slf4j; | 33 | import lombok.extern.slf4j.Slf4j; |
| 40 | import org.apache.commons.lang3.time.DateFormatUtils; | 34 | import org.apache.commons.lang3.time.DateFormatUtils; |
| @@ -54,7 +48,7 @@ import java.util.stream.IntStream; | @@ -54,7 +48,7 @@ import java.util.stream.IntStream; | ||
| 54 | public class XlyErpService { | 48 | public class XlyErpService { |
| 55 | //中文对话模型 | 49 | //中文对话模型 |
| 56 | private final OllamaChatModel chatModel; | 50 | private final OllamaChatModel chatModel; |
| 57 | - private final ChatLanguageModel chatiModel; | 51 | + private final OllamaChatModel chatiModel; |
| 58 | private final SceneSelectorAiAgent sceneSelectorAiAgent; | 52 | private final SceneSelectorAiAgent sceneSelectorAiAgent; |
| 59 | private final UserSceneSessionService userSceneSessionService; | 53 | private final UserSceneSessionService userSceneSessionService; |
| 60 | private final DynamicToolProvider dynamicToolProvider; | 54 | private final DynamicToolProvider dynamicToolProvider; |
| @@ -923,7 +917,7 @@ public class XlyErpService { | @@ -923,7 +917,7 @@ public class XlyErpService { | ||
| 923 | // .repeatPenalty(1.1) // 减少重复 | 917 | // .repeatPenalty(1.1) // 减少重复 |
| 924 | .build(); | 918 | .build(); |
| 925 | aiAgent = AiServices.builder(DynamicTableNl2SqlAiAgent.class) | 919 | aiAgent = AiServices.builder(DynamicTableNl2SqlAiAgent.class) |
| 926 | - .chatLanguageModel(ol) | 920 | + .chatModel(ol) |
| 927 | .chatMemoryProvider(operableChatMemoryProvider) | 921 | .chatMemoryProvider(operableChatMemoryProvider) |
| 928 | .toolProvider(dynamicToolProvider) | 922 | .toolProvider(dynamicToolProvider) |
| 929 | .build(); | 923 | .build(); |
| @@ -952,7 +946,7 @@ public class XlyErpService { | @@ -952,7 +946,7 @@ public class XlyErpService { | ||
| 952 | ErpAiAgent aiAgent = UserSceneSessionService.ERP_AGENT_CACHE.get(userId); | 946 | ErpAiAgent aiAgent = UserSceneSessionService.ERP_AGENT_CACHE.get(userId); |
| 953 | if(ObjectUtil.isEmpty(aiAgent)){ | 947 | if(ObjectUtil.isEmpty(aiAgent)){ |
| 954 | aiAgent = AiServices.builder(ErpAiAgent.class) | 948 | aiAgent = AiServices.builder(ErpAiAgent.class) |
| 955 | - .chatLanguageModel(chatModel) | 949 | + .chatModel(chatModel) |
| 956 | .chatMemoryProvider(operableChatMemoryProvider) | 950 | .chatMemoryProvider(operableChatMemoryProvider) |
| 957 | .toolProvider(dynamicToolProvider) | 951 | .toolProvider(dynamicToolProvider) |
| 958 | // .toolChoice(ChatCompletionToolChoice.ofRequired()) // 👈 必须调用一个工具 | 952 | // .toolChoice(ChatCompletionToolChoice.ofRequired()) // 👈 必须调用一个工具 |
| @@ -1174,7 +1168,7 @@ public class XlyErpService { | @@ -1174,7 +1168,7 @@ public class XlyErpService { | ||
| 1174 | ChatiAgent chatiAgent = UserSceneSessionService.CHAT_AGENT_CACHE.get(session.getUserId()); | 1168 | ChatiAgent chatiAgent = UserSceneSessionService.CHAT_AGENT_CACHE.get(session.getUserId()); |
| 1175 | if (ObjectUtil.isEmpty(chatiAgent)) { | 1169 | if (ObjectUtil.isEmpty(chatiAgent)) { |
| 1176 | chatiAgent = AiServices.builder(ChatiAgent.class) | 1170 | chatiAgent = AiServices.builder(ChatiAgent.class) |
| 1177 | - .chatLanguageModel(chatiModel) | 1171 | + .chatModel(chatiModel) |
| 1178 | .chatMemoryProvider(operableChatMemoryProvider) | 1172 | .chatMemoryProvider(operableChatMemoryProvider) |
| 1179 | .build(); | 1173 | .build(); |
| 1180 | UserSceneSessionService.CHAT_AGENT_CACHE.put(session.getUserId(), chatiAgent); | 1174 | UserSceneSessionService.CHAT_AGENT_CACHE.put(session.getUserId(), chatiAgent); |
| @@ -1204,7 +1198,7 @@ public class XlyErpService { | @@ -1204,7 +1198,7 @@ public class XlyErpService { | ||
| 1204 | ChatiAgent chatiAgent = UserSceneSessionService.CHAT_AGENT_CACHE.get(session.getUserId()); | 1198 | ChatiAgent chatiAgent = UserSceneSessionService.CHAT_AGENT_CACHE.get(session.getUserId()); |
| 1205 | if(ObjectUtil.isEmpty(chatiAgent)){ | 1199 | if(ObjectUtil.isEmpty(chatiAgent)){ |
| 1206 | chatiAgent = AiServices.builder(ChatiAgent.class) | 1200 | chatiAgent = AiServices.builder(ChatiAgent.class) |
| 1207 | - .chatLanguageModel(chatiModel) | 1201 | + .chatModel(chatiModel) |
| 1208 | .chatMemoryProvider(operableChatMemoryProvider) | 1202 | .chatMemoryProvider(operableChatMemoryProvider) |
| 1209 | .build(); | 1203 | .build(); |
| 1210 | UserSceneSessionService.CHAT_AGENT_CACHE.put(session.getUserId(), chatiAgent); } | 1204 | UserSceneSessionService.CHAT_AGENT_CACHE.put(session.getUserId(), chatiAgent); } |
src/main/java/com/xly/thread/AiUserAgentQuestionThread.java
| @@ -67,21 +67,6 @@ public class AiUserAgentQuestionThread implements Runnable { | @@ -67,21 +67,6 @@ public class AiUserAgentQuestionThread implements Runnable { | ||
| 67 | dynamicExeDbService.getCallPro(searMap, sProName); | 67 | dynamicExeDbService.getCallPro(searMap, sProName); |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | - //获取组ID | ||
| 71 | - private String getQuestionGroupNo(){ | ||
| 72 | - String sQuestionGroupNo = userMessage.stream() | ||
| 73 | - .filter(one -> one.type().equals(ChatMessageType.USER) && !"用户输入:initAiService".equals(one.text())) | ||
| 74 | - .findFirst() | ||
| 75 | - .map(one->one.text()) | ||
| 76 | - .orElse(StrUtil.EMPTY); | ||
| 77 | - sQuestionGroupNo = sQuestionGroupNo.replace("用户输入:",StrUtil.EMPTY); | ||
| 78 | - sQuestionGroupNo = sQuestionGroupNo.replace(" ",StrUtil.EMPTY); | ||
| 79 | - sQuestionGroupNo = sQuestionGroupNo.replace("\\t",StrUtil.EMPTY); | ||
| 80 | - sQuestionGroupNo = sQuestionGroupNo.replace("\\n",StrUtil.EMPTY); | ||
| 81 | - sQuestionGroupNo = sQuestionGroupNo.toLowerCase(); | ||
| 82 | - return sQuestionGroupNo; | ||
| 83 | - } | ||
| 84 | - | ||
| 85 | 70 | ||
| 86 | /*** | 71 | /*** |
| 87 | * @Author 钱豹 | 72 | * @Author 钱豹 |
src/main/java/com/xly/thread/MultiThreadPoolServer.java
| @@ -8,8 +8,8 @@ import java.util.concurrent.ThreadFactory; | @@ -8,8 +8,8 @@ import java.util.concurrent.ThreadFactory; | ||
| 8 | import java.util.concurrent.ThreadPoolExecutor; | 8 | import java.util.concurrent.ThreadPoolExecutor; |
| 9 | import java.util.concurrent.TimeUnit; | 9 | import java.util.concurrent.TimeUnit; |
| 10 | 10 | ||
| 11 | +import com.google.common.util.concurrent.ThreadFactoryBuilder; | ||
| 11 | import org.apache.poi.ss.formula.functions.T; | 12 | import org.apache.poi.ss.formula.functions.T; |
| 12 | -import org.python.google.common.util.concurrent.ThreadFactoryBuilder; | ||
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | /** | 15 | /** |
src/main/java/com/xly/tool/DynamicToolProvider.java
| 1 | package com.xly.tool; | 1 | package com.xly.tool; |
| 2 | 2 | ||
| 3 | 3 | ||
| 4 | -import cn.hutool.core.util.NumberUtil; | ||
| 5 | import cn.hutool.core.util.ObjectUtil; | 4 | import cn.hutool.core.util.ObjectUtil; |
| 6 | import cn.hutool.core.util.StrUtil; | 5 | import cn.hutool.core.util.StrUtil; |
| 7 | import cn.hutool.json.JSONUtil; | 6 | import cn.hutool.json.JSONUtil; |
| 8 | -import com.alibaba.fastjson.JSONObject; | 7 | +import com.alibaba.fastjson2.JSONObject; |
| 9 | import com.fasterxml.jackson.core.type.TypeReference; | 8 | import com.fasterxml.jackson.core.type.TypeReference; |
| 10 | 9 | ||
| 11 | import com.fasterxml.jackson.databind.ObjectMapper; | 10 | import com.fasterxml.jackson.databind.ObjectMapper; |
| @@ -29,6 +28,8 @@ import dev.langchain4j.data.message.ToolExecutionResultMessage; | @@ -29,6 +28,8 @@ import dev.langchain4j.data.message.ToolExecutionResultMessage; | ||
| 29 | import dev.langchain4j.data.message.UserMessage; | 28 | import dev.langchain4j.data.message.UserMessage; |
| 30 | import dev.langchain4j.memory.ChatMemory; | 29 | import dev.langchain4j.memory.ChatMemory; |
| 31 | 30 | ||
| 31 | +import dev.langchain4j.model.chat.request.json.JsonObjectSchema; | ||
| 32 | +import dev.langchain4j.model.chat.request.json.JsonSchema; | ||
| 32 | import dev.langchain4j.service.tool.ToolExecutor; | 33 | import dev.langchain4j.service.tool.ToolExecutor; |
| 33 | import dev.langchain4j.service.tool.ToolProvider; | 34 | import dev.langchain4j.service.tool.ToolProvider; |
| 34 | 35 | ||
| @@ -255,17 +256,15 @@ public class DynamicToolProvider implements ToolProvider { | @@ -255,17 +256,15 @@ public class DynamicToolProvider implements ToolProvider { | ||
| 255 | StringBuffer stoolDesc = new StringBuffer(); | 256 | StringBuffer stoolDesc = new StringBuffer(); |
| 256 | StringBuffer sbt = new StringBuffer(); | 257 | StringBuffer sbt = new StringBuffer(); |
| 257 | StringBuffer xt = new StringBuffer(); | 258 | StringBuffer xt = new StringBuffer(); |
| 258 | - StringBuffer sl = new StringBuffer(); | ||
| 259 | 259 | ||
| 260 | - // ====================== 【超级强制:必须调用工具】 ====================== | 260 | + // 强制指令【完全保留】 |
| 261 | String forceToolPrompt = """ | 261 | String forceToolPrompt = """ |
| 262 | 【重要·强制指令】 | 262 | 【重要·强制指令】 |
| 263 | 1. 这是当前唯一可用工具,必须调用,禁止直接回答 | 263 | 1. 这是当前唯一可用工具,必须调用,禁止直接回答 |
| 264 | 2. 用户输入包含:确认、全部确认、合并确认、行号(第1行/第一行等) | 264 | 2. 用户输入包含:确认、全部确认、合并确认、行号(第1行/第一行等) |
| 265 | - 3. 必须调用本工具,必须调用,并且只调用一次,不要重复调用! | 265 | + 3. 必须调用本工具,只调用一次! |
| 266 | """; | 266 | """; |
| 267 | stoolDesc.append(forceToolPrompt); | 267 | stoolDesc.append(forceToolPrompt); |
| 268 | - // ======================================================================== | ||
| 269 | 268 | ||
| 270 | if (ObjectUtil.isNotEmpty(meta.getStoolDesc())) { | 269 | if (ObjectUtil.isNotEmpty(meta.getStoolDesc())) { |
| 271 | stoolDesc.append("MethodNo:").append(meta.getSMethodNo()) | 270 | stoolDesc.append("MethodNo:").append(meta.getSMethodNo()) |
| @@ -274,130 +273,79 @@ public class DynamicToolProvider implements ToolProvider { | @@ -274,130 +273,79 @@ public class DynamicToolProvider implements ToolProvider { | ||
| 274 | .append(",").append(meta.getStoolDesc()); | 273 | .append(",").append(meta.getStoolDesc()); |
| 275 | } | 274 | } |
| 276 | 275 | ||
| 276 | + JsonObjectSchema.Builder schemaBuilder = JsonObjectSchema.builder(); | ||
| 277 | + List<String> requiredParams = new ArrayList<>(); | ||
| 278 | + | ||
| 277 | try { | 279 | try { |
| 278 | List<ParamRule> paramRuleData = meta.getParamRuleList(); | 280 | List<ParamRule> paramRuleData = meta.getParamRuleList(); |
| 279 | - Map<String, Object> slMap = new HashMap<>(); | ||
| 280 | 281 | ||
| 281 | for (ParamRule paramRule : paramRuleData) { | 282 | for (ParamRule paramRule : paramRuleData) { |
| 282 | - String paramDesc = ObjectUtil.isEmpty(paramRule.getSParam()) ? null : paramRule.getSParam(); | 283 | + String paramDesc = paramRule.getSParam(); |
| 283 | String paramType = paramRule.getSType(); | 284 | String paramType = paramRule.getSType(); |
| 284 | Boolean bEmpty = paramRule.getBEmpty(); | 285 | Boolean bEmpty = paramRule.getBEmpty(); |
| 285 | - String sExampleValue = paramRule.getSExampleValue(); | ||
| 286 | 286 | ||
| 287 | - if (ObjectUtil.isNotEmpty(sExampleValue) && "enum".equals(paramType.toLowerCase())) { | ||
| 288 | - slMap.put(paramDesc, sExampleValue); | ||
| 289 | - } | ||
| 290 | - if (paramDesc == null || paramDesc.trim().isEmpty()) { | 287 | + if (paramDesc == null || paramDesc.isEmpty()) { |
| 291 | continue; | 288 | continue; |
| 292 | } | 289 | } |
| 293 | 290 | ||
| 294 | - List<JsonSchemaProperty> properties = new ArrayList<>(); | ||
| 295 | String sRuleCost = getConstMeg(paramRule.getSParamConfig(), paramRule); | 291 | String sRuleCost = getConstMeg(paramRule.getSParamConfig(), paramRule); |
| 296 | 292 | ||
| 293 | + // ===================== 修复后:安全不报错 ===================== | ||
| 297 | switch (paramType.toLowerCase()) { | 294 | switch (paramType.toLowerCase()) { |
| 298 | case "string": | 295 | case "string": |
| 299 | - if (bEmpty) { | ||
| 300 | - sbt.append(paramDesc).append("(字符串").append(sRuleCost).append(")、"); | ||
| 301 | - } else { | ||
| 302 | - xt.append(paramDesc).append("(字符串").append(sRuleCost).append(")、"); | ||
| 303 | - } | ||
| 304 | - properties.add(JsonSchemaProperty.STRING); | 296 | + if (bEmpty) sbt.append(paramDesc).append("(字符串)、"); |
| 297 | + else xt.append(paramDesc).append("(字符串)、"); | ||
| 298 | + schemaBuilder.addStringProperty(paramDesc, paramDesc); | ||
| 305 | break; | 299 | break; |
| 300 | + | ||
| 306 | case "integer": | 301 | case "integer": |
| 307 | case "int": | 302 | case "int": |
| 308 | - if (bEmpty) { | ||
| 309 | - sbt.append(paramDesc).append("(数字").append(sRuleCost).append(")、"); | ||
| 310 | - } else { | ||
| 311 | - xt.append(paramDesc).append("(数字").append(sRuleCost).append(")、"); | ||
| 312 | - } | ||
| 313 | - properties.add(JsonSchemaProperty.INTEGER); | 303 | + if (bEmpty) sbt.append(paramDesc).append("(数字)、"); |
| 304 | + else xt.append(paramDesc).append("(数字)、"); | ||
| 305 | + schemaBuilder.addIntegerProperty(paramDesc, paramDesc); | ||
| 314 | break; | 306 | break; |
| 307 | + | ||
| 315 | case "number": | 308 | case "number": |
| 316 | case "double": | 309 | case "double": |
| 317 | case "float": | 310 | case "float": |
| 318 | - properties.add(JsonSchemaProperty.NUMBER); | ||
| 319 | - if (bEmpty) { | ||
| 320 | - sbt.append(paramDesc).append("(浮点").append(sRuleCost).append(")、"); | ||
| 321 | - } else { | ||
| 322 | - xt.append(paramDesc).append("(浮点").append(sRuleCost).append(")、"); | ||
| 323 | - } | 311 | + if (bEmpty) sbt.append(paramDesc).append("(浮点)、"); |
| 312 | + else xt.append(paramDesc).append("(浮点)、"); | ||
| 313 | + schemaBuilder.addNumberProperty(paramDesc, paramDesc); | ||
| 324 | break; | 314 | break; |
| 315 | + | ||
| 325 | case "boolean": | 316 | case "boolean": |
| 326 | case "bool": | 317 | case "bool": |
| 327 | - if (bEmpty) { | ||
| 328 | - sbt.append(paramDesc).append("(布尔型").append(sRuleCost).append(")、"); | ||
| 329 | - } else { | ||
| 330 | - xt.append(paramDesc).append("(布尔型").append(sRuleCost).append(")、"); | ||
| 331 | - } | ||
| 332 | - properties.add(JsonSchemaProperty.BOOLEAN); | 318 | + if (bEmpty) sbt.append(paramDesc).append("(布尔)、"); |
| 319 | + else xt.append(paramDesc).append("(布尔)、"); | ||
| 320 | + schemaBuilder.addBooleanProperty(paramDesc, paramDesc); | ||
| 333 | break; | 321 | break; |
| 322 | + | ||
| 334 | case "array": | 323 | case "array": |
| 335 | - String sRuleArray = getArrrayBySql(paramRule); | ||
| 336 | - if (ObjectUtil.isNotEmpty(sRuleArray)) { | ||
| 337 | - sRuleArray = StrUtil.replace(sRuleArray, ",", "/"); | ||
| 338 | - properties.add(JsonSchemaProperty.enums(sRuleArray.split("/"))); | ||
| 339 | - } | ||
| 340 | - if (bEmpty) { | ||
| 341 | - sbt.append(paramDesc).append("(数组类型,可多选枚举值 [").append(sRuleArray).append("]"); | ||
| 342 | - if (ObjectUtil.isNotEmpty(paramRule.getSDefaultValue()) || (ObjectUtil.isNotEmpty(sRuleArray) && sRuleArray.split("/").length == 1)) { | ||
| 343 | - String sDefaultVal = (ObjectUtil.isNotEmpty(sRuleArray) && sRuleArray.split("/").length == 1) ? sRuleArray : paramRule.getSDefaultValue(); | ||
| 344 | - sbt.append(",默认值[").append(sDefaultVal).append("]"); | ||
| 345 | - } else { | ||
| 346 | - sbt.append(",无默认值"); | ||
| 347 | - } | ||
| 348 | - sbt.append(")、"); | ||
| 349 | - } else { | ||
| 350 | - xt.append(paramDesc).append("(数组类型,可多选枚举值 [").append(sRuleArray).append("]"); | ||
| 351 | - if (ObjectUtil.isNotEmpty(paramRule.getSDefaultValue())) { | ||
| 352 | - xt.append(",默认值[").append(paramRule.getSDefaultValue()).append("]"); | ||
| 353 | - } else { | ||
| 354 | - xt.append(",无默认值"); | ||
| 355 | - } | ||
| 356 | - xt.append(")、"); | ||
| 357 | - } | ||
| 358 | - properties.add(JsonSchemaProperty.ARRAY); | ||
| 359 | - properties.add(JsonSchemaProperty.items(JsonSchemaProperty.STRING)); | 324 | + schemaBuilder.addStringProperty(paramDesc, paramDesc); |
| 360 | break; | 325 | break; |
| 326 | + | ||
| 361 | case "enum": | 327 | case "enum": |
| 362 | - if (ObjectUtil.isNotEmpty(sRuleCost)) { | ||
| 363 | - properties.add(JsonSchemaProperty.enums(sRuleCost.split("/"))); | ||
| 364 | - } else { | ||
| 365 | - sRuleCost = getArrrayBySql(paramRule); | 328 | + List<String> enums = new ArrayList<>(); |
| 329 | + if (StrUtil.isNotBlank(sRuleCost)) { | ||
| 330 | + enums = Arrays.asList(sRuleCost.split("/")); | ||
| 366 | } | 331 | } |
| 367 | - if (bEmpty) { | ||
| 368 | - sbt.append(paramDesc).append("(字符串,互斥枚举值 [").append(sRuleCost).append("]"); | ||
| 369 | - if (ObjectUtil.isNotEmpty(paramRule.getSDefaultValue())) { | ||
| 370 | - sbt.append(",默认值[").append(paramRule.getSDefaultValue()).append("]"); | ||
| 371 | - } else { | ||
| 372 | - sbt.append(",无默认值"); | ||
| 373 | - } | ||
| 374 | - sbt.append(")、"); | 332 | + |
| 333 | + // ===================== 核心修复 ===================== | ||
| 334 | + if (enums.isEmpty()) { | ||
| 335 | + // 空枚举 → 自动转字符串,绝对不报错 | ||
| 336 | + schemaBuilder.addStringProperty(paramDesc, paramDesc); | ||
| 375 | } else { | 337 | } else { |
| 376 | - xt.append(paramDesc).append("(字符串,互斥枚举值 [").append(sRuleCost).append("]"); | ||
| 377 | - if (ObjectUtil.isNotEmpty(paramRule.getSDefaultValue())) { | ||
| 378 | - xt.append(",默认值[").append(paramRule.getSDefaultValue()).append("]"); | ||
| 379 | - } else { | ||
| 380 | - xt.append(",无默认值"); | ||
| 381 | - } | ||
| 382 | - xt.append(")、"); | 338 | + schemaBuilder.addEnumProperty(paramDesc, enums, paramDesc); |
| 383 | } | 339 | } |
| 384 | - properties.add(JsonSchemaProperty.ARRAY); | ||
| 385 | - properties.add(JsonSchemaProperty.items(JsonSchemaProperty.STRING)); | ||
| 386 | break; | 340 | break; |
| 341 | + | ||
| 387 | default: | 342 | default: |
| 388 | - properties.add(JsonSchemaProperty.STRING); | 343 | + schemaBuilder.addStringProperty(paramDesc, paramDesc); |
| 389 | break; | 344 | break; |
| 390 | } | 345 | } |
| 391 | 346 | ||
| 392 | - if (!paramDesc.isEmpty()) { | ||
| 393 | - properties.add(JsonSchemaProperty.description(paramDesc)); | ||
| 394 | - } | ||
| 395 | - | ||
| 396 | - boolean required = bEmpty; | ||
| 397 | - if (required) { | ||
| 398 | - builder.addParameter(paramDesc, properties); | ||
| 399 | - } else { | ||
| 400 | - builder.addOptionalParameter(paramDesc, properties); | 347 | + if (bEmpty) { |
| 348 | + requiredParams.add(paramDesc); | ||
| 401 | } | 349 | } |
| 402 | } | 350 | } |
| 403 | 351 | ||
| @@ -407,29 +355,24 @@ public class DynamicToolProvider implements ToolProvider { | @@ -407,29 +355,24 @@ public class DynamicToolProvider implements ToolProvider { | ||
| 407 | if (ObjectUtil.isNotEmpty(xt)) { | 355 | if (ObjectUtil.isNotEmpty(xt)) { |
| 408 | stoolDesc.append(System.lineSeparator()).append("2.选填参数:").append(xt); | 356 | stoolDesc.append(System.lineSeparator()).append("2.选填参数:").append(xt); |
| 409 | } | 357 | } |
| 410 | - if (ObjectUtil.isNotEmpty(slMap)) { | ||
| 411 | - stoolDesc.append(System.lineSeparator()).append(sl).append("**强制输出标准JSON对象**:") | ||
| 412 | - .append(System.lineSeparator()).append("示例:").append(JSONUtil.toJsonStr(slMap)); | ||
| 413 | - } | ||
| 414 | 358 | ||
| 415 | - log.info("方法描述========================{}", stoolDesc); | ||
| 416 | } catch (Exception e) { | 359 | } catch (Exception e) { |
| 417 | e.printStackTrace(); | 360 | e.printStackTrace(); |
| 418 | - log.error("Failed to parse parameter rules: {}", meta.getSMethodName(), e); | ||
| 419 | } | 361 | } |
| 420 | 362 | ||
| 421 | - // ====================== 【关键修复:强制添加两个参数】 ====================== | 363 | + // 固定添加 operateType |
| 422 | if (meta.getIBizType() == 4 || meta.getIBizType() == 5) { | 364 | if (meta.getIBizType() == 4 || meta.getIBizType() == 5) { |
| 423 | - // 强制添加 operateType(必填) | ||
| 424 | - builder.addParameter("operateType", | ||
| 425 | - JsonSchemaProperty.STRING, | ||
| 426 | - JsonSchemaProperty.description("操作类型:全部确认/合并确认/单行确认") | ||
| 427 | - ); | 365 | + schemaBuilder.addStringProperty("operateType", "操作类型:全部确认/合并确认/单行确认"); |
| 366 | + requiredParams.add("operateType"); | ||
| 428 | } | 367 | } |
| 429 | - // ============================================================================ | ||
| 430 | - | ||
| 431 | - builder.description(stoolDesc.toString()); | ||
| 432 | - return builder.build(); | 368 | + if (!requiredParams.isEmpty()) { |
| 369 | + schemaBuilder.required(requiredParams); | ||
| 370 | + } | ||
| 371 | + JsonObjectSchema parameters = schemaBuilder.build(); | ||
| 372 | + return builder | ||
| 373 | + .description(stoolDesc.toString()) | ||
| 374 | + .parameters(parameters) | ||
| 375 | + .build(); | ||
| 433 | } | 376 | } |
| 434 | 377 | ||
| 435 | /*** | 378 | /*** |
| @@ -615,8 +558,11 @@ public class DynamicToolProvider implements ToolProvider { | @@ -615,8 +558,11 @@ public class DynamicToolProvider implements ToolProvider { | ||
| 615 | 558 | ||
| 616 | // 6. 【最终确认信息】所有检测通过后,需要和客户确认交互 | 559 | // 6. 【最终确认信息】所有检测通过后,需要和客户确认交互 |
| 617 | List<ChatMessage> chatMessage = operableChatMemoryProvider.getCurrentChatMessages(session.getUserId()); | 560 | List<ChatMessage> chatMessage = operableChatMemoryProvider.getCurrentChatMessages(session.getUserId()); |
| 618 | - ChatMessage userMessage = getLasterUserMssage(chatMessage); | ||
| 619 | - String input = StrUtil.replace(userMessage.text(),"用户输入:",StrUtil.EMPTY); | 561 | + ChatMessage userMessage = getLastUserMessage(chatMessage); |
| 562 | + String input = ""; | ||
| 563 | + if (userMessage != null) { | ||
| 564 | + input = StrUtil.replace(getChatMessageContent(userMessage), "用户输入:", StrUtil.EMPTY); | ||
| 565 | + } | ||
| 620 | // {"0":"查询","1":"执行"} 查询不需要确认 | 566 | // {"0":"查询","1":"执行"} 查询不需要确认 |
| 621 | Boolean isConfirmed = isConfirmed(input) || input.contains("生成") || input.contains("确认"); | 567 | Boolean isConfirmed = isConfirmed(input) || input.contains("生成") || input.contains("确认"); |
| 622 | // //判断是否生成数据 | 568 | // //判断是否生成数据 |
| @@ -661,6 +607,37 @@ public class DynamicToolProvider implements ToolProvider { | @@ -661,6 +607,37 @@ public class DynamicToolProvider implements ToolProvider { | ||
| 661 | return executeWithConfirmation(askconfirmMsg, session, meta); | 607 | return executeWithConfirmation(askconfirmMsg, session, meta); |
| 662 | } | 608 | } |
| 663 | 609 | ||
| 610 | + /** | ||
| 611 | + * 安全获取 ChatMessage 内容,适配你当前所有版本 | ||
| 612 | + * 不依赖 UserMessage / .text() | ||
| 613 | + */ | ||
| 614 | + private String getChatMessageContent(ChatMessage message) { | ||
| 615 | + if (message == null) return ""; | ||
| 616 | + | ||
| 617 | + try { | ||
| 618 | + // 通用反射获取内容(兼容所有版本) | ||
| 619 | + return message.toString() | ||
| 620 | + .replace("ChatMessage{", "") | ||
| 621 | + .replace("}", "") | ||
| 622 | + .replace("text=", "") | ||
| 623 | + .trim(); | ||
| 624 | + } catch (Exception e) { | ||
| 625 | + return ""; | ||
| 626 | + } | ||
| 627 | + } | ||
| 628 | + private ChatMessage getLastUserMessage(List<ChatMessage> messages) { | ||
| 629 | + if (messages == null || messages.isEmpty()) return null; | ||
| 630 | + | ||
| 631 | + for (int i = messages.size() - 1; i >= 0; i--) { | ||
| 632 | + ChatMessage msg = messages.get(i); | ||
| 633 | + if (msg.type() == ChatMessageType.USER) { | ||
| 634 | + return msg; | ||
| 635 | + } | ||
| 636 | + } | ||
| 637 | + return null; | ||
| 638 | + } | ||
| 639 | + | ||
| 640 | + | ||
| 664 | /*** | 641 | /*** |
| 665 | * @Author 钱豹 | 642 | * @Author 钱豹 |
| 666 | * @Date 15:16 2026/2/9 | 643 | * @Date 15:16 2026/2/9 |
| @@ -983,7 +960,7 @@ public class DynamicToolProvider implements ToolProvider { | @@ -983,7 +960,7 @@ public class DynamicToolProvider implements ToolProvider { | ||
| 983 | args.put("sToolId", meta.getSId()); | 960 | args.put("sToolId", meta.getSId()); |
| 984 | if (iBizType == 1 || iBizType == 4) { | 961 | if (iBizType == 1 || iBizType == 4) { |
| 985 | Map<String, Object> data = new HashMap<>(args); | 962 | Map<String, Object> data = new HashMap<>(args); |
| 986 | - data.put("sData", JSONObject.toJSONString(data)); | 963 | + data.put("sData", JSONObject.toJSONString((data))); |
| 987 | if(ObjectUtil.isEmpty(sBizContent) && iBizType == 4){ | 964 | if(ObjectUtil.isEmpty(sBizContent) && iBizType == 4){ |
| 988 | sBizContent ="Sp_Ai_AddCommonAfterNew"; | 965 | sBizContent ="Sp_Ai_AddCommonAfterNew"; |
| 989 | //获取未清数据 | 966 | //获取未清数据 |
src/main/java/com/xly/tts/service/PythonTtsProxyService.java
| @@ -11,6 +11,7 @@ import com.xly.service.UserSceneSessionService; | @@ -11,6 +11,7 @@ import com.xly.service.UserSceneSessionService; | ||
| 11 | import com.xly.service.XlyErpService; | 11 | import com.xly.service.XlyErpService; |
| 12 | import com.xly.tts.bean.*; | 12 | import com.xly.tts.bean.*; |
| 13 | import com.xly.util.AdvancedSymbolRemover; | 13 | import com.xly.util.AdvancedSymbolRemover; |
| 14 | +import jakarta.annotation.PostConstruct; | ||
| 14 | import lombok.RequiredArgsConstructor; | 15 | import lombok.RequiredArgsConstructor; |
| 15 | import lombok.extern.slf4j.Slf4j; | 16 | import lombok.extern.slf4j.Slf4j; |
| 16 | import org.springframework.beans.factory.annotation.Value; | 17 | import org.springframework.beans.factory.annotation.Value; |
| @@ -20,7 +21,7 @@ import org.springframework.stereotype.Service; | @@ -20,7 +21,7 @@ import org.springframework.stereotype.Service; | ||
| 20 | import org.springframework.web.client.RestTemplate; | 21 | import org.springframework.web.client.RestTemplate; |
| 21 | import reactor.core.publisher.Flux; | 22 | import reactor.core.publisher.Flux; |
| 22 | 23 | ||
| 23 | -import javax.annotation.PostConstruct; | 24 | + |
| 24 | import java.io.*; | 25 | import java.io.*; |
| 25 | import java.time.Duration; | 26 | import java.time.Duration; |
| 26 | import java.util.*; | 27 | import java.util.*; |
src/main/java/com/xly/util/SqlExecuteUtil.java
| @@ -2,16 +2,14 @@ package com.xly.util; | @@ -2,16 +2,14 @@ package com.xly.util; | ||
| 2 | 2 | ||
| 3 | 3 | ||
| 4 | import com.xly.exception.sqlexception.SqlExecuteException; | 4 | import com.xly.exception.sqlexception.SqlExecuteException; |
| 5 | +import jakarta.annotation.Resource; | ||
| 5 | import org.slf4j.Logger; | 6 | import org.slf4j.Logger; |
| 6 | import org.slf4j.LoggerFactory; | 7 | import org.slf4j.LoggerFactory; |
| 7 | import org.springframework.jdbc.core.JdbcTemplate; | 8 | import org.springframework.jdbc.core.JdbcTemplate; |
| 8 | import org.springframework.jdbc.core.RowMapper; | 9 | import org.springframework.jdbc.core.RowMapper; |
| 9 | import org.springframework.stereotype.Component; | 10 | import org.springframework.stereotype.Component; |
| 10 | 11 | ||
| 11 | -import javax.annotation.Resource; | ||
| 12 | -import java.sql.ResultSet; | ||
| 13 | import java.sql.ResultSetMetaData; | 12 | import java.sql.ResultSetMetaData; |
| 14 | -import java.sql.SQLException; | ||
| 15 | import java.util.LinkedHashMap; | 13 | import java.util.LinkedHashMap; |
| 16 | import java.util.List; | 14 | import java.util.List; |
| 17 | import java.util.Map; | 15 | import java.util.Map; |
src/main/java/com/xly/web/TTSStreamController.java
| @@ -7,6 +7,8 @@ import com.xly.tool.DynamicToolProvider; | @@ -7,6 +7,8 @@ import com.xly.tool.DynamicToolProvider; | ||
| 7 | import com.xly.tts.bean.*; | 7 | import com.xly.tts.bean.*; |
| 8 | import com.xly.tts.service.LocalAudioCache; | 8 | import com.xly.tts.service.LocalAudioCache; |
| 9 | import com.xly.tts.service.PythonTtsProxyService; | 9 | import com.xly.tts.service.PythonTtsProxyService; |
| 10 | +import jakarta.annotation.PostConstruct; | ||
| 11 | +import jakarta.annotation.PreDestroy; | ||
| 10 | import jakarta.validation.Valid; | 12 | import jakarta.validation.Valid; |
| 11 | import lombok.RequiredArgsConstructor; | 13 | import lombok.RequiredArgsConstructor; |
| 12 | import lombok.extern.slf4j.Slf4j; | 14 | import lombok.extern.slf4j.Slf4j; |
| @@ -14,13 +16,8 @@ import org.springframework.core.io.InputStreamResource; | @@ -14,13 +16,8 @@ import org.springframework.core.io.InputStreamResource; | ||
| 14 | import org.springframework.http.MediaType; | 16 | import org.springframework.http.MediaType; |
| 15 | import org.springframework.http.ResponseEntity; | 17 | import org.springframework.http.ResponseEntity; |
| 16 | import org.springframework.web.bind.annotation.*; | 18 | import org.springframework.web.bind.annotation.*; |
| 17 | -import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; | ||
| 18 | import reactor.core.publisher.Flux; | 19 | import reactor.core.publisher.Flux; |
| 19 | -import reactor.core.publisher.Mono; | ||
| 20 | 20 | ||
| 21 | -import javax.annotation.PostConstruct; | ||
| 22 | -import javax.annotation.PreDestroy; | ||
| 23 | -import java.io.InputStream; | ||
| 24 | import java.util.List; | 21 | import java.util.List; |
| 25 | import java.util.Map; | 22 | import java.util.Map; |
| 26 | import java.util.concurrent.CompletableFuture; | 23 | import java.util.concurrent.CompletableFuture; |
src/main/resources/application.yml
| @@ -48,7 +48,7 @@ spring: | @@ -48,7 +48,7 @@ spring: | ||
| 48 | add-mappings: false | 48 | add-mappings: false |
| 49 | datasource: | 49 | datasource: |
| 50 | driver-class-name: com.mysql.cj.jdbc.Driver | 50 | driver-class-name: com.mysql.cj.jdbc.Driver |
| 51 | - url: jdbc:mysql://8.130.144.93:3306/xlyweberp_saas?allowPublicKeyRetrieval=true&keepAlive=true&autoReconnect=true&autoReconnectForPools=true&connectTimeout=30000&socketTimeout=180000&nullCatalogMeansCurrent=true&&allowMultiQueries=true&useSSL=false&useUnicode=true&characterEncoding=utf-8&failOverReadOnly=false&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=CONVERT_TO_NULL | 51 | + url: jdbc:mysql://118.178.19.35:3318/xlyweberp_saas?allowPublicKeyRetrieval=true&keepAlive=true&autoReconnect=true&autoReconnectForPools=true&connectTimeout=30000&socketTimeout=180000&nullCatalogMeansCurrent=true&&allowMultiQueries=true&useSSL=false&useUnicode=true&characterEncoding=utf-8&failOverReadOnly=false&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=CONVERT_TO_NULL |
| 52 | username: xlyprint | 52 | username: xlyprint |
| 53 | password: xlyXLYprint2016 | 53 | password: xlyXLYprint2016 |
| 54 | # 连接池配置(使用HikariCP) | 54 | # 连接池配置(使用HikariCP) |