Files
xianjing-ai/engine/app/retrieval.py
T

81 lines
2.8 KiB
Python
Raw Normal View History

from __future__ import annotations
from typing import Any
from .config_loader import business_config
2026-09-20 01:08:11 +00:00
from .ragflow_client import RagflowClient, RagflowError
from .settings import settings
class RetrievalResult:
2026-09-20 01:08:11 +00:00
def __init__(self, chunks: list[dict[str, Any]], backend: str, warning: str = ""):
self.chunks = chunks
2026-09-20 01:08:11 +00:00
self.backend = backend
self.warning = warning
def retrieve_for_scheme(slots: dict[str, str], bundle: list[str]) -> RetrievalResult:
2026-09-20 01:08:11 +00:00
backend = (settings.retrieval_backend or "ragflow").lower()
if backend == "mock":
return _retrieve_mock(slots, bundle)
try:
return _retrieve_ragflow(slots, bundle)
2026-09-20 01:08:11 +00:00
except RagflowError as exc:
return RetrievalResult([], "ragflow", warning=str(exc))
def _retrieve_mock(slots: dict[str, str], bundle: list[str]) -> RetrievalResult:
chunks = business_config.chunks
picked: list[dict[str, Any]] = []
bundle_set = set(bundle)
2026-09-20 01:08:11 +00:00
for chunk in chunks:
if chunk.get("product") in bundle_set:
picked.append(chunk)
blob = " ".join(slots.values())
2026-09-20 01:08:11 +00:00
for chunk in chunks:
if chunk in picked:
continue
2026-09-20 01:08:11 +00:00
tags = chunk.get("tags") or []
if any(str(tag) in blob for tag in tags):
picked.append(chunk)
if len(picked) >= 4:
break
if not picked:
picked = chunks[:2]
2026-09-20 01:08:11 +00:00
return RetrievalResult(picked[:4], "mock")
def _retrieve_ragflow(slots: dict[str, str], bundle: list[str]) -> RetrievalResult:
2026-09-20 01:08:11 +00:00
client = RagflowClient()
query = " ".join(
[
slots.get("tech_category", ""),
slots.get("scenario", ""),
slots.get("key_metric", ""),
2026-09-20 01:08:11 +00:00
slots.get("constraints", ""),
" ".join(bundle),
2026-09-20 01:08:11 +00:00
"产品组合 适用场景 注意事项",
]
2026-09-20 01:08:11 +00:00
).strip()
dataset_ids = [item.strip() for item in settings.ragflow_dataset_ids.split(",") if item.strip()]
raw = client.retrieve(query, dataset_ids, page_size=4)
normalized = []
2026-09-20 01:08:11 +00:00
for index, item in enumerate(raw[:4]):
if not isinstance(item, dict):
continue
normalized.append(
{
2026-09-20 01:08:11 +00:00
"id": item.get("id") or f"rf-{index}",
"title": item.get("document_keyword")
or item.get("document_name")
or item.get("docnm_kwd")
or "知识片段",
"product": item.get("document_id") or "",
"content": item.get("content") or item.get("content_with_weight") or "",
"tags": [],
2026-09-20 01:08:11 +00:00
"score": item.get("similarity"),
}
)
2026-09-20 01:08:11 +00:00
warning = "" if normalized else "知识库没有召回到可用片段,方案仅供草稿,建议转人工。"
return RetrievalResult(normalized, "ragflow", warning=warning)