From 3c9796524f27e2adfe9af6fadc8923ee4b589ced Mon Sep 17 00:00:00 2001 From: gewuyou <1063891901@qq.com> Date: Sat, 26 Apr 2025 19:00:29 +0800 Subject: [PATCH] =?UTF-8?q?feat(core):=20=E6=B7=BB=E5=8A=A0=E6=A0=B8?= =?UTF-8?q?=E5=BF=83=E6=9C=8D=E5=8A=A1=E6=A8=A1=E5=9D=97=E5=B9=B6=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E5=9F=BA=E6=9C=AC=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 llmhub-core-service 模块,实现聊天和嵌入功能 - 添加 LLMService 接口及其实现类 LLMServiceImpl - 实现了与 LLM 提供商的交互接口 LLMProvider- 新增模型路由管理器 ModelRouteManager 和相关配置 - 添加开发和生产环境配置文件 - 更新项目依赖,引入 Spring Cloud 和 Nacos --- llmhub-base/build.gradle.kts | 40 +++++++++++++++-- .../buildSrc/src/main/kotlin/Modules.kt | 19 ++++++++ .../buildSrc/src/main/kotlin/ProjectFlags.kt | 3 ++ llmhub-base/gradle/libs.versions.toml | 23 +++++++++- .../llmhub-core-service/build.gradle.kts | 21 ++++++++- .../service/LlmhubCoreServiceApplication.kt | 0 .../core/service/config/AppConfiguration.kt | 31 +++++++++++++ .../core/service/config/ModelProperties.kt | 19 ++++++++ .../core/service/controller/ChatController.kt | 21 +++++++++ .../core/service/manager/ModelRouteManager.kt | 39 +++++++++++++++++ .../llmhub/core/service/service/LLMService.kt | 26 +++++++++++ .../service/service/impl/LLMServiceImpl.kt | 42 ++++++++++++++++++ .../src/main/resources/application-dev.yml | 13 ++++++ .../src/main/resources/application-prod.yml | 7 +++ .../src/main/resources/application.yml | 4 +- .../llmhub-core-spi/build.gradle.kts | 10 ++++- .../core/spi/entities/request/ChatRequest.kt | 17 ++++++++ .../spi/entities/request/EmbeddingRequest.kt | 18 ++++++++ .../spi/entities/response/ChatResponse.kt | 38 ++++++++++++++++ .../entities/response/EmbeddingResponse.kt | 18 ++++++++ .../llmhub/core/spi/provider/LLMProvider.kt | 43 +++++++++++++++++++ llmhub-base/llmhub-impl/build.gradle.kts | 9 +--- .../llmhub-impl-baiLian/build.gradle.kts | 2 +- 23 files changed, 444 insertions(+), 19 deletions(-) create mode 100644 llmhub-base/buildSrc/src/main/kotlin/Modules.kt rename llmhub-base/llmhub-core/llmhub-core-service/src/main/{java => kotlin}/org/jcnc/llmhub/core/service/LlmhubCoreServiceApplication.kt (100%) create mode 100644 llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/config/AppConfiguration.kt create mode 100644 llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/config/ModelProperties.kt create mode 100644 llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/controller/ChatController.kt create mode 100644 llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/manager/ModelRouteManager.kt create mode 100644 llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/service/LLMService.kt create mode 100644 llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/service/impl/LLMServiceImpl.kt create mode 100644 llmhub-base/llmhub-core/llmhub-core-service/src/main/resources/application-dev.yml create mode 100644 llmhub-base/llmhub-core/llmhub-core-service/src/main/resources/application-prod.yml create mode 100644 llmhub-base/llmhub-core/llmhub-core-spi/src/main/kotlin/org/jcnc/llmhub/core/spi/entities/request/ChatRequest.kt create mode 100644 llmhub-base/llmhub-core/llmhub-core-spi/src/main/kotlin/org/jcnc/llmhub/core/spi/entities/request/EmbeddingRequest.kt create mode 100644 llmhub-base/llmhub-core/llmhub-core-spi/src/main/kotlin/org/jcnc/llmhub/core/spi/entities/response/ChatResponse.kt create mode 100644 llmhub-base/llmhub-core/llmhub-core-spi/src/main/kotlin/org/jcnc/llmhub/core/spi/entities/response/EmbeddingResponse.kt create mode 100644 llmhub-base/llmhub-core/llmhub-core-spi/src/main/kotlin/org/jcnc/llmhub/core/spi/provider/LLMProvider.kt diff --git a/llmhub-base/build.gradle.kts b/llmhub-base/build.gradle.kts index d50cf83..3936242 100644 --- a/llmhub-base/build.gradle.kts +++ b/llmhub-base/build.gradle.kts @@ -10,18 +10,28 @@ group = "org.jcnc" version = "1.0-SNAPSHOT" /** - * 由于 Kotlin 插件被引入时会自动添加依赖,但根项目不需要 Kotlin 依赖,因此需要排除 Kotlin 依赖 + * 由于 Kotlin 插件引入时会自动添加依赖,但根项目不需要 Kotlin 依赖,因此需要排除 Kotlin 依赖 */ configurations.implementation { exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib") } allprojects { // 设置全局属性 - ext{ - set(ProjectFlags.USE_SPRING_BOOT,false) + ext { + set(ProjectFlags.USE_SPRING_BOOT, false) + set(ProjectFlags.USE_LLM_CORE_SPI, false) + set(ProjectFlags.USE_SPRING_CLOUD_BOM, false) + set(ProjectFlags.IS_ROOT_MODULE, false) } repositories { mavenLocal() + val host = System.getenv("GEWUYOU_GITEA_HOST") + host?.let { + maven { + url = uri("http://${host}/api/packages/gewuyou/maven") + isAllowInsecureProtocol = true + } + } maven { url = uri("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev") } @@ -44,6 +54,16 @@ allprojects { google() gradlePluginPortal() } + afterEvaluate { + if (project.getPropertyByBoolean(ProjectFlags.IS_ROOT_MODULE)) { + /** + * 由于 Kotlin 插件引入时会自动添加依赖,但根项目不需要 Kotlin 依赖,因此需要排除 Kotlin 依赖 + */ + configurations.implementation { + exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib") + } + } + } } subprojects { @@ -62,13 +82,25 @@ subprojects { testRuntimeOnly(libs.junitPlatform.launcher) } } + // llm-core-spi + if (project.getPropertyByBoolean(ProjectFlags.USE_LLM_CORE_SPI)) { + dependencies { + implementation(project(Modules.Core.SPI)) + } + } + // springCloudBom + if (project.getPropertyByBoolean(ProjectFlags.USE_SPRING_CLOUD_BOM)) { + dependencies { + implementation(libs.springCloudDependencies.bom) + } + } } val libs = rootProject.libs apply { plugin(libs.plugins.java.get().pluginId) plugin(libs.plugins.kotlin.jvm.get().pluginId) } - println(project.name+":"+project.getPropertyByBoolean(ProjectFlags.USE_SPRING_BOOT)) + println(project.name + ":" + project.getPropertyByBoolean(ProjectFlags.USE_SPRING_BOOT)) kotlin { compilerOptions { diff --git a/llmhub-base/buildSrc/src/main/kotlin/Modules.kt b/llmhub-base/buildSrc/src/main/kotlin/Modules.kt new file mode 100644 index 0000000..488bf43 --- /dev/null +++ b/llmhub-base/buildSrc/src/main/kotlin/Modules.kt @@ -0,0 +1,19 @@ +/** + * Modules对象用于统一管理项目中的各个模块路径 + * 主要作用是提供一个集中定义和访问模块路径的地方,以便在项目中保持一致性和可维护性 + * + * @since 2025-04-03 09:07:33 + * @author gewuyou + */ +object Modules { + + /** + * Core对象定义了核心模块的相关路径 + * 主要包含核心模块的SPI(Service Provider Interface)路径 + */ + object Core{ + // llmhub-core-spi模块的路径,用于定义核心功能的SPI + const val SPI = ":llmhub-core:llmhub-core-spi" + } + +} diff --git a/llmhub-base/buildSrc/src/main/kotlin/ProjectFlags.kt b/llmhub-base/buildSrc/src/main/kotlin/ProjectFlags.kt index 04ea3b9..eb7999b 100644 --- a/llmhub-base/buildSrc/src/main/kotlin/ProjectFlags.kt +++ b/llmhub-base/buildSrc/src/main/kotlin/ProjectFlags.kt @@ -1,3 +1,6 @@ object ProjectFlags { const val USE_SPRING_BOOT = "useSpringBoot" + const val USE_SPRING_CLOUD_BOM = "useSpringCloudBom" + const val USE_LLM_CORE_SPI = "useLLMCoreSPI" + const val IS_ROOT_MODULE = "isRootModule" } \ No newline at end of file diff --git a/llmhub-base/gradle/libs.versions.toml b/llmhub-base/gradle/libs.versions.toml index 3bca5d3..7a089a8 100644 --- a/llmhub-base/gradle/libs.versions.toml +++ b/llmhub-base/gradle/libs.versions.toml @@ -1,10 +1,12 @@ [versions] kotlin-version = "2.0.0" - +spring-cloud-version = "2024.0.1" +spring-cloud-starter-version = "4.2.1" spring-boot-version = "3.4.4" spring-dependency-management-version = "1.1.7" - aliyun-bailian-version = "2.0.0" +spring-cloud-starter-alibaba-nacos-discovery-version = "2023.0.3.2" +forgeBoot-version = "1.0.0" [plugins] # 应用 Java 插件,提供基本的 Java 代码编译和构建能力 java = { id = "java" } @@ -23,10 +25,27 @@ spring-dependency-management = { id = "io.spring.dependency-management", version spring-boot = { id = "org.springframework.boot", version.ref = "spring-boot-version" } [libraries] +# bom +springCloudDependencies-bom = { module = "org.springframework.cloud:spring-cloud-dependencies", version.ref = "spring-cloud-version" } +# kotlinx +# 响应式协程库 +kotlinx-coruntes-reactor = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-reactor"} + # 阿里云百炼 aliyun-bailian = { group = "com.aliyun", name = "bailian20231229", version.ref = "aliyun-bailian-version" } + +# SrpingCloud +springCloudStarter-alibaba-nacos-discovery = { group = "com.alibaba.cloud", name = "spring-cloud-starter-alibaba-nacos-discovery", version.ref = "spring-cloud-starter-alibaba-nacos-discovery-version" } +springCloudStarter-loadbalancer = { group = "org.springframework.cloud", name = "spring-cloud-starter-loadbalancer" ,version.ref="spring-cloud-starter-version"} + # SpringBootStarter +springBootStarter-webflux = { group = "org.springframework.boot", name = "spring-boot-starter-webflux" } springBootStarter-web = { group = "org.springframework.boot", name = "spring-boot-starter-web" } springBootStarter-test = { group = "org.springframework.boot", name = "spring-boot-starter-test" } + junitPlatform-launcher = { group = "org.junit.platform", name = "junit-platform-launcher" } + +# forgeBoot +forgeBoot-webmvc-version-springBootStarter = { group = "com.gewuyou.forgeboot", name = "forgeboot-webmvc-version-spring-boot-starter",version.ref="forgeBoot-version" } +forgeBoot-core-extension = { group = "com.gewuyou.forgeboot", name = "forgeboot-core-extension",version.ref="forgeBoot-version" } [bundles] diff --git a/llmhub-base/llmhub-core/llmhub-core-service/build.gradle.kts b/llmhub-base/llmhub-core/llmhub-core-service/build.gradle.kts index 8397ec7..fd6b045 100644 --- a/llmhub-base/llmhub-core/llmhub-core-service/build.gradle.kts +++ b/llmhub-base/llmhub-core/llmhub-core-service/build.gradle.kts @@ -1,5 +1,22 @@ -// 开启springboot -extra[ProjectFlags.USE_SPRING_BOOT] = true +extra { + // 开启springboot + setProperty(ProjectFlags.USE_SPRING_BOOT, true) +} dependencies { + val libs = rootProject.libs + // Nacos 服务发现和配置 + implementation(libs.springCloudStarter.alibaba.nacos.discovery) + + // WebClient 和 Spring Cloud LoadBalancer + implementation(libs.springBootStarter.webflux) + implementation(libs.springCloudStarter.loadbalancer) + + implementation(project(Modules.Core.SPI)) + + // Kotlin Coroutines + implementation(libs.kotlinx.coruntes.reactor) + + implementation(libs.forgeBoot.webmvc.version.springBootStarter) + implementation(libs.forgeBoot.core.extension) } diff --git a/llmhub-base/llmhub-core/llmhub-core-service/src/main/java/org/jcnc/llmhub/core/service/LlmhubCoreServiceApplication.kt b/llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/LlmhubCoreServiceApplication.kt similarity index 100% rename from llmhub-base/llmhub-core/llmhub-core-service/src/main/java/org/jcnc/llmhub/core/service/LlmhubCoreServiceApplication.kt rename to llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/LlmhubCoreServiceApplication.kt diff --git a/llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/config/AppConfiguration.kt b/llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/config/AppConfiguration.kt new file mode 100644 index 0000000..50f0a86 --- /dev/null +++ b/llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/config/AppConfiguration.kt @@ -0,0 +1,31 @@ +package org.jcnc.llmhub.core.service.config + +import org.springframework.boot.context.properties.EnableConfigurationProperties +import org.springframework.cloud.client.loadbalancer.LoadBalanced +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.web.reactive.function.client.WebClient + +/** + *应用程序配置 + * + * @since 2025-04-25 20:36:18 + * @author gewuyou + */ +@Configuration +@EnableConfigurationProperties(ModelProperties::class) +class AppConfiguration { + /** + * 创建一个配置了负载均衡的WebClient构建器 + * + * 该方法通过Spring框架的WebClient.builder()初始化一个WebClient构建器,并为其配置负载均衡功能 + * 负载均衡功能使得WebClient能够智能地在多个服务实例间分配请求,提高系统的可伸缩性和可靠性 + * + * @return WebClient.Builder 配置了负载均衡功能的WebClient构建器 + */ + @Bean + @LoadBalanced + fun webClientBuilder(): WebClient.Builder { + return WebClient.builder() + } +} \ No newline at end of file diff --git a/llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/config/ModelProperties.kt b/llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/config/ModelProperties.kt new file mode 100644 index 0000000..c07bfe9 --- /dev/null +++ b/llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/config/ModelProperties.kt @@ -0,0 +1,19 @@ +package org.jcnc.llmhub.core.service.config + +import org.springframework.boot.context.properties.ConfigurationProperties + +/** + *模型属性 + * + * @since 2025-04-26 18:01:48 + * @author gewuyou + */ +@ConfigurationProperties(prefix = "llmhub.model-route") +class ModelProperties { + /** + * 模型名前缀 -> 服务名映射 + * 该映射表存储了模型名前缀与服务名的对应关系,用于快速查找模型对应的服务 + * 例:openai -> llmhub-impl-openai + */ + var modelServiceMap: Map = emptyMap() +} \ No newline at end of file diff --git a/llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/controller/ChatController.kt b/llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/controller/ChatController.kt new file mode 100644 index 0000000..31cbb5f --- /dev/null +++ b/llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/controller/ChatController.kt @@ -0,0 +1,21 @@ +package org.jcnc.llmhub.core.service.controller + +import com.gewuyou.forgeboot.webmvc.version.annotation.ApiVersion +import org.jcnc.llmhub.core.service.service.impl.LLMServiceImpl +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +/** + *聊天控制器 + * + * @since 2025-04-26 16:13:26 + * @author gewuyou + */ +@ApiVersion +@RestController +@RequestMapping("/chat") +class ChatController( + private val llmServiceImpl: LLMServiceImpl +) { + +} \ No newline at end of file diff --git a/llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/manager/ModelRouteManager.kt b/llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/manager/ModelRouteManager.kt new file mode 100644 index 0000000..17dcf5b --- /dev/null +++ b/llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/manager/ModelRouteManager.kt @@ -0,0 +1,39 @@ +package org.jcnc.llmhub.core.service.manager + +import org.jcnc.llmhub.core.service.config.ModelProperties +import org.springframework.cloud.context.config.annotation.RefreshScope +import org.springframework.stereotype.Component + +/** + * 模型路由表管理器 + * + * 该类负责管理模型名与服务名之间的映射关系,根据模型名前缀来确定对应的后端服务 + * 主要作用是动态解析和路由模型请求到正确的服务实例 + * + * @since 2025-04-26 17:53:06 + * @author gewuyou + */ +@Component +@RefreshScope // 支持Nacos热刷新,使得配置更新时无需重启应用即可生效 +class ModelRouteManager( + private val modelProperties: ModelProperties +) { + /** + * 根据模型名查找对应服务 + * + * 该方法通过遍历模型服务映射表,找到与模型名前缀匹配的服务名并返回 + * 如果没有找到匹配项,则抛出异常表示不支持该模型类型 + * + * @param model 模型名,用于查找对应服务 + * @return 匹配的后端服务名 + * @throws IllegalArgumentException 如果模型名不匹配任何已知前缀,抛出此异常 + */ + fun resolveServiceName(model: String): String { + for ((prefix, serviceName) in modelProperties.modelServiceMap) { + if (model.startsWith(prefix)) { + return serviceName + } + } + throw IllegalArgumentException("Unsupported model type: $model") + } +} diff --git a/llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/service/LLMService.kt b/llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/service/LLMService.kt new file mode 100644 index 0000000..ec0fe58 --- /dev/null +++ b/llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/service/LLMService.kt @@ -0,0 +1,26 @@ +package org.jcnc.llmhub.core.service.service + +import kotlinx.coroutines.flow.Flow +import org.jcnc.llmhub.core.spi.entities.request.ChatRequest +import org.jcnc.llmhub.core.spi.entities.response.ChatResponsePart +import org.springframework.web.bind.annotation.PostMapping + +/** + *LLM服务 + * + * @since 2025-04-26 17:38:18 + * @author gewuyou + */ +fun interface LLMService { + /** + * 初始化与聊天服务的连接,以处理聊天请求 + * + * 此函数接收一个聊天请求对象,并返回一个Flow流,用于接收聊天响应的部分数据 + * 它主要用于建立聊天通信的通道,而不是发送具体的消息 + * + * @param request 聊天请求对象,包含建立聊天所需的信息,如用户标识、会话标识等 + * @return 返回一个Flow流,通过该流可以接收到聊天响应的部分数据,如消息、状态更新等 + */ + @PostMapping("/chat") + fun chat(request: ChatRequest): Flow +} \ No newline at end of file diff --git a/llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/service/impl/LLMServiceImpl.kt b/llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/service/impl/LLMServiceImpl.kt new file mode 100644 index 0000000..786d643 --- /dev/null +++ b/llmhub-base/llmhub-core/llmhub-core-service/src/main/kotlin/org/jcnc/llmhub/core/service/service/impl/LLMServiceImpl.kt @@ -0,0 +1,42 @@ +package org.jcnc.llmhub.core.service.service.impl + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.reactive.asFlow +import org.jcnc.llmhub.core.service.manager.ModelRouteManager +import org.jcnc.llmhub.core.service.service.LLMService +import org.jcnc.llmhub.core.spi.entities.request.ChatRequest +import org.jcnc.llmhub.core.spi.entities.response.ChatResponsePart +import org.springframework.stereotype.Service +import org.springframework.web.reactive.function.client.WebClient + +/** + *LLM服务实现 + * + * @since 2025-04-25 20:38:13 + * @author gewuyou + */ +@Service +class LLMServiceImpl( + private val modelRouteManager: ModelRouteManager, + private val webClientBuilder: WebClient.Builder +) : LLMService { + /** + * 初始化与聊天服务的连接,以处理聊天请求 + * + * 此函数接收一个聊天请求对象,并返回一个Flow流,用于接收聊天响应的部分数据 + * 它主要用于建立聊天通信的通道,而不是发送具体的消息 + * + * @param request 聊天请求对象,包含建立聊天所需的信息,如用户标识、会话标识等 + * @return 返回一个Flow流,通过该流可以接收到聊天响应的部分数据,如消息、状态更新等 + */ + override fun chat(request: ChatRequest): Flow { + val serviceName = modelRouteManager.resolveServiceName(request.model) + val webClient = webClientBuilder.build() + return webClient.post() + .uri("http://$serviceName/provider/chat/stream") + .bodyValue(request) + .retrieve() + .bodyToFlux(ChatResponsePart::class.java) + .asFlow() + } +} \ No newline at end of file diff --git a/llmhub-base/llmhub-core/llmhub-core-service/src/main/resources/application-dev.yml b/llmhub-base/llmhub-core/llmhub-core-service/src/main/resources/application-dev.yml new file mode 100644 index 0000000..a16b1e1 --- /dev/null +++ b/llmhub-base/llmhub-core/llmhub-core-service/src/main/resources/application-dev.yml @@ -0,0 +1,13 @@ +server: + port: 8081 +spring: + cloud: + nacos: + discovery: + server-addr: 49.235.96.75:8848 # Nacos 服务地址 +llmhub: + model-route: + modelServiceMap: + openai: llmhub-impl-openai + anotherModel: llmhub-impl-another + diff --git a/llmhub-base/llmhub-core/llmhub-core-service/src/main/resources/application-prod.yml b/llmhub-base/llmhub-core/llmhub-core-service/src/main/resources/application-prod.yml new file mode 100644 index 0000000..e78b1c6 --- /dev/null +++ b/llmhub-base/llmhub-core/llmhub-core-service/src/main/resources/application-prod.yml @@ -0,0 +1,7 @@ +server: + port: 9002 +spring: + cloud: + nacos: + discovery: + server-addr: 49.235.96.75:9001 \ No newline at end of file diff --git a/llmhub-base/llmhub-core/llmhub-core-service/src/main/resources/application.yml b/llmhub-base/llmhub-core/llmhub-core-service/src/main/resources/application.yml index 9bf9dba..22cad4a 100644 --- a/llmhub-base/llmhub-core/llmhub-core-service/src/main/resources/application.yml +++ b/llmhub-base/llmhub-core/llmhub-core-service/src/main/resources/application.yml @@ -1,3 +1,5 @@ spring: application: - name: llmhub-core-service \ No newline at end of file + name: llmhub-core-service + profiles: + active: dev \ No newline at end of file diff --git a/llmhub-base/llmhub-core/llmhub-core-spi/build.gradle.kts b/llmhub-base/llmhub-core/llmhub-core-spi/build.gradle.kts index 5fbab79..540aa86 100644 --- a/llmhub-base/llmhub-core/llmhub-core-spi/build.gradle.kts +++ b/llmhub-base/llmhub-core/llmhub-core-spi/build.gradle.kts @@ -1,4 +1,10 @@ - +apply { + plugin(libs.plugins.spring.dependency.management.get().pluginId) + plugin(libs.plugins.spring.boot.get().pluginId) + plugin(libs.plugins.kotlin.plugin.spring.get().pluginId) +} dependencies { - + val libs = rootProject.libs + compileOnly(libs.kotlinx.coruntes.reactor) + compileOnly(libs.springBootStarter.web) } \ No newline at end of file diff --git a/llmhub-base/llmhub-core/llmhub-core-spi/src/main/kotlin/org/jcnc/llmhub/core/spi/entities/request/ChatRequest.kt b/llmhub-base/llmhub-core/llmhub-core-spi/src/main/kotlin/org/jcnc/llmhub/core/spi/entities/request/ChatRequest.kt new file mode 100644 index 0000000..55fc319 --- /dev/null +++ b/llmhub-base/llmhub-core/llmhub-core-spi/src/main/kotlin/org/jcnc/llmhub/core/spi/entities/request/ChatRequest.kt @@ -0,0 +1,17 @@ +package org.jcnc.llmhub.core.spi.entities.request + + +/** + * ChatRequest数据类,用于封装聊天请求的参数 + * @since 2025-04-25 17:07:02 + * @author gewuyou + * @param prompt 用户的聊天提示或消息,是聊天请求的主要输入 + * @param model 使用的聊天模型名称,决定了解析和响应的方式 + * @param options 可选的额外参数集合,用于定制聊天请求的行为和输出 + * 可以包括如最大回复长度、温度(随机性)等 + */ +data class ChatRequest( + val prompt: String, + val model: String, + val options: Map? = null +) diff --git a/llmhub-base/llmhub-core/llmhub-core-spi/src/main/kotlin/org/jcnc/llmhub/core/spi/entities/request/EmbeddingRequest.kt b/llmhub-base/llmhub-core/llmhub-core-spi/src/main/kotlin/org/jcnc/llmhub/core/spi/entities/request/EmbeddingRequest.kt new file mode 100644 index 0000000..9f8c329 --- /dev/null +++ b/llmhub-base/llmhub-core/llmhub-core-spi/src/main/kotlin/org/jcnc/llmhub/core/spi/entities/request/EmbeddingRequest.kt @@ -0,0 +1,18 @@ +package org.jcnc.llmhub.core.spi.entities.request + +/** + * 嵌入请求类 + * + * 该类用于定义文本嵌入的请求数据结构,包含需要进行嵌入处理的输入文本列表 + * 和用于处理嵌入的模型标识符 + * + * @param input 输入文本列表,每个文本作为一个列表元素 + * @param model 指定的嵌入模型标识符,用于确定使用哪种模型进行嵌入处理 + * + * @since 2025-04-25 17:08:13 + * @author gewuyou + */ +data class EmbeddingRequest( + val input: List, + val model: String +) diff --git a/llmhub-base/llmhub-core/llmhub-core-spi/src/main/kotlin/org/jcnc/llmhub/core/spi/entities/response/ChatResponse.kt b/llmhub-base/llmhub-core/llmhub-core-spi/src/main/kotlin/org/jcnc/llmhub/core/spi/entities/response/ChatResponse.kt new file mode 100644 index 0000000..47ac65a --- /dev/null +++ b/llmhub-base/llmhub-core/llmhub-core-spi/src/main/kotlin/org/jcnc/llmhub/core/spi/entities/response/ChatResponse.kt @@ -0,0 +1,38 @@ +package org.jcnc.llmhub.core.spi.entities.response + +/** + * 聊天响应类 + * + * 该类用于封装聊天机器人的响应内容,包括聊天内容和使用情况 + * 主要用途是提供一个结构化的方式来处理和展示聊天机器人的回复信息 + * + * @param content 聊天内容字符串,表示机器人的回复 + * @param other 可选参数,表示其他信息,例如提示词、完成词等 + * @param done 可选参数,表示聊天是否完成,默认为false + * @param usage 可选参数,表示聊天的使用情况,包括使用的token数量等信息 + * @since 2025-04-25 17:07:40 + * @author gewuyou + */ +data class ChatResponsePart( + val content: String, + val other: String? = null, + val done: Boolean = false, + val usage: Usage? = null +) + + +/** + * 使用情况类 + * + * 该类用于详细记录聊天过程中token的使用情况,包括提示词、完成词和总词数 + * 主要用途是提供详细的统计信息,以便用户了解token的消耗情况 + * + * @param promptTokens 提示词使用的token数量 + * @param completionTokens 完成词使用的token数量 + * @param totalTokens 总共使用的token数量 + */ +data class Usage( + val promptTokens: Int, + val completionTokens: Int, + val totalTokens: Int +) diff --git a/llmhub-base/llmhub-core/llmhub-core-spi/src/main/kotlin/org/jcnc/llmhub/core/spi/entities/response/EmbeddingResponse.kt b/llmhub-base/llmhub-core/llmhub-core-spi/src/main/kotlin/org/jcnc/llmhub/core/spi/entities/response/EmbeddingResponse.kt new file mode 100644 index 0000000..d08aa62 --- /dev/null +++ b/llmhub-base/llmhub-core/llmhub-core-spi/src/main/kotlin/org/jcnc/llmhub/core/spi/entities/response/EmbeddingResponse.kt @@ -0,0 +1,18 @@ +package org.jcnc.llmhub.core.spi.entities.response + +/** + * 嵌入响应类 + * + * 该类用于表示嵌入向量的响应结果,包括向量数据及其维度信息 + * 主要用于自然语言处理、图像识别等领域,where向量表示法被广泛应用 + * + * @param vectors 一个包含多个浮点数列表的列表,每个浮点数列表代表一个嵌入向量 + * @param dimensions 一个整数,表示嵌入向量的维度 + * + * @since 2025-04-25 17:10:50 + * @author gewuyou + */ +data class EmbeddingResponse( + val vectors: List>, + val dimensions: Int +) diff --git a/llmhub-base/llmhub-core/llmhub-core-spi/src/main/kotlin/org/jcnc/llmhub/core/spi/provider/LLMProvider.kt b/llmhub-base/llmhub-core/llmhub-core-spi/src/main/kotlin/org/jcnc/llmhub/core/spi/provider/LLMProvider.kt new file mode 100644 index 0000000..08c08bf --- /dev/null +++ b/llmhub-base/llmhub-core/llmhub-core-spi/src/main/kotlin/org/jcnc/llmhub/core/spi/provider/LLMProvider.kt @@ -0,0 +1,43 @@ +package org.jcnc.llmhub.core.spi.provider + +import kotlinx.coroutines.flow.Flow +import org.jcnc.llmhub.core.spi.entities.request.ChatRequest +import org.jcnc.llmhub.core.spi.entities.request.EmbeddingRequest +import org.jcnc.llmhub.core.spi.entities.response.ChatResponsePart +import org.jcnc.llmhub.core.spi.entities.response.EmbeddingResponse +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestMapping + +/** + * LLM 提供商接口 + * 该接口定义了与LLM(Large Language Model)提供商交互的标准方法 + * 主要提供了聊天和嵌入两种功能 + * + * @since 2025-04-25 16:13:00 + * @author gewuyou + */ +@RequestMapping("/provider/chat") +interface LLMProvider { + + /** + * 初始化与聊天服务的连接,以处理聊天请求 + * + * 此函数接收一个聊天请求对象,并返回一个Flow流,用于接收聊天响应的部分数据 + * 它主要用于建立聊天通信的通道,而不是发送具体的消息 + * + * @param request 聊天请求对象,包含建立聊天所需的信息,如用户标识、会话标识等 + * @return 返回一个Flow流,通过该流可以接收到聊天响应的部分数据,如消息、状态更新等 + */ + @PostMapping("/chat") + fun chat(request: ChatRequest): Flow + + /** + * 嵌入功能方法 + * 该方法允许用户发送嵌入请求,以获取LLM生成的嵌入向量 + * + * @param request 嵌入请求对象,包含需要进行嵌入处理的数据 + * @return EmbeddingResponse 嵌入响应对象,包含生成的嵌入向量信息 + */ + @PostMapping("/embedding") + fun embedding(request: EmbeddingRequest): EmbeddingResponse +} diff --git a/llmhub-base/llmhub-impl/build.gradle.kts b/llmhub-base/llmhub-impl/build.gradle.kts index 4551339..e16fdcf 100644 --- a/llmhub-base/llmhub-impl/build.gradle.kts +++ b/llmhub-base/llmhub-impl/build.gradle.kts @@ -1,10 +1,5 @@ - +// 开启springboot +extra[ProjectFlags.IS_ROOT_MODULE] = true dependencies { } -/** - * 由于 Kotlin 插件被引入时会自动添加依赖,但根项目不需要 Kotlin 依赖,因此需要排除 Kotlin 依赖 - */ -configurations.implementation { - exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib") -} diff --git a/llmhub-base/llmhub-impl/llmhub-impl-baiLian/build.gradle.kts b/llmhub-base/llmhub-impl/llmhub-impl-baiLian/build.gradle.kts index 2f4a037..e8b7647 100644 --- a/llmhub-base/llmhub-impl/llmhub-impl-baiLian/build.gradle.kts +++ b/llmhub-base/llmhub-impl/llmhub-impl-baiLian/build.gradle.kts @@ -2,6 +2,6 @@ // 开启springboot extra[ProjectFlags.USE_SPRING_BOOT] = true dependencies { - + implementation(project(Modules.Core.SPI)) }