feat: RAG 配置优化与检索日志增强 [AC-AISVC-16, AC-AISVC-17]
This commit is contained in:
parent
cee884d9a0
commit
02f03a3a12
|
|
@ -1,4 +1,5 @@
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
|
import { useTenantStore } from '@/stores/tenant'
|
||||||
|
|
||||||
export interface AIResponse {
|
export interface AIResponse {
|
||||||
content: string
|
content: string
|
||||||
|
|
@ -73,6 +74,8 @@ export function createSSEConnection(
|
||||||
const baseUrl = import.meta.env.VITE_APP_BASE_API || '/api'
|
const baseUrl = import.meta.env.VITE_APP_BASE_API || '/api'
|
||||||
const fullUrl = `${baseUrl}${url}`
|
const fullUrl = `${baseUrl}${url}`
|
||||||
|
|
||||||
|
const tenantStore = useTenantStore()
|
||||||
|
|
||||||
const controller = new AbortController()
|
const controller = new AbortController()
|
||||||
|
|
||||||
fetch(fullUrl, {
|
fetch(fullUrl, {
|
||||||
|
|
@ -80,6 +83,7 @@ export function createSSEConnection(
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Accept': 'text/event-stream',
|
'Accept': 'text/event-stream',
|
||||||
|
'X-Tenant-Id': tenantStore.currentTenantId || '',
|
||||||
},
|
},
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
signal: controller.signal
|
signal: controller.signal
|
||||||
|
|
|
||||||
|
|
@ -44,10 +44,17 @@ class Settings(BaseSettings):
|
||||||
ollama_embedding_model: str = "nomic-embed-text"
|
ollama_embedding_model: str = "nomic-embed-text"
|
||||||
|
|
||||||
rag_top_k: int = 5
|
rag_top_k: int = 5
|
||||||
rag_score_threshold: float = 0.3
|
rag_score_threshold: float = 0.01
|
||||||
rag_min_hits: int = 1
|
rag_min_hits: int = 1
|
||||||
rag_max_evidence_tokens: int = 2000
|
rag_max_evidence_tokens: int = 2000
|
||||||
|
|
||||||
|
rag_two_stage_enabled: bool = True
|
||||||
|
rag_two_stage_expand_factor: int = 10
|
||||||
|
rag_hybrid_enabled: bool = True
|
||||||
|
rag_rrf_k: int = 60
|
||||||
|
rag_vector_weight: float = 0.7
|
||||||
|
rag_bm25_weight: float = 0.3
|
||||||
|
|
||||||
confidence_low_threshold: float = 0.5
|
confidence_low_threshold: float = 0.5
|
||||||
confidence_high_threshold: float = 0.8
|
confidence_high_threshold: float = 0.8
|
||||||
confidence_insufficient_penalty: float = 0.3
|
confidence_insufficient_penalty: float = 0.3
|
||||||
|
|
|
||||||
|
|
@ -61,14 +61,23 @@ class VectorRetriever(BaseRetriever):
|
||||||
RetrievalResult with filtered hits.
|
RetrievalResult with filtered hits.
|
||||||
"""
|
"""
|
||||||
logger.info(
|
logger.info(
|
||||||
f"[AC-AISVC-16] Starting vector retrieval for tenant={ctx.tenant_id}, query={ctx.query[:50]}..."
|
f"[AC-AISVC-16] Starting vector retrieval for tenant={ctx.tenant_id}, "
|
||||||
|
f"query={ctx.query[:50]}..."
|
||||||
|
)
|
||||||
|
logger.info(
|
||||||
|
f"[AC-AISVC-16] Retrieval config: top_k={self._top_k}, "
|
||||||
|
f"score_threshold={self._score_threshold}, min_hits={self._min_hits}"
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
client = await self._get_client()
|
client = await self._get_client()
|
||||||
|
logger.info(f"[AC-AISVC-16] Got Qdrant client: {type(client).__name__}")
|
||||||
|
|
||||||
|
logger.info("[AC-AISVC-16] Generating embedding for query...")
|
||||||
query_vector = await self._get_embedding(ctx.query)
|
query_vector = await self._get_embedding(ctx.query)
|
||||||
|
logger.info(f"[AC-AISVC-16] Embedding generated: dim={len(query_vector)}")
|
||||||
|
|
||||||
|
logger.info(f"[AC-AISVC-16] Searching in tenant collection: tenant_id={ctx.tenant_id}")
|
||||||
hits = await client.search(
|
hits = await client.search(
|
||||||
tenant_id=ctx.tenant_id,
|
tenant_id=ctx.tenant_id,
|
||||||
query_vector=query_vector,
|
query_vector=query_vector,
|
||||||
|
|
@ -76,6 +85,8 @@ class VectorRetriever(BaseRetriever):
|
||||||
score_threshold=self._score_threshold,
|
score_threshold=self._score_threshold,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
logger.info(f"[AC-AISVC-16] Search returned {len(hits)} raw hits")
|
||||||
|
|
||||||
retrieval_hits = [
|
retrieval_hits = [
|
||||||
RetrievalHit(
|
RetrievalHit(
|
||||||
text=hit.get("payload", {}).get("text", ""),
|
text=hit.get("payload", {}).get("text", ""),
|
||||||
|
|
@ -105,13 +116,19 @@ class VectorRetriever(BaseRetriever):
|
||||||
f"insufficient={is_insufficient}, max_score={diagnostics['max_score']:.3f}"
|
f"insufficient={is_insufficient}, max_score={diagnostics['max_score']:.3f}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if len(retrieval_hits) == 0:
|
||||||
|
logger.warning(
|
||||||
|
f"[AC-AISVC-17] No hits found! tenant={ctx.tenant_id}, "
|
||||||
|
f"query={ctx.query[:50]}..., raw_hits={len(hits)}, threshold={self._score_threshold}"
|
||||||
|
)
|
||||||
|
|
||||||
return RetrievalResult(
|
return RetrievalResult(
|
||||||
hits=retrieval_hits,
|
hits=retrieval_hits,
|
||||||
diagnostics=diagnostics,
|
diagnostics=diagnostics,
|
||||||
)
|
)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"[AC-AISVC-16] Retrieval error: {e}")
|
logger.error(f"[AC-AISVC-16] Retrieval error: {e}", exc_info=True)
|
||||||
return RetrievalResult(
|
return RetrievalResult(
|
||||||
hits=[],
|
hits=[],
|
||||||
diagnostics={"error": str(e), "is_insufficient": True},
|
diagnostics={"error": str(e), "is_insufficient": True},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue