Spring AI Component - thought-corner/backend-roadmap GitHub Wiki

  • ChatClient ๋‚ด๋ถ€์—๋Š” ์œ ์ €์˜ ์งˆ๋ฌธ์ด AI๋ฅผ ๊ฑฐ์ณ ์ตœ์ข… ๊ฒฐ๊ณผ๋ฌผ๋กœ ๋‚˜์˜ค๊ธฐ๊นŒ์ง€ ๊ฐ๊ฐ์˜ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•˜๋Š” 5๊ฐ€์ง€์˜ ํ•ต์‹ฌ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์œ ๊ธฐ์ ์œผ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋‹ค.
  • AI ๋Œ€ํ™”์˜ ์‹œ์ž‘๊ณผ ๋์„ ๊ด€๋ฆฌํ•˜๋Š” ์ปจํŠธ๋กค๋Ÿฌ ์—ญํ• ์„ ํ•œ๋‹ค.
  • ํ•ด๋‹น ๊ฐ์ฒด์˜ .prompt() ๋ฉ”์„œ๋“œ๋ฅผ ์‹œ์ž‘์œผ๋กœ ์ „์ฒด ๋Œ€ํ™” ๊ณผ์ •์„ ์ œ์–ดํ•œ๋‹ค.
    • Spring AI ์ƒํƒœ๊ณ„์—์„œ AI ๋ชจ๋ธ(ChatGPT, Claude ๋“ฑ)๊ณผ ๋Œ€ํ™”๋ฅผ ์ฃผ๊ณ ๋ฐ›๋Š” ๋ชจ๋“  ๊ณผ์ •์„ ์ด๊ด„ํ•˜๊ณ  ์ œ์–ดํ•˜๋Š” ์ตœ์ƒ์œ„ ํ•ต์‹ฌ ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค.
    • ChatClient๋Š” ์ด ๋ณต์žกํ•œ ๋Œ€ํ™” ํŒŒ์ดํ”„๋ผ์ธ์„ ์Šคํ”„๋ง์—์„œ ์‰ฝ๊ฒŒ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์กŒ๋‹ค.
    • ๋นŒ๋” ํŒจํ„ด(Fluent API) ์Šคํƒ€์ผ์„ ์ œ๊ณตํ•˜์—ฌ ํ•„์š”ํ•œ ์˜ต์…˜๋“ค์„ ์ง๊ด€์ ์œผ๋กœ ์กฐ๋ฆฝ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ์ „์ฒ˜๋ฆฌ ๋‹จ๊ณ„
  • ์œ ์ €๊ฐ€ ๋ณด๋‚ธ ์งˆ๋ฌธ์ด AI ๋ชจ๋ธ๋กœ ๋„˜์–ด๊ฐ€๊ธฐ ์ง์ „, ์ค‘๊ฐ„์— ๊ฐœ์ž…ํ•˜์—ฌ ์งˆ๋ฌธ์„ ๊ฐ€๊ณตํ•˜๊ฑฐ๋‚˜ ํ•„์š”ํ•œ ๋ฐฐ๊ฒฝ์ง€์‹(Context)์„ ์ฃผ์ž…ํ•œ๋‹ค.
  • ์ด์ „ ๋Œ€ํ™” ๊ธฐ๋ก์„ ๋ถˆ๋Ÿฌ์™€ ์งˆ๋ฌธ์— ๋ถ™์—ฌ์ฃผ๊ฑฐ๋‚˜, Vector DB ๊ด€๋ จ ๋ฌธ์„œ๋ฅผ ์ฐพ์•„์™€ ์ฐธ๊ณ  ์ž๋ฃŒ๋กœ ๊ฒฐํ•ฉํ•ด์ฃผ๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
    • AI ๋ชจ๋ธ๊ณผ ์ฃผ๊ณ ๋ฐ›๋Š” ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ์ค‘๊ฐ„์—์„œ ๊ฐ€๋กœ์ฑ„ ๋ฐ์ดํ„ฐ๋ฅผ ๋™์ ์œผ๋กœ ์ˆ˜์ •, ํ™•์žฅ, ์ฐจ๋‹จํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์ปดํฌ๋„ŒํŠธ์ด๋‹ค.
    • ์Šคํ”„๋ง ์›น ๊ฐœ๋ฐœ์˜ ์ธํ„ฐ์…‰ํ„ฐ, ํ•„ํ„ฐ, ์ •ํ†ต AOP์™€ ๋™์ผํ•œ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
  • Chat Memory Advisors(๋Œ€ํ™” ํ๋ฆ„ ๊ด€๋ฆฌ)
    • MessageChatMemoryAdvisor : ๋Œ€ํ™” ์ด๋ ฅ์„ ์œ ์ €/AI ๋ฉ”์‹œ์ง€ ๊ตฌ์กฐ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•˜๋ฉฐ ํ”„๋กฌํ”„ํŠธ์— ์ถ”๊ฐ€
    • PromptChatMemoryAdvisor : ๊ณผ๊ฑฐ ๋Œ€ํ™”๋ฅผ ๋‹จ์ˆœ ํ…์ŠคํŠธ๋กœ ๋ฝ‘์•„์„œ ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ์— ์‚ฝ์ž…
  • Question Answering Advisors(RAG ๊ฒ€์ƒ‰ ์ฆ๊ฐ• ์ƒ์„ฑ)
    • QuestionAnswerAdvisor : Vector DB ์ž๋™ ์—ฐ๋™ ๋“ฑ์˜ ํŒจํ„ด์„ ์ˆ˜ํ–‰
    • RetrievalAugmentationAdvisor : ๊ณ ๋„ํ™”๋œ RAG ์•„ํ‚คํ…์ฒ˜๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ ์‚ฌ์šฉ
  • Reasoning & Safety Advisors(์ถ”๋ก  ๋ฐ ๋ณด์•ˆ)
    • ReReadingAdvisor(RE2) : LLM์˜ ์ถ”๋ก  ๋Šฅ๋ ฅ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ์ž…๋ ฅ๋œ ์งˆ๋ฌธ์„ ํ•œ ๋ฒˆ ๋” ์ฝ๊ฒŒ๋” ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ž๋™์œผ๋กœ ๋ณด๊ฐ•
    • SafeGuardAdvisor : AI ๋ชจ๋ธ์ด ํ•ด๋กญ๊ฑฐ๋‚˜ ๋ถ€์ ์ ˆํ•œ ๋‹ต๋ณ€์„ ์ƒ์„ฑํ•˜์ง€ ์•Š๋„๋ก ์‚ฌ์ „์— ๋ฐฉ์–ด๋ง‰์„ ์ณ์ค€๋‹ค.

Advisor์˜ ํ•ต์‹ฌ ๋™์ž‘ ์›๋ฆฌ : ์Šคํƒ(Stack) ๊ตฌ์กฐ

  • ์‹คํ–‰์ˆœ์„œ ๊ทœ์น™ : getOrder() ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ’์ด ์ž‘์„์ˆ˜๋ก(=์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์„์ˆ˜๋ก) ์ฒด์ธ์˜ ๊ฐ€์žฅ ๋ฐ”๊นฅ์ชฝ(=๋งจ ์œ„)์— ์œ„์น˜ํ•œ๋‹ค.
    • ์š”์ฒญ(Request) ๋‹จ๊ณ„ : ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์€(=Order ๊ฐ’์ด ์ž‘์€) Advisor๊ฐ€ ๊ฐ€์žฅ ๋จผ์ € ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ„์„œ ์ „์ฒ˜๋ฆฌํ•œ๋‹ค.
    • ์‘๋‹ต(Response) ๋‹จ๊ณ„ : ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์€(=Order ๊ฐ’์ด ์ž‘์€) Advisor๊ฐ€ ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰์— ์‘๋‹ต์„ ๊ฐ€๋กœ์ฑ„์„œ ํ›„์ฒ˜๋ฆฌํ•จ
  • ์ตœ์ข… ํ”„๋กฌํ”„ํŠธ ์ƒ์„ฑ
  • Advisors๊ฐ€ ์ˆ˜์ง‘ํ•œ ๋ฐฐ๊ฒฝ์ง€์‹(Context)๊ณผ ์œ ์ €๊ฐ€ ์ฒ˜์Œ ์ž…๋ ฅํ•œ ๋‚ด์šฉ์„ ๊ฒฐํ•ฉํ•˜์—ฌ, AI ๋ชจ๋ธ์ด ์™„๋ฒฝํ•˜๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” ์ตœ์ข… ํ”„๋กฌํ”„ํŠธ(๋ช…๋ น์–ด)๋ฅผ ์™„์„ฑํ•˜๋Š” ๋‹จ๊ณ„์ด๋‹ค.
  • Prompt ๊ฐ์ฒด์˜ ๋‚ด๋ถ€๋Š” List<Message>์™€ ChatOptions์ด ์žˆ๋‹ค.
    • ChatOptions : ๋Œ€ํ™”์˜ ๋งฅ๋ฝ์„ ๊ตฌ์„ฑํ•˜๋Š” ์—ฌ๋Ÿฌ ์ข…๋ฅ˜์˜ ๋ฉ”์‹œ์ง€ ๋ฌถ์Œ
    • List<Message> : ์˜จ๋„, ์‚ฌ์šฉํ•  ๋ชจ๋ธ๋ช…๊ณผ ๊ฐ™์€ AI ์‹คํ–‰ ์˜ต์…˜

MessageType

  • SYSTEM : AI์˜ ์„ฑ๊ฒฉ, ์ง์—…, ํ–‰๋™ ์ง€์นจ, ์ œ์•ฝ ์‚ฌํ•ญ ๋“ฑ์„ ์„ธ๋‡Œ์‹œํ‚ค๋Š” ๋ฉ”์‹œ์ง€
  • USER : ์‹ค์ œ ์„œ๋น„์Šค๋ฅผ ์ด์šฉํ•˜๋Š” ์œ ์ €๊ฐ€ ์ž…๋ ฅํ•œ ์งˆ๋ฌธ์ด๋‚˜ ์ง€์‹œ ๋‚ด์šฉ
  • ASSISTANT : AI๊ฐ€ ์ด์ „์— ๋Œ€๋‹ตํ–ˆ๋˜ ์‘๋‹ต ๋‚ด์šฉ์„ ์ฑ—๋ด‡์ด ๊ธฐ์–ตํ•˜๊ณ  ์ด์–ด๊ฐ€๊ธฐ ์œ„ํ•ด(Chat Memory) ๋ง๋ถ™์ด๋Š” ๋ฉ”์‹œ์ง€
  • TOOL : AI๊ฐ€ ์™ธ๋ถ€ API๋‚˜ ํ•จ์ˆ˜(์˜ˆ: ๋‚ ์”จ ์กฐํšŒ, ์‚ฌ๋‚ด DB ์กฐํšŒ)๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ๋Œ์•„์˜จ ๊ฒฐ๊ณผ๊ฐ’์„ ๋‹ด๋Š” ํŠน์ˆ˜ ๋ฉ”์‹œ์ง€

PromptTemplate

  • ์‹ค์ œ๋กœ ์งˆ๋ฌธ์ด ๊ณ ์ •๋˜์–ด ์žˆ์ง€ ์•Š๊ธฐ์— ์œ ์ €์˜ ์ž…๋ ฅ๊ฐ’์— ๋”ฐ๋ผ ์งˆ๋ฌธ ๋‚ด์šฉ์ด ๋งค๋ฒˆ ๋ฐ”๋€Œ์–ด์•ผ ํ•˜๋ฏ€๋กœ PromptTemplate์„ ํ•„์ˆ˜์ ์œผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.
  • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง(์ž๋ฐ” ์ฝ”๋“œ)๊ณผ ํ”„๋กฌํ”„ํŠธ ๋ฌธ๊ตฌ(ํ…์ŠคํŠธ)๋ฅผ ๊น”๋”ํ•˜๊ฒŒ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ๋งค์šฐ ํŽธํ•ด์ง„๋‹ค.

ChatOptions

  • ChatOptions๋ž€, ์˜จ๋„(Temperature), ์‚ฌ์šฉํ•  ๋ชจ๋ธ๋ช…(GPT-4)์™€ ๊ฐ™์€ AI ์‹คํ–‰ ์˜ต์…˜์„ ๋งํ•œ๋‹ค.
  • Temperature(์˜จ๋„)
    • 0.0 ~ 0.3(๋‚ฎ์€ ์˜จ๋„) : ๋งค์šฐ ๊ฒฐ์ •์ ์ด๊ณ  ์ผ๊ด€๋œ ์‘๋‹ต, ์‚ฌ์‹ค ๊ธฐ๋ฐ˜ ๋‹ต๋ณ€, ๋ฐ์ดํ„ฐ ๋ถ„๋ฅ˜, ์ฝ”๋“œ ์ƒ์„ฑ์— ์ ํ•ฉํ•˜๋‹ค.
    • 0.4 ~ 0.7(์ค‘๊ฐ„ ์˜จ๋„) : ๊ท ํ˜• ์žกํžŒ ์‘๋‹ต, ์ผ๋ฐ˜์ ์ธ ๋Œ€ํ™”๋‚˜ ์ •๋ณด ์ œ๊ณต์šฉ ์ฑ—๋ด‡์— ๊ฐ€์žฅ ๋งŽ์ด ์“ฐ๋Š” ํ‘œ์ค€ ๊ฐ’์ด๋‹ค.
    • 0.8 ~ 1.0(๋†’์€ ์˜จ๋„) : ์ฐฝ์˜์ ์ด๊ณ  ๋‹ค์–‘ํ•œ ์‘๋‹ต, ์—‰๋šฑํ•˜๊ณ  ๊ธฐ๋ฐœํ•œ ์ƒ๊ฐ์ด ํ•„์š”ํ•œ ์Šคํ† ๋ฆฌํ…”๋ง, ์†Œ์„ค ์“ฐ๊ธฐ, ์•„์ด๋””์–ด ๋ธŒ๋ ˆ์ธ์Šคํ† ๋ฐ์— ์ ํ•ฉํ•˜๋‹ค.
  • Output Length(์ตœ๋Œ€ ๊ธธ์ด ์ œํ•œ)
    • 5 ~ 25 : ํ•œ๋‘ ๋‹จ์–ด, ์งง์€ ๊ตฌ์ ˆ, ํ˜น์€ "๊ธ์ •/๋ถ€์ •" ๊ฐ™์€ ๋ถ„๋ฅ˜ ๋ผ๋ฒจ์ด๋‹ค.
    • 50 ~ 500 : ํ•˜๋‚˜์˜ ๊น”๋”ํ•œ ๋ฌธ๋‹จ์ด๋‚˜ ์งง์€ ์„ค๋ช…์„ ์›ํ•  ๋•Œ ์ ํ•ฉํ•˜๋‹ค.
    • 1000+ : ์žฅ๋ฌธ์˜ ๊ธ€, ์†Œ์„ค ์Šคํ† ๋ฆฌ, ๋ณต์žกํ•œ ๋กœ์ง์˜ ์•„ํ‚คํ…์ฒ˜ ์„ค๋ช…์ด๋‹ค.
  • Sampling Controls(์ƒ˜ํ”Œ๋ง ์ œ์–ด)
    • AI๊ฐ€ ๋‹ค์Œ์— ์˜ฌ ๋‹จ์–ด(ํ† ํฐ) ํ›„๋ณด๊ตฐ์„ ์ถ”๋ ค๋‚ด๋Š” ๊ณ ๋„์˜ ํ•„ํ„ฐ๋ง ๊ธฐ๋ฒ•์ด๋‹ค.
    • Top-K(์ƒ์œ„ K๊ฐœ ํ•„ํ„ฐ๋ง) : ๋‹ค์Œ ํ† ํฐ์„ ์„ ํƒํ•  ๋•Œ, ํ™•๋ฅ ์ด ๊ฐ€์žฅ ๋†’์€ ์ƒ์œ„ K๊ฐœ์˜ ํ† ํฐ์œผ๋กœ๋งŒ ํ›„๋ณด๊ตฐ์„ ์ œํ•œํ•œ๋‹ค. ๊ฐ’์ด ํด์ˆ˜๋ก ๋‹ค์–‘ํ•œ ๋‹จ์–ด๊ฐ€ ์„ž์—ฌ ๋‚˜์™€ ๋‹ค์–‘์„ฑ์ด ์ฆ๊ฐ€ํ•˜๊ณ , ์ž‘์„์ˆ˜๋ก ๋Š˜ ์“ฐ๋˜ ๋‹จ์–ด๋งŒ ์จ์„œ ๊ฒฐ์ •์ ์ธ ๋‹ต๋ณ€์ด ๋‚˜์˜จ๋‹ค.
    • Top-P (๋ˆ„์  ํ™•๋ฅ  ํ•„ํ„ฐ๋ง / Nucleus Sampling) : ํ›„๋ณด ๋‹จ์–ด๋“ค์„ ํ™•๋ฅ  ๋†’์€ ์ˆœ์œผ๋กœ ์ค„ ์„ธ์šด ๋’ค, ๋ˆ„์  ํ™•๋ฅ ์ด P(์˜ˆ: 90%)๋ฅผ ์ดˆ๊ณผํ•˜๊ธฐ ์ „๊นŒ์ง€๋งŒ ๋™์ ์œผ๋กœ ๋‹จ์–ด ํ›„๋ณด๊ตฐ์„ ์„ ํƒํ•œ๋‹ค. ์ƒ์œ„ 90%์˜ ์•ˆ์ „ํ•œ ๋‹จ์–ด๋“ค ์•ˆ์—์„œ๋งŒ ๊ณ ๋ฅด๊ฒŒ ํ•˜๋ฏ€๋กœ ๋ฌธ๋งฅ์ด ๊ผฌ์ด์ง€ ์•Š์œผ๋ฉด์„œ๋„ ์ž์—ฐ์Šค๋Ÿฌ์šด ๋ณ€ํ™”๋ฅผ ์ฃผ๋ฉฐ, ์ผ๋ฐ˜์ ์œผ๋กœ 0.8 ~ 0.95 ์‚ฌ์ด์˜ ๊ฐ’์„ ์‚ฌ์šฉํ•œ๋‹ค.

Spring AI ํ”„๋กฌํ”„ํŠธ ์—”์ง€๋‹ˆ์–ด๋ง 9๊ฐ€์ง€ ํŒจํ„ด

  • Zero-Shot Prompting : ์‚ฌ์ „ ์ •๋ณด๋‚˜ ์˜ˆ์‹œ ์—†์ด AI์—๊ฒŒ ๊ณง๋ฐ”๋กœ ์งˆ๋ฌธ์„ ๋˜์ง€๋Š” ๋ฐฉ์‹
  • Few-Shot Prompting : AI์—๊ฒŒ 1๊ฐœ ๋˜๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ •๋‹ต ์˜ˆ์‹œ๋ฅผ ๋ฏธ๋ฆฌ ๋ณด์—ฌ์ฃผ๊ณ  ํŒจํ„ด์„ ํ•™์Šต์‹œํ‚จ ๋’ค ์งˆ๋ฌธ์„ ๋˜์ง€๋Š” ๋ฐฉ์‹
  • Role & System Prompting : ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์‚ฌ์šฉํ•ด AI์—๊ฒŒ 'ํŽ˜๋ฅด์†Œ๋‚˜(์ง์—…, ์„ฑ๊ฒฉ, ํ†ค์•ค๋งค๋„ˆ)'๋ฅผ ๋ถ€์—ฌํ•˜๋Š” ๋ฐฉ์‹
  • Step-Back Prompting : AI๊ฐ€ ์„ฃ๋ถˆ๋ฆฌ ๋Œ€๋‹ตํ•˜๊ธฐ ์ „์—, ์ƒํ™ฉ์„ ๋จผ์ € ๊ฐ๊ด€์ ์œผ๋กœ ๋ถ„์„ํ•˜๊ณ  ์„ฑ์ฐฐํ•˜๋„๋ก ์œ ๋„ํ•˜๋Š” ๋ฐฉ์‹
  • Chain-of-Thought, CoT : ๋‹จ์ˆœํžˆ ๋‹ต๋งŒ ๋ฑ‰๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ, ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ณผ์ •์„ ๋‹จ๊ณ„๋ณ„๋กœ ํ’€์–ด์„œ ์„ค๋ช…ํ•˜๋„๋ก ์ง€์‹œํ•˜๋Š” ๋ฐฉ์‹
  • Self-Consistency Prompting : CoT(์ƒ๊ฐ์˜ ์‚ฌ์Šฌ) ํ”„๋กฌํ”„ํŠธ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ฐ˜๋ณตํ•ด์„œ ํ˜ธ์ถœํ•œ ๋’ค, ๊ฐ€์žฅ ๋งŽ์ด ๋‚˜์˜จ(์ผ๊ด€๋œ) ๋‹ต๋ณ€์„ ์ตœ์ข… ์ •๋‹ต์œผ๋กœ ์ฑ„ํƒํ•˜๋Š” ๋ฐฉ์‹
  • Tree-of-Thoughts, ToT : ํ•˜๋‚˜์˜ ๋ฌธ์ œ์— ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ํ•ด๊ฒฐ์ฑ…์„ ๋จผ์ € ์ œ์•ˆํ•˜๊ฒŒ ํ•˜๊ณ , ๊ทธ ์ค‘ ๊ฐ€์žฅ ์ข‹์€ ๊ฒƒ์„ ์Šค์Šค๋กœ ์„ ํƒํ•ด ํ‰๊ฐ€ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฐฉ์‹
  • Automatic Prompt Engineering : ๋‚ด๊ฐ€ ์“ด ๋ถ€์‹คํ•œ ํ”„๋กฌํ”„ํŠธ๋ฅผ AI์—๊ฒŒ ๋˜์ ธ์„œ "๋„ค๊ฐ€ ๋” ์™„๋ฒฝํ•œ ํ”„๋กฌํ”„ํŠธ๋กœ ๋‹ค๋“ฌ์–ด๋ด"๋ผ๊ณ  ์‹œํ‚ค๋Š” ๋ฐฉ์‹
  • Code Prompting : ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ๋ถ„์„ํ•˜๋„๋ก ์š”์ฒญํ•˜๋Š” ๋ฐฉ์‹
  • AI ๋ชจ๋ธ ์‹คํ–‰
  • ์™„์„ฑ๋œ ์ตœ์ข… ํ”„๋กฌํ”„ํŠธ๋ฅผ ์‹ค์ œ ์™ธ๋ถ€ AI API(OpenAI, ๊ตฌ๊ธ€ ๋“ฑ)์— ๋˜์ ธ ๋‹ต๋ณ€์„ ๋ฐ›์•„์˜จ๋‹ค.
  • ์ด ๋‹จ๊ณ„์—์„œ ์„ค์ •(์ผ๋ฐ˜ ์‘๋‹ต vs ์ŠคํŠธ๋ฆฌ๋ฐ)์— ๋”ฐ๋ผ ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ ๋ฒˆ์— ํ†ต์งธ๋กœ ๋ฐ›์„์ง€, ๊ธ€์ž ๋‹จ์œ„๋กœ ์‹ค์‹œ๊ฐ„ ์ŠคํŠธ๋ฆฌ๋ฐ์œผ๋กœ ๋ฐ›์„์ง€ ์‘๋‹ต ๊ทœ๊ฒฉ์ด ๊ฒฐ์ •๋œ๋‹ค.
    • OpenAI(ChatGPT), Google(Gemini), Anthropic(Claude) ๋“ฑ ๋‹ค์–‘ํ•œ ์™ธ๋ถ€ AI ์„œ๋น„์Šค์™€ ํ†ต์‹ ํ•˜๊ธฐ ์œ„ํ•œ ์ž๋ฐ” ํ‘œ์ค€ ์ธํ„ฐํŽ˜์ด์Šค
    • Spring AI Models๋Š” ์ž๋ฐ”์˜ ๋‹คํ˜•์„ฑ(Polymorphism)์„ ๊ทน๋Œ€ํ™”ํ•˜์—ฌ, ๊ฐœ๋ฐœ์ž๊ฐ€ ๋‹จ์ผํ•œ ์Šคํ”„๋ง ์ธํ„ฐํŽ˜์ด์Šค(Model)๋งŒ ๋ณด๊ณ  ์ฝ”๋”ฉํ•˜๋„๋ก ์„ค๊ณ„๋˜์–ด์žˆ๋‹ค.
    • application.yaml๊ณผ ๊ฐ™์€ ์„ค์ • ํŒŒ์ผ์—์„œ API ํ‚ค์™€ ์˜์กด์„ฑ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋งŒ ๊ต์ฒดํ•˜์—ฌ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ChatModel : ํ…์ŠคํŠธ ๋Œ€ํ™” ์—”์ง„, ํ…์ŠคํŠธ(Prompt)๋ฅผ ์ž…๋ ฅ๋ฐ›์•„ ํ…์ŠคํŠธ(ChatResponse)๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ด๊ณ  ํ•ต์‹ฌ์ ์ธ ๋ชจ๋ธ
  • EmbeddingModel : Vector ๋ณ€ํ™˜ ์—”์ง„, RAG(๊ฒ€์ƒ‰ ์ฆ๊ฐ• ์ƒ์„ฑ) ์‹œ์Šคํ…œ์˜ ํ•ต์‹ฌ. ์ค„๊ธ€ ํ…์ŠคํŠธ๋ฅผ ์ž…๋ ฅ๋ฐ›์•„ Vector DB์— ์ €์žฅํ•  ์ˆ˜ ์žˆ๋„๋ก ์ˆซ์ž ๋ฐฐ์—ด(Vector)๋กœ ๋ณ€ํ™˜ํ•ด์ฃผ๋Š” ๋ชจ๋ธ
  • ImageModel : ์ด๋ฏธ์ง€ ์ƒ์„ฑ ์—”์ง„, ํ…์ŠคํŠธ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ž…๋ ฅ๋ฐ›์•„ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑ
  • AudioModel : ์Œ์„ฑ ์ฒ˜๋ฆฌ ์—”์ง„, ์Œ์„ฑ์„ ํ…์ŠคํŠธ๋กœ ๋ณ€ํ™˜(STT)ํ•˜๊ฑฐ๋‚˜, ํ…์ŠคํŠธ๋ฅผ ์Œ์„ฑ์œผ๋กœ ๋ณ€ํ™˜(TTS)ํ•˜๋Š” ๋ชจ๋ธ
  • ํ›„์ฒ˜๋ฆฌ ๋ฐ ๊ฐ์ฒด ๋ณ€ํ™˜
  • AI ๋ชจ๋ธ์ด ๋ฑ‰์–ด๋‚ธ ์ค„๊ธ€ ํ˜•ํƒœ์˜ ํ…์ŠคํŠธ ๋‹ต๋ณ€์„ ๋ฐ›์•„, ๋ฐฑ์—”๋“œ ๋กœ์ง์—์„œ ์ฆ‰์‹œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ •ํ•ด์ง„ ์ž๋ฐ” ๊ฐ์ฒด(DTO)๋‚˜ JSON ๊ทœ๊ฒฉ์œผ๋กœ ์ž๋™ ํŒŒ์‹ฑํ•ด์ฃผ๋Š” ์ตœ์ข… ๋ณ€ํ™˜ ๋‹จ๊ณ„์ด๋‹ค.
    • AI ๋ชจ๋ธ์ด ๋ฑ‰์–ด๋‚ด๋Š” ์˜ˆ์ธก ๋ถˆ๊ฐ€๋Šฅํ•œ ๋ฌธ์ž์—ด(String) ํ˜•ํƒœ์˜ ๋‹ต๋ณ€์„, ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๊ฐ€ ์ฆ‰์‹œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ •ํ˜•ํ™”๋œ ๋ฐ์ดํ„ฐ ๊ทœ๊ฒฉ(JSON, ์ž๋ฐ” ๊ฐ์ฒด, ๋ฆฌ์ŠคํŠธ ๋“ฑ)์œผ๋กœ ๊ฐ•์ œํ•˜๊ณ  ๋ณ€ํ™˜ํ•ด์ฃผ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ ์ง€์› ๊ธฐ๋Šฅ์ด๋‹ค.
    • Structured Output ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ฉด, ๋ฐฑ์—”๋“œ ๋กœ์ง์€ AI์˜ ์‘๋‹ต์„ String์ด ์•„๋‹Œ ์ฒ˜์Œ๋ถ€ํ„ฐ ์ž๋ฐ” DTO๋‚˜ List<String> ๊ฐ™์€ ๊น”๋”ํ•œ ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ๋ฐ”๋กœ ๊ฑด๋„ค๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.
  • BeanOutputConverter : AI์˜ ๋‹ต๋ณ€์„ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ๋งŒ๋“  ์ปค์Šคํ…€ ์ž๋ฐ” ํด๋ž˜์Šค(DTO ๋˜๋Š” Record)๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.
  • ListOutputConverter : ๋‹ต๋ณ€์„ ๋‹จ์ˆœํ•œ List<String> ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • MapOutputConverter : ๋‹ต๋ณ€์„ Map<String, Object> ํ˜•ํƒœ์˜ ํ‚ค-๊ฐ’ ์Œ์œผ๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
spring:
  application:
    name: spring-ai
  ai:
#    anthropic:
#      api-key: "TEST-API-KEY"
#      chat:
#        model: claude-opus-4-8
#        max-tokens: 4096
    ollama:
      init:
        pull-model-strategy: when_missing
      chat:
        model: hf.co/Qwen/Qwen2.5-1.5B-Instruct-GGUF # https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct-GGUF
@RestController
public class ChatController {

    private final ChatClient client;

    @Autowired
    public ChatController(ChatClient.Builder builder) {
        this.client = builder.build();
    }

    // 1) ๋‹จ์ˆœํ•˜๊ฒŒ ๋ฐ›๊ธฐ: call().content() ๋กœ ์‘๋‹ต ๋ณธ๋ฌธ ํ…์ŠคํŠธ๋งŒ String ์œผ๋กœ ๋ฐ˜ํ™˜๋ฐ›๋Š”๋‹ค. ๊ฐ€์žฅ ๊ธฐ๋ณธ ํ˜•ํƒœ.
    @GetMapping("/chat/simple")
    public String simple(@RequestParam String prompt) {
        return this.client.prompt()
                .user(prompt)
                .call()
                .content();
    }

    // 2) ChatResponse ๊ฐ์ฒด๋กœ ๋ฐ›๊ธฐ: call().chatResponse() ๋กœ ๋ณธ๋ฌธ + ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ํ†ต์งธ๋กœ ๋ฐ›๋Š”๋‹ค.
    //    ๋ณธ๋ฌธ ํ…์ŠคํŠธ โ†’ getResult().getOutput().getText(), ํ† ํฐ ์‚ฌ์šฉ๋Ÿ‰ โ†’ getMetadata().getUsage()
    @GetMapping("/chat/response")
    public ChatResponse response(@RequestParam String prompt) {
        return this.client.prompt()
                .user(prompt)
                .call()
                .chatResponse();
    }

    // 3) ์ž๋ฐ” ๊ฐ์ฒด๋กœ ๋ฐ›๊ธฐ: call().entity(ActorFilms.class) ๋กœ ์‘๋‹ต์„ DTO(record)์— ๋งคํ•‘ํ•œ๋‹ค.
    //    Spring AI ๊ฐ€ JSON ์ถœ๋ ฅ ํฌ๋งท ์ง€์นจ์„ ํ”„๋กฌํ”„ํŠธ์— ์ž๋™์œผ๋กœ ๋ง๋ถ™์—ฌ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.
    @GetMapping("/chat/entity")
    public ActorFilms entity(@RequestParam String actor) {
        return this.client.prompt()
                .user(u -> u.text("{actor}์ด(๊ฐ€) ์ถœ์—ฐํ•œ ๋Œ€ํ‘œ ์˜ํ™” 5ํŽธ์„ ์•Œ๋ ค์ค˜.")
                            .param("actor", actor))
                .call()
                .entity(ActorFilms.class);
    }

    // 4) Flux ๋กœ ๋ฐ›๊ธฐ: stream().content() ๋กœ ํ† ํฐ์„ ์ƒ์„ฑ๋˜๋Š” ์ฆ‰์‹œ ํ˜๋ ค๋ณด๋‚ธ๋‹ค(SSE).
    //    produces = text/event-stream ์ด๋ผ ์‘๋‹ต์ด data: ์ฒญํฌ๋กœ ์‹ค์‹œ๊ฐ„ ์ŠคํŠธ๋ฆฌ๋ฐ๋œ๋‹ค. (curl -N ๋กœ ํ™•์ธ)
    @GetMapping(value = "/chat/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> stream(@RequestParam String prompt) {
        return this.client.prompt()
                .user(prompt)
                .stream()
                .content();
    }
}
โš ๏ธ **GitHub.com Fallback** โš ๏ธ