Agent (TypeScript)

์—ญํ• 

Agent๋Š” Starnion์˜ AI ๋‘๋‡Œ์ž…๋‹ˆ๋‹ค. TypeScript/Node.js๋กœ ์ž‘์„ฑ๋˜์—ˆ์œผ๋ฉฐ Anthropic AI SDK v6์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. Gateway๋กœ๋ถ€ํ„ฐ gRPC ์š”์ฒญ์„ ๋ฐ›์•„ AI ์ถ”๋ก , ์Šคํ‚ฌ ์‹คํ–‰์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์ตœ์ข… ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ์—ญํ• :

  • ์‚ฌ์šฉ์ž ๋ฉ”์‹œ์ง€๋ฅผ ๋ถ„์„ํ•˜์—ฌ ์˜๋„ ํŒŒ์•…
  • ์ ์ ˆํ•œ ์Šคํ‚ฌ(Tool)์„ ์„ ํƒํ•˜๊ณ  ์‹คํ–‰ (diary, finance, goals, image)
  • Anthropic Claude ๋ชจ๋ธ๋กœ ์‘๋‹ต ์ƒ์„ฑ
  • gRPC ์ŠคํŠธ๋ฆฌ๋ฐ์œผ๋กœ ์‹ค์‹œ๊ฐ„ ์‘๋‹ต ์ „๋‹ฌ

AI SDK v6 ์•„ํ‚คํ…์ฒ˜

Agent๋Š” Anthropic AI SDK v6์˜ Tool Use ํŒจํ„ด์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž ๋ฉ”์‹œ์ง€
      โ”‚
      โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚         AI SDK v6 ์ฒ˜๋ฆฌ ๋ฃจํ”„             โ”‚
โ”‚                                         โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   ์Šคํ‚ฌ ์„ ํƒ           โ”‚
โ”‚  โ”‚ Claude ๋ชจ๋ธ  โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚ (Anthropic)  โ”‚                  โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                  โ–ผ    โ”‚
โ”‚       โ–ฒ              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”โ”‚
โ”‚       โ”‚ ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜    โ”‚ ์Šคํ‚ฌ ์‹คํ–‰       โ”‚โ”‚
โ”‚       โ”‚              โ”‚ (diary/finance/ โ”‚โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”‚  goals/image)   โ”‚โ”‚
โ”‚  โ”‚ ์Šคํ‚ฌ ๊ฒฐ๊ณผ  โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”˜                 โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
      โ”‚ SSE ์ŠคํŠธ๋ฆฌ๋ฐ ์‘๋‹ต
      โ–ผ
   gRPC ์ŠคํŠธ๋ฆฌ๋ฐ โ†’ Gateway โ†’ ํด๋ผ์ด์–ธํŠธ

๋™์ž‘ ํ๋ฆ„ ์š”์•ฝ

  1. ์ž…๋ ฅ ์ˆ˜์‹ : Gateway๋กœ๋ถ€ํ„ฐ gRPC ์š”์ฒญ ์ˆ˜์‹  (์‚ฌ์šฉ์ž ๋ฉ”์‹œ์ง€ + ์„ธ์…˜ ID)
  2. ์ปจํ…์ŠคํŠธ ๋กœ๋”ฉ: ๋Œ€ํ™” ์ด๋ ฅ ๋ฐ ์‚ฌ์šฉ์ž ์„ค์ • ๋กœ๋“œ
  3. LLM ์ถ”๋ก : ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ + ๋Œ€ํ™” ์ด๋ ฅ์„ Claude ๋ชจ๋ธ์— ์ „๋‹ฌ
  4. ์Šคํ‚ฌ ์‹คํ–‰: ๋ชจ๋ธ์ด ํ•„์š”ํ•œ ์Šคํ‚ฌ์„ ์„ ํƒํ•˜๋ฉด ํ•ด๋‹น ํ•จ์ˆ˜ ์‹คํ–‰
  5. ์‘๋‹ต ์ŠคํŠธ๋ฆฌ๋ฐ: SSE ํ˜•์‹์œผ๋กœ gRPC ์ŠคํŠธ๋ฆผ์„ ํ†ตํ•ด ์‹ค์‹œ๊ฐ„ ์ „์†ก

๋ฉ”์‹œ์ง€ ์ฒ˜๋ฆฌ ํ๋ฆ„

์‚ฌ์šฉ์ž ์ž…๋ ฅ: "์ด๋ฒˆ ๋‹ฌ ์‹๋น„๊ฐ€ ์–ผ๋งˆ์•ผ?"
      โ”‚
      โ–ผ
[์˜๋„ ํŒŒ์•…]
  โ†’ "๊ฐ€๊ณ„๋ถ€ ์กฐํšŒ" ์˜๋„ ๊ฐ์ง€
      โ”‚
      โ–ผ
[๋ฉ”๋ชจ๋ฆฌ ๊ฒ€์ƒ‰]
  โ†’ ๊ด€๋ จ ๊ฐ€๊ณ„๋ถ€ ๋ฐ์ดํ„ฐ ๊ฒ€์ƒ‰ (Layer 4: SQL)
  โ†’ ์ด์ „ ์œ ์‚ฌ ์งˆ๋ฌธ ๊ธฐ์–ต ๊ฒ€์ƒ‰ (Layer 1: pgvector)
      โ”‚
      โ–ผ
[์Šคํ‚ฌ ์„ ํƒ]
  โ†’ get_finance_summary(category="์‹๋น„", period="this_month") ํ˜ธ์ถœ
      โ”‚
      โ–ผ
[์Šคํ‚ฌ ์‹คํ–‰]
  โ†’ DB์—์„œ ์ด๋ฒˆ ๋‹ฌ ์‹๋น„ ํŠธ๋žœ์žญ์…˜ ์ง‘๊ณ„
  โ†’ ๊ฒฐ๊ณผ: {"total": 234500, "transactions": [...]}
      โ”‚
      โ–ผ
[LLM ์ตœ์ข… ์‘๋‹ต ์ƒ์„ฑ]
  โ†’ "์ด๋ฒˆ ๋‹ฌ ์‹๋น„๋Š” 234,500์›์ด์—์š”. ์ง€๋‚œ๋‹ฌ(198,000์›)๋ณด๋‹ค 18% ๋Š˜์—ˆ๋„ค์š”."
      โ”‚
      โ–ผ
[gRPC ์ŠคํŠธ๋ฆฌ๋ฐ ์ „์†ก]
  โ†’ ์‘๋‹ต ํ† ํฐ์„ ์‹ค์‹œ๊ฐ„์œผ๋กœ Gateway์— ์ „์†ก
      โ”‚
      โ–ผ
[๋ฉ”๋ชจ๋ฆฌ ์ €์žฅ]
  โ†’ ์ด๋ฒˆ ๋Œ€ํ™” ๋‚ด์šฉ์„ ์ผ์ผ ๋กœ๊ทธ์— ๊ธฐ๋ก

๋ฉ€ํ‹ฐ LLM ๋ผ์šฐํŒ…

Agent๋Š” ์‚ฌ์šฉ์ž๋ณ„๋กœ ๋“ฑ๋ก๋œ LLM ํ”„๋กœ๋ฐ”์ด๋”์™€ ํ˜„์žฌ ์„ ํƒ๋œ ํŽ˜๋ฅด์†Œ๋‚˜(Persona)๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ˜ธ์ถœํ•  ๋ชจ๋ธ์„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋ธ ์„ ํƒ ์šฐ์„ ์ˆœ์œ„

1. ํ˜„์žฌ ๋Œ€ํ™”์—์„œ ๋ช…์‹œ์ ์œผ๋กœ ์„ ํƒ๋œ ๋ชจ๋ธ
      โ†“ (์—†์œผ๋ฉด)
2. ํ˜„์žฌ ํŽ˜๋ฅด์†Œ๋‚˜์— ์—ฐ๊ฒฐ๋œ ๋ชจ๋ธ
      โ†“ (์—†์œผ๋ฉด)
3. ์‚ฌ์šฉ์ž ๊ธฐ๋ณธ ํ”„๋กœ๋ฐ”์ด๋”์˜ ์ฒซ ๋ฒˆ์งธ ํ™œ์„ฑ ๋ชจ๋ธ
      โ†“ (์—†์œผ๋ฉด)
4. ์‹œ์Šคํ…œ ๊ธฐ๋ณธ๊ฐ’ (Gemini Flash)

์ง€์› ํ”„๋กœ๋ฐ”์ด๋”

ํ”„๋กœ๋ฐ”์ด๋” ๊ตฌํ˜„ ๋ฐฉ์‹
Gemini google-generativeai SDK
OpenAI openai SDK (ChatCompletion API)
Anthropic anthropic SDK (Messages API)
Z.AI OpenAI ํ˜ธํ™˜ ์—”๋“œํฌ์ธํŠธ
Custom OpenAI ํ˜ธํ™˜ ๋ฒ ์ด์Šค URL

4-Layer ๋ฉ”๋ชจ๋ฆฌ ์‹œ์Šคํ…œ

Agent๋Š” 4๊ฐœ์˜ ๊ณ„์ธต์œผ๋กœ ๊ตฌ์„ฑ๋œ ๋ฉ”๋ชจ๋ฆฌ ์‹œ์Šคํ…œ์„ ํ†ตํ•ด ์‚ฌ์šฉ์ž ์ปจํ…์ŠคํŠธ๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                 4-Layer Memory                      โ”‚
โ”‚                                                     โ”‚
โ”‚  Layer 1: ์ผ์ผ ๋กœ๊ทธ                                 โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                   โ”‚
โ”‚  โ”‚ pgvector, 768์ฐจ์› ์ž„๋ฒ ๋”ฉ     โ”‚                   โ”‚
โ”‚  โ”‚ ๋Œ€ํ™” ๊ธฐ๋ก, ๊ฐ์ •, ํ‚ค์›Œ๋“œ      โ”‚                   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                   โ”‚
โ”‚                 โ†‘ ์œ ์‚ฌ๋„ ๊ฒ€์ƒ‰                       โ”‚
โ”‚  Layer 2: ์ง€์‹ ๋ฒ ์ด์Šค                               โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                   โ”‚
โ”‚  โ”‚ pgvector, 768์ฐจ์› ์ž„๋ฒ ๋”ฉ     โ”‚                   โ”‚
โ”‚  โ”‚ ์‚ฌ์šฉ์ž ์„ ํ˜ธ, ํ•™์Šต๋œ ํŒจํ„ด     โ”‚                   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                   โ”‚
โ”‚                 โ†‘ ์œ ์‚ฌ๋„ ๊ฒ€์ƒ‰                       โ”‚
โ”‚  Layer 3: ๋ฌธ์„œ ์„น์…˜                                 โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                   โ”‚
โ”‚  โ”‚ pgvector, 768์ฐจ์› ์ž„๋ฒ ๋”ฉ     โ”‚                   โ”‚
โ”‚  โ”‚ ์—…๋กœ๋“œ๋œ ๋ฌธ์„œ์˜ ์ฒญํฌ         โ”‚                   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                   โ”‚
โ”‚                 โ†‘ SQL ์ฟผ๋ฆฌ                          โ”‚
โ”‚  Layer 4: ์ตœ๊ทผ ๊ฐ€๊ณ„๋ถ€                               โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                   โ”‚
โ”‚  โ”‚ PostgreSQL SQL               โ”‚                   โ”‚
โ”‚  โ”‚ ์ตœ๊ทผ 30์ผ ๊ฑฐ๋ž˜ ๋‚ด์—ญ          โ”‚                   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Layer 1: ์ผ์ผ ๋กœ๊ทธ

  • ์ €์žฅ์†Œ: PostgreSQL + pgvector ํ™•์žฅ
  • ์ž„๋ฒ ๋”ฉ ์ฐจ์›: 768์ฐจ์› (Gemini text-embedding-004)
  • ๋‚ด์šฉ: ๋Œ€ํ™” ๋‚ด์šฉ, ๊ฐ์ • ์ƒํƒœ, ์ฃผ์š” ํ‚ค์›Œ๋“œ, ์š”์•ฝ
  • ๊ฒ€์ƒ‰ ๋ฐฉ์‹: ์ฝ”์‚ฌ์ธ ์œ ์‚ฌ๋„ ๊ธฐ๋ฐ˜ ์˜๋ฏธ ๊ฒ€์ƒ‰
  • ์šฉ๋„: โ€œ์ €๋ฒˆ์— ๋ญ๋ผ๊ณ  ํ–ˆ๋”๋ผ?โ€ ๊ฐ™์€ ๊ณผ๊ฑฐ ๋Œ€ํ™” ํšŒ์ƒ

Layer 2: ์ง€์‹ ๋ฒ ์ด์Šค

  • ์ €์žฅ์†Œ: PostgreSQL + pgvector
  • ์ž„๋ฒ ๋”ฉ ์ฐจ์›: 768์ฐจ์›
  • ๋‚ด์šฉ: ์‚ฌ์šฉ์ž ์„ ํ˜ธ, ๋ฐ˜๋ณต ํŒจํ„ด, ํ•™์Šต๋œ ๊ฐœ์ธํ™” ์ •๋ณด
  • ์šฉ๋„: โ€œ์‚ฌ์šฉ์ž๊ฐ€ ์ปคํ”ผ๋ฅผ ์ข‹์•„ํ•œ๋‹คโ€, โ€œ๋งค๋‹ฌ 25์ผ์— ์›”๊ธ‰ ์ž…๊ธˆโ€ ๋“ฑ ๊ฐœ์ธํ™” ์ปจํ…์ŠคํŠธ

Layer 3: ๋ฌธ์„œ ์„น์…˜

  • ์ €์žฅ์†Œ: PostgreSQL + pgvector
  • ์ž„๋ฒ ๋”ฉ ์ฐจ์›: 768์ฐจ์›
  • ๋‚ด์šฉ: ์‚ฌ์šฉ์ž๊ฐ€ ์—…๋กœ๋“œํ•œ PDF, Word ๋“ฑ์˜ ๋ฌธ์„œ ์ฒญํฌ
  • ์ฒญํ‚น ๋ฐฉ์‹: ์˜๋ฏธ ๋‹จ์œ„๋กœ ๋ถ„ํ•  (๊ธฐ๋ณธ 512 ํ† ํฐ)
  • ์šฉ๋„: โ€œ๋‚ด๊ฐ€ ์—…๋กœ๋“œํ•œ ๊ณ„์•ฝ์„œ์—์„œ ์œ„์•ฝ๊ธˆ ์กฐํ•ญ ์ฐพ์•„์ค˜โ€

Layer 4: ์ตœ๊ทผ ๊ฐ€๊ณ„๋ถ€

  • ์ €์žฅ์†Œ: PostgreSQL (์ผ๋ฐ˜ SQL, ๋ฒกํ„ฐ ์—†์Œ)
  • ๋‚ด์šฉ: ์ตœ๊ทผ 30์ผ ๊ฑฐ๋ž˜ ๋‚ด์—ญ
  • ๊ฒ€์ƒ‰ ๋ฐฉ์‹: SQL ์ง‘๊ณ„ ์ฟผ๋ฆฌ
  • ์šฉ๋„: โ€œ์ด๋ฒˆ ๋‹ฌ ์‹๋น„ ์–ผ๋งˆ์•ผ?โ€, โ€œ์–ด์ œ ์นดํŽ˜ ์ง€์ถœ ์žˆ์—ˆ์–ด?โ€

์ž„๋ฒ ๋”ฉ

๋ชจ๋“  ๋ฒกํ„ฐ ์ž„๋ฒ ๋”ฉ์€ Google์˜ text-embedding-004 ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

ํ•ญ๋ชฉ ๊ฐ’
๋ชจ๋ธ text-embedding-004
์ฐจ์› 768
์œ ์‚ฌ๋„ ํ•จ์ˆ˜ ์ฝ”์‚ฌ์ธ ์œ ์‚ฌ๋„ (<=> ์—ฐ์‚ฐ์ž)
์–ธ์–ด ํ•œ๊ตญ์–ด ํฌํ•จ ๋‹ค๊ตญ์–ด ์ง€์›

์ž„๋ฒ ๋”ฉ ์ƒ์„ฑ ํ๋ฆ„:

ํ…์ŠคํŠธ ์ž…๋ ฅ
    โ”‚
    โ–ผ
Gemini Embedding API ํ˜ธ์ถœ
    โ”‚
    โ–ผ
768์ฐจ์› float ๋ฒกํ„ฐ ๋ฐ˜ํ™˜
    โ”‚
    โ–ผ
PostgreSQL pgvector ์ปฌ๋Ÿผ์— ์ €์žฅ
(์˜ˆ: VECTOR(768))

gRPC ์ธํ„ฐํŽ˜์ด์Šค

Agent๋Š” gRPC ์„œ๋ฒ„๋กœ ๋™์ž‘ํ•˜๋ฉฐ ๊ธฐ๋ณธ ํฌํŠธ 50051์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์„œ๋น„์Šค ์ •์˜ (protobuf)

service AgentService {
  // ๋‹จ๋ฐฉํ–ฅ ์ฑ„ํŒ… ์š”์ฒญ/์‘๋‹ต
  rpc Chat(ChatRequest) returns (ChatResponse);

  // ์„œ๋ฒ„ ์ŠคํŠธ๋ฆฌ๋ฐ: ์‘๋‹ต ํ† ํฐ์„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ „์†ก
  rpc ChatStream(ChatRequest) returns (stream ChatStreamResponse);
}

ํ†ต์‹  ํ๋ฆ„

Gateway (Go)                    Agent (Python)
    โ”‚                               โ”‚
    โ”‚โ”€โ”€ ChatRequest โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚
    โ”‚   (message, user_id,          โ”‚
    โ”‚    conversation_id,           โ”‚  ReAct ๋ฃจํ”„ ์‹คํ–‰
    โ”‚    context, files)            โ”‚  ์Šคํ‚ฌ ์‹คํ–‰
    โ”‚                               โ”‚
    โ”‚โ—„โ”€โ”€ ChatStreamResponse โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚ (ํ† ํฐ ๋‹จ์œ„ ์ŠคํŠธ๋ฆฌ๋ฐ)
    โ”‚โ—„โ”€โ”€ ChatStreamResponse โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚
    โ”‚โ—„โ”€โ”€ ChatStreamResponse โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚
    โ”‚         ...                   โ”‚
    โ”‚โ—„โ”€โ”€ [stream end] โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚

Gateway๋Š” ์ŠคํŠธ๋ฆฌ๋ฐ ์‘๋‹ต์„ ๋ฐ›์•„ WebSocket ๋˜๋Š” SSE(Server-Sent Events)๋กœ ํด๋ผ์ด์–ธํŠธ์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.


์Šคํ‚ฌ ์‹คํ–‰ ๋ฉ”์ปค๋‹ˆ์ฆ˜

์Šคํ‚ฌ์€ LangChain Tool๋กœ ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค. LLM์ด JSON ํ˜•์‹์œผ๋กœ ํ˜ธ์ถœํ•  ์Šคํ‚ฌ๊ณผ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ฒฐ์ •ํ•˜๋ฉด Agent๊ฐ€ ํ•ด๋‹น Python ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

์Šคํ‚ฌ ์นดํ…Œ๊ณ ๋ฆฌ

์นดํ…Œ๊ณ ๋ฆฌ ์Šคํ‚ฌ ์˜ˆ์‹œ
๊ฐ€๊ณ„๋ถ€ ๊ฑฐ๋ž˜ ์ถ”๊ฐ€/์กฐํšŒ, ์˜ˆ์‚ฐ ํ™•์ธ, ํ†ต๊ณ„
์ผ์ • Google Calendar ์—ฐ๋™
๋ฉ”๋ชจ ๋ฉ”๋ชจ ์ƒ์„ฑ/์กฐํšŒ/์‚ญ์ œ
์ผ๊ธฐ ์ผ๊ธฐ ์ž‘์„ฑ/์กฐํšŒ
๋ชฉํ‘œ ๋ชฉํ‘œ ์„ค์ •/์ฒดํฌ์ธ/ํ‰๊ฐ€
D-Day D-Day ๋“ฑ๋ก/์กฐํšŒ
๋ฌธ์„œ ๋ฌธ์„œ ๊ฒ€์ƒ‰, PDF ์š”์•ฝ
์›น ๊ฒ€์ƒ‰ Tavily, ๋„ค์ด๋ฒ„ ๊ฒ€์ƒ‰ API
๋‚ ์”จ ํ˜„์žฌ ๋‚ ์”จ ์กฐํšŒ
๊ณ„์‚ฐ๊ธฐ ์ˆ˜์‹ ๊ณ„์‚ฐ
๋ฒˆ์—ญ ๋‹ค๊ตญ์–ด ๋ฒˆ์—ญ

์Šคํ‚ฌ ํ™œ์„ฑํ™”

์Šคํ‚ฌ์€ ์‚ฌ์šฉ์ž๋ณ„๋กœ ํ™œ์„ฑํ™”/๋น„ํ™œ์„ฑํ™”๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋น„ํ™œ์„ฑํ™”๋œ ์Šคํ‚ฌ์€ LLM์˜ Tool ๋ชฉ๋ก์— ํฌํ•จ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ํ˜ธ์ถœ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Settings โ†’ Skills ๋ฉ”๋‰ด์—์„œ ํ† ๊ธ€๋กœ ์ œ์–ดํ•˜๊ฑฐ๋‚˜ API POST /api/v1/skills/:id/toggle์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.


Docker ๊ตฌ์„ฑ

Agent๋Š” docker/Dockerfile.agent๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  docker-compose.yml์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜๋ฉ๋‹ˆ๋‹ค.

agent:
  build:
    context: ../agent
    dockerfile: ../docker/Dockerfile.agent
  container_name: starnion-agent
  ports:
    - "${GRPC_PORT:-50051}:50051"  # gRPC ์„œ๋ฒ„
  environment:
    DATABASE_URL: postgres://...   # PostgreSQL ์—ฐ๊ฒฐ
    GRPC_PORT: 50051
  depends_on:
    postgres:
      condition: service_healthy

Agent๋Š” PostgreSQL์ด ์ค€๋น„๋œ ํ›„์— ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. Gateway๋Š” Agent๊ฐ€ ์‹œ์ž‘๋œ ํ›„ ์—ฐ๊ฒฐ์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.


๊ธฐ์ˆ  ์Šคํƒ ์š”์•ฝ

ํ•ญ๋ชฉ ์„ ํƒ ๋ฒ„์ „
์–ธ์–ด Python 3.13+
AI ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ LangGraph 0.4+
LLM ํด๋ผ์ด์–ธํŠธ langchain-google-genai, langchain-anthropic, langchain-openai ์ตœ์‹ 
๋Œ€ํ™” ์ƒํƒœ ์ €์žฅ langgraph-checkpoint-postgres 2.0+
DB ๋“œ๋ผ์ด๋ฒ„ psycopg (psycopg3) + psycopg-pool 3.2+
gRPC ์„œ๋ฒ„ grpcio 1.70+
์ด๋ฏธ์ง€ ์ƒ์„ฑ/๋ถ„์„ google-genai (Gemini) 1.0+
๋ฌธ์„œ ํŒŒ์‹ฑ pypdf, python-docx, openpyxl, python-pptx ์ตœ์‹ 
์›น ๊ฒ€์ƒ‰ tavily-python 0.5+
๋ธŒ๋ผ์šฐ์ € ์ž๋™ํ™” playwright 1.40+
QR ์ฝ”๋“œ qrcode[pil] 8.0+
PDF ์ƒ์„ฑ reportlab 4.4+

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

๊ฐ ์Šคํ‚ฌ์€ ๋…๋ฆฝ๋œ Python ํŒจํ‚ค์ง€๋กœ ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค.

agent/src/starnion_agent/skills/
โ”œโ”€โ”€ finance/          # ๊ฐ€๊ณ„๋ถ€
โ”‚   โ”œโ”€โ”€ __init__.py   # ์Šคํ‚ฌ ๋“ฑ๋ก
โ”‚   โ”œโ”€โ”€ tools.py      # LangChain Tool ํ•จ์ˆ˜ ์ •์˜
โ”‚   โ””โ”€โ”€ SKILL.md      # ์Šคํ‚ฌ ์„ค๋ช… (LLM ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ์— ์ฃผ์ž…)
โ”œโ”€โ”€ weather/
โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”œโ”€โ”€ tools.py
โ”‚   โ””โ”€โ”€ SKILL.md
โ”œโ”€โ”€ loader.py         # ์Šคํ‚ฌ ๋™์  ๋กœ๋”ฉ
โ”œโ”€โ”€ guard.py          # ์Šคํ‚ฌ ์ ‘๊ทผ ๊ถŒํ•œ ๊ฒ€์‚ฌ
โ””โ”€โ”€ registry.py       # ์ „์ฒด ์Šคํ‚ฌ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ

SKILL.md์˜ ์—ญํ• 

๊ฐ ์Šคํ‚ฌ ๋””๋ ‰ํ„ฐ๋ฆฌ์˜ SKILL.md ํŒŒ์ผ์€ LLM ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ์— ์ง์ ‘ ์ฃผ์ž…๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด LLM์ด ๊ฐ ์Šคํ‚ฌ์˜ ์‚ฌ์šฉ ์กฐ๊ฑด๊ณผ ๋ฐฉ๋ฒ•์„ ์ •ํ™•ํžˆ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ = ๊ธฐ๋ณธ ํŽ˜๋ฅด์†Œ๋‚˜ + ํ™œ์„ฑ ์Šคํ‚ฌ์˜ SKILL.md ๋‚ด์šฉ

์Šคํ‚ฌ ๊ฐ€๋“œ (Skill Guard)

์‚ฌ์šฉ์ž๊ฐ€ ๋น„ํ™œ์„ฑํ™”ํ•œ ์Šคํ‚ฌ์€ guard.py์—์„œ ์ฐจ๋‹จ๋ฉ๋‹ˆ๋‹ค. ๋น„ํ™œ์„ฑ ์Šคํ‚ฌ์˜ ๋„๊ตฌ(Tool)๋Š” LLM์— ๋…ธ์ถœ๋˜์ง€ ์•Š์•„ ํ˜ธ์ถœ ์ž์ฒด๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.


๋กœ๊ทธ ๋ฐ HTTP ์„œ๋ฒ„

Agent๋Š” gRPC ํฌํŠธ(50051) ์™ธ์—๋„ HTTP ์„œ๋ฒ„(8082 ํฌํŠธ)๋ฅผ ์šด์˜ํ•ฉ๋‹ˆ๋‹ค.

ํฌํŠธ ์šฉ๋„
50051 gRPC ์„œ๋ฒ„ (Gateway์™€ ํ†ต์‹ )
8082 HTTP ์„œ๋ฒ„ (๋กœ๊ทธ ์ŠคํŠธ๋ฆฌ๋ฐ, ๋ฌธ์„œ ์ธ๋ฑ์‹ฑ, ๊ฒ€์ƒ‰ ์ž„๋ฒ ๋”ฉ)

Gateway์˜ /api/v1/logs/agent ์—”๋“œํฌ์ธํŠธ๋Š” Agent์˜ 8082 ํฌํŠธ๋กœ ํ”„๋ก์‹œํ•˜์—ฌ ์‹ค์‹œ๊ฐ„ Agent ๋กœ๊ทธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.


Copyright © 2025 StarNion. All rights reserved.  |  v0.1.1