๐Ÿ“• LLM ์ฑ„ํŒ…์— RAG ๋ผ์–น๊ธฐยถ

AI ๋ฉ”์‹œ์ง€ ์ƒ์„ฑ ์‹œ์— ์œ ์‚ฌ ๋ฌธ์„œ๋ฅผ ์ง€์‹์œผ๋กœ ํ™œ์šฉํ•˜๊ธฐยถ

AI ๋ฉ”์‹œ์ง€ ์ƒ์„ฑ ์‹œ์— ํ”„๋กฌํ”„ํŠธ์— ์œ ์‚ฌ ๋ฌธ์„œ๋ฅผ ์ง€์‹์œผ๋กœ ํ™œ์šฉํ•˜๋ฉด RAG๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. Room ๋ชจ๋ธ์˜ create_ai_message ๋ฉ”์„œ๋“œ ๋‚ด์—์„œ โ€œ์„ธ๋ฒ• ํ•ด์„๋ก€โ€ ๋ฌธ์„œ ๊ฒ€์ƒ‰์ด ํ•„์š”ํ•  ๋•Œ, TaxLawDocument ๋ชจ๋ธ์„ ํ†ตํ•ด ์œ ์‚ฌ ๋ฌธ์„œ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ณ , ๊ฒ€์ƒ‰๋œ ๋ฌธ์„œ๋ฅผ ์ง€์‹์œผ๋กœ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค.

chat/models.py ํŒŒ์ผ ๋ฎ์–ด์“ฐ๊ธฐยถ
 1import json
 2
 3from django.db import models
 4from django.utils.functional import cached_property
 5from django_lifecycle import LifecycleModelMixin, hook, AFTER_UPDATE
 6from pyhub.rag.fields.sqlite import SQLiteVectorField
 7from pyhub.rag.models.sqlite import SQLiteVectorDocument
 8
 9from chat.llm import LLM
10
11
12class TaxLawDocument(SQLiteVectorDocument):
13    embedding = SQLiteVectorField(
14        dimensions=3072,
15        editable=False,
16        embedding_model="text-embedding-3-large",
17    )
18
19    @cached_property
20    def page_content_obj(self):
21        return json.loads(self.page_content)
22
23
24class Room(LifecycleModelMixin, models.Model):
25    name = models.CharField(max_length=255)
26    system_prompt = models.TextField(blank=True)
27    created_at = models.DateTimeField(auto_now_add=True)
28    updated_at = models.DateTimeField(auto_now=True)
29
30    def __str__(self):
31        return self.name
32
33    @hook(AFTER_UPDATE, when="system_prompt", has_changed=True)
34    def on_after_update(self):
35        self.message_set.all().delete()
36
37    def create_ai_message(self):
38        # ํ˜„์žฌ ๋ฐฉ์˜ ์ด์ „ ๋ฉ”์‹œ์ง€๋“ค์„ ์ˆ˜์ง‘
39        message_qs = self.message_set.all()
40        messages = [{"role": msg.role, "content": msg.content} for msg in message_qs]
41
42        # ์„ธ๋ฒ• ํ•ด์„๋ก€ ๋ฌธ์„œ ๊ฒ€์ƒ‰์ด ํ•„์š”ํ•  ๋•Œ
43        user_message = messages[-1]["content"].strip()
44        if user_message.startswith("!"):
45            user_message = user_message[1:]
46            # RAG๋ฅผ ์›ํ•˜๋Š” ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์œ ์‚ฌ ๋ฌธ์„œ ๊ฒ€์ƒ‰
47            doc_list = TaxLawDocument.objects.similarity_search(user_message)
48            ์ง€์‹ = str(doc_list)
49            system_prompt = self.system_prompt + "\n\n" + f"์ฐธ๊ณ ๋ฌธ์„œ : {์ง€์‹}"
50        else:
51            system_prompt = self.system_prompt
52
53        # AI ์‘๋‹ต ์ƒ์„ฑ
54        llm = LLM(
55            model="gpt-4o-mini",
56            temperature=1,
57            system_prompt=system_prompt,
58            initial_messages=messages,
59        )
60        ai_message = llm.make_reply()
61
62        # AI ์‘๋‹ต์„ ์ƒˆ ๋ฉ”์‹œ์ง€๋กœ ์ €์žฅ
63        return self.message_set.create(
64            role=Message.Role.ASSISTANT,
65            content=ai_message,
66        )
67
68    class Meta:
69        ordering = ["-pk"]
70
71
72class Message(models.Model):
73    class Role(models.TextChoices):
74        USER = "user"
75        ASSISTANT = "assistant"
76
77    room = models.ForeignKey(Room, on_delete=models.CASCADE)
78    role = models.CharField(max_length=255, choices=Role.choices, default=Role.USER)
79    content = models.TextField()
80    created_at = models.DateTimeField(auto_now_add=True)
81    updated_at = models.DateTimeField(auto_now=True)
82
83    def __str__(self):
84        return self.content
85
86    class Meta:
87        ordering = ["pk"]

์ฐธ๊ณ 

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

๋™์ž‘ ํ™”๋ฉดยถ

http://localhost:8000/chat/new/ ํŽ˜์ด์ง€์—์„œ ์ƒˆ๋กœ์šด ์„ธ๋ฌด/ํšŒ๊ณ„ ์ฑ—๋ด‡ ์ฑ„ํŒ…๋ฐฉ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

../../_images/form.png

์ฑ„ํŒ…๋ฐฉ์ด ์ƒ์„ฑ๋˜์—ˆ๊ตฌ์š”.

../../_images/room-list.png

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

../../_images/play2.gif