elec_rag_ui/src/main/ipc/queryHandler.ts
surui 836d25cad2 refactor: 推理请求统一走 er_backend 代理(127.0.0.1:17700)
- 嵌入/生成服务地址不再由前端按 cardType 推导端口,改为经 er_backend
  的 /v1/* 代理转发,服务端口以后端配置为唯一真相来源
- config.ts: 新增 ER_BACKEND_URL 统一常量,删除端口推导逻辑
- generator/statusHandler/queryHandler/erBackendHandler 跟随改造
- fix: package-kylin-arm64-deb.sh 从 .app-version 读版本号时剥离 v 前缀,
  修复无 git 环境下 dpkg-deb 报"版本号没有以数字开头"
2026-08-16 21:16:01 +08:00

64 lines
2.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { ipcMain, BrowserWindow } from 'electron'
import { getConfig, getDbPath } from '../config'
import { embedOne } from '../rag/embedder'
import { search } from '../db/lancedb'
import { streamGenerate } from '../rag/generator'
export function registerQueryHandlers(getWin: () => BrowserWindow | null): void {
ipcMain.handle('query', async (_event, payload: {
question: string
systemPrompt: string
topK: number
}) => {
const config = getConfig()
const dbPath = getDbPath()
console.log(`\n${'='.repeat(60)}`)
console.log('[query] 问题:', payload.question)
console.log('[query] topK:', payload.topK)
console.log('[query] 向量化方式:', config.embed.provider, '生成/嵌入服务:er_backend 代理(127.0.0.1:17700)')
const send = (channel: string, data: unknown): void => {
getWin()?.webContents.send(channel, data)
}
try {
// 1. 问题向量化
send('query:stage', { stage: '正在向量化...' })
const queryVector = await embedOne(payload.question, config.embed)
console.log('[query] 问题向量化完成,维度:', queryVector.length)
// 2. 向量检索
send('query:stage', { stage: '正在检索...' })
const chunks = await search(dbPath, queryVector, payload.topK)
console.log(`[query] 检索到 ${chunks.length} 个片段:`)
chunks.forEach((c, i) => {
console.log(` 片段${i + 1} 相关度=${c.score} 来源=${c.source}`)
console.log(` 内容前100字:${c.content.slice(0, 100).replace(/\n/g, ' ')}`)
})
send('query:context', { chunks })
send('query:stage', { stage: '正在生成...' })
if (chunks.length === 0) {
send('query:delta', { delta: '我不知道。' })
send('query:done', {})
return
}
// 3. 流式生成
await streamGenerate(
payload.question,
chunks,
payload.systemPrompt,
{
onDelta: (delta) => send('query:delta', { delta }),
onDone: (stats) => send('query:done', { stats: stats ?? null }),
onError: (message) => send('query:error', { message })
}
)
} catch (e) {
send('query:error', { message: String(e) })
}
})
}