66๊ฐ์ ์ค์ ์ํ ์ฝ๊ด PDF ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ง์ถคํ ์ํ์ ์ ์์กฐ์ฌํ๊ณ , ๋ฐฑ์๋ ์ฐ์ฐ ์์ง์ ํตํด ํ๊ฐ ์๋ ๋ง๊ธฐ ์ด์๋ฅผ ๊ณ์ฐํ๋ ๋ํํ ReAct ๊ธ์ต ๋น์ ์๋น์ค์ ๋๋ค.
- ๊ธ์ต ์ ๋ณด์ ๋น๋์นญ์ฑ ํด์: ์์ค์ ์กด์ฌํ๋ ์๋ง์ ์ ๊ธ ์ํ๊ณผ ๋ณต์กํ ์ฐ๋๊ธ๋ฆฌ ์กฐ๊ฑด์ ์๋น์๊ฐ ์ง์ ๋น๊ตยท๋ถ์ํด์ผ ํ๋ ๋ฒ๊ฑฐ๋ก์์ ์ค์ด๊ณ ์ ํฉ๋๋ค.
- ์ฌ์ฉ์ ์ค์ฌ์ ํด๊ฒฐ ๋ฐฉ์: ์์ฐ์ด ์ง๋ฌธ ํ๋๋ก ์ฌ๋ฌ ์ํ์ ์ํ์ ํ๋์ ๋น๊ตํ๊ณ , ๊ตฌ์ฒด์ ์ธ ์ฐ๋์กฐ๊ฑด ์กฐํ๋ถํฐ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ด ๋ณด์ฅ๋ ๋ง๊ธฐ ์๋ น์ก ๊ณ์ฐ๊น์ง ์์คํฑ์ผ๋ก ํด๊ฒฐํ๋ ๊ธ์ต ์์ด์ ํธ๋ฅผ ๊ตฌํํ์ต๋๋ค.
๋ณธ ํ๋ก์ ํธ๋ ๋ฐ์ดํฐ์ ์ ํ์ฑ๊ณผ ๋ฉํฐํด ๋ํ์ ์์ ์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํด ๊ตฌ์กฐ์ ์ฑ ์์ 4๊ฐ์ ๋ ๋ฆฝ๋ ๋ ์ด์ด๋ก ์ด์ํํ์ฌ ์ค๊ณํ์ต๋๋ค.
- State & Routing Layer (
LangGraph):AgentState์ค์ฌ์ ์ค์ ์ง์คํ ๋ํ ์ ์ด ํ๋ฆ์ ๊ตฌ์ถํ์ต๋๋ค. ๋ด์ฅ๋MemorySaver์ฒดํฌํฌ์ธํฐ์thread_id์ธ์ ์ค์ฝํ๋ฅผ ํ์ฉํด ๋ค์ค ์ฌ์ฉ์์ ๋ ๋ฆฝ์ ์ธ ๋ฉํฐํด ๋ํ ๋งฅ๋ฝ์ ์์ ์ ์ผ๋ก ๋ณด์กดํฉ๋๋ค. - Abstraction Layer (
LangChain): ์ ์ฑ์ ํค์๋ ๊ฒ์ ํด๊ณผ ์ ๋์ ์์น ์ฐ์ฐ ํด์ OpenAI ๊ท๊ฒฉ์ JSON Schema ํํ๋ก ์ ์ํ์ฌ LLM๊ณผ ์ ๊ธฐ์ ์ผ๋ก ๋ฐ์ธ๋ฉํ์ต๋๋ค. - Data Layer (
ChromaDB&Upstage Solar): ๊ฒ์ ์ ํ๋์ ์๋ต ์๋๋ฅผ ๋ชจ๋ ๊ณ ๋ํํ๊ธฐ ์ํด 2-Track ํ์ด๋ธ๋ฆฌ๋ RAG ์ํคํ ์ฒ๋ฅผ ์ค๊ณํ์ต๋๋ค.- Track A (์์ฝ ์ปฌ๋ ์ ): LLM์ผ๋ก ์ฌ์ ์์ถํ ๊ณ ์๋ ์ฝ๊ด ์์ฝ๋ณธ์ ๊ธฐ๋ฐ์ผ๋ก 1์ฐจ ํ๋ณด๊ตฐ์ ๋น ๋ฅด๊ฒ ์ ์์กฐ์ฌํฉ๋๋ค.
- Track B (์์ธ ์ปฌ๋ ์
): ์๋ณธ ๋ฌธ์๋ฅผ 1,000์ ๋จ์๋ก ์ ๋ฐํ๊ฒ ๋ถํ ํ ํํธ ์ปฌ๋ ์
์
๋๋ค. ํน์ ์ํ์ด ํ๊ฒํ
๋๋ฉด
filename๋ฉํ๋ฐ์ดํฐ ํํฐ๋ง์ ํตํด ํด๋น ์กฐํญ๋ง ๊ฒฉ๋ฆฌํ์ฌ ๋ฅ๋ค์ด๋ธ ๊ฒ์์ ์ํํฉ๋๋ค.
- Compute Layer (๋ฐฑ์๋ ์ฐ์ฐ ๋ชจ๋): LLM์ ๊ณ ์ง์ ์ธ '์ํ์ ํ๊ฐ(Math Hallucination)'์ ์์ฒ ๊ฒฉ๋ฆฌํ๊ธฐ ์ํด ์ฐ์ฐ ์ฑ ์์ ํ์ด์ฌ ๋ฐํ์ ์ฝ๋๋ก ์ด๊ดํ์ฌ ์ด์ ๊ณ์ฐ์ ๋ฌด๊ฒฐ์ฑ์ ๋ณด์ฅํฉ๋๋ค.
graph TD
%% ์คํ์ผ ์ ์
classDef startEnd fill:#f9f,stroke:#333,stroke-width:2px;
classDef nodeStyle fill:#bbf,stroke:#333,stroke-width:1px;
classDef toolStyle fill:#ffb,stroke:#333,stroke-width:1px;
classDef routeStyle fill:#f96,stroke:#333,stroke-width:1px;
START([์ฌ์ฉ์ ์ง๋ฌธ ์
๋ ฅ]) --> F_INSPECT{1. force_first_inspection<br>์ค๋งํธ ๋ฉ๋ชจ๋ฆฌ ๊ฐ์ง}
%% 1๋จ๊ณ ๋ถ๊ธฐ (์ต์ด vs ์ฐ์)
F_INSPECT -- "์ต์ด ์ง๋ฌธ<br>(len=1)" --> TRACK_A[Track A: ์์ฝ๋ณธ DB ์ ์์กฐ์ฌ<br>์์ 5๊ฐ ํ๋ณด ์ํ ์ถ์ถ]
F_INSPECT -- "์ฐ์ ์ง๋ฌธ<br>(len>1)" --> BYPASS[DB ์กฐํ ์คํต<br>๊ธฐ์กด ๋งฅ๋ฝ ๋ณด์กด ํจ์ค]
TRACK_A --> AGENT[2. agent ๋
ธ๋<br>Upstage Solar LLM ์ถ๋ก ]
BYPASS --> AGENT
%% ์์ด์ ํธ ๋ผ์ฐํ
๋ถ๊ธฐ
AGENT --> ROUTER{3. router<br>์ปจํธ๋กค ๋ผ์ฐํฐ}
ROUTER -- "end<br>(์ต์ข
๋ต๋ณ ์๋ฃ)" --> END([๐ END<br>Streamlit UI ์ต์ข
์ถ๋ ฅ])
ROUTER -- "continue<br>(๋๊ตฌ ํธ์ถ ํ์)" --> TOOLS[4. tools ๋
ธ๋<br>์์ด์ ํธ ๋๊ตฌ ๊ฐ๋]
%% ๋๊ตฌ ์คํ ๋ ์ด์ด
TOOLS --> TOOL_EXEC{์ด๋ค ์ฐ์ฐ์ด ํ์ํ๊ฐ?}
TOOL_EXEC -- "์์ธ RAG" --> T1[search_specific_details<br>Track B: ์์ธ ์ฝ๊ด ๊ฒฉ๋ฆฌ ๊ฒ์]
TOOL_EXEC -- "์์ ์ฐ์ฐ" --> T2[calculate_maturity_amount<br>ํ์ด์ฌ ๋จ๋ฆฌ ๊ณ์ฐ๊ธฐ]
%% ๋ค์ ๋ฃจํ ์ํ
T1 --> AGENT
T2 --> AGENT
%% ํด๋์ค ๋ฐ์ธ๋ฉ
class START,END startEnd;
class AGENT,F_INSPECT nodeStyle;
class T1,T2,TOOLS toolStyle;
class ROUTER,TOOL_EXEC routeStyle;
- 1๋จ๊ณ ์ํ ํ๋ณด ์ ์์กฐ์ฌ: ์ฌ์ฉ์์ ์๊ฒฉ ์๊ฑด๊ณผ ์ ์ฑ์ ์๊ตฌ์ฌํญ์ ๋ถํฉํ๋ ์์ 5๊ฐ ๊ธ์ต ์ํ ํ(Pool)์ ๊ณ ์ ์ถ์ถํฉ๋๋ค.
- 2๋จ๊ณ ์ฐ๋๊ธ๋ฆฌ ์กฐ๊ฑด ๋ฅ๋ค์ด๋ธ: ๋ฌธ๋งฅ์ ์ถ์ ํ์ฌ ํน์ ์ํ์ ์ค์ ์์ธ ์กฐํญ(๊ธ์ฌ ์ค์ , ์นด๋ ์ฐ๊ณ ์กฐ๊ฑด ๋ฑ)์ ์ ํํ ๋งค์นญํ๊ณ ์ธ๋ถ ์ฝ๊ด์ ํฉํธ ๊ธฐ๋ฐ์ผ๋ก ์ญ์ถ์ ํฉ๋๋ค.
- ๋ฌด๊ฒฐ์ฑ ๋ง๊ธฐ ์๋ น์ก ์ฐ์ถ: ๋จ๋ฆฌ ๊ณ์ฐ ๋ก์ง์ ๊ธฐ๋ฐ์ผ๋ก ์ค์ฐจ ์๋ ์์ ์ธ์ ์ด์์ ์์น ๊ธ์ก๋ณ ์ต์ข ๋ง๊ธฐ ์ด ์๋ น์ก์ ์ฐ์ถํฉ๋๋ค.
-
์์ธ: UI ๋จ์์ ๊ณผ๊ฑฐ ๋ํ๋ก์ ์๋์ผ๋ก ๋์ ํ์ฌ ์ ๋ฌํ๋ ๋ฐฉ์์ด ๋ญ๊ทธ๋ํ์ ์ํ ์ ์ด๊ถ๊ณผ ์ถฉ๋ํ๋ฉด์ API ํ์์์์ ์ ๋ฐํ์ต๋๋ค. ๋ํ ์ด๊ธฐ ์ง์ ๋ ธ๋(
force_first_inspection)๊ฐ ์ฐ์ ์ง๋ฌธ์ ๋ฌธ๋งฅ์ ์ธ์งํ์ง ๋ชปํ๊ณ ๋ฐ์ดํฐ๋ฅผ ์ค์ผ์์ผ ์ปจํ ์คํธ๊ฐ ์์ค๋๋ ๋ฌธ์ ๋ฅผ ๋ฐ๊ฒฌํ์ต๋๋ค. -
ํด๊ฒฐ: ์ธ์ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ๋ฅผ ๋ญ๊ทธ๋ํ ๋ด์ฅ ์ฒดํฌํฌ์ธํฐ ์์คํ ์ผ๋ก ์ด๊ดํ์ฌ ๋ฉ๋ชจ๋ฆฌ ์ด์ค ๊ผฌ์ ๊ตฌ์กฐ๋ฅผ ํํผํ์ต๋๋ค. ์ฐ์ ์ง๋ฌธ์ด ๊ฐ์ง๋๋ฉด 1์ฐจ ์์ฝ DB ์กฐํ๋ฅผ ์ค๋งํธํ๊ฒ ์คํตํ๊ณ ์์ด์ ํธ ๋ ธ๋๋ก ์งํํ๋ ์ฐํ ๋ผ์ฐํ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ถํ์ฌ, ์์คํ ๋ฝ์ ํด์ ํ๊ณ ์๋ต ์๋๋ฅผ 0.5์ด ๋๋ก ๊ทน๋ํํจ๊ณผ ๋์์ UI ์ค๋ณต ํ์์ ์๋ฒฝํ ํด๊ฒฐํ์ต๋๋ค.
-
์์ธ: ํ๋กฌํํธ์ ๊ฐ์ ๋ ฅ ๋ถ์กฑ์ผ๋ก ์ธํด LLM์ด ์ง์ ๋ ๊ณ์ฐ๊ธฐ ๋๊ตฌ๋ฅผ ๋๋ฝํ ์ฑ ์์๋ก ์ซ์๋ฅผ ์ง์ด๋ด๋ ํ๊ฐ ํ์์ด ๋ฐ์ํ์ต๋๋ค. ๋๋ถ์ด LLM์ด ๋๊ตฌ ์ธ์์ ํน์๊ธฐํธ(%, ์)๋ ๊ณต๋ฐฑ์ ๋ฌด์์๋ก ์์ด ๋ณด๋ด ๋ฐฑ์๋ ์ฝ๋๊ฐ ํฌ๋์๋๋ ํ์์ ์๋ณํ์ต๋๋ค.
-
ํด๊ฒฐ:
system_prompt์ ํ๋ ํ๋กํ ์ฝ์ ์ฃผ์ ํ์ฌ ๋๊ตฌ์ ์ฐ์ฐ ๊ฒฐ๊ณผ๊ฐ ๋ฐํ๋๊ธฐ ์ ๊น์ง ๋ต๋ณ ์์ ์์ฑ์ ๊ฐ์ ๋ก ๋ธ๋กํนํ์ต๋๋ค. ์ด์ ํจ๊ป ๊ณ์ฐ๊ธฐ ํด ํธ๋ค๋ฌ ์ ๋ฉด์ ์ ๊ท์ ๊ธฐ๋ฐ ํจํด ๋งค์นญ ์๊ณ ๋ฆฌ์ฆ(re.findall) ๊ฐ๊ณต ๋ ์ด์ด๋ฅผ ๋ฐฐ์นํ์ฌ, ์ธ์ ์ ๋ ฅ ํ์์ ๊ตฌ์ ๋ฐ์ง ์๊ณ ์์ ์ซ์ ๋ฐ์ดํฐ๋ง ์์ ํ๊ฒ ํ์ฑํ๋๋ก ์ฝ๋๋ฅผ ๋ณด์ํ์ฌ ์ฐ์ฐ ๋ฌด๊ฒฐ์ฑ์ ๋ฌ์ฑํ์ต๋๋ค.
- LLM & Embedding: Upstage Solar-1-Mini-Chat, Solar-Embedding-1-Large
- Framework: LangGraph, LangChain
- Vector DB: ChromaDB (PersistentClient)
- Frontend: Streamlit
app/config.py: ํ๋ก์ ํธ ๊ฒฝ๋ก, ๋ชจ๋ธ๋ช , ์ปฌ๋ ์ ๋ช ์ค์ app/agent/graph.py: LangGraph ์์ด์ ํธ ์ํฌํ๋ก์ฐapp/agent/tools.py: Chroma ๊ฒ์ ๋๊ตฌ์ ๋ง๊ธฐ ๊ธ์ก ๊ณ์ฐ ๋๊ตฌapp_ui.py: Streamlit ์ฑํ UIworkers/tasks.py: PDF ์ฝ๊ด ์ธ์ ์ค์ workers/verify.py: ChromaDB ๋ฐ์ดํฐ ํ์ธscripts/check_project.py: ์คํ ์ ํ๋ก์ ํธ ์ํ ์ ๊ฒ
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
Copy-Item .env.example .env.env์ UPSTAGE_API_KEY ๊ฐ์ ์
๋ ฅํ์ธ์.
python scripts/check_project.py
python workers/verify.pystreamlit run app_ui.pyuvicorn app.main:app --reload๋ธ๋ผ์ฐ์ ์์ http://127.0.0.1:8000/health๋ฅผ ํ์ธํ๋ฉด ๋ฉ๋๋ค.
python workers/tasks.py