Skip to content

Repository files navigation

๐ŸŽผ Orchestrion

์ถœ์ฒ˜์— ๊ธฐ๋ฐ˜ํ•ด ์•ˆ์ „ํ•˜๊ฒŒ ๋‹ตํ•˜๋Š”, ํ†ต์ œ๋œ LLM ์—์ด์ „ํŠธ ํ™˜๊ฒฝ.

์„œ๋น„์Šค์— LLM์„ ๋ถ™์ผ ๋•Œ, ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฑด ๋ญ˜๊นŒ์š”? ์œ ์ฐฝํ•œ ์˜ค๋‹ต๋ณด๋‹ค๋Š” ๋ฏฟ์„ ์ˆ˜ ์žˆ๋Š” ๋‹ต๋ณ€์ด ํ•„์š”ํ•  ๋•Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทผ๊ฑฐ ์—†์ด ๊ทธ๋Ÿด๋“ฏํ•˜๊ฒŒ ์ง€์–ด๋‚ธ ํ•œ ๋ฌธ์žฅ์ด, ๊ทธ๋Œ€๋กœ ์‚ฌ๊ณ ๊ฐ€ ๋˜๊ธฐ๋„ ํ•˜๋‹ˆ๊นŒ์š”.

๋ณดํ†ต์˜ ๋‹จ์ผ ์—์ด์ „ํŠธ๋Š” ๋ชจ๋ธ ํ•˜๋‚˜๊ฐ€ ์•Œ์•„์„œ ํŒ๋‹จํ•˜๊ณ , ๋„๊ตฌ๋ฅผ ๋ถ€๋ฅด๊ณ , ๋‹ต๊นŒ์ง€ ์”๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ง€์–ด๋‚ด์ง€ ์•Š์•˜๊ธฐ๋ฅผ ๋ฐ”๋ž„ ์ˆ˜๋ฐ–์— ์—†์ฃ . Orchestrion์€ ์ด ๊ตฌ์กฐ๋ฅผ ๋’ค์ง‘์—ˆ์Šต๋‹ˆ๋‹ค. ์ˆœ์„œ๋Š” ์ฝ”๋“œ๊ฐ€ ์ •ํ•˜๊ณ , ๋ชจ๋ธ์€ ๊ฐ ๋‹จ๊ณ„์—์„œ ์ž๊ธฐ ํŒ๋‹จ๋งŒ ๋‚ด๋ฆฝ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋ชจ๋“  ๋‹ต๋ณ€์€ ์ž…๋ ฅ ๊ฒŒ์ดํŠธ๋ฅผ ์ง€๋‚˜๊ณ , ๋ฌธ์žฅ๋งˆ๋‹ค ๊ทผ๊ฑฐ๋ฅผ ๋‹ฌ๊ณ , ์ถœ๋ ฅ ๊ฒ€์ฆ๊นŒ์ง€ ํ†ต๊ณผํ•œ ๋’ค์—์•ผ ํ™”๋ฉด์— ๋„๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

Claude Code์™€ ๋ช‡ ๊ฐ€์ง€ ์˜์กด์„ฑ๋งŒ ์žˆ์œผ๋ฉด ๋ฐ”๋กœ ๋Œ๋ ค๋ณผ ์ˆ˜ ์žˆ๋Š” ์ƒ˜ํ”Œ ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. ํ†ต์ œ๋œ ์—์ด์ „ํŠธ ๋ผ์šฐํŒ…, ๊ฐ€๋“œ๋ ˆ์ผ, ์ง€์‹๋ฒ ์ด์Šค(KB) ๊ธฐ๋ฐ˜ ์‘๋‹ต์ด ํ•˜๋‚˜์˜ ์‹œ๋‚˜๋ฆฌ์˜ค๋กœ ๋ฌถ์—ฌ ์žˆ์Šต๋‹ˆ๋‹ค. ํ™”๋ฉด์€ ํ•œ๊ตญ์–ด์ด๊ณ , ์˜ˆ์‹œ๋กœ ํ™”ํ•™ ์•ˆ์ „ ๋ฌธ์„œ๋ฅผ ๋„ฃ์–ด ๋’€์ง€๋งŒ ์—”์ง„์€ ๋„๋ฉ”์ธ์„ ๊ฐ€๋ฆฌ์ง€ ์•Š์•„ ์–ด๋–ค ๋งˆํฌ๋‹ค์šด ๋ฌธ์„œ ๋ฌถ์Œ์—๋„ ๊ทธ๋Œ€๋กœ ๋ถ™์Šต๋‹ˆ๋‹ค.

Orchestrion ํ”„๋กœ์„ธ์Šค ๋Œ€์‹œ๋ณด๋“œ โ€” ์งˆ๋ฌธ์ด ๋…ธ๋“œ ๊ทธ๋ž˜ํ”„๋ฅผ ํ†ต๊ณผํ•˜๋ฉฐ [S#]ยท[DB#] ๊ทผ๊ฑฐ๋ฅผ ์ธ์šฉํ•˜๊ณ  ์ถœ๋ ฅ ๊ฒ€์ฆ๊นŒ์ง€ ํ†ต๊ณผํ•˜๋Š” ํ™”๋ฉด

์งˆ๋ฌธ ํ•˜๋‚˜๊ฐ€ ์ž…๋ ฅ ๊ฒŒ์ดํŠธ โ†’ ๊ณ„ํš โ†’ ๊ทผ๊ฑฐ ์ˆ˜์ง‘ โ†’ ๊ฒ€์ˆ˜ โ†’ ์ถœ๋ ฅ ๊ฒ€์ฆ 6๋‹จ๊ณ„๋ฅผ ์ง€๋‚˜๋ฉฐ, ๋‹ต๋ณ€์˜ ๋ชจ๋“  ์‚ฌ์‹ค ๋ฌธ์žฅ์ด ๋ฌธ์„œ ์ฒญํฌ([S#])์™€ ์ •ํ˜• ํŒฉํŠธ([DB#])์— ๊ฑธ๋ ค ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ค๋ฅธ์ชฝ ํŒจ๋„์—๋Š” ์‹คํ–‰๋œ SQL, ์กฐํšŒ๋œ ํŒฉํŠธ ํ‘œ, ๋„๊ตฌ ํ˜ธ์ถœ, ๊ฐ€๋“œ๋ ˆ์ผ ํŒ์ •์ด ์‹ค์‹œ๊ฐ„์œผ๋กœ ์Œ“์ž…๋‹ˆ๋‹ค.


ํ•ต์‹ฌ ์›์น™

  • ์ง€ํœ˜๋Š” ๋ชจ๋ธ์ด ์•„๋‹ˆ๋ผ ๋ธŒ๋ฆฌ์ง€๊ฐ€ ํ•œ๋‹ค. ๊ฐ ๋…ธ๋“œ๋Š” ๋”ฑ ํ•œ ๊ฐ€์ง€ ์ผ๋งŒ ํ•˜๋Š” LLM ํ˜ธ์ถœ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค(๊ฒŒ์ดํŠธ โ†’ ๋ผ์šฐํŒ… โ†’ ๊ณ„ํš โ†’ ์ž‘์—… โ†’ ๊ฒ€์ˆ˜ โ†’ ๊ฒ€์ฆ). ๋‹ค์Œ์— ์–ด๋А ๋…ธ๋“œ๊ฐ€ ๋Œ์ง€๋Š” ๋ชจ๋ธ์ด ์•„๋‹ˆ๋ผ ํŒŒ์ด์ฌ ๋ธŒ๋ฆฌ์ง€๊ฐ€ ๊ทœ์น™๋Œ€๋กœ ์ •ํ•ฉ๋‹ˆ๋‹ค. ์ œ์–ด ํ๋ฆ„์ด ๊ธด ๋Œ€ํ™” ์†์—์„œ ์šฐ์—ฐํžˆ ๊ฒฐ์ •๋˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ, ์–ธ์ œ๋“  ๋”ฐ๋ผ ์ฝ๊ณ  ์žฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋กœ ๋‚จ์Šต๋‹ˆ๋‹ค.
  • ๊ทผ๊ฑฐ๊ฐ€ ๊ฒ€์ฆ๋ผ์•ผ ๋‚˜๊ฐ„๋‹ค. ์ž‘์—… ๋…ธ๋“œ๋Š” ์‚ฌ์‹ค์„ ๋‹ด์€ ๋ฌธ์žฅ๋งˆ๋‹ค ๊ทผ๊ฑฐ๋ฅผ ๋‹ต๋‹ˆ๋‹ค โ€” ๋ฌธ์„œ์—์„œ ์™”์œผ๋ฉด [S#], ์ •ํ˜• ๋ฐ์ดํ„ฐ์—์„œ ์™”์œผ๋ฉด [DB#]. ๋ฐ›์ณ ์ค„ ๊ทผ๊ฑฐ๊ฐ€ ์—†์œผ๋ฉด ๊ทธ๋Ÿด๋“ฏํ•˜๊ฒŒ ์ง€์–ด๋‚ด๋Š” ๋Œ€์‹  "์ œ๊ณต ์ž๋ฃŒ์— ์—†์Œ" ์ด๋ผ๊ณ  ๋ถ„๋ช…ํžˆ ๋ฐํž™๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ณ„๋„์˜ ๊ฒ€์ฆ ๋…ธ๋“œ๊ฐ€ ์ดˆ์•ˆ์„ ๊ทผ๊ฑฐ์™€ ํ•œ ๋ฒˆ ๋” ๋งž์ถฐ ๋ด…๋‹ˆ๋‹ค.
  • ๋„๊ตฌ ๊ฒŒ์ดํŠธ๋Š” ๋‹จ ํ•˜๋‚˜, ๋น ์ง์—†์ด ์ง€๋‚œ๋‹ค. ๋ชจ๋“  ๋„๊ตฌ ํ˜ธ์ถœ์€ ์˜ˆ์™ธ ์—†์ด ํ•˜๋‚˜์˜ ์ •์ฑ… ํ›…์„ ์ง€๋‚ฉ๋‹ˆ๋‹ค. ์ด ํ›…์€ ๊ทœ์น™ ์ €์žฅ์†Œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ ์ฝ๊ธฐ ๋•Œ๋ฌธ์—, ํ™”๋ฉด์ด๋‚˜ ์ž์—ฐ์–ด๋กœ ๊ทœ์น™์„ ์ผœ๊ณ  ๋„๋ฉด ๋ฐ”๋กœ ๋‹ค์Œ ํ˜ธ์ถœ๋ถ€ํ„ฐ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • ๋ฌด์—‡์ด ๋น ์ ธ๋„ ๋ฉˆ์ถ”์ง€ ์•Š๊ณ  ๋ฌผ๋Ÿฌ์„ ๋‹ค. ์ž„๋ฒ ๋”ฉ ๋ชจ๋ธ์ด ์—†์œผ๋ฉด ๊ฒ€์ƒ‰์€ BM25๋งŒ์œผ๋กœ ๋Œ์•„๊ฐ€๊ณ , ์ง€์‹์ด ์•„์˜ˆ ์—†์–ด๋„ ๊ทธ๋ž˜ํ”„๋Š” ๊ทธ๋Œ€๋กœ ๋Œ๋ฉด์„œ ์†”์งํ•˜๊ฒŒ ๋ชจ๋ฅธ๋‹ค๊ณ  ๋‹ตํ•ฉ๋‹ˆ๋‹ค. ์–ด๋А ์ง€์ ์—์„œ๋„ ์†Œ๋ฆฌ ์—†์ด ๋ฌด๋„ˆ์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์ •์ฒด์„ฑ์€ ์ฝ”๋“œ๊ฐ€ ์•„๋‹ˆ๋ผ ์ฝ˜ํ…์ธ ๋‹ค. ํ•˜๋‚˜์˜ ์—์ด์ „ํŠธ๋Š” scenario.md + knowledge/raw/ + data/demo.json + ๊ฐ€๋“œ๋ ˆ์ผ ์ •์ฑ…์œผ๋กœ ์ •์˜๋˜๊ณ , ์‹คํ–‰ํ•  ๋•Œ๋งˆ๋‹ค ์ด ํŒŒ์ผ๋“ค์„ ์ƒˆ๋กœ ์ฝ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ƒˆ ์—…๋ฌด๋ฅผ ๋งŒ๋“œ๋Š” ์ผ์€ ์—”์ง„์„ ๋‹ค์‹œ ์งœ๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ์ฝ˜ํ…์ธ ๋ฅผ ๊ฐˆ์•„ ๋ผ์šฐ๋Š” ์ผ์ž…๋‹ˆ๋‹ค.

์•„ํ‚คํ…์ฒ˜

์‹คํ–‰ ํ๋ฆ„

์งˆ๋ฌธ ํ•˜๋‚˜๋Š” ์ด ๋…ธ๋“œ ๊ทธ๋ž˜ํ”„๋ฅผ ๋”ฐ๋ผ ํ๋ฆ…๋‹ˆ๋‹ค. ๊ฐˆ๋ฆผ๊ธธ๊ณผ ์ˆœ์„œ๋Š” ๋ธŒ๋ฆฌ์ง€๊ฐ€ ๊ทœ์น™๋Œ€๋กœ ์ •ํ•˜๊ณ , ๊ฐ ๋…ธ๋“œ๋Š” ๋ชจ๋ธ์„ ํ•œ ๋ฒˆ ๋ถˆ๋Ÿฌ ์ž๊ธฐ ๋ชซ์˜ ํŒ๋‹จ๋งŒ ๋‚ด๋ฆฝ๋‹ˆ๋‹ค.

flowchart LR
    Q([์งˆ๋ฌธ]) --> RMI["์ž…๋ ฅ ๊ฒŒ์ดํŠธ<br/>rm_input"]
    RMI -. REJECT .-> DECL([์ •์ค‘ํ•œ ๊ฑฐ์ ˆ])
    RMI -- ALLOW --> RT{"๋ผ์šฐํŒ…<br/>route"}
    RT -- ๋‹จ์ˆœ --> SA["์ฆ‰๋‹ต<br/>simple_answer"]
    RT -- ์—…๋ฌด --> PL["๊ณ„ํš<br/>plan"]
    PL --> WK["๊ทผ๊ฑฐ ์ˆ˜์ง‘ยท์ดˆ์•ˆ<br/>worker"]
    WK --> RV["๊ฒ€์ˆ˜<br/>review"]
    RV -. "REDO โ‰ค 2" .-> WK
    RV --> RMO["์ถœ๋ ฅ ๊ฒ€์ฆ<br/>rm_output"]
    SA --> RMO
    RMO --> ANS([๊ฒ€์ฆ ํ†ต๊ณผ ๋‹ต๋ณ€])

    classDef rm fill:#fde2e2,stroke:#c0392b,color:#7b241c;
    classDef hyp fill:#e2ecfd,stroke:#2c5aa0,color:#1a3c6e;
    classDef wrk fill:#e6f6ea,stroke:#27ae60,color:#186a3b;
    class RMI,RMO rm;
    class RT,SA,PL,RV hyp;
    class WK wrk;
Loading

๋…ธ๋“œ โ€” ๋ฌด์—‡์„, ์–ด๋–ค ๋ชจ๋ธ๋กœ

๋…ธ๋“œ ๋ ˆ์ธ ์—ญํ•  ๋ชจ๋ธ
rm_input ์œ„ํ—˜๊ด€๋ฆฌ ์งˆ๋ฌธ์ด ์—…๋ฌด ๋ฒ”์œ„ ์•ˆ์ธ์ง€ ํŒ์ • โ€” ๋ฒ—์–ด๋‚˜๋ฉด ์ •์ค‘ํžˆ ๊ฑฐ์ ˆ haiku
route ์ด๊ด„ ๋‹จ์ˆœ ์งˆ๋ฌธ(์ฆ‰๋‹ต)์ธ์ง€ ์‹ค์ œ ์—…๋ฌด์ธ์ง€ ๋ถ„๊ธฐ haiku
simple_answer ์ด๊ด„ ์ธ์‚ฌยท์•ˆ๋‚ด ๊ฐ™์€ ๋‹จ์ˆœ ์งˆ๋ฌธ์— ์งง๊ฒŒ ์ฆ‰๋‹ต sonnet
plan ์ด๊ด„ ์—…๋ฌด ๋ฐฉ์‹ ์ ˆ์ฐจ์— ๋”ฐ๋ผ ๊ฒ€์ƒ‰ ๊ณ„ํš ์ˆ˜๋ฆฝ sonnet
worker ์‹ค๋ฌด ์ง€์‹ ๋„๊ตฌ๋กœ ๊ทผ๊ฑฐ๋ฅผ ๋ชจ์•„ [S#]/[DB#] ์ธ์šฉ ์ดˆ์•ˆ ์ž‘์„ฑ sonnet
review ์ด๊ด„ ์ดˆ์•ˆ์ด ์งˆ๋ฌธ์— ๋‹ตํ•˜๊ณ  ์ธ์šฉ์„ ๊ฐ–์ท„๋Š”์ง€ ๊ฒ€์ˆ˜ โ€” ๋ฏธํกํ•˜๋ฉด REDO(์ตœ๋Œ€ 2ํšŒ) haiku
rm_output ์œ„ํ—˜๊ด€๋ฆฌ ์ดˆ์•ˆ์„ ๊ทผ๊ฑฐ์™€ ๋Œ€์กฐํ•ด ์‚ฌ์‹คยทํ†ค ๊ฒ€์ฆ, JSON ํŒ์ • ์‚ฐ์ถœ haiku

์„ธ ๋ ˆ์ธ(์œ„ํ—˜๊ด€๋ฆฌ / ์ด๊ด„ / ์‹ค๋ฌด)์€ ๋Œ€์‹œ๋ณด๋“œ์—์„œ ์ƒ‰์œผ๋กœ ๊ตฌ๋ถ„๋˜์–ด, ์ง€๊ธˆ ์–ด๋–ค ์„ฑ๊ฒฉ์˜ ๋…ธ๋“œ๊ฐ€ ๋Œ๊ณ  ์žˆ๋Š”์ง€ ํ•œ๋ˆˆ์— ๋“ค์–ด์˜ต๋‹ˆ๋‹ค.

๊ฒ€์ฆ ๊ณ„์•ฝ โ€” [S#]์™€ [DB#]

์ด ํ”„๋กœ์ ํŠธ์—์„œ ๊ฐ€์žฅ ๊ณต๋“ค์ธ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. ์ž‘์—… ๋…ธ๋“œ๊ฐ€ ์ธ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ทผ๊ฑฐ๋Š” ๋”ฑ ๋‘ ์ข…๋ฅ˜์ž…๋‹ˆ๋‹ค.

  • [S#] โ€” ๋ฌธ์„œ์—์„œ ์ž˜๋ผ๋‚ธ ์ฒญํฌ. ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ๊ฒ€์ƒ‰์œผ๋กœ ์ฐพ์€ ์›๋ฌธ์ด๊ณ , ํ™”๋ฉด์—๋Š” ์ฃผํ™ฉ์ƒ‰์œผ๋กœ ๋‚˜์˜ต๋‹ˆ๋‹ค.
  • [DB#] โ€” ์ •ํ˜• ํŒฉํŠธ ํ…Œ์ด๋ธ”์˜ ํ•œ ํ–‰. ์ •ํ™•ํ•œ ์ˆ˜์น˜๋‚˜ ์†์„ฑ์„ SQL๋กœ ์กฐํšŒํ•œ ๊ฒƒ์ด๊ณ , ๋…ธ๋ž€์ƒ‰์œผ๋กœ ํ‘œ์‹œํ•˜๋ฉด์„œ ์‹คํ–‰ํ•œ ์ฟผ๋ฆฌ์™€ ๊ฒฐ๊ณผ ํ‘œ๊นŒ์ง€ ํ•จ๊ป˜ ๋ณด์—ฌ ์ค๋‹ˆ๋‹ค.

๊ทผ๊ฑฐ๊ฐ€ ์—†๋Š” ๋ฌธ์žฅ์€ ์• ์ดˆ์— ์“ธ ์ˆ˜ ์—†๊ณ , ๊ทธ๋Ÿด ๋•Œ๋Š” "์ œ๊ณต ์ž๋ฃŒ์— ์—†์Œ"์ด๋ผ๊ณ  ๋‹ตํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ rm_output ๋…ธ๋“œ๊ฐ€ ์ดˆ์•ˆ์˜ ์‚ฌ์‹ค ๋ฌธ์žฅ์„ ํ•˜๋‚˜ํ•˜๋‚˜ ๊ทผ๊ฑฐ์™€ ๋‹ค์‹œ ๋งž์ถฐ ๋ณด๊ณ , ์—ฌ๊ธฐ๊นŒ์ง€ ํ†ต๊ณผํ•œ ๋‹ต๋ณ€๋งŒ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.

์ง€์‹ ํŒŒ์ดํ”„๋ผ์ธ

knowledge/raw/*.md
      โ”‚  ingest (make ingest)
      โ–ผ
  ์ฒญํฌ ๋ถ„ํ•  โ”€โ†’ FTS5 ์ƒ‰์ธ(BM25) + ์ž„๋ฒ ๋”ฉ(bge-m3) + LLM ํŒฉํŠธ ์ถ”์ถœ
      โ–ผ
  SQLite (docs ยท chunks ยท chunks_fts ยท embeddings ยท facts)
      โ–ฒ
      โ”‚  worker์˜ 4๊ฐœ ์ฝ๊ธฐ ์ „์šฉ ๋„๊ตฌ๋งŒ ์ ‘๊ทผ (MCP)
      โ”‚  search_knowledge ยท read_doc ยท query_facts ยท list_sources

๊ฒ€์ƒ‰์€ BM25์™€ ์ฝ”์‚ฌ์ธ ์œ ์‚ฌ๋„๋ฅผ ์ƒํ˜ธ ์ˆœ์œ„ ์œตํ•ฉ(RRF)์œผ๋กœ ์„ž์–ด ์”๋‹ˆ๋‹ค. ์ž„๋ฒ ๋”ฉ ๋ชจ๋ธ์ด ์—†์œผ๋ฉด ์ž๋™์œผ๋กœ BM25๋งŒ ์“ฐ๊ธฐ ๋•Œ๋ฌธ์—, ์–ด๋–ค ํ™˜๊ฒฝ์—์„œ๋„ ๋ฐ๋ชจ๊ฐ€ ๋ฉˆ์ถ”์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ตฌ์„ฑ ์š”์†Œ

ํŒŒ์ผ ์—ญํ• 
bridge/graph.py ๋…ธ๋“œ ๊ทธ๋ž˜ํ”„ + ๋ชจ๋ธ ํ‹ฐ์–ด๋ณ„ ์›œ ์„ธ์…˜ ํ’€(๋Ÿฐ ๊ฐ„ ์œ ์ง€, ๋…ธ๋“œ๋งˆ๋‹ค ์ƒˆ ์„ธ์…˜ id๋กœ ํžˆ์Šคํ† ๋ฆฌ ๊ฒฉ๋ฆฌ)
bridge/hooks.py ยท bridge/policy.py ์œ ์ผํ•œ ๋„๊ตฌ ๊ฒŒ์ดํŠธ + ํŽธ์ง‘ ๊ฐ€๋Šฅํ•œ first-match ๊ทœ์น™ ์ €์žฅ์†Œ
bridge/api.py ยท bridge/app.py REST API + WebSocket ์ด๋ฒคํŠธ ํ”ผ๋“œ, ์ •์  ํ”„๋ŸฐํŠธ ์„œ๋น™
bridge/scenario.py scenario.md๋ฅผ ํŒŒ์‹ฑํ•ด ๊ทธ๋ž˜ํ”„ ํ”„๋กฌํ”„ํŠธ์— ๋Ÿฐํƒ€์ž„ ์ฃผ์ž…
core/db.py ยท core/search.py ยท core/embed.py SQLite ์Šคํ‚ค๋งˆ ยท ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ๊ฒ€์ƒ‰ ยท ์ž„๋ฒ ๋”ฉ(๊ฐ•๋“ฑ ์ง€์›)
ingest/ ๋งˆํฌ๋‹ค์šด โ†’ ์ฒญํฌ โ†’ FTS โ†’ ์ž„๋ฒ ๋”ฉ โ†’ ํŒฉํŠธ ์ ์žฌ
mcpserver/server.py FastMCP โ€” worker์—๊ฒŒ ๋…ธ์ถœ๋˜๋Š” ์ง€์‹ ๋„๊ตฌ 4์ข…
frontend/ ๊ทธ๋ž˜ํ”„๊ฐ€ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ผœ์ง€๋Š” ๊ณผ์ •์„ ๋ณด์—ฌ ์ฃผ๋Š” React ๋Œ€์‹œ๋ณด๋“œ

๊ตฌ์„ฑ ์š”์†Œ๋ณ„ ์ž์„ธํ•œ ์„ค๋ช…๊ณผ ์ง€์ผœ์•ผ ํ•  ๋ถˆ๋ณ€์‹(invariant)์€ CLAUDE.md์— ์ •๋ฆฌํ•ด ๋’€์Šต๋‹ˆ๋‹ค.


๋น ๋ฅธ ์‹œ์ž‘

์ค€๋น„๋ฌผ: uv(Python 3.11), Node 18+, Claude ๊ตฌ๋… ๋˜๋Š” API ํ‚ค, ๊ทธ๋ฆฌ๊ณ  ์ž„๋ฒ ๋”ฉ์„ ์“ฐ๋ ค๋ฉด ollama + bge-m3(์„ ํƒ).

cp .env.example .env          # ์„ ํƒ: ANTHROPIC_API_KEY ์„ค์ •, ์—†์œผ๋ฉด ๊ตฌ๋… ์ธ์ฆ
make setup                    # uv sync
make ingest                   # knowledge/raw/ โ†’ kb.sqlite
./start.sh                    # FastMCP + ๋ธŒ๋ฆฌ์ง€, ํ”„๋ŸฐํŠธ ๋นŒ๋“œ, ๋ธŒ๋ผ์šฐ์ € ์ž๋™ ์—ด๋ฆผ

ํ™”๋ฉด ์ ‘์†

./start.sh๋Š” ํ”„๋ŸฐํŠธ์—”๋“œ๋ฅผ ๋นŒ๋“œํ•ด์„œ ๋ธŒ๋ฆฌ์ง€๊ฐ€ ๊ฐ™์ด ๋„์›Œ ์ค๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋ธŒ๋ผ์šฐ์ €์—์„œ http://localhost:8787 ํ•œ ๊ณณ์œผ๋กœ ๋Œ€์‹œ๋ณด๋“œ์— ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค(์ž๋™์œผ๋กœ ์—ด๋ฆฌ๊ณ , ์›์น˜ ์•Š์œผ๋ฉด ./start.sh --no-open). ์œ„์ชฝ ํƒญ์œผ๋กœ ์„ธ ํ™”๋ฉด์„ ์˜ค๊ฐ‘๋‹ˆ๋‹ค.

ํ™”๋ฉด ๋ฌด์—‡์„ ๋ณด๋‚˜
ํ”„๋กœ์„ธ์Šค ์งˆ๋ฌธ์„ ๋„ฃ์œผ๋ฉด ๋…ธ๋“œ ๊ทธ๋ž˜ํ”„๊ฐ€ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ผœ์ง€๊ณ , ์ธ์šฉ๋œ ๊ทผ๊ฑฐยท๊ฒ€์ฆ ํŒ์ •์ด ๋‚˜ํƒ€๋‚˜๋Š” ๋ฉ”์ธ ํ™”๋ฉด
์ง€์‹์ฒด๊ณ„ ์ ์žฌ๋œ ๋ฌธ์„œยท์ฒญํฌยทํŒฉํŠธ๋ฅผ ํ›‘์–ด๋ณด๊ณ  ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ๊ฒ€์ƒ‰์„ ์ง์ ‘ ๋˜์ ธ ๋ณด๋Š” ํ™”๋ฉด
๊ฐ€๋“œ๋ ˆ์ผ ๋„๊ตฌ ์ •์ฑ… ๊ทœ์น™์„ ์ผœ๊ณ  ๋„๊ณ , ์ง€๊ธˆ๊นŒ์ง€์˜ ํ—ˆ์šฉยท์ฐจ๋‹จ ๋กœ๊ทธ๋ฅผ ๋ณด๋Š” ํ™”๋ฉด

ํ”„๋ŸฐํŠธ์—”๋“œ๋งŒ ๋”ฐ๋กœ ๋งŒ์งˆ ๋•Œ๋Š” HMR์ด ๋ถ™์€ ๊ฐœ๋ฐœ ์„œ๋ฒ„๊ฐ€ ํŽธํ•ฉ๋‹ˆ๋‹ค. ./start.sh --dev๋ฅผ ์“ฐ๋ฉด Vite๊ฐ€ http://localhost:5173 ์— ๋œจ๊ณ , /ws๋Š” ๋ธŒ๋ฆฌ์ง€๋กœ ํ”„๋ก์‹œ๋ฉ๋‹ˆ๋‹ค.

๋Œ€์‹œ๋ณด๋“œ์—์„œ ์งˆ๋ฌธ์„ ๋„ฃ์œผ๋ฉด ๊ทธ๋ž˜ํ”„๊ฐ€ ๋„๋Š” ๋ชจ์Šต์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ™”๋ฉด ์—†์ด ํ™•์ธํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด:

python scripts/graph_probe.py "๋ฌผ์งˆ A์˜ 1์ผ ์ตœ๋Œ€ ์ทจ๊ธ‰๋Ÿ‰๊ณผ ์ธํ™”์ ์€?"
curl -s localhost:8787/api/kb/stats

๋‚ด ์ง€์‹์œผ๋กœ ๋ฐ”๊พธ๊ธฐ

  1. knowledge/raw/์— ์ž˜ ์ •๋ฆฌ๋œ .md ํŒŒ์ผ์„ ๋„ฃ์Šต๋‹ˆ๋‹ค. (PDF ํŒŒ์„œ๋Š” ์ผ๋ถ€๋Ÿฌ ๋„ฃ์ง€ ์•Š์•˜์œผ๋‹ˆ, ๋จผ์ € ๋งˆํฌ๋‹ค์šด์œผ๋กœ ๋ฐ”๊ฟ” ์ฃผ์„ธ์š”.)
  2. scenario.md๋ฅผ ๋‹ค์‹œ ์”๋‹ˆ๋‹ค(์š”์•ฝ/๋Œ€์ƒ/๊ธˆ์ง€ + ์—…๋ฌด ๋ฐฉ์‹: ๋ถˆ๋ฆฟ). ์ด ๋‚ด์šฉ์ด ์‹คํ–‰ํ•  ๋•Œ ๊ทธ๋ž˜ํ”„ ํ”„๋กฌํ”„ํŠธ๋กœ ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.
  3. make ingest ํ›„ ๋‹ค์‹œ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ๋งŒ๋“  ๋ฒˆ๋“ค์€ scenarios/<์ด๋ฆ„>/์— ์Šค๋ƒ…์ƒท์œผ๋กœ ์ €์žฅํ•ด ๋‘๊ณ  ํ•„์š”ํ•  ๋•Œ ๊ฐˆ์•„ ๋ผ์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์œผ๋กœ ๋“ค์–ด ์žˆ๋Š” scenarios/chemical/์ด ๊ทธ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.

๋ผ์ด์„ ์Šค

MIT โ€” LICENSE ์ฐธ๊ณ .

About

Deterministic multi-LLM orchestration with grounded, verified answers, an editable guardrail gate, and a live process dashboard.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages