Spaces:
Running
Running
luanpoppe
commited on
Commit
·
7fa7a9c
1
Parent(s):
cb23311
refactor: pequenas refatorações
Browse files
_utils/gerar_relatorio_modelo_usuario/EnhancedDocumentSummarizer.py
CHANGED
@@ -229,7 +229,7 @@ class EnhancedDocumentSummarizer(DocumentSummarizer):
|
|
229 |
|
230 |
documento_gerado = llm.invoke(
|
231 |
prompt_gerar_documento.format(
|
232 |
-
context=
|
233 |
# modelo_usuario=serializer.data["modelo"],
|
234 |
)
|
235 |
).content
|
|
|
229 |
|
230 |
documento_gerado = llm.invoke(
|
231 |
prompt_gerar_documento.format(
|
232 |
+
context=self.resumo_gerado,
|
233 |
# modelo_usuario=serializer.data["modelo"],
|
234 |
)
|
235 |
).content
|
_utils/gerar_relatorio_modelo_usuario/contextual_retriever.py
CHANGED
@@ -1,8 +1,9 @@
|
|
1 |
import os
|
2 |
|
3 |
-
|
4 |
-
|
5 |
-
|
|
|
6 |
from _utils.bubble_integrations.obter_arquivo import get_pdf_from_bubble
|
7 |
from _utils.chains.Chain_class import Chain
|
8 |
from _utils.prompts.Prompt_class import Prompt
|
@@ -20,6 +21,7 @@ from multiprocessing import Process, Barrier, Queue
|
|
20 |
from dataclasses import dataclass
|
21 |
from langchain_core.messages import HumanMessage
|
22 |
from asgiref.sync import sync_to_async
|
|
|
23 |
|
24 |
from _utils.gerar_relatorio_modelo_usuario.llm_calls import aclaude_answer, agpt_answer
|
25 |
from _utils.gerar_relatorio_modelo_usuario.prompts import contextual_prompt
|
@@ -28,6 +30,7 @@ from _utils.models.gerar_relatorio import (
|
|
28 |
DocumentChunk,
|
29 |
RetrievalConfig,
|
30 |
)
|
|
|
31 |
|
32 |
lista_contador = []
|
33 |
|
@@ -43,11 +46,13 @@ class ContextualRetriever:
|
|
43 |
self.bm25 = None
|
44 |
self.claude_context_model = claude_context_model
|
45 |
|
46 |
-
async def llm_generate_context(
|
|
|
|
|
47 |
"""Generate contextual description using ChatOpenAI"""
|
48 |
try:
|
49 |
print("COMEÇOU A REQUISIÇÃO")
|
50 |
-
prompt = contextual_prompt(
|
51 |
# response = await aclaude_answer(
|
52 |
# self.claude_client, self.claude_context_model, prompt
|
53 |
# )
|
@@ -67,20 +72,24 @@ class ContextualRetriever:
|
|
67 |
# Chain(prompt, ChatOpenAI())
|
68 |
# return
|
69 |
|
70 |
-
async def create_contextualized_chunk(
|
|
|
|
|
71 |
lista_contador.append(0)
|
72 |
print("contador: ", len(lista_contador))
|
73 |
# Código comentado abaixo é para ler as páginas ao redor da página atual do chunk
|
74 |
# page_content = ""
|
75 |
# for i in range(
|
76 |
# max(0, chunk.page_number - 1),
|
77 |
-
# min(len(
|
78 |
# ):
|
79 |
-
# page_content +=
|
80 |
page_number = chunk.page_number - 1
|
81 |
-
page_content =
|
82 |
|
83 |
-
context = await self.llm_generate_context(
|
|
|
|
|
84 |
return ContextualizedChunk(
|
85 |
content=chunk.content,
|
86 |
page_number=chunk.page_number,
|
@@ -91,15 +100,40 @@ class ContextualRetriever:
|
|
91 |
)
|
92 |
|
93 |
async def contextualize_all_chunks(
|
94 |
-
self,
|
95 |
) -> List[ContextualizedChunk]:
|
96 |
"""Add context to all chunks"""
|
97 |
contextualized_chunks = []
|
98 |
lista_contador = []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
|
100 |
async with asyncio.TaskGroup() as tg:
|
101 |
tasks = [
|
102 |
-
tg.create_task(
|
|
|
|
|
|
|
|
|
103 |
for chunk in chunks
|
104 |
]
|
105 |
|
|
|
1 |
import os
|
2 |
|
3 |
+
from _utils.gerar_relatorio_modelo_usuario.prompts import (
|
4 |
+
prompt_auxiliar_do_contextual_prompt,
|
5 |
+
create_prompt_auxiliar_do_contextual_prompt,
|
6 |
+
)
|
7 |
from _utils.bubble_integrations.obter_arquivo import get_pdf_from_bubble
|
8 |
from _utils.chains.Chain_class import Chain
|
9 |
from _utils.prompts.Prompt_class import Prompt
|
|
|
21 |
from dataclasses import dataclass
|
22 |
from langchain_core.messages import HumanMessage
|
23 |
from asgiref.sync import sync_to_async
|
24 |
+
from setup.easy_imports import ChatPromptTemplate, ChatOpenAI
|
25 |
|
26 |
from _utils.gerar_relatorio_modelo_usuario.llm_calls import aclaude_answer, agpt_answer
|
27 |
from _utils.gerar_relatorio_modelo_usuario.prompts import contextual_prompt
|
|
|
30 |
DocumentChunk,
|
31 |
RetrievalConfig,
|
32 |
)
|
33 |
+
from _utils.prompts.Prompt_class import prompt as prompt_obj
|
34 |
|
35 |
lista_contador = []
|
36 |
|
|
|
46 |
self.bm25 = None
|
47 |
self.claude_context_model = claude_context_model
|
48 |
|
49 |
+
async def llm_generate_context(
|
50 |
+
self, page_text: str, chunk: DocumentChunk, resumo_auxiliar
|
51 |
+
) -> str:
|
52 |
"""Generate contextual description using ChatOpenAI"""
|
53 |
try:
|
54 |
print("COMEÇOU A REQUISIÇÃO")
|
55 |
+
prompt = contextual_prompt(page_text, resumo_auxiliar, chunk.content)
|
56 |
# response = await aclaude_answer(
|
57 |
# self.claude_client, self.claude_context_model, prompt
|
58 |
# )
|
|
|
72 |
# Chain(prompt, ChatOpenAI())
|
73 |
# return
|
74 |
|
75 |
+
async def create_contextualized_chunk(
|
76 |
+
self, chunk, single_page_text, response_auxiliar_summary
|
77 |
+
):
|
78 |
lista_contador.append(0)
|
79 |
print("contador: ", len(lista_contador))
|
80 |
# Código comentado abaixo é para ler as páginas ao redor da página atual do chunk
|
81 |
# page_content = ""
|
82 |
# for i in range(
|
83 |
# max(0, chunk.page_number - 1),
|
84 |
+
# min(len(single_page_text), chunk.page_number + 2),
|
85 |
# ):
|
86 |
+
# page_content += single_page_text[i].page_content if single_page_text[i] else ""
|
87 |
page_number = chunk.page_number - 1
|
88 |
+
page_content = single_page_text[page_number].page_content
|
89 |
|
90 |
+
context = await self.llm_generate_context(
|
91 |
+
page_content, chunk, response_auxiliar_summary
|
92 |
+
)
|
93 |
return ContextualizedChunk(
|
94 |
content=chunk.content,
|
95 |
page_number=chunk.page_number,
|
|
|
100 |
)
|
101 |
|
102 |
async def contextualize_all_chunks(
|
103 |
+
self, full_text_as_array: List[Document], chunks: List[DocumentChunk]
|
104 |
) -> List[ContextualizedChunk]:
|
105 |
"""Add context to all chunks"""
|
106 |
contextualized_chunks = []
|
107 |
lista_contador = []
|
108 |
+
full_text = ""
|
109 |
+
for x in full_text_as_array:
|
110 |
+
full_text += x.page_content
|
111 |
+
|
112 |
+
# prompt_auxiliar_summary = prompt_obj.create_prompt_template(
|
113 |
+
# "", prompt_auxiliar_do_contextual_prompt
|
114 |
+
# ).invoke({"PROCESSO_JURIDICO": full_text})
|
115 |
+
|
116 |
+
# response_auxiliar_summary = await ChatOpenAI(max_tokens=128000).ainvoke(
|
117 |
+
# prompt_auxiliar_summary
|
118 |
+
# )
|
119 |
+
|
120 |
+
prompt_auxiliar_summary = create_prompt_auxiliar_do_contextual_prompt(full_text)
|
121 |
+
|
122 |
+
print("\n\n\nprompt_auxiliar_summary: ", prompt_auxiliar_summary)
|
123 |
+
|
124 |
+
response_auxiliar_summary = await aclaude_answer(
|
125 |
+
self.claude_client, self.claude_context_model, prompt_auxiliar_summary
|
126 |
+
)
|
127 |
+
|
128 |
+
print("\n\n\n\nresponse_auxiliar_summary: ", response_auxiliar_summary)
|
129 |
|
130 |
async with asyncio.TaskGroup() as tg:
|
131 |
tasks = [
|
132 |
+
tg.create_task(
|
133 |
+
self.create_contextualized_chunk(
|
134 |
+
chunk, full_text_as_array, response_auxiliar_summary
|
135 |
+
)
|
136 |
+
)
|
137 |
for chunk in chunks
|
138 |
]
|
139 |
|
_utils/gerar_relatorio_modelo_usuario/llm_calls.py
CHANGED
@@ -8,7 +8,7 @@ async def aclaude_answer(claude_client, claude_context_model, prompt):
|
|
8 |
print("\n\nComeçou uma requisição pelo Claude")
|
9 |
response = await claude_client.messages.create(
|
10 |
model=claude_context_model,
|
11 |
-
max_tokens=100,
|
12 |
messages=[{"role": "user", "content": prompt}],
|
13 |
)
|
14 |
return response.content[
|
|
|
8 |
print("\n\nComeçou uma requisição pelo Claude")
|
9 |
response = await claude_client.messages.create(
|
10 |
model=claude_context_model,
|
11 |
+
max_tokens=100, # Máximo é 4096
|
12 |
messages=[{"role": "user", "content": prompt}],
|
13 |
)
|
14 |
return response.content[
|
_utils/gerar_relatorio_modelo_usuario/prompts.py
CHANGED
@@ -16,7 +16,7 @@ Siga este passo a passo para criar o resumo:
|
|
16 |
|
17 |
1. Leia atentamente todo o processo jurídico fornecido.
|
18 |
<processo_juridico>
|
19 |
-
{
|
20 |
</processo_juridico>
|
21 |
|
22 |
2. Identifique e anote as datas e conteúdos relevantes relacionados às 10 peças processuais listadas acima.
|
@@ -57,24 +57,119 @@ Formate sua resposta da seguinte maneira:
|
|
57 |
</resumo_final>"""
|
58 |
|
59 |
|
60 |
-
def
|
61 |
-
return f"""
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
2.
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
|
79 |
|
80 |
# Novo nome --> prompt-auxiliar --> Para gerar documentos (é usado como auxiliar no prompt final)
|
|
|
16 |
|
17 |
1. Leia atentamente todo o processo jurídico fornecido.
|
18 |
<processo_juridico>
|
19 |
+
{PROCESSO_JURIDICO}
|
20 |
</processo_juridico>
|
21 |
|
22 |
2. Identifique e anote as datas e conteúdos relevantes relacionados às 10 peças processuais listadas acima.
|
|
|
57 |
</resumo_final>"""
|
58 |
|
59 |
|
60 |
+
def create_prompt_auxiliar_do_contextual_prompt(PROCESSO_JURIDICO: str):
|
61 |
+
return f"""Você é um assistente jurídico especializado em direito brasileiro. Sua tarefa é criar um resumo conciso e informativo de um processo jurídico, de acordo com as leis do Brasil. O resumo deve focar nos momentos cruciais do processo, na última movimentação processual e nas principais movimentações que ocorreram.
|
62 |
+
|
63 |
+
Aqui estão as 10 principais peças processuais em ordem cronológica do processo civil brasileiro que você deve priorizar em sua análise:
|
64 |
+
1. Petição Inicial
|
65 |
+
2. Contestação
|
66 |
+
3. Réplica
|
67 |
+
4. Decisão de Saneamento
|
68 |
+
5. Sentença
|
69 |
+
6. Recurso de Apelação
|
70 |
+
7. Embargos de Declaração
|
71 |
+
8. Cumprimento de Sentença
|
72 |
+
9. Embargos à Execução
|
73 |
+
10. Agravo de Instrumento
|
74 |
+
|
75 |
+
Siga este passo a passo para criar o resumo:
|
76 |
+
|
77 |
+
1. Leia atentamente todo o processo jurídico fornecido.
|
78 |
+
<processo_juridico>
|
79 |
+
{PROCESSO_JURIDICO}
|
80 |
+
</processo_juridico>
|
81 |
+
|
82 |
+
2. Identifique e anote as datas e conteúdos relevantes relacionados às 10 peças processuais listadas acima.
|
83 |
+
|
84 |
+
3. Organize cronologicamente as informações coletadas.
|
85 |
+
|
86 |
+
4. Destaque a última movimentação processual e seu significado para o andamento do processo.
|
87 |
+
|
88 |
+
5. Resuma as principais movimentações, focando em seu impacto no processo.
|
89 |
+
|
90 |
+
6. Elabore um texto coeso que apresente o fluxo do processo, destacando os pontos cruciais e as decisões mais importantes.
|
91 |
+
|
92 |
+
Após criar o resumo inicial, utilize a técnica socrática de reflexão para garantir a precisão e completude do resumo. Faça a si mesmo as seguintes perguntas:
|
93 |
+
|
94 |
+
1. O resumo abrange todas as 10 peças processuais principais?
|
95 |
+
2. A última movimentação processual está claramente identificada e explicada?
|
96 |
+
3. O texto apresenta uma visão clara do fluxo do processo?
|
97 |
+
4. Todas as informações cruciais para o entendimento do caso estão incluídas?
|
98 |
+
5. O resumo está livre de opiniões pessoais e se atém aos fatos do processo?
|
99 |
+
6. A linguagem utilizada é clara e acessível, mesmo para quem não é especialista em direito?
|
100 |
+
|
101 |
+
Revise e ajuste o resumo conforme necessário com base nessa reflexão.
|
102 |
+
|
103 |
+
O resumo final deve ter no máximo 2 páginas de extensão (aproximadamente 1000 palavras).
|
104 |
+
|
105 |
+
Formate sua resposta da seguinte maneira:
|
106 |
+
|
107 |
+
<resumo_processo>
|
108 |
+
[Insira aqui o resumo do processo jurídico]
|
109 |
+
</resumo_processo>
|
110 |
+
|
111 |
+
<reflexao_socratica>
|
112 |
+
[Insira aqui suas respostas às perguntas da reflexão socrática]
|
113 |
+
</reflexao_socratica>
|
114 |
+
|
115 |
+
<resumo_final>
|
116 |
+
[Insira aqui o resumo final revisado, se houver alterações após a reflexão]
|
117 |
+
</resumo_final>"""
|
118 |
+
|
119 |
+
|
120 |
+
def contextual_prompt(single_page_text, summary_text, chunk_content):
|
121 |
+
return f"""You are an AI assistant specialized in providing context for document retrieval. Your task is to analyze a chunk of text from a larger document and provide a brief context for it.
|
122 |
+
|
123 |
+
Here's the summary of the full text of the document:
|
124 |
+
<summary_text>
|
125 |
+
{summary_text}
|
126 |
+
</summary_text>
|
127 |
+
|
128 |
+
Here's the single page where the chunk is situated:
|
129 |
+
|
130 |
+
<single_page>
|
131 |
+
{single_page_text}
|
132 |
+
</single_page>
|
133 |
+
|
134 |
+
And here's the specific chunk to contextualize:
|
135 |
+
<chunk>
|
136 |
+
{chunk_content}
|
137 |
+
</chunk>
|
138 |
+
|
139 |
+
Follow these steps:
|
140 |
+
1. Identify and quote the document ID (found between "NUM." and "- Pág") and the document name (from the header).
|
141 |
+
2. Summarize the main topics or themes of the single page and where it fit within the summary of the full text.
|
142 |
+
3. Identify where the specific chunk fits within these themes.
|
143 |
+
4. Create a concise context that situates the chunk within the document.
|
144 |
+
|
145 |
+
With this informations, your response should be a single, concise paragraph that includes:
|
146 |
+
- The document ID
|
147 |
+
- The document name
|
148 |
+
- A brief context for the chunk
|
149 |
+
|
150 |
+
Example final output structure (do not copy the content, only the format):
|
151 |
+
<chunk_context>
|
152 |
+
[Single paragraph with document ID, name, and chunk context]
|
153 |
+
</chunk_context>"""
|
154 |
+
|
155 |
+
|
156 |
+
# return f"""You are a language model tasked with providing context to improve the retrieval of information from a chunk extracted from a document. Follow these steps internally (do not display reasoning or reflection in the final output):
|
157 |
+
# 1. **Chain of Thought (internal)**:
|
158 |
+
# - Identify the document ID, which is the value between "NUM." and "- Pág".
|
159 |
+
# - Identify the document name from the header.
|
160 |
+
# 2. **Reflection (internal)**:
|
161 |
+
# - Confirm the document ID and name are correctly identified.
|
162 |
+
# - Ensure the final context is concise and helpful.
|
163 |
+
# 3. **Final Response**:
|
164 |
+
# - Provide a short context situating the *chunk* within the document, including the document ID and document name.
|
165 |
+
# - Do not include any reasoning or reflection in your response.
|
166 |
+
# **Example Usage:**
|
167 |
+
# ```
|
168 |
+
# <document> {full_text} </document>
|
169 |
+
# <chunk> {chunk_content} </chunk>
|
170 |
+
# Please return only the succinct context (without displaying your internal reasoning), including the document ID and the document name.
|
171 |
+
# ```
|
172 |
+
# """
|
173 |
|
174 |
|
175 |
# Novo nome --> prompt-auxiliar --> Para gerar documentos (é usado como auxiliar no prompt final)
|
_utils/prompts/Prompt_class.py
CHANGED
@@ -10,3 +10,5 @@ class Prompt:
|
|
10 |
[("system", system_prompt), ("user", user_prompt)]
|
11 |
)
|
12 |
return prompt_template
|
|
|
|
|
|
10 |
[("system", system_prompt), ("user", user_prompt)]
|
11 |
)
|
12 |
return prompt_template
|
13 |
+
|
14 |
+
prompt = Prompt()
|