IDEA-2/1/5/7: 스마트 알림, 대화 기반 RAG, CRAG, 파라미터 자동 튜닝
- IDEA-2 스마트 알림: td_reminders 테이블, set_reminder/list_reminders 도구,
SchedulerService(asyncio 60초 루프, D-7/D-1/D-0 Telegram push),
FastAPI lifespan 연동, GET /reminders/{user_id} 엔드포인트
- IDEA-1 대화 기반 RAG: IngestionService.store_text() 추가,
AgentService._maybe_index_conversation() — 응답 후 LLM 판단 → Qdrant 저장
(CONV_RAG_ENABLED=true 활성화, background task로 응답 속도 무관)
- IDEA-5 CRAG: AgentState에 crag_fallback_used 플래그 추가,
crag_check LangGraph 노드 — search_documents 결과 없으면 web_search 자동 주입,
route_after_crag으로 fallback 1회 루프 제어 (CRAG_ENABLED=true 활성화)
- IDEA-7 RAG Auto-Eval: eval/auto_tune.py — API 서버 없이 파라미터 조합별
context_precision/recall 비교, 최적 설정 추천
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -110,6 +110,18 @@ class DatabaseService:
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
""")
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS td_reminders (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id VARCHAR(50) NOT NULL,
|
||||
remind_date DATE NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
sent_d0 TINYINT(1) NOT NULL DEFAULT 0,
|
||||
sent_d1 TINYINT(1) NOT NULL DEFAULT 0,
|
||||
sent_d7 TINYINT(1) NOT NULL DEFAULT 0,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
""")
|
||||
conn.commit()
|
||||
self._migrate_schema(conn)
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
from __future__ import annotations
|
||||
from datetime import date, timedelta
|
||||
|
||||
from services.db.mysql_service import DatabaseService
|
||||
|
||||
|
||||
class ReminderRepository:
|
||||
"""td_reminders 테이블을 통한 알림 저장소."""
|
||||
|
||||
def __init__(self, db: DatabaseService):
|
||||
self._db = db
|
||||
|
||||
def add(self, user_id: str, remind_date: date, message: str) -> int:
|
||||
return self._db.execute_write(
|
||||
"INSERT INTO td_reminders (user_id, remind_date, message) VALUES (%s, %s, %s)",
|
||||
(user_id, remind_date.isoformat(), message),
|
||||
)
|
||||
|
||||
def get_upcoming(self, user_id: str, days_ahead: int = 30) -> list[dict]:
|
||||
today = date.today()
|
||||
limit = today + timedelta(days=days_ahead)
|
||||
return self._db.execute(
|
||||
"""SELECT id, remind_date, message
|
||||
FROM td_reminders
|
||||
WHERE user_id = %s AND remind_date >= %s AND remind_date <= %s
|
||||
ORDER BY remind_date""",
|
||||
(user_id, today.isoformat(), limit.isoformat()),
|
||||
)
|
||||
|
||||
def get_due(self, today: date) -> list[dict]:
|
||||
"""D-0(당일), D-1(내일), D-7(7일 후) 미발송 알림 반환."""
|
||||
d1 = today + timedelta(days=1)
|
||||
d7 = today + timedelta(days=7)
|
||||
return self._db.execute(
|
||||
"""SELECT *,
|
||||
CASE
|
||||
WHEN remind_date = %s THEN 'd0'
|
||||
WHEN remind_date = %s THEN 'd1'
|
||||
WHEN remind_date = %s THEN 'd7'
|
||||
END AS notify_type
|
||||
FROM td_reminders
|
||||
WHERE (remind_date = %s AND sent_d0 = 0)
|
||||
OR (remind_date = %s AND sent_d1 = 0)
|
||||
OR (remind_date = %s AND sent_d7 = 0)""",
|
||||
(
|
||||
today.isoformat(), d1.isoformat(), d7.isoformat(),
|
||||
today.isoformat(), d1.isoformat(), d7.isoformat(),
|
||||
),
|
||||
)
|
||||
|
||||
def mark_sent(self, reminder_id: int, notify_type: str) -> None:
|
||||
col = {"d0": "sent_d0", "d1": "sent_d1", "d7": "sent_d7"}.get(notify_type)
|
||||
if col:
|
||||
self._db.execute_write(
|
||||
f"UPDATE td_reminders SET {col} = 1 WHERE id = %s",
|
||||
(reminder_id,),
|
||||
)
|
||||
Reference in New Issue
Block a user