ํ”ผ๋“œ๋กœ ๋Œ์•„๊ฐ€๊ธฐ
You Can't Even Make an AI Wrapper Chat App ๐Ÿ˜†๐Ÿซต
Dev.toDev.to
Backend

๋‹จ์ˆœ API Wrapper๋ฅผ ๋„˜์–ด Streaming๊ณผ Persistence๋ฅผ ๊ฒฐํ•ฉํ•œ AI ์ฑ„ํŒ… ์•„ํ‚คํ…์ฒ˜ ์„ค๊ณ„

You Can't Even Make an AI Wrapper Chat App ๐Ÿ˜†๐Ÿซต

Shuvo2026๋…„ 6์›” 5์ผ5๋ถ„intermediate

Context

๋‹จ์ˆœ Request-Response ๋ฐฉ์‹์˜ AI API ํ˜ธ์ถœ๋กœ ์ธํ•œ 10~15์ดˆ์˜ ์‘๋‹ต ์ง€์—ฐ ๋ฐ ์‚ฌ์šฉ์ž ์ดํƒˆ ๋ฐœ์ƒ. ์ƒํƒœ ๊ด€๋ฆฌ ๋ถ€์žฌ๋กœ ์ธํ•œ Page Refresh ์‹œ ๋Œ€ํ™” ๊ธฐ๋ก ์†Œ์‹ค ๋ฐ ๋ฌธ๋งฅ ์œ ์ง€ ๋ถˆ๊ฐ€๋ผ๋Š” ๊ตฌ์กฐ์  ํ•œ๊ณ„ ์ง๋ฉด.

Technical Solution

  • Server-Sent Events(SSE) ๊ธฐ๋ฐ˜์˜ text/event-stream ๋„์ž…์„ ํ†ตํ•œ Token ๋‹จ์œ„ ์‹ค์‹œ๊ฐ„ ๋ Œ๋”๋ง ๊ตฌํ˜„
  • Frontend์˜ ReadableStream ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ™œ์šฉํ•œ ์ ์ง„์  UI ์—…๋ฐ์ดํŠธ ๋ฐ UX ์ง€์—ฐ ์‹œ๊ฐ„ ์ œ๊ฑฐ
  • User Message์˜ ์ฆ‰๊ฐ์ ์ธ DB Insert์™€ AI Response์˜ ๋ˆ„์  ์ €์žฅ์„ ํ†ตํ•œ ๋Œ€ํ™” Persistence ํ™•๋ณด
  • conversationId ๊ธฐ๋ฐ˜์˜ History Loading ๋กœ์ง ์„ค๊ณ„๋ฅผ ํ†ตํ•œ ์„ธ์…˜ ์—ฐ์†์„ฑ ๋ฐ ๋ฉ€ํ‹ฐ ๋””๋ฐ”์ด์Šค ๋™๊ธฐํ™” ๊ตฌํ˜„
  • ์ „์ฒด ๋Œ€ํ™” ์ด๋ ฅ์„ AI Prompt์— ํฌํ•จํ•˜๋Š” Context Window ๊ด€๋ฆฌ ์ „๋žต ์ ์šฉ
  • DB ๋ถ€ํ•˜ ๊ฐ์†Œ๋ฅผ ์œ„ํ•œ ์ €์žฅ ๋กœ์ง์˜ Debouncing ์ฒ˜๋ฆฌ ๋ฐ ์˜ˆ์™ธ์ ์ธ ์—ฐ๊ฒฐ ๋Š๊น€ ๋Œ€์‘ ์„ค๊ณ„

- AI ์‘๋‹ต์˜ TTFB(Time to First Byte) ๊ฐœ์„ ์„ ์œ„ํ•ด Streaming API ์ฑ„ํƒ ์—ฌ๋ถ€ ๊ฒ€ํ†  - ๋‹จ์ˆœ ๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ๋„˜์–ด Refresh ๋ฐ ์„ธ์…˜ ๋งŒ๋ฃŒ ์ƒํ™ฉ์— ๋Œ€๋น„ํ•œ ๋ฐ์ดํ„ฐ Persistence ์ „๋žต ์ˆ˜๋ฆฝ - ๋Œ€ํ™” ๋ฌธ๋งฅ ์œ ์ง€๋ฅผ ์œ„ํ•œ History ๊ด€๋ฆฌ ๋ฐ ํ† ํฐ ์ œํ•œ์„ ๊ณ ๋ คํ•œ Context Window ์„ค๊ณ„ ํ™•์ธ - ์‹ค์‹œ๊ฐ„ ์ŠคํŠธ๋ฆฌ๋ฐ ๋ฐ์ดํ„ฐ์˜ DB ์ €์žฅ ์‹œ Write ๋ถ€ํ•˜๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•œ ๋ฒ„ํผ๋ง/๋””๋ฐ”์šด์‹ฑ ์ ์šฉ ๊ณ ๋ ค

์›๋ฌธ ์ฝ๊ธฐ