feat(ASA-P5,P6): 实现嵌入管理与LLM配置API服务层 [AC-ASA-08~AC-ASA-15]
This commit is contained in:
parent
fc53fdc6ac
commit
935dcd1611
|
|
@ -0,0 +1,50 @@
|
||||||
|
import request from '@/utils/request'
|
||||||
|
import type {
|
||||||
|
LLMProviderInfo,
|
||||||
|
LLMConfig,
|
||||||
|
LLMConfigUpdate,
|
||||||
|
LLMTestResult,
|
||||||
|
LLMTestRequest,
|
||||||
|
LLMProvidersResponse,
|
||||||
|
LLMConfigUpdateResponse
|
||||||
|
} from '@/types/llm'
|
||||||
|
|
||||||
|
export function getLLMProviders(): Promise<LLMProvidersResponse> {
|
||||||
|
return request({
|
||||||
|
url: '/llm/providers',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getLLMConfig(): Promise<LLMConfig> {
|
||||||
|
return request({
|
||||||
|
url: '/llm/config',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function saveLLMConfig(data: LLMConfigUpdate): Promise<LLMConfigUpdateResponse> {
|
||||||
|
return request({
|
||||||
|
url: '/llm/config',
|
||||||
|
method: 'put',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function testLLM(data: LLMTestRequest): Promise<LLMTestResult> {
|
||||||
|
return request({
|
||||||
|
url: '/llm/test',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export type {
|
||||||
|
LLMProviderInfo,
|
||||||
|
LLMConfig,
|
||||||
|
LLMConfigUpdate,
|
||||||
|
LLMTestResult,
|
||||||
|
LLMTestRequest,
|
||||||
|
LLMProvidersResponse,
|
||||||
|
LLMConfigUpdateResponse
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,131 @@
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
|
|
||||||
export function runRagExperiment(data: { query: string, kbIds?: string[], params?: any }) {
|
export interface AIResponse {
|
||||||
|
content: string
|
||||||
|
prompt_tokens?: number
|
||||||
|
completion_tokens?: number
|
||||||
|
total_tokens?: number
|
||||||
|
latency_ms?: number
|
||||||
|
model?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RetrievalResult {
|
||||||
|
content: string
|
||||||
|
score: number
|
||||||
|
source: string
|
||||||
|
metadata?: Record<string, any>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RagExperimentRequest {
|
||||||
|
query: string
|
||||||
|
kb_ids?: string[]
|
||||||
|
top_k?: number
|
||||||
|
score_threshold?: number
|
||||||
|
llm_provider?: string
|
||||||
|
generate_response?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RagExperimentResult {
|
||||||
|
query: string
|
||||||
|
retrieval_results?: RetrievalResult[]
|
||||||
|
final_prompt?: string
|
||||||
|
ai_response?: AIResponse
|
||||||
|
total_latency_ms?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export function runRagExperiment(data: RagExperimentRequest): Promise<RagExperimentResult> {
|
||||||
return request({
|
return request({
|
||||||
url: '/admin/rag/experiments/run',
|
url: '/admin/rag/experiments/run',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function runRagExperimentStream(
|
||||||
|
data: RagExperimentRequest,
|
||||||
|
onMessage: (event: MessageEvent) => void,
|
||||||
|
onError?: (error: Event) => void,
|
||||||
|
onComplete?: () => void
|
||||||
|
): EventSource {
|
||||||
|
const baseUrl = import.meta.env.VITE_APP_BASE_API || '/api'
|
||||||
|
const url = `${baseUrl}/admin/rag/experiments/stream`
|
||||||
|
|
||||||
|
const eventSource = new EventSource(url, {
|
||||||
|
withCredentials: true
|
||||||
|
})
|
||||||
|
|
||||||
|
eventSource.onmessage = onMessage
|
||||||
|
eventSource.onerror = (error) => {
|
||||||
|
eventSource.close()
|
||||||
|
onError?.(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
return eventSource
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createSSEConnection(
|
||||||
|
url: string,
|
||||||
|
body: RagExperimentRequest,
|
||||||
|
onMessage: (data: string) => void,
|
||||||
|
onError?: (error: Error) => void,
|
||||||
|
onComplete?: () => void
|
||||||
|
): () => void {
|
||||||
|
const baseUrl = import.meta.env.VITE_APP_BASE_API || '/api'
|
||||||
|
const fullUrl = `${baseUrl}${url}`
|
||||||
|
|
||||||
|
const controller = new AbortController()
|
||||||
|
|
||||||
|
fetch(fullUrl, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Accept': 'text/event-stream',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
signal: controller.signal
|
||||||
|
})
|
||||||
|
.then(async (response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP error! status: ${response.status}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const reader = response.body?.getReader()
|
||||||
|
if (!reader) {
|
||||||
|
throw new Error('No response body')
|
||||||
|
}
|
||||||
|
|
||||||
|
const decoder = new TextDecoder()
|
||||||
|
let buffer = ''
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const { done, value } = await reader.read()
|
||||||
|
|
||||||
|
if (done) {
|
||||||
|
onComplete?.()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer += decoder.decode(value, { stream: true })
|
||||||
|
const lines = buffer.split('\n')
|
||||||
|
buffer = lines.pop() || ''
|
||||||
|
|
||||||
|
for (const line of lines) {
|
||||||
|
if (line.startsWith('data: ')) {
|
||||||
|
const data = line.slice(6)
|
||||||
|
if (data === '[DONE]') {
|
||||||
|
onComplete?.()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
onMessage(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
if (error.name !== 'AbortError') {
|
||||||
|
onError?.(error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return () => controller.abort()
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
export interface LLMProviderInfo {
|
||||||
|
name: string
|
||||||
|
display_name: string
|
||||||
|
description?: string
|
||||||
|
config_schema: Record<string, any>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LLMConfig {
|
||||||
|
provider: string
|
||||||
|
config: Record<string, any>
|
||||||
|
updated_at?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LLMConfigUpdate {
|
||||||
|
provider: string
|
||||||
|
config?: Record<string, any>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LLMTestResult {
|
||||||
|
success: boolean
|
||||||
|
response?: string
|
||||||
|
latency_ms?: number
|
||||||
|
prompt_tokens?: number
|
||||||
|
completion_tokens?: number
|
||||||
|
total_tokens?: number
|
||||||
|
message?: string
|
||||||
|
error?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LLMTestRequest {
|
||||||
|
test_prompt?: string
|
||||||
|
config?: LLMConfigUpdate
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LLMProvidersResponse {
|
||||||
|
providers: LLMProviderInfo[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LLMConfigUpdateResponse {
|
||||||
|
success: boolean
|
||||||
|
message: string
|
||||||
|
}
|
||||||
|
|
@ -50,7 +50,7 @@ version: "0.3.0"
|
||||||
- [x] (P5-01~P5-06) 后端管理接口实现
|
- [x] (P5-01~P5-06) 后端管理接口实现
|
||||||
|
|
||||||
#### Phase 6: 嵌入模型管理(待处理)
|
#### Phase 6: 嵌入模型管理(待处理)
|
||||||
- [ ] (P5-01) API 服务层与类型定义 [AC-ASA-08, AC-ASA-09]
|
- [x] (P5-01) API 服务层与类型定义 [AC-ASA-08, AC-ASA-09]
|
||||||
- [ ] (P5-02) 提供者选择组件 [AC-ASA-09]
|
- [ ] (P5-02) 提供者选择组件 [AC-ASA-09]
|
||||||
- [ ] (P5-03) 动态配置表单 [AC-ASA-09, AC-ASA-10]
|
- [ ] (P5-03) 动态配置表单 [AC-ASA-09, AC-ASA-10]
|
||||||
- [ ] (P5-04) 测试连接组件 [AC-ASA-11, AC-ASA-12]
|
- [ ] (P5-04) 测试连接组件 [AC-ASA-11, AC-ASA-12]
|
||||||
|
|
@ -60,7 +60,7 @@ version: "0.3.0"
|
||||||
- [ ] (P5-08) 组件整合与测试 [AC-ASA-08~AC-ASA-13]
|
- [ ] (P5-08) 组件整合与测试 [AC-ASA-08~AC-ASA-13]
|
||||||
|
|
||||||
#### Phase 7: LLM 配置与 RAG 调试输出(当前)
|
#### Phase 7: LLM 配置与 RAG 调试输出(当前)
|
||||||
- [ ] (P6-01) LLM API 服务层与类型定义:创建 src/api/llm.ts 和 src/types/llm.ts [AC-ASA-14, AC-ASA-15]
|
- [x] (P6-01) LLM API 服务层与类型定义:创建 src/api/llm.ts 和 src/types/llm.ts [AC-ASA-14, AC-ASA-15]
|
||||||
- [ ] (P6-02) LLM 提供者选择组件:创建 LLMProviderSelect.vue [AC-ASA-15]
|
- [ ] (P6-02) LLM 提供者选择组件:创建 LLMProviderSelect.vue [AC-ASA-15]
|
||||||
- [ ] (P6-03) LLM 动态配置表单:创建 LLMConfigForm.vue [AC-ASA-15, AC-ASA-16]
|
- [ ] (P6-03) LLM 动态配置表单:创建 LLMConfigForm.vue [AC-ASA-15, AC-ASA-16]
|
||||||
- [ ] (P6-04) LLM 测试连接组件:创建 LLMTestPanel.vue [AC-ASA-17, AC-ASA-18]
|
- [ ] (P6-04) LLM 测试连接组件:创建 LLMTestPanel.vue [AC-ASA-17, AC-ASA-18]
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ principles:
|
||||||
|
|
||||||
> 页面导向:嵌入模型配置页面,支持提供者切换、参数配置、连接测试。
|
> 页面导向:嵌入模型配置页面,支持提供者切换、参数配置、连接测试。
|
||||||
|
|
||||||
- [ ] (P5-01) API 服务层与类型定义:创建 src/api/embedding.ts 和 src/types/embedding.ts
|
- [x] (P5-01) API 服务层与类型定义:创建 src/api/embedding.ts 和 src/types/embedding.ts
|
||||||
- AC: [AC-ASA-08, AC-ASA-09]
|
- AC: [AC-ASA-08, AC-ASA-09]
|
||||||
|
|
||||||
- [ ] (P5-02) 提供者选择组件:实现 `EmbeddingProviderSelect` 下拉组件,对接 `/admin/embedding/providers`
|
- [ ] (P5-02) 提供者选择组件:实现 `EmbeddingProviderSelect` 下拉组件,对接 `/admin/embedding/providers`
|
||||||
|
|
@ -153,7 +153,7 @@ principles:
|
||||||
|
|
||||||
| 任务 | 描述 | 状态 |
|
| 任务 | 描述 | 状态 |
|
||||||
|------|------|------|
|
|------|------|------|
|
||||||
| P5-01 | API 服务层与类型定义 | ⏳ 待处理 |
|
| P5-01 | API 服务层与类型定义 | ✅ 已完成 |
|
||||||
| P5-02 | 提供者选择组件 | ⏳ 待处理 |
|
| P5-02 | 提供者选择组件 | ⏳ 待处理 |
|
||||||
| P5-03 | 动态配置表单 | ⏳ 待处理 |
|
| P5-03 | 动态配置表单 | ⏳ 待处理 |
|
||||||
| P5-04 | 测试连接组件 | ⏳ 待处理 |
|
| P5-04 | 测试连接组件 | ⏳ 待处理 |
|
||||||
|
|
@ -170,7 +170,7 @@ principles:
|
||||||
|
|
||||||
### 6.1 LLM 模型配置
|
### 6.1 LLM 模型配置
|
||||||
|
|
||||||
- [ ] (P6-01) LLM API 服务层与类型定义:创建 src/api/llm.ts 和 src/types/llm.ts
|
- [x] (P6-01) LLM API 服务层与类型定义:创建 src/api/llm.ts 和 src/types/llm.ts
|
||||||
- AC: [AC-ASA-14, AC-ASA-15]
|
- AC: [AC-ASA-14, AC-ASA-15]
|
||||||
|
|
||||||
- [ ] (P6-02) LLM 提供者选择组件:实现 `LLMProviderSelect` 下拉组件
|
- [ ] (P6-02) LLM 提供者选择组件:实现 `LLMProviderSelect` 下拉组件
|
||||||
|
|
@ -208,7 +208,7 @@ principles:
|
||||||
|
|
||||||
| 任务 | 描述 | 状态 |
|
| 任务 | 描述 | 状态 |
|
||||||
|------|------|------|
|
|------|------|------|
|
||||||
| P6-01 | LLM API 服务层与类型定义 | ⏳ 待处理 |
|
| P6-01 | LLM API 服务层与类型定义 | ✅ 已完成 |
|
||||||
| P6-02 | LLM 提供者选择组件 | ⏳ 待处理 |
|
| P6-02 | LLM 提供者选择组件 | ⏳ 待处理 |
|
||||||
| P6-03 | LLM 动态配置表单 | ⏳ 待处理 |
|
| P6-03 | LLM 动态配置表单 | ⏳ 待处理 |
|
||||||
| P6-04 | LLM 测试连接组件 | ⏳ 待处理 |
|
| P6-04 | LLM 测试连接组件 | ⏳ 待处理 |
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue