Files
youlbot/main.py
T
shinalok 06bcdb03ac Implement Phase 4~14: LangGraph Agent, RAG pipeline, Gradio Web UI, voice interface
- Upgrade LLM to Qwen3-14B-4bit with Thinking mode (MlxChatModel as LangChain BaseChatModel)
- Add LangGraph ReAct agent with tool calling loop (search_documents, web_search, get_current_date, remember/recall_user_info)
- Add RAG pipeline: BAAI/bge-m3 embeddings + Qdrant vector store + semantic chunking (SemanticSplitter via cosine similarity)
- Replace fixed-size RecursiveCharacterTextSplitter with meaning-based SemanticSplitter (numpy only, no extra deps)
- Add Gradio Web UI (app.py): chat, document ingestion, document management tabs
- Add multi-user support (user_id isolation in DB + per-user agent cache + dropdown selector)
- Add conversation history restore from MySQL on agent init (Phase 11)
- Add UserProfileRepository for persistent user profile (remember/recall tools)
- Add thread-local DB connections to fix pymysql thread-safety with LangGraph ToolNode
- Add Phase 14 voice interface: Whisper STT (microphone → text) + macOS TTS (say -v Yuna)
- Enforce search_documents-first policy in system prompt and tool descriptions
- Update ROADMAP2.md: Phase 14 완료, Phase 13 청킹 부분 완료

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 14:06:22 +09:00

53 lines
1.2 KiB
Python

import asyncio
from dotenv import load_dotenv
load_dotenv()
from container import Container
async def main_async() -> None:
container = Container()
ui = container.ui_service()
db = container.db_service()
db.connect()
db.init_schema()
ui.show_banner(container.config().model_id)
# AgentService 초기화 — MlxChatModel 모델 로딩 + LangGraph 그래프 구성 포함
agent = container.agent_service()
while True:
try:
user_input = ui.prompt_user()
except (EOFError, KeyboardInterrupt):
print("\n대화를 종료합니다.")
break
if not user_input:
continue
if ui.is_exit_command(user_input):
print("대화를 종료합니다.")
break
if ui.is_reset_command(user_input):
agent.reset()
print("\n[대화가 초기화되었습니다.]\n")
continue
ui.show_assistant_prefix()
async for token in agent.stream_response(user_input):
print(token, end="", flush=True)
print("\n")
def main() -> None:
asyncio.run(main_async())
if __name__ == "__main__":
main()