Skip to content

Commit 32c2940

Browse files
committed
RAG adjustment
1 parent c054708 commit 32c2940

File tree

6 files changed

+63
-6
lines changed

6 files changed

+63
-6
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Generated by Django 5.1.5 on 2025-05-23 03:15
2+
3+
import django.contrib.postgres.fields
4+
from django.db import migrations, models
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('api', '0015_chat_memories_user_message_sentiment'),
11+
]
12+
13+
operations = [
14+
migrations.AddField(
15+
model_name='chat_memories',
16+
name='embedding',
17+
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(), blank=True, null=True, size=None),
18+
),
19+
]

happy-kids/api/models.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from django.db import models
22
from django.contrib.auth.models import User
3+
from django.contrib.postgres.fields import ArrayField
34

45
class historicalSessions(models.Model):
56
sessionDate = models.DateTimeField("session date", default="")
@@ -23,6 +24,7 @@ class chat_memories(models.Model):
2324
user_message_sentiment = models.CharField(max_length=20, blank=True, null=True)
2425
chat_message = models.TextField()
2526
date_time = models.DateTimeField(auto_now_add=True)
27+
embedding = ArrayField(models.FloatField(), blank=True, null=True)
2628

2729
class dim_question_type(models.Model):
2830
question_type = models.TextField(unique=True)

happy-kids/frontend/utils.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from datetime import timedelta
66
from api import models
77
import openai
8+
import numpy as np
89

910
def get_short_term_memory(user_id):
1011
"""Recupera a memória de curto prazo do banco de dados"""
@@ -61,3 +62,32 @@ def classify_sentiment(text):
6162
except Exception as e:
6263
print(f"Error during sentiment analysis: {e}")
6364
return None
65+
66+
67+
client = openai.OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
68+
69+
def get_embedding(text):
70+
response = client.embeddings.create(
71+
model="text-embedding-3-small",
72+
input=text,
73+
)
74+
return response.data[0].embedding
75+
76+
77+
78+
def cosine_similarity(a, b):
79+
a = np.array(a)
80+
b = np.array(b)
81+
return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
82+
83+
def get_relevant_memories(user_id, question, top_k=3):
84+
question_emb = get_embedding(question)
85+
86+
history = models.chat_memories.objects.filter(user_id=user_id).exclude(embedding=None)
87+
scored = []
88+
for h in history:
89+
sim = cosine_similarity(question_emb, h.embedding)
90+
scored.append((sim, h))
91+
scored.sort(reverse=True, key=lambda x: x[0])
92+
top_memories = [x[1] for x in scored[:top_k]]
93+
return top_memories

happy-kids/frontend/views.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from .utils import get_short_term_memory, classify_sentiment
1+
from .utils import get_short_term_memory, classify_sentiment, get_embedding, get_relevant_memories
22
from .forms import *
33
from django.contrib.admin.views.decorators import staff_member_required
44
from django.contrib.auth.decorators import login_required
@@ -16,7 +16,6 @@
1616
from django.db.models.functions import TruncDate
1717
from django.db.models import Count
1818

19-
2019
# Create your views here.
2120
@login_required
2221
@staff_member_required
@@ -89,6 +88,8 @@ def view_lulu(request):
8988

9089
recent_memory = get_short_term_memory(user_id)
9190

91+
relevant_memories = get_relevant_memories(user_id, question, top_k=3)
92+
9293
messages = [
9394
{
9495
"role": "system",
@@ -100,6 +101,12 @@ def view_lulu(request):
100101
}
101102
]
102103

104+
for mem in relevant_memories:
105+
messages.append({"role": "user", "content": f"(Previously) {mem.user_message}"})
106+
if mem.chat_message:
107+
messages.append({"role": "assistant", "content": f"(Previously) {mem.chat_message}"})
108+
109+
103110
messages.extend(recent_memory)
104111

105112
messages.append({"role": "user", "content": question})
@@ -121,12 +128,14 @@ def stream_gpt():
121128
response_text_html = markdown.markdown(text=response_text, output_format='html')
122129

123130
sentiment = classify_sentiment(question)
131+
embedding = get_embedding(question)
124132

125133
models.chat_memories.objects.create(
126134
user_id=request.user.id,
127135
user_message=question,
128136
user_message_sentiment=sentiment,
129-
chat_message=response_text
137+
chat_message=response_text,
138+
embedding=embedding
130139
)
131140

132141
yield response_text_html
@@ -137,7 +146,6 @@ def stream_gpt():
137146

138147
return response_server
139148

140-
141149
######################### Memos and Feedback #########################
142150
@login_required
143151
def view_save_memo(request):
@@ -186,7 +194,6 @@ def view_save_feedback(request):
186194
if not user_prompt or not bot_message or not feedback_type:
187195
return JsonResponse({"error": "Dados inválidos."}, status=400)
188196

189-
# Verifica se já existe feedback desse usuário para esse par prompt/resposta
190197
existing_feedback = models.chat_facts_feedback.objects.filter(
191198
user=request.user,
192199
user_prompt=user_prompt,
@@ -202,7 +209,6 @@ def view_save_feedback(request):
202209
existing_feedback.save()
203210
return JsonResponse({"status": "updated"})
204211

205-
# Nenhum feedback anterior → criar novo
206212
models.chat_facts_feedback.objects.create(
207213
user=request.user,
208214
user_prompt=user_prompt,

happy-kids/polls

0 Bytes
Binary file not shown.

happy-kids/requirements.txt

556 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)