๐Ÿ’Š ์˜์–‘์ œ Check! ๊ฐœ๋ฐœ๊ธฐ

jul eeยท2025๋…„ 7์›” 3์ผ

๋ฐ์ดํ„ฐ ์„ฑ์žฅ๊ธฐ

๋ชฉ๋ก ๋ณด๊ธฐ
135/139

๊ฐœ์ธ ๋งž์ถค๊ณผ ์‹ ๋ขฐ ๊ธฐ๋ฐ˜์„ ๋ชจ๋‘ ๊ฐ–์ถ˜ ๊ฑด๊ฐ•๊ธฐ๋Šฅ์‹ํ’ˆ ์ถ”์ฒœ ์‹œ์Šคํ…œ์˜ ์„ค๊ณ„์™€ ๊ตฌํ˜„

๐Ÿ”— GitHub repository

ํ”„๋กœ์ ํŠธ ๊ธฐ๊ฐ„: ย 2025.06.30 - 2025.07.03 ย (4์ธ ํ”„๋กœ์ ํŠธ)



0. ๋ชฉ์ฐจ

  1. ํ”„๋กœ์ ํŠธ ๋„์ž…: ์™œ '์˜์–‘์ œ ์ถ”์ฒœ'์ธ๊ฐ€?
  2. ํ”„๋กœ์ ํŠธ ๋ชฉํ‘œ
  3. ์–ด๋–ค ๊ธฐ์ˆ ์„ ์™œ ์„ ํƒํ–ˆ๋Š”๊ฐ€?
  4. ๋ฌธํ—Œ ์ˆ˜์ง‘ ๋ฐ ์ „์ฒ˜๋ฆฌ ๋ฐฉ์‹
  5. ๊ธฐ์ˆ ์  ์„ค๊ณ„ ํฌ์ธํŠธ
  6. ์‚ฌ์šฉ์ž ์ž…๋ ฅ ์ฒ˜๋ฆฌ ๋ฐ Case ๋ถ„๋ฅ˜ ๋กœ์ง
  7. ๊ณต๊ณต๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜ ์ œํ’ˆ ์ถ”์ฒœ ํŒŒ์ดํ”„๋ผ์ธ
  8. Streamlit ๊ธฐ๋ฐ˜ UI ๊ตฌ์„ฑ ๋ฐ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜ ์„ค๊ณ„
  9. ์‹คํ–‰ ๊ฒฐ๊ณผ
  10. ๊ฐœ์„  ๋ฐฉํ–ฅ
  11. ํ”„๋กœ์ ํŠธ ํšŒ๊ณ 



1. ํ”„๋กœ์ ํŠธ ๋„์ž…: ์™œ '์˜์–‘์ œ ์ถ”์ฒœ'์ธ๊ฐ€?

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

๊ฒŒ๋‹ค๊ฐ€ ์ตœ๊ทผ์—๋Š” ๊ฒ€์ƒ‰๋ณด๋‹ค ChatGPT, Gemini์™€ ๊ฐ™์€ ๋Œ€ํ˜• ์–ธ์–ด๋ชจ๋ธ(Large Language Model, LLM) ๊ธฐ๋ฐ˜ ์ฑ—๋ด‡์—๊ฒŒ ์ง์ ‘ ์งˆ๋ฌธํ•˜์—ฌ ์ •๋ณด๋ฅผ ์–ป๋Š” ๊ฒŒ ์ž์—ฐ์Šค๋Ÿฌ์šด ์‹œ๋Œ€๊ฐ€ ๋˜์—ˆ๋‹ค.

โ€œ๋ฌด์Šจ ์˜์–‘์ œ๋ฅผ ๋จน๋Š” ๊ฒŒ ์ข‹์„๊นŒ?โ€, โ€œ๋ฃจํ…Œ์ธ์€ ๋ˆˆ์— ์ง„์งœ ํšจ๊ณผ ์žˆ์–ด?โ€, โ€œ์ด ์ œํ’ˆ์€ ๋‹น๋‡จ ํ™˜์ž๋„ ๋จน์„ ์ˆ˜ ์žˆ์–ด?โ€ ๊ฐ™์€ ์งˆ๋ฌธ๋„ ์ „๋ฌธ๊ฐ€๊ฐ€ ์•„๋‹ˆ๋ผ ์ฑ—๋ด‡์—๊ฒŒ ๋จผ์ € ๋ฌป๊ณ ๋Š” ํ•œ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ "๊ทธ ์ •๋ณด, ๊ทธ๋Œ€๋กœ ๋ฏฟ์–ด๋„ ๋ ๊นŒ?" ํ•˜๋Š” ์˜๋ฌธ๋„ ๊ฐ€์ง€๊ณ  ์žˆ์„ ๊ฒƒ์ด๋‹ค.

์‹ค์ œ๋กœ ๊ฑด๊ฐ• ์ •๋ณด๋‚˜ ์„ฑ๋ถ„ ์ถ”์ฒœ์— ๋Œ€ํ•ด ์ด๋“ค ์ฑ—๋ด‡์ด ์ œ๊ณตํ•˜๋Š” ์‘๋‹ต์€ ๊ณผ๊ฑฐ์— ๋น„ํ•ด ์ƒ๋‹นํžˆ ์ •ํ™•ํ•˜๊ณ  ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋ณด์ด์ง€๋งŒ, ์—ฌ์ „ํžˆ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ์ ์ธ ๋ฌธ์ œ๊ฐ€ ์กด์žฌํ•œ๋‹ค.

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

์ด๋Ÿฌํ•œ ๋ฐฐ๊ฒฝ์—์„œ ๋ณธ ํ”„๋กœ์ ํŠธ๋Š” '์˜์–‘์ œ ์ถ”์ฒœ ์‹œ์Šคํ…œ'์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, LLM์˜ ๋ถˆํ™•์‹คํ•œ ์‘๋‹ต ๊ตฌ์กฐ ์ž์ฒด๋ฅผ ์‹ ๋ขฐ ๊ฐ€๋Šฅํ•œ ๊ตฌ์กฐ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐ์ˆ ์  ์‹คํ—˜์œผ๋กœ ์‹œ์ž‘๋˜์—ˆ๋‹ค.

" GPT๋ณด๋‹ค ๋ฏฟ์„ ์ˆ˜ ์žˆ๋Š”, ์‹ค์ œ๋กœ ๋„์›€์ด ๋˜๋Š” ย ์˜์–‘์ œ ์ถ”์ฒœ ์‹œ์Šคํ…œ โ€




2. ํ”„๋กœ์ ํŠธ ๋ชฉํ‘œ

์šฐ๋ฆฌ ํŒ€์€ ํ•˜๋‚˜์˜ ๋ฐฉํ–ฅ ์†์—์„œ ์„ธ ๊ฐ€์ง€์˜ ๋ชฉํ‘œ๋ฅผ ์ •ํ™•ํ•˜๊ฒŒ ์žก์•˜๋‹ค.

2.1 ย ์‹ ๋ขฐ ๊ฐ€๋Šฅํ•œ ์ •๋ณด ์ œ๊ณต

  • GPT-4 ๊ธฐ๋ฐ˜ LLM์ด ๋‹ต๋ณ€์„ ์ƒ์„ฑํ•  ๋•Œ ์ž„์˜์˜ ์„ฑ๋ถ„์„ '์ฐฝ์ž‘'ํ•˜์ง€ ์•Š๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด ์˜ค์ง ๋ฌธ์„œ ๊ธฐ๋ฐ˜์˜ RAG ๊ตฌ์กฐ๋ฅผ ์ฑ„ํƒํ•˜์˜€๋‹ค.
  • ์‚ฌ์šฉ๋œ ๋ฌธ์„œ๋Š” ํ•™์ˆ  ๋…ผ๋ฌธ, ์ •๋ถ€ ๊ฐ€์ด๋“œ๋ผ์ธ, ์‹์•ฝ์ฒ˜ ์ž๋ฃŒ ๋“ฑ 46ํŽธ์˜ PDF ๋ฌธ์„œ์ด๋ฉฐ, LLM์€ ๋ฐ˜๋“œ์‹œ ์ด ๋ฌธ์„œ ๋‚ด ์ •๋ณด์— ๊ธฐ๋ฐ˜ํ•˜์—ฌ ๋‹ต๋ณ€์„ ์ƒ์„ฑํ•ด์•ผ ํ•œ๋‹ค.

2.2 ย ์‚ฌ์šฉ์ž ๋งž์ถคํ˜• ์ถ”์ฒœ

  • ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ๋‚˜์ด, ์„ฑ๋ณ„, ์งˆํ™˜, ๋ณต์šฉ ์ค‘ ์•ฝ๋ฌผ, ์„ ํ˜ธ ์„ฑ๋ถ„ ๋“ฑ์˜ ์ •๋ณด๋ฅผ ์ž…๋ ฅ๋ฐ›๊ณ , ํ‚ค์›Œ๋“œ ๊ธฐ๋ฐ˜์œผ๋กœ ์‚ฌ์ „ ์ •์˜๋œ Case A~D ์‹œ๋‚˜๋ฆฌ์˜ค ๋กœ ๋ถ„๋ฅ˜ํ•˜์—ฌ ๊ฐ๊ธฐ ๋‹ค๋ฅธ ์ฒ˜๋ฐฉ์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ์„ค๊ณ„ํ•˜์˜€๋‹ค.
  • ๋™์ผํ•œ ์‚ฌ์šฉ์ž ์งˆ๋ฌธ์ด๋ผ๋„ ๋ณต์šฉ ์ค‘ ์•ฝ๋ฌผ ๋˜๋Š” ์งˆํ™˜์— ๋”ฐ๋ผ ๊ธˆ๊ธฐ ์„ฑ๋ถ„์ด ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด ๋ถ„๋ฅ˜๋ฅผ ํ†ตํ•ด ์ƒํ˜ธ๋ฐฐํƒ€์ ์ธ ์กฐ๊ฑด ์ฒ˜๋ฆฌ ๋ฐ ๋‹ค์ค‘ ์ฒ˜๋ฐฉ ์ ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ๊ตฌ์„ฑํ•˜์˜€๋‹ค.

2.3 ย ์‹ค์ œ ์ œํ’ˆ ์ถ”์ฒœ ๋ฐ ์‹คํ–‰ ๊ฐ€๋Šฅ์„ฑ ํ™•๋ณด

  • ์„ฑ๋ถ„ ์ •๋ณด๋ฅผ ์•Œ๋ ค์ฃผ๋Š” ๋ฐ ๊ทธ์น˜์ง€ ์•Š๊ณ , ์‹ํ’ˆ์˜์•ฝํ’ˆ์•ˆ์ „์ฒ˜ ๊ณต๊ณต๋ฐ์ดํ„ฐ(API)๋ฅผ ํ†ตํ•ด ์ถ”์ฒœ ์„ฑ๋ถ„์ด ํฌํ•จ๋œ, ํ”ผํ•ด์•ผ ํ•  ์„ฑ๋ถ„์€ ์ œ์™ธ๋œ ์‹ค์ œ ์ œํ’ˆ์„ ์ถ”์ฒœํ•œ๋‹ค.
  • ์œ ์‚ฌ๋„ ๊ธฐ๋ฐ˜ ๋ฒกํ„ฐ ๊ฒ€์ƒ‰์„ ํ†ตํ•ด ์ถ”์ฒœ ์ œํ’ˆ์„ ์ฐพ์•„์ฃผ๋ฉฐ, ๊ธˆ๊ธฐ ์„ฑ๋ถ„์ด ํฌํ•จ๋œ ์ œํ’ˆ์€ ์‹ค์‹œ๊ฐ„์œผ๋กœ ํ•„ํ„ฐ๋งํ•˜์—ฌ ์ œ์™ธํ•œ๋‹ค.
  • ์‹ค์ œ ์ œํ’ˆ์„ ์‚ฌ์šฉ์ž์—๊ฒŒ ์—ฐ๊ฒฐํ•˜์—ฌ ์ •๋ณด ์†Œ๋น„์— ๊ทธ์น˜์ง€ ์•Š๊ณ  ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ์‚ฌ์šฉ์ž ํ–‰๋™์œผ๋กœ ์ด์–ด์ง€๋Š” ๊ฒƒ์„ ๊ธฐ๋Œ€ํ•˜์˜€๋‹ค.

ํ”„๋กœ์ ํŠธ์˜ ๋ฐฉํ–ฅ ์„ค์ • ํ›„, ์•„๋ž˜์™€ ๊ฐ™์ด ์—ญํ• ์„ ๋ถ„๋ฐฐํ•˜์˜€๋‹ค.

ํŒ€์žฅ AํŒ€์› B (๋ณธ์ธ)ํŒ€์› CํŒ€์› D
โธฐ PM
โธฐ ์•„์ด๋””์–ด ๊ธฐํš
โธฐ ๊ธฐ์ˆ  ์กฐ์‚ฌ
โธฐ ํ”„๋กฌํ”„ํŠธ ์—”์ง€๋‹ˆ์–ด๋ง
โธฐ 1์ฐจ RAG ์„ค๊ณ„
โธฐ ์‘๋‹ต ์ •๋ฐ€๋„ ๊ฐœ์„ 
โธฐ ํ•™์ˆ  ๋…ผ๋ฌธ ์กฐ์‚ฌ
โธฐ ๋ฌธ์„œ ์ •์ œ
โธฐ ์‹œ๋‚˜๋ฆฌ์˜ค ๊ธฐ๋ฐ˜ ํ…Œ์ŠคํŠธ
โธฐ ๊ณต๊ณต๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌ์ถ•
โธฐ 2์ฐจ RAG ์„ค๊ณ„
โธฐ ๋ฒกํ„ฐ DB ๊ตฌ์ถ•




3. ์–ด๋–ค ๊ธฐ์ˆ ์„ ์™œ ์„ ํƒํ–ˆ๋Š”๊ฐ€?

3.1 ย LLM ํ™˜๊ฐ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•œ RAG ๊ตฌ์กฐ ๋„์ž…

GPT-4๋Š” ๊ฐ•๋ ฅํ•œ ๋ฌธ์žฅ ์ƒ์„ฑ ๋Šฅ๋ ฅ์„ ๊ฐ–์ถ”์—ˆ์ง€๋งŒ, ์ •ํ•ด์ง„ ์ง€์‹ ๋ฒ”์œ„ ๋‚ด์—์„œ๋งŒ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค. ํŠนํžˆ ๊ฑด๊ฐ• ๋„๋ฉ”์ธ์—์„œ๋Š” ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์„ฑ๋ถ„์ด๋‚˜ ์ œํ’ˆ๋ช…์„ ์ œ์‹œํ•˜๋Š” 'ํ™˜๊ฐ(Hallucination)' ๋ฌธ์ œ๊ฐ€ ์น˜๋ช…์ ์ด๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด, ๋ณธ ํ”„๋กœ์ ํŠธ์—์„œ RAG (Retrieval-Augmented Generation) ๊ตฌ์กฐ๋ฅผ ์ฑ„ํƒํ•˜๋Š” ๊ฒƒ์ด ์ ์ ˆํ•˜๋‹ค๊ณ  ํŒ๋‹จํ•˜์˜€๋‹ค.

RAG๋Š” ์™ธ๋ถ€ ๋ฌธ์„œ์—์„œ ์ •๋ณด๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ณ  ์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ LLM์ด ์‘๋‹ต์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ,"๋ฌธ์„œ ๊ธฐ๋ฐ˜ ์ง€์‹์˜ ํ†ต์ œ" ์™€ "LLM ์‘๋‹ต์˜ ์ •ํ™•์„ฑ" ์„ ๋™์‹œ์— ํ™•๋ณดํ•  ์ˆ˜ ์žˆ๋Š” ๊ตฌ์กฐ์ด๋‹ค.

  • Hallucination์„ ์›์ฒœ์ ์œผ๋กœ ์ฐจ๋‹จ ๊ฐ€๋Šฅ (๋ฌธ์„œ ์™ธ ์ •๋ณด ์‚ฌ์šฉ ์ œํ•œ)
  • ์‘๋‹ต ์‹ ๋ขฐ๋„ ํ–ฅ์ƒ ๋ฐ ์ถœ์ฒ˜ ๋ช…์‹œ ๊ฐ€๋Šฅ
  • LangChain ๊ธฐ๋ฐ˜์œผ๋กœ RAG ์ฒด์ธ์„ ๊ตฌ์„ฑํ•˜๊ธฐ ์šฉ์ดํ•จ

3.2 ย ๋ฌธ์„œ ์ž„๋ฒ ๋”ฉ ๋ฐ ๊ฒ€์ƒ‰์„ ์œ„ํ•œ FAISS ์‚ฌ์šฉ

๋ฌธ์„œ ๊ฒ€์ƒ‰ ๊ณผ์ •์—์„œ ํ•ต์‹ฌ์ด ๋˜๋Š” ๊ฒƒ์€ ์‚ฌ์šฉ์ž์˜ ์งˆ๋ฌธ๊ณผ ๊ฐ€์žฅ ์œ ์‚ฌํ•œ ๋ฌธ๋‹จ์„ ๋น ๋ฅด๊ฒŒ ์ฐพ์•„๋‚ด๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋ฅผ ์œ„ํ•ด

OpenAI Embedding + FAISS ์ธ๋ฑ์‹ฑ ๊ตฌ์กฐ๋ฅผ ์„ ํƒํ•˜์˜€๋‹ค.

FAISS(Facebook AI Similarity Search)๋Š” ๊ณ ์ฐจ์› ๋ฒกํ„ฐ ๊ฐ„ ์œ ์‚ฌ๋„ ๊ณ„์‚ฐ์— ํŠนํ™”๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ, ์ˆ˜์ฒœ~์ˆ˜๋งŒ ๊ฐœ์˜ ๋ฒกํ„ฐ์—์„œ ์œ ์‚ฌํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋น ๋ฅด๊ฒŒ ์ฐพ์•„๋‚ด๋Š” ๋ฐ ์ ํ•ฉํ•˜๋‹ค.

Document ๊ฐ์ฒด์— ๋ฉ”ํƒ€ ์ •๋ณด๋ฅผ ํ•จ๊ป˜ ์ €์žฅํ•˜๋ฏ€๋กœ ๊ฒ€์ƒ‰ ํ›„ ์›๋ฌธ ์ถœ์ฒ˜, ๋ฌธ์„œ๋ช…, ์ถœํŒ์—ฐ๋„ ๋“ฑ๋„ ํ•จ๊ป˜ ์ถ”์ถœ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์ ์—์„œ ํ”„๋กœ์ ํŠธ์˜ ๋ฐฉํ–ฅ์„ฑ์— ๋ถ€ํ•ฉํ•œ๋‹ค.

from langchain.vectorstores import FAISS
from langchain.embeddings import OpenAIEmbeddings

embedding = OpenAIEmbeddings()
vectorstore = FAISS.from_documents(documents, embedding)
vectorstore.save_local("faiss_db/")
  • 1๋งŒ ๊ฑด ์ด์ƒ์˜ ๋ฌธ์„œ๋ฅผ ๋ฒกํ„ฐํ™”ํ•˜์—ฌ๋„ ๊ฒ€์ƒ‰ ์†๋„๊ฐ€ ๋น ๋ฆ„
  • Local ํ™˜๊ฒฝ์—์„œ ์ €์žฅ, ๋กœ๋“œ, ์ถ”๊ฐ€ ์‚ฝ์ž…(add_documents) ๊ฐ€๋Šฅ
  • LangChain๊ณผ ํ†ตํ•ฉ ๊ฐ€๋Šฅ (FAISS.from_documents(), load_local() ๋“ฑ)

3.3 ย ์‹ค์ œ ์ œํ’ˆ ์ถ”์ฒœ์„ ์œ„ํ•œ ๊ณต๊ณต๋ฐ์ดํ„ฐ API ํ™œ์šฉ

๋ฌธ์„œ ๊ธฐ๋ฐ˜ ์„ฑ๋ถ„ ์ถ”์ฒœ๋งŒ์œผ๋กœ๋Š” ์‹ค์ œ ์‚ฌ์šฉ์ž ์•ก์…˜์œผ๋กœ ์ด์–ด์ง€๊ธฐ ์–ด๋ ต๋‹ค.

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์‹ํ’ˆ์˜์•ฝํ’ˆ์•ˆ์ „์ฒ˜ ๊ฑด๊ฐ•๊ธฐ๋Šฅ์‹ํ’ˆ์ •๋ณด Open API ๋ฅผ ์‚ฌ์šฉํ•˜์˜€๋‹ค.

์ด API๋Š” ์•ฝ 10,000๊ฑด์˜ ์˜์–‘์ œ ์ œํ’ˆ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ ๊ธฐ๋Šฅ์„ฑ, ์„ฑ๋ถ„, ์ฃผ์˜์‚ฌํ•ญ, ์„ญ์ทจ๋ฐฉ๋ฒ• ๋“ฑ์˜ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ๋‹ค.

  • ๊ณต๊ณต๊ธฐ๊ด€์ด ์ œ๊ณตํ•˜๋Š” ์‹ ๋ขฐ ๊ฐ€๋Šฅํ•œ ์ œํ’ˆ ์ •๋ณด
  • ์ผ์ผ 10,000๊ฑด ํ˜ธ์ถœ ๊ฐ€๋Šฅ
  • ์ œํ’ˆ๋ช…, ๊ธฐ๋Šฅ์„ฑ, ์ฃผ์˜์‚ฌํ•ญ, ์„ญ์ทจ๋Ÿ‰ ๋“ฑ์˜ ํ•„๋“œ๊ฐ€ ์กด์žฌํ•˜์—ฌ ์ถ”์ฒœ ํ›„ ์—ฐ๊ณ„ ๊ฐ€๋Šฅ




4. ๋ฌธํ—Œ ์ˆ˜์ง‘ ๋ฐ ์ „์ฒ˜๋ฆฌ ๋ฐฉ์‹

์‚ฌ์šฉ๋œ ๋ฌธํ—Œ์€ ์ด 46ํŽธ์˜ ํ•™์ˆ  ๋…ผ๋ฌธ, ๊ฑด๊ฐ•๊ธฐ๋Šฅ์‹ํ’ˆ ๊ฐ€์ด๋“œ๋ผ์ธ, ์‹์•ฝ์ฒ˜ ์ž๋ฃŒ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค. ์ด ๋ฌธํ—Œ๋“ค์€ PDF ํ˜•์‹์œผ๋กœ ์ˆ˜์ง‘๋˜์—ˆ๊ณ , ๋ฌธ๋‹จ ๋‹จ์œ„๋กœ ๋ถ„ํ• ํ•˜๊ณ  ๋ฒกํ„ฐํ™”ํ•˜๊ธฐ ์œ„ํ•œ ์‚ฌ์ „ ์ •์ œ ์ž‘์—…์ด ํ•„์š”ํ•˜์˜€๋‹ค.

์•„๋ž˜์˜ ๊ณผ์ •์œผ๋กœ ์ „์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜์˜€๋‹ค.

  1. ํ…์ŠคํŠธ ์ถ”์ถœ: ย PyMuPDF ๊ธฐ๋ฐ˜์œผ๋กœ PDF์—์„œ ๋ณธ๋ฌธ ํ…์ŠคํŠธ ์ถ”์ถœ
  2. ์˜๋ฏธ ๋‹จ์œ„ ๋ถ„๋ฆฌ: ย ๋ถˆํ•„์š”ํ•œ ๊ณต๋ฐฑ/๋จธ๋ฆฌ๋ง ์ œ๊ฑฐ ํ›„, ๋ฌธ๋‹จ ๋˜๋Š” ํ•ญ๋ชฉ ๊ธฐ๋ฐ˜์œผ๋กœ ์˜๋ฏธ ๋‹จ์œ„ ๋ถ„๋ฆฌ
  3. LangChain ๋ฌธ์„œํ™”: ย Document ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ (๋ฉ”ํƒ€ ์ •๋ณด ํฌํ•จ: ์ถœ์ฒ˜, ์ œ๋ชฉ, ๋ฌธ์„œ ์œ ํ˜• ๋“ฑ)

๋ฌธ์„œ ๋ถ„ํ• ์€ ๋‹จ์ˆœ ๊ธธ์ด ๊ธฐ์ค€์ด ์•„๋‹Œ ๋ฌธ๋งฅ ๋ณด์กด์„ ์œ„ํ•œ chunk overlap ๊ธฐ๋ฒ•์„ ์ ์šฉํ•˜์˜€์œผ๋ฉฐ ์ดํ›„ Embedding ๊ณผ์ •์œผ๋กœ ์—ฐ๊ฒฐ๋œ๋‹ค.

from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter

loader = PyPDFLoader("๊ฐ„๊ฑด๊ฐ•_๊ฐ€์ด๋“œ๋ผ์ธ.pdf")
pages = loader.load()
splitter = RecursiveCharacterTextSplitter(chunk_size=700, chunk_overlap=100)
documents = splitter.split_documents(pages)




5. ๊ธฐ์ˆ ์  ์„ค๊ณ„ ํฌ์ธํŠธ

RAG(Retrieval-Augmented Generation)๋ฅผ ๋‘ ๋ฒˆ ํ™œ์šฉํ•ด ์‹ ๋ขฐ์„ฑ๊ณผ ์ •๋ฐ€๋„๋ฅผ ๋™์‹œ์— ํ™•๋ณดํ•ฉ๋‹ˆ๋‹ค.

  1. ์ฒซ ๋ฒˆ์งธ RAG๋Š” ์‚ฌ์šฉ์ž์˜ ๊ฑด๊ฐ• ์ƒํƒœ์™€ ์„ ํ˜ธ์— ๋”ฐ๋ผ ๋…ผ๋ฌธ ๊ธฐ๋ฐ˜ ์„ฑ๋ถ„ ์ •๋ณด๋ฅผ ์ถ”์ถœํ•˜๊ณ ,
  2. ๋‘ ๋ฒˆ์งธ RAG๋Š” ํ•ด๋‹น ์„ฑ๋ถ„์„ ๊ธฐ์ค€์œผ๋กœ ๊ณต๊ณต๋ฐ์ดํ„ฐ์—์„œ ์‹ค์ œ ์ œํ’ˆ์„ ์ถ”์ฒœํ•œ๋‹ค.

์ด๋ ‡๊ฒŒ 2๋‹จ๊ณ„๋กœ ๋ถ„๋ฆฌ๋œ ๊ตฌ์กฐ๋Š” "์™œ ์ด ์„ฑ๋ถ„์„ ์ถ”์ฒœํ•˜๋Š”๊ฐ€" ์™€ "๊ทธ ์„ฑ๋ถ„์ด ํฌํ•จ๋œ ์ œํ’ˆ์€ ๋ฌด์—‡์ธ๊ฐ€" ๋ฅผ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

5.0 ย RAG ๊ตฌ์กฐ

5.1 ย ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ๋ฌธ์„œ ๋ฒกํ„ฐ DB ๋ถ„๋ฆฌ ๋ฐ ์•™์ƒ๋ธ” ๋ฆฌํŠธ๋ฆฌ๋ฒ„ ๊ตฌ์„ฑ

์‚ฌ์šฉ์ž ์ž…๋ ฅ์€ ๋‹จ์ผ ์ฆ์ƒ์ด ์•„๋‹Œ ์—ฌ๋Ÿฌ ๊ฑด๊ฐ• ์˜์—ญ์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋‹ค.
ย ย ย ย ย ex. ๋ˆˆ ๊ฑด๊ฐ• + ํ”ผ๋กœ + ์ปคํ”ผ ๊ณผ๋‹ค ์„ญ์ทจ

์ด๋ฅผ ๊ณ ๋ คํ•˜์—ฌ ๋ฌธ์„œ ๋ฒกํ„ฐ DB๋ฅผ ์งˆํ™˜/์ด์Šˆ๋ณ„ ์‹œ๋‚˜๋ฆฌ์˜ค ์ผ€์ด์Šค๋ฅผ ๋ถ„๋ฆฌ ์ €์žฅํ•˜์˜€์œผ๋ฉฐ, LangChain์˜ EnsembleRetriever๋ฅผ ํ†ตํ•ด ๋‹ค์ค‘ ๊ฒ€์ƒ‰์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ๊ตฌ์„ฑํ•˜์˜€๋‹ค.

retriever1 = FAISS.load_local("faiss_db/case_A", embedding)
retriever2 = FAISS.load_local("faiss_db/case_b", embedding)

ensemble_retriever = EnsembleRetriever(
    retrievers=[retriever1, retriever2],
    weights=[0.5, 0.5]
)

5.2 ย ์‚ฌ์šฉ์ž ์ž…๋ ฅ ์ฒ˜๋ฆฌ ๋ฐ Case ๋ถ„๋ฅ˜ ๋กœ์ง

์‚ฌ์šฉ์ž ์ž…๋ ฅ ํ‚ค์›Œ๋“œ ์ถ”์ถœ ํ›„, ์‹œ๋‚˜๋ฆฌ์˜ค๋ณ„ Case๋ฅผ ๋ถ„๋ฅ˜ํ•˜์—ฌ ํ™”์ดํŠธ๋ฆฌ์ŠคํŠธ ๊ธฐ๋ฐ˜ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์„ค๊ณ„ํ•˜์˜€๋‹ค.

  • RAG ์‘๋‹ต ์ƒ์„ฑ ์‹œ, LLM์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์„ฑ๋ถ„ ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์ „์— ๋ช…์‹œํ•˜์—ฌ ์ „๋‹ฌ
  • ํ”„๋กฌํ”„ํŠธ ๋‚ด์— "JSON only", "๋งˆํฌ๋‹ค์šด ๊ธˆ์ง€", "ํ—ˆ์šฉ๋œ ์„ฑ๋ถ„ ์™ธ ์‚ฌ์šฉ ๊ธˆ์ง€" ๋ช…์‹œ
  • ๊ฒฐ๊ณผ์ ์œผ๋กœ ํ™˜๊ฐ ๋ฐฉ์ง€ + ์‘๋‹ต ์ผ๊ด€์„ฑ + ํŒŒ์‹ฑ ์•ˆ์ •์„ฑ ํ™•๋ณด

>> ย 6. ์‚ฌ์šฉ์ž ์ž…๋ ฅ ์ฒ˜๋ฆฌ ๋ฐ Case ๋ถ„๋ฅ˜ ๋กœ์ง ์ฐธ๊ณ 


5.3 ย ๊ณต๊ณต๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜ ์ œํ’ˆ ์ถ”์ฒœ ํŒŒ์ดํ”„๋ผ์ธ

>> ย 7. ๊ณต๊ณต๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜ ์ œํ’ˆ ์ถ”์ฒœ ํŒŒ์ดํ”„๋ผ์ธ ์ฐธ๊ณ 





6. ์‚ฌ์šฉ์ž ์ž…๋ ฅ ์ฒ˜๋ฆฌ ๋ฐ Case ๋ถ„๋ฅ˜ ๋กœ์ง

์˜๋ฃŒยท์˜์–‘ ๋„๋ฉ”์ธ์€ "์ฐฝ์˜์„ฑ" ๋ณด๋‹ค ์•ˆ์ „์„ฑยท๊ทผ๊ฑฐ ๊ธฐ๋ฐ˜์ด ์ตœ์šฐ์„ ์ด๋‹ค.

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

๋ณธ ํ”„๋กœ์ ํŠธ๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ๋‹ค์Œ ํ•ญ๋ชฉ์˜ ์ž…๋ ฅ์„ ์š”๊ตฌํ•œ๋‹ค.

  • ๋‚˜์ด, ์„ฑ๋ณ„
  • ํ˜„์žฌ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์งˆํ™˜ ํ˜น์€ ์ฆ์ƒ
  • ๋ณต์šฉ ์ค‘์ธ ์•ฝํ’ˆ ๋ฐ ์˜์–‘์ œ
  • ์›ํ•˜๋Š” ์˜์–‘์ œ์˜ ํŠน์ง• ๋˜๋Š” ์กฐ๊ฑด (ex. ๋ˆˆ ๊ฑด๊ฐ•, ๊ทผ์œก ํšŒ๋ณต, ๋‡Œ ๊ฑด๊ฐ• ๊ฐœ์„  ๋“ฑ)

์ด ์ž…๋ ฅ์€ ๋‹จ์ˆœํžˆ ๋ฌธ์ž์—ด๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์œผ๋‚˜, ์ดํ›„ ์ „์ฒด ํŒŒ์ดํ”„๋ผ์ธ์—์„œ ํ•ต์‹ฌ์ ์ธ ์—ญํ• ์„ ํ•˜๊ฒŒ ๋˜๋ฉฐ

ํŠนํžˆ "์‚ฌ์šฉ์ž ์ƒํƒœ ๋ถ„๋ฅ˜ โ†’ case๋ณ„ ์ฒ˜๋ฐฉ ๋ถ„๊ธฐ" ์˜ ๊ธฐ์ค€์ด ๋œ๋‹ค.

6.1 ย Case A~D ๋ถ„๋ฅ˜ ์ฒด๊ณ„

์ดˆ๊ธฐ ์„ค๊ณ„ ๋‹จ๊ณ„์—์„œ ๊ตฌ์ฒด์ ์ธ ํŽ˜๋ฅด์†Œ๋‚˜๋ฅผ ์ง€์ •ํ•˜์—ฌ ์‚ฌ์šฉ์ž ์š”๊ตฌ๋ฅผ ๋ช‡ ๊ฐ€์ง€ ์œ ํ˜•์œผ๋กœ ๋ถ„๋ฅ˜ํ•˜์˜€๋‹ค.

์ด๋Š” ์งˆ๋ฌธ์˜ ํ˜•ํƒœ๋ฅผ ์ œํ•œํ•˜๊ธฐ ์œ„ํ•จ์ด ์•„๋‹ˆ๋ผ, LLM์˜ ํ”„๋กฌํ”„ํŠธ ์•ˆ์ •์„ฑ๊ณผ ์‘๋‹ต ํ’ˆ์งˆ์„ ํ™•๋ณดํ•˜๊ธฐ ์œ„ํ•œ ๊ตฌ์กฐ์  ์žฅ์น˜์ด๋‹ค. ์•ž์„œ ์–ธ๊ธ‰ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋„๋ฉ”์ธ ํŠน์„ฑ ์ƒ "๋ชจ๋“  ์ƒํ™ฉ์— ๋งž๋Š” ๋‹ต๋ณ€" ๋ณด๋‹ค๋Š” ํ•œ์ •๋œ ๋Œ€์ƒ์ด๋ผ๋„ ๊ฒ€์ฆ๋œ ์„ฑ๋ถ„ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

  1. Case_A, Case_B ์—์„œ๋Š” ๋™์ผํ•œ "์Œ์ฃผ/ํก์—ฐ" ์ด๋ผ๋Š” ๋ณ€์ˆ˜๋ฅผ ์ฃผ์–ด ๋น„๊ต ์‹คํ—˜์„ ์„ค๊ณ„ํ•˜์˜€๋‹ค.
  2. Case_C, Case_D ์—์„œ๋Š” ํŠน์ • ์งˆํ™˜์— ์ค‘์ ์„ ๋‘๊ณ  ์ •ํ™•ํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋„์ถœํ•ด ๋‚ด๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•˜์˜€๋‹ค.
  • Case_A: ย ๋ˆˆ ๊ฑด๊ฐ• + ๊ฐ„ ๊ฑด๊ฐ• ๊ด€๋ จ
  • Case_B: ย ์ปคํ”ผ/์นดํŽ˜์ธ ๊ณผ๋‹ค ์„ญ์ทจ
  • Case_C: ย ์‹ฌํ˜ˆ๊ด€ ๋ฐ ํ˜ˆ์•• ๊ด€๋ฆฌ
  • Case_D: ย ๋ณต์šฉ ์ค‘์ธ ์•ฝํ’ˆ๊ณผ ์ถฉ๋Œ ๊ฐ€๋Šฅ์„ฑ (์˜ˆ: ์ฒ ๋ถ„ + ํ•ญ์ƒ์ œ)

6.2 ย ์‚ฌ์šฉ์ž ์ž…๋ ฅ ๋ถ„์„ ํ•จ์ˆ˜

์‚ฌ์šฉ์ž์˜ ์ž์œ  ์ž…๋ ฅ์„ ์‚ฌ์ „ ์ •์˜๋œ Case์— ๋งคํ•‘ํ•˜๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜๋ฅผ ๊ตฌ์„ฑํ•˜์˜€๋‹ค.

def categorize_user_query(user_input: str) -> list:
    case_list = []
    if "๊ฐ„" in user_input or "์Œ์ฃผ" in user_input or "ํšŒ์‹" in user_input:
        case_list.append("A")
    if "์ปคํ”ผ" in user_input or "์นดํŽ˜์ธ" in user_input:
        case_list.append("B")
    if "๋ˆˆ" in user_input or "๋ฃจํ…Œ์ธ" in user_input:
        case_list.append("C")
    if "์•ฝ" in user_input or "๋ณต์šฉ" in user_input:
        case_list.append("D")
    return case_list

ํ•ด๋‹น ํ•จ์ˆ˜๋Š” ์ž์œ  ์ž…๋ ฅ์„ ๋ถ„์„ํ•˜์—ฌ ์ค‘์ฒฉ๋œ case๋ฅผ ๋‹ค์ค‘ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

์ฆ‰, ํ•œ ์‚ฌ์šฉ์ž๊ฐ€ ๋™์‹œ์— ๊ฐ„ ๊ฑด๊ฐ• + ๋ˆˆ ๊ฑด๊ฐ• + ์•ฝ๋ฌผ ๋ณต์šฉ ์ •๋ณด๋ฅผ ์ž…๋ ฅํ•œ ๊ฒฝ์šฐ, ์„ธ ๊ฐ€์ง€ ์ฒ˜๋ฐฉ ๋…ผ๋ฆฌ๋ฅผ ๋ชจ๋‘ ํ”„๋กฌํ”„ํŠธ์— ๋ฐ˜์˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„ํ•˜์˜€๋‹ค.


6.3 ย ํ”„๋กฌํ”„ํŠธ ํ…œํ”Œ๋ฆฟ๊ณผ ์—ฐ๊ฒฐ

๊ฐ case์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ์˜ JSON ์‘๋‹ต ํ…œํ”Œ๋ฆฟ์ด ์‚ฌ์ „์— ์ •์˜๋˜์–ด ์žˆ๋‹ค.

{
  "recommended": [...],
  "avoid": [...],
  "caution": [...],
  "reference": [...]
}

์ด ํ…œํ”Œ๋ฆฟ์€ ๊ฐ case๋ณ„๋กœ ๋‹ค๋ฅด๊ฒŒ ์ •์˜๋˜๊ณ , ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์ด ์—ฌ๋Ÿฌ case์— ํ•ด๋‹น๋  ๊ฒฝ์šฐ ํ•ด๋‹น ํ…œํ”Œ๋ฆฟ์„ ๋ณ‘ํ•ฉํ•˜์—ฌ LLM ํ”„๋กฌํ”„ํŠธ๋กœ ์ „๋‹ฌํ•œ๋‹ค.

ํ”„๋กœ์ ํŠธ ์ง„ํ–‰ ๊ณผ์ •์—์„œ

ํ”„๋กฌํ”„ํŠธ๋Š” "ํ—ˆ์šฉ๋œ ์„ฑ๋ถ„๋งŒ ์‚ฌ์šฉํ•˜๋ผ" ๋Š” whitelist ๊ตฌ์กฐ๋ฅผ ๊ฐ–์ถ”๋„๋ก ์„ค๊ณ„ ๋ฐฉํ–ฅ์„ ์žก๊ฒŒ ๋˜์—ˆ๋‹ค. ์ด ๊ตฌ์กฐ ๋•๋ถ„์— ๊ตฌ์กฐํ™”๋œ ์‘๋‹ต, ์ผ๊ด€๋œ ํ•„๋“œ, ์•ˆ์ •์ ์ธ ํŒŒ์‹ฑ์ด ๊ฐ€๋Šฅํ•ด์กŒ๋‹ค.





7. ๊ณต๊ณต๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜ ์ œํ’ˆ ์ถ”์ฒœ ํŒŒ์ดํ”„๋ผ์ธ

7.1 ย ๋ฐ์ดํ„ฐ ์ถœ์ฒ˜ ๋ฐ ํ˜•์‹

์‚ฌ์šฉ๋œ ๋ฐ์ดํ„ฐ๋Š” ์‹์•ฝ์ฒ˜ ๊ฑด๊ฐ•๊ธฐ๋Šฅ์‹ํ’ˆ์ •๋ณด ๊ณต๊ณต API๋กœ, ์ด 10,000๊ฑด์˜ ์˜์–‘์ œ ์ œํ’ˆ ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•˜์˜€๋‹ค.

๋ณธ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ๋‹ค์Œ 5๊ฐ€์ง€ ํ•„๋“œ๋งŒ ์œ ์ง€ํ•˜์—ฌ ๋ฒกํ„ฐํ™” ๋Œ€์ƒ ๋ฌธ์„œ๋ฅผ ๊ตฌ์„ฑํ•˜์˜€๋‹ค.

  • ์ œํ’ˆ๋ช…
  • ๊ธฐ๋Šฅ์„ฑ
  • ์„ญ์ทจ ๋ฐฉ๋ฒ•
  • ์ฃผ์˜์‚ฌํ•ญ
  • ์ฃผ์„ฑ๋ถ„

[์ฐธ๊ณ ] ์‹ํ’ˆ์˜์•ฝํ’ˆ์•ˆ์ „์ฒ˜_๊ฑด๊ฐ•๊ธฐ๋Šฅ์‹ํ’ˆ์ •๋ณด Open API


7.2 ย ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘ ๋ฐ ์ €์žฅ ์ „๋žต

์‚ฌ์šฉํ•œ ์‹์•ฝ์ฒ˜ API์— ์•„๋ž˜๊ณผ ๊ฐ™์€ ์ œ์•ฝ์ด ์กด์žฌํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•˜์˜€๋‹ค.

  • numOfRows ์ตœ๋Œ€๊ฐ’: 100
  • ํ˜ธ์ถœ ๋‹จ์œ„: ํŽ˜์ด์ง€๋‹น 100๊ฐœ
  • ์ผ์ผ ์ตœ๋Œ€ ํ˜ธ์ถœ ๊ฑด์ˆ˜: 10,000ํšŒ

์ด๋ฅผ ๊ณ ๋ คํ•˜์—ฌ ๋‹ค์Œ ์ „๋žต์œผ๋กœ ์ˆ˜์ง‘์„ ์ง„ํ–‰ํ•˜์˜€๋‹ค.

๋‹จ๊ณ„์ฒ˜๋ฆฌ ๋ฐฉ์‹๋ชฉ์ 
โ‘  1,000๊ฑด ํ”„๋กœํ† ํƒ€์ž…500 + 500๊ฑด์„ ํ˜ธ์ถœํ•˜์—ฌ ํ…Œ์ŠคํŠธ์‘๋‹ต ํ˜•์‹ ๋ถ„์„, ํŒŒ์‹ฑ ํ…Œ์ŠคํŠธ
โ‘ก ์ž„๋ฒ ๋”ฉ ํ† ํฐ ์ดˆ๊ณผ ๋Œ€์‘500๊ฑด์”ฉ ์ˆ˜์ง‘ โ†’ ๋‹ค์‹œ 100๊ฐœ์”ฉ ๋‚˜๋ˆ„์–ด ์ž„๋ฒ ๋”ฉOpenAI ์ž„๋ฒ ๋”ฉ ํ† ํฐ ์ œํ•œ ํšŒํ”ผ
โ‘ข ์ „์ฒด ์ˆ˜์ง‘100ํŽ˜์ด์ง€ ร— 100๊ฐœ = 10,000๊ฑด ์ˆ˜์ง‘ ์™„๋ฃŒ์ „์ฒด ๋ฐ์ดํ„ฐ ํ™•๋ณด
โ‘ฃ ๋ฌธ์„œํ™”ํ•„์š”ํ•œ ํ•„๋“œ๋งŒ LangChain Document๋กœ ์ €์žฅ์ž„๋ฒ ๋”ฉ ๋ถ€ํ•˜ ์ตœ์†Œํ™”, ๊ฒ€์ƒ‰ ์ •ํ™•๋„ ํ–ฅ์ƒ

7.3 ย ์ œํ’ˆ ์ถ”์ฒœ ๋กœ์ง

์ œํ’ˆ ์ถ”์ฒœ์€ recommended ์„ฑ๋ถ„ ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ธฐ์ค€์œผ๋กœ FAISS ๊ฒ€์ƒ‰์„ ์ˆ˜ํ–‰ํ•˜๊ณ ,

๋™์‹œ์— avoid ์„ฑ๋ถ„ ๋ฆฌ์ŠคํŠธ์— ํ•ด๋‹นํ•˜๋Š” ์ œํ’ˆ์€ ํ•„ํ„ฐ๋งํ•˜์—ฌ ์ œ์™ธํ•œ๋‹ค.

def filter_avoid_products(results, avoid_list):
    return [
        r for r in results
        if not any(avoid in r.page_content for avoid in avoid_list)
    ]

์ตœ์ข…์ ์œผ๋กœ 5๊ฐœ ์ œํ’ˆ๋งŒ ์ถ”๋ ค์„œ ์‚ฌ์šฉ์ž์—๊ฒŒ ์นด๋“œ ํ˜•ํƒœ๋กœ ์ œ์‹œํ•˜๊ณ , ์ œํ’ˆ ์ •๋ณด๋Š” UI ์ƒ์—์„œ ํ™•์žฅ ๊ฐ€๋Šฅ(expandable)ํ•˜๊ฒŒ ๊ตฌ์„ฑํ•˜์˜€๋‹ค.





8. Streamlit ๊ธฐ๋ฐ˜ UI ๊ตฌ์„ฑ ๋ฐ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜ ์„ค๊ณ„

8.1 ย ์ „์ฒด UI ํ๋ฆ„

UI๋Š” Streamlit ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌ์„ฑํ•˜์˜€์œผ๋ฉฐ, ์‚ฌ์šฉ์ž๋Š” ํ•œ ํ™”๋ฉด ๋‚ด์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ๋ฆ„์„ ๊ฒฝํ—˜ํ•˜๊ฒŒ ๋œ๋‹ค.

  1. ์ •๋ณด ์ž…๋ ฅ (ํผ ๊ธฐ๋ฐ˜)
  2. RAG ๊ธฐ๋ฐ˜ ์ฑ— ์‘๋‹ต (์„ฑ๋ถ„ ์ถ”์ฒœ ๋ฐ ์ฃผ์˜์‚ฌํ•ญ ํฌํ•จ)
  3. ํ•ด๋‹น ์„ฑ๋ถ„ ๊ธฐ๋ฐ˜์˜ ์ œํ’ˆ ์นด๋“œ ์ถ”์ฒœ
  4. ๋ชจ๋“  ์‘๋‹ต์˜ ์ถœ์ฒ˜ ๋ช…์‹œ ๋ฐ JSON ๊ธฐ๋ฐ˜ ์‹œ๊ฐํ™”

์ด๋Ÿฌํ•œ ๊ตฌ์„ฑ์€ ์‚ฌ์šฉ์ž๊ฐ€ ์‘๋‹ต ์‹ ๋ขฐ๋„๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์‹ค์‹œ๊ฐ„ ์ œํ’ˆ ๋น„๊ต ํ–‰๋™์œผ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ๋„๋ก UX ํ๋ฆ„์„ ์„ค๊ณ„ํ•˜์˜€๋‹ค.

8.2 ย ํŒŒ์‹ฑ ์˜ค๋ฅ˜ ๋ฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ

LLM์˜ ์‘๋‹ต์€ JSON์œผ๋กœ ์ œํ•œ๋˜์–ด ์žˆ์ง€๋งŒ,

์‘๋‹ต์ด ๋ˆ„๋ฝ๋˜๊ฑฐ๋‚˜ ํฌ๋งท ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์„ ๋Œ€๋น„ํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์•ˆ์ „ ์žฅ์น˜๋ฅผ ๋งˆ๋ จํ•˜์˜€๋‹ค.

  • json.loads() ์‹คํŒจ ์‹œ ์ฆ‰์‹œ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ
  • Streamlit ์ƒ์—์„œ ์‘๋‹ต ์ค‘๋‹จ ์—†์ด ์ด์ „ ๊ฒฐ๊ณผ ์œ ์ง€
  • ์ž˜๋ชป๋œ ์‘๋‹ต์ด ๋ฐ˜๋ณต๋˜๋Š” ๊ฒฝ์šฐ ๋กœ๊ทธ ์ €์žฅ ํ›„ LLM ํ˜ธ์ถœ ์žฌ์‹œ๋„




9. ์‹คํ–‰ ๊ฒฐ๊ณผ

๐Ÿ’ฌ ย ์˜์–‘์ œ Check! ์‹คํ–‰ ๊ฒฐ๊ณผ

์•„๋ž˜๋Š” ์ตœ์ข…์ ์œผ๋กœ ์™„์„ฑ๋œ "์˜์–‘์ œ Check!" ์„œ๋น„์Šค๋ฅผ ์‹คํ–‰ํ•œ ํ™”๋ฉด์ด๋‹ค.

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

์‚ฌ์šฉ์ž๋Š” ์ž์‹ ์˜ ์ƒํƒœ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›๊ฒŒ ๋˜๋ฉฐ, ๊ทธ ์ฐจ์ด๋ฅผ ๋ช…ํ™•ํžˆ ์ฒด๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค.

  • Case_A, Case_B

  • Case_C, Case_D

์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ํ•ด์„ํ•  ๋•Œ ๊ฐ€์žฅ ์ค‘์š”ํ–ˆ๋˜ ๊ฑด, ์ œ์‹œ๋œ ์„ฑ๋ถ„์ด ์‹ค์ œ๋กœ ํ•ด๋‹น ์‚ฌ์šฉ์ž์—๊ฒŒ ์ ์ ˆํ•œ๊ฐ€๋ฅผ ๋„๋ฉ”์ธ ๊ธฐ์ค€์—์„œ ๊ฒ€์ฆํ•˜๋Š” ๊ฒƒ์ด์—ˆ๋‹ค.

๊ณต๋ถ€ํ•˜๊ณ  ์ดํ•ดํ•œ ๋„๋ฉ”์ธ ์ง€์‹์„ ๋ฐ”ํƒ•์œผ๋กœ ๋‚˜์™€์•ผ ํ•  ์„ฑ๋ถ„์ด ๋น ์ง€๊ฑฐ๋‚˜ ๋‚˜์˜ค๋ฉด ์•ˆ ๋˜๋Š” ์„ฑ๋ถ„์ด ํฌํ•จ๋œ ๊ฒฝ์šฐ๋ฅผ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ , ์ด ๊ณผ์ •์„ ํ†ตํ•ด ํ˜„์žฌ ๋กœ์ง์— ์–ด๋–ค ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š”์ง€ ์งš์–ด๋‚ด๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ–ˆ๋‹ค.

๊ถ๊ทน์ ์œผ๋กœ๋Š” โ€œ๊ทธ๋Ÿด๋“ฏํ•œ ๋‹ต๋ณ€โ€ ์ด ์•„๋‹ˆ๋ผ ์ •ํ™•ํ•˜๊ณ  ์‹ ๋ขฐ ๊ฐ€๋Šฅํ•œ ๊ฒฐ๊ณผ๋งŒ์„ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์— ๊ฐ€๊นŒ์›Œ์งˆ ์ˆ˜ ์žˆ์—ˆ๋‹ค.





10. ๊ฐœ์„  ๋ฐฉํ–ฅ

์‘๋‹ต ์ •๋ฐ€๋„ ๊ฐœ์„  ์ „๋žต ๋ฐ ํ›„์† ๊ฐœ์„  ๋ฐฉํ–ฅ

๋žญ์ฒด์ธํ†ค ๋ฐœํ‘œ ํ›„,
ํผ์‹ค๋‹˜์˜ ํ”ผ๋“œ๋ฐฑ์„ ํ†ตํ•ด ์–ป์€ ์ธ์‚ฌ์ดํŠธ๋กœ ๊ฐœ์„  ๋ฐฉํ–ฅ์„ ์ƒ๊ฐํ•ด ๋ณผ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

10.1 ย ๋ฌธ์ œ์ : ์„ฑ๋ถ„ ๊ฐ„ ์œ ์‚ฌ๋„์™€ ์šฐ์„ ์ˆœ์œ„ ๋ถˆ์ผ์น˜

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

์œ ์‚ฌํ•œ ํšจ๋Šฅ์„ ์ง€๋‹Œ ์„ฑ๋ถ„๋“ค์ด ๋‹ค์ˆ˜ ์กด์žฌํ•  ๋•Œ, ์œ ์‚ฌ๋„ ๊ธฐ๋ฐ˜ ๊ฒ€์ƒ‰์ด ์‹ค์ œ ์ถ”์ฒœ์˜ ์šฐ์„ ์ˆœ์œ„์™€ ๋‹ค๋ฅด๊ฒŒ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ด ๊ฒฝ์šฐ ์ •ํ˜•ํ™”๋œ ๊ตฌ์กฐ์˜ RDB(Relational Database)๋ฅผ ํ™œ์šฉํ•œ ์ •๋ ฌ ๋ฐฉ์‹์ด ๋” ํšจ๊ณผ์ ์ผ ์ˆ˜ ์žˆ๋‹ค. ํ–ฅํ›„์—๋Š” RAG ๊ธฐ๋ฐ˜ ์ถ”์ฒœ๊ณผ RDB ๊ธฐ๋ฐ˜ ์ •๋ ฌ์˜ ์„ฑ๋Šฅ์„ ๋น„๊ตํ•˜์—ฌ ์ถ”์ฒœ ์ •ํ™•๋„ ๋ฐ ์‚ฌ์šฉ์ž ๋งŒ์กฑ๋„๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ๊ตฌ์กฐ ๋„์ž…๋„ ๊ณ ๋ คํ•  ์ˆ˜ ์žˆ๋‹ค.

10.2 ย ์—ฐ๊ตฌ ๊ทผ๊ฑฐ ์ธ์šฉ ๊ธฐ๋Šฅ ๊ฐ•ํ™”

์‚ฌ์šฉ์ž์—๊ฒŒ "์ถ”์ฒœ ์„ฑ๋ถ„" ๋˜๋Š” "ํ”ผํ•ด์•ผ ํ•  ์„ฑ๋ถ„"์„ ์ œ์‹œํ•  ๋•Œ, ํ•ด๋‹น ๋‚ด์šฉ์„ ๋’ท๋ฐ›์นจํ•˜๋Š” ์—ฐ๊ตฌ ๊ฒฐ๊ณผ๋‚˜ ์ž„์ƒ ๊ทผ๊ฑฐ(๋…ผ๋ฌธ, ๊ฐ€์ด๋“œ๋ผ์ธ ๋“ฑ)๋ฅผ ํ•จ๊ป˜ ์ œ์‹œํ•˜๋ฉด ์ •๋ณด์˜ ์‹ ๋ขฐ๋„์™€ ์ „๋ฌธ์„ฑ์ด ํ•œ์ธต ๋†’์•„์งˆ ์ˆ˜ ์žˆ๋‹ค. RAG์˜ ์‘๋‹ต ๊ฒฐ๊ณผ์— ๋…ผ๋ฌธ ์ถœ์ฒ˜ ๋˜๋Š” ํ•ต์‹ฌ ๋ฌธ์žฅ์„ ์ธ์šฉํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜, ๊ทผ๊ฑฐ ๊ธฐ๋ฐ˜ ์š”์•ฝ ๊ธฐ๋Šฅ์„ ๋ณด์™„ํ•˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ๋„ ๊ฐœ์„ ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.





11. ํ”„๋กœ์ ํŠธ ํšŒ๊ณ 

๐Ÿ”— ย ๋‹ค์Œ ๊ธ€

๐Ÿ’Š ์˜์–‘์ œ Check! ํ”„๋กœ์ ํŠธ ํšŒ๊ณ 

profile
AI์— ๊ด€์‹ฌ์„ ๊ฐ€์ง€๊ณ , ๋ฐ์ดํ„ฐ๋กœ ๊ฐ€์น˜๋ฅผ ๋งŒ๋“ค์–ด ๋‚˜๊ฐ€๋Š” ๊ณผ์ •์„ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€