Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 0 additions & 22 deletions ai/src/ai_server/chain/prompts/rerank.py

This file was deleted.

5 changes: 2 additions & 3 deletions ai/src/ai_server/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@ class Settings(BaseSettings):
ai_realtime_exchange: str = "stackup.realtime"
ai_realtime_routing_user: str = "realtime.user.notify"
feedback_rag_top_k: int = 5
# 리랭킹: 하이브리드 검색으로 후보 N개(candidate_k)를 가져와 LLM 으로 재정렬 후 top_k 주입.
rerank_enabled: bool = True
rerank_candidate_k: int = 20
# RAG 컨텍스트 구성(임베딩+검색) 전체 상한. 초과 시 (none) 으로 폴백해 첫 토큰을 막지 않는다.
followup_rag_timeout_sec: float = 1.5
# 질문 풀 초기 크기. Core 의 applyPool 이 questions[0] 만 INSERT 하므로 1 로 고정해 토큰 낭비 차단.
# 후속 작업에서 풀 저장 도입 시 늘리기 (예: 5).
questions_initial_pool_size: int = 1
Expand Down
10 changes: 1 addition & 9 deletions ai/src/ai_server/messaging/consumers/feedback_consumer.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
VoiceAnalysisSummary,
)
from ai_server.rag.embedder import EmbeddingProvider
from ai_server.rag.reranker import NoopReranker, Reranker, rerank_hits

log = structlog.get_logger(__name__)

Expand All @@ -41,8 +40,6 @@ def __init__(
core_client: CoreClient,
embedder: EmbeddingProvider | None = None,
rag_top_k: int = 5,
reranker: Reranker | None = None,
candidate_k: int = 20,
) -> None:
self._generator = generator
self._publisher = publisher
Expand All @@ -51,8 +48,6 @@ def __init__(
self._core = core_client
self._embedder = embedder
self._rag_top_k = rag_top_k
self._reranker = reranker or NoopReranker()
self._candidate_k = max(candidate_k, rag_top_k)

async def handle(self, message: AbstractIncomingMessage) -> None:
async with message.process(requeue=False):
Expand Down Expand Up @@ -148,16 +143,13 @@ async def _build_rag_context(self, req: GenerateFeedbackRequest) -> str:
query_embedding=query_vec,
query_text=last_answer,
document_ids=req.context_document_ids,
top_k=self._candidate_k,
top_k=self._rag_top_k,
)
except Exception as exc:
log.warn("feedback.rag.failed", error=str(exc), session_id=req.session_id)
return "(none)"
if not hits:
return "(none)"
hits = await rerank_hits(
self._reranker, query=last_answer, hits=hits, top_k=self._rag_top_k
)
return "\n---\n".join(
f"[doc#{h.document_id} chunk#{h.chunk_index}] {h.chunk_text}" for h in hits
)
Expand Down
24 changes: 15 additions & 9 deletions ai/src/ai_server/messaging/consumers/followup_consumer.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
GenerateFollowupRequest,
)
from ai_server.rag.embedder import EmbeddingProvider
from ai_server.rag.reranker import NoopReranker, Reranker, rerank_hits

log = structlog.get_logger(__name__)

Expand All @@ -43,13 +42,12 @@ def __init__(
core_client: CoreClient | None = None,
embedder: EmbeddingProvider | None = None,
rag_top_k: int = 5,
reranker: Reranker | None = None,
candidate_k: int = 20,
streaming_generator: StreamingFollowupGenerator | None = None,
session_notifier: SessionRealtimeNotifier | None = None,
tts=None,
storage=None,
tts_voice: str = "",
rag_timeout_sec: float = 1.5,
) -> None:
self._generator = generator
self._publisher = publisher
Expand All @@ -58,13 +56,12 @@ def __init__(
self._core = core_client
self._embedder = embedder
self._rag_top_k = rag_top_k
self._reranker = reranker or NoopReranker()
self._candidate_k = max(candidate_k, rag_top_k)
self._streaming = streaming_generator
self._notifier = session_notifier
self._tts = tts
self._storage = storage
self._tts_voice = tts_voice
self._rag_timeout_sec = rag_timeout_sec

async def handle(self, message: AbstractIncomingMessage) -> None:
async with message.process(requeue=False):
Expand Down Expand Up @@ -233,7 +230,19 @@ async def _synth_segment(
async def _build_rag_context(self, req: GenerateFollowupRequest) -> str:
if not self._core or not self._embedder or not req.context_document_ids:
return "(none)"
try:
return await asyncio.wait_for(
self._do_build_rag_context(req), timeout=self._rag_timeout_sec
)
except asyncio.TimeoutError:
log.warning(
"followup.rag.timeout",
session_id=req.session_id,
timeout_sec=self._rag_timeout_sec,
)
return "(none)"

async def _do_build_rag_context(self, req: GenerateFollowupRequest) -> str:
query = f"{req.previous_question}\n\n{req.answer_text}"
try:
query_vec = (
Expand All @@ -243,17 +252,14 @@ async def _build_rag_context(self, req: GenerateFollowupRequest) -> str:
query_embedding=query_vec,
query_text=query,
document_ids=req.context_document_ids,
top_k=self._candidate_k,
top_k=self._rag_top_k,
)
except Exception as exc:
log.warn("followup.rag.failed", error=str(exc), session_id=req.session_id)
return "(none)"

if not hits:
return "(none)"
hits = await rerank_hits(
self._reranker, query=query, hits=hits, top_k=self._rag_top_k
)
return "\n---\n".join(
f"[doc#{h.document_id} chunk#{h.chunk_index}] {h.chunk_text}" for h in hits
)
Expand Down
10 changes: 1 addition & 9 deletions ai/src/ai_server/messaging/consumers/questions_consumer.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
QuestionPoolCallbackPayload,
)
from ai_server.rag.embedder import EmbeddingProvider
from ai_server.rag.reranker import NoopReranker, Reranker, rerank_hits

log = structlog.get_logger(__name__)

Expand All @@ -31,8 +30,6 @@ def __init__(
core_client: CoreClient | None = None,
embedder: EmbeddingProvider | None = None,
rag_top_k: int = 5,
reranker: Reranker | None = None,
candidate_k: int = 20,
) -> None:
self._generator = generator
self._publisher = publisher
Expand All @@ -44,8 +41,6 @@ def __init__(
self._core = core_client
self._embedder = embedder
self._rag_top_k = rag_top_k
self._reranker = reranker or NoopReranker()
self._candidate_k = max(candidate_k, rag_top_k)

async def handle(self, message: AbstractIncomingMessage) -> None:
async with message.process(requeue=False):
Expand Down Expand Up @@ -138,17 +133,14 @@ async def _build_context(self, req: GenerateQuestionsRequest) -> str:
query_embedding=query_vec,
query_text=query,
document_ids=document_ids,
top_k=self._candidate_k,
top_k=self._rag_top_k,
)
except Exception as exc:
log.warn("questions.rag.failed", error=str(exc), session_id=req.session_id)
return base_context

if not hits:
return base_context
hits = await rerank_hits(
self._reranker, query=query, hits=hits, top_k=self._rag_top_k
)
rag_context = "\n---\n".join(
f"[doc#{h.document_id} chunk#{h.chunk_index}] {h.chunk_text}" for h in hits
)
Expand Down
9 changes: 1 addition & 8 deletions ai/src/ai_server/messaging/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
from ai_server.messaging.connection import RabbitConnection
from ai_server.rag.chunker import MarkdownChunker
from ai_server.rag.embedder import build_embedding_provider
from ai_server.rag.reranker import build_reranker
from ai_server.messaging.consumers.feedback_consumer import FeedbackConsumer
from ai_server.messaging.consumers.followup_consumer import FollowupConsumer
from ai_server.messaging.consumers.questions_consumer import QuestionsConsumer
Expand Down Expand Up @@ -102,7 +101,6 @@ def __init__(self, settings: Settings) -> None:
max_retries=settings.embedding_max_retries,
retry_base_delay_sec=settings.embedding_retry_base_delay_sec,
)
reranker = build_reranker(settings, core_client=core_client)
vision_pdf_reader = build_vision_pdf_reader(settings, core_client=core_client)

# 이력서 PDF
Expand Down Expand Up @@ -182,8 +180,6 @@ def __init__(self, settings: Settings) -> None:
initial_pool_size=settings.questions_initial_pool_size,
core_client=core_client,
embedder=embedder,
reranker=reranker,
candidate_k=settings.rerank_candidate_k,
)

# 꼬리질문 생성 (US-19)
Expand All @@ -206,13 +202,12 @@ def __init__(self, settings: Settings) -> None:
callback_routing_key=settings.ai_callback_routing_questions,
core_client=core_client,
embedder=embedder,
reranker=reranker,
candidate_k=settings.rerank_candidate_k,
streaming_generator=streaming_followup_generator,
session_notifier=session_notifier,
tts=tts,
storage=storage,
tts_voice=settings.openai_tts_voice,
rag_timeout_sec=settings.followup_rag_timeout_sec,
)

# 종합 피드백 생성 (US-24)
Expand All @@ -226,8 +221,6 @@ def __init__(self, settings: Settings) -> None:
callback_routing_key=settings.ai_callback_routing_feedback,
core_client=core_client,
embedder=embedder,
reranker=reranker,
candidate_k=settings.rerank_candidate_k,
rag_top_k=settings.feedback_rag_top_k,
)

Expand Down
119 changes: 0 additions & 119 deletions ai/src/ai_server/rag/reranker.py

This file was deleted.

Loading