mirla commited on
Commit
a211924
·
verified ·
1 Parent(s): d7b9d9d

Upload 3 files

Browse files
Files changed (3) hide show
  1. app.py +200 -0
  2. ecommerce.db +0 -0
  3. requirements.txt +27 -0
app.py ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sqlalchemy import create_engine, MetaData
2
+
3
+ url = 'ecommerce.db'
4
+ engine = create_engine(f'sqlite:///{url}')
5
+
6
+ metadata_obj = MetaData()
7
+ metadata_obj.reflect(engine)
8
+
9
+ import os
10
+
11
+ key = os.getenv("GROQ_API")
12
+
13
+ modelo="llama-3.1-70b-versatile"
14
+ modelo_hf_emb="BAAI/bge-m3"
15
+
16
+ from llama_index.core import Settings
17
+ from llama_index.llms.groq import Groq
18
+ from llama_index.embeddings.huggingface import HuggingFaceEmbedding
19
+
20
+ Settings.llm = Groq(model=modelo, api_key = key)
21
+ Settings.embed_model = HuggingFaceEmbedding(model_name = modelo_hf_emb)
22
+
23
+ from llama_index.core import SQLDatabase
24
+ from llama_index.core.objects import SQLTableNodeMapping
25
+
26
+ sql_database = SQLDatabase(engine)
27
+ table_node_map = SQLTableNodeMapping(sql_database)
28
+
29
+ llm = Groq(model=modelo, api_key = key)
30
+
31
+ def gerar_descricao_tabela(nome_tabela, df_amostra):
32
+ prompt = f"""
33
+ Analise a amostra da tabela '{nome_tabela}' abaixo e forneça uma curta e breve descrição do conteúdo dessa tabela.
34
+ Informe até o máximo de 5 valores únicos de cada coluna.
35
+
36
+
37
+ Amostra da Tabela:
38
+ {df_amostra}
39
+
40
+ Descrição:
41
+ """
42
+
43
+ resposta = llm.complete(prompt = prompt)
44
+
45
+ return resposta.text
46
+
47
+ import pandas as pd
48
+
49
+ nomes_tabelas = metadata_obj.tables.keys()
50
+ dicionario_tabelas = {}
51
+
52
+ for nome_tabela in nomes_tabelas:
53
+ df = pd.read_sql_table(nome_tabela,engine)
54
+ df_amostra = df.head(5).to_string()
55
+
56
+ descricao = gerar_descricao_tabela(nome_tabela, df_amostra)
57
+ dicionario_tabelas[nome_tabela] = descricao
58
+ print(f'Tabela: {nome_tabela}\n Descrição: {descricao}')
59
+ print('-'*15)
60
+
61
+ from llama_index.core.objects import SQLTableSchema
62
+ from llama_index.core import VectorStoreIndex
63
+ from llama_index.core.objects import ObjectIndex
64
+
65
+ table_schema_objs = [
66
+ SQLTableSchema(table_name= nome_tabela,context_str= dicionario_tabelas[nome_tabela])
67
+ for nome_tabela in nomes_tabelas
68
+ ]
69
+
70
+ obj_index = ObjectIndex.from_objects(table_schema_objs,table_node_map, VectorStoreIndex)
71
+ obj_retriever = obj_index.as_retriever(similarity_top_k=1)
72
+
73
+ texto2sql = """Dada uma pergunta em linguagem natural, crie uma consulta {dialect} sintaticamente correta para executar e, em seguida, verifique os resultados da consulta e retorne a resposta. Você pode ordenar os resultados por uma coluna relevante para retornar os exemplos mais informativos no banco de dados.
74
+
75
+ Nunca consulte todas as colunas de uma tabela específica. Pergunte apenas por algumas colunas relevantes, de acordo com a pergunta.
76
+
77
+ Preste atenção para usar apenas os nomes de colunas que você pode ver na descrição do esquema. Tenha cuidado para não consultar colunas que não existem. Preste atenção em qual coluna está em qual tabela. Além disso, qualifique os nomes das colunas com o nome da tabela quando necessário.
78
+
79
+ Use o seguinte formato, cada um em uma linha:
80
+
81
+ Pergunta: Pergunta aqui
82
+ ConsultaSQL: Consulta SQL para executar
83
+ ResultadoSQL: Resultado da ConsultaSQL
84
+ Resposta: Resposta final aqui
85
+
86
+ Use apenas as tabelas listadas abaixo.
87
+
88
+ {schema}
89
+
90
+ Pergunta: {pergunta_user}
91
+ ConsultaSQL:
92
+ """
93
+
94
+ from llama_index.core import PromptTemplate
95
+
96
+ prompt_1 = PromptTemplate(texto2sql, dialect = engine.dialect.name)
97
+
98
+ from typing import List
99
+
100
+ def descricao_tabela (schema_tabelas: List[SQLTableSchema]):
101
+ descricao_str = []
102
+ for tabela_schema in schema_tabelas:
103
+ info_tabela = sql_database.get_single_table_info(tabela_schema.table_name)
104
+ info_tabela += (' A descrição da tabela é: '+tabela_schema.context_str)
105
+
106
+ descricao_str.append(info_tabela)
107
+ return '\n\n'.join(descricao_str)
108
+
109
+ from llama_index.core.query_pipeline import FnComponent
110
+
111
+ contexto_tabela = FnComponent(fn=descricao_tabela)
112
+
113
+ from llama_index.core.llms import ChatResponse
114
+
115
+ def resposta_sql (resposta: ChatResponse) -> str:
116
+ conteudo_resposta = resposta.message.content
117
+
118
+ sql_consulta = conteudo_resposta.split("ConsultaSQL: ", 1)[-1].split("ResultadoSQL: ", 1)[0]
119
+ return sql_consulta.strip().strip('```').strip()
120
+
121
+ consulta_sql = FnComponent(fn=resposta_sql)
122
+
123
+ from llama_index.core.retrievers import SQLRetriever
124
+
125
+ resultado_sql = SQLRetriever(sql_database)
126
+
127
+ prompt_2_str = '''
128
+ Você é o "Assitente de consulta de banco de dados da Zoop".
129
+ Dada a seguinte pergunta, a consulta SQL correspondente e o resultado SQL, responda à pergunta de modo agradável e objetivamente.
130
+ Evite iniciar conversas com cumprimentos e apresentações, como "Olá".
131
+
132
+ Pergunta: {pergunta_user}
133
+ Consulta SQL: {consulta}
134
+ Resultado SQL: {resultado}
135
+ Resposta:
136
+ '''
137
+
138
+ prompt_2 = PromptTemplate(
139
+ prompt_2_str,
140
+ )
141
+
142
+ from llama_index.core.query_pipeline import QueryPipeline, InputComponent
143
+
144
+ qp = QueryPipeline(
145
+ modules = {
146
+ 'entrada': InputComponent(),
147
+ 'acesso_tabela': obj_retriever,
148
+ 'contexto_tabela': contexto_tabela,
149
+ 'prompt_1': prompt_1,
150
+ 'llm_1': llm,
151
+ 'consulta_sql': consulta_sql,
152
+ 'resultado_sql': resultado_sql,
153
+ 'prompt_2': prompt_2,
154
+ 'llm_2': llm,
155
+ },
156
+ verbose=False
157
+ )
158
+
159
+ qp.add_chain(['entrada', 'acesso_tabela', 'contexto_tabela'])
160
+ qp.add_link('entrada', 'prompt_1', dest_key='pergunta_user')
161
+ qp.add_link('contexto_tabela', 'prompt_1', dest_key='schema')
162
+ qp.add_chain(['prompt_1', 'llm_1', 'consulta_sql', 'resultado_sql'])
163
+ qp.add_link('entrada', 'prompt_2', dest_key='pergunta_user')
164
+ qp.add_link('consulta_sql', 'prompt_2', dest_key= 'consulta')
165
+ qp.add_link('resultado_sql', 'prompt_2', dest_key='resultado')
166
+ qp.add_link('prompt_2', 'llm_2')
167
+
168
+ def entrada_saida (msg_user: str):
169
+ saida = qp.run(query=msg_user)
170
+ return str(saida.message.content)
171
+
172
+ def adicao_historico(msg_user, historico):
173
+ msg_assistente = entrada_saida(msg_user)
174
+
175
+ historico.append([msg_user, msg_assistente])
176
+ return msg_assistente, historico
177
+
178
+ import gradio as gr
179
+
180
+ with gr.Blocks() as demo:
181
+ gr.Markdown('## Chat com Assistente SQL')
182
+ gr.Markdown(
183
+ '''
184
+ Este é um assistente SQL interativo, projetado para responder perguntas sobre os dados da loja Zoop.
185
+ Insira sua pergunta no campo abaixo e o assistente irá responder com base no resultado da consulta SQL
186
+ nos dados disponíveis.
187
+ '''
188
+ )
189
+ chatbot = gr.Chatbot(label='Chat com Assistente')
190
+ msg = gr.Textbox(label='Digite a sua pergunta e tecle Enter para enviar',
191
+ placeholder='Digite o texto aqui.')
192
+ limpeza = gr.Button('Limpar a conversa')
193
+ def atualizar_historico (msg_user, historico):
194
+ msg_assistente, historico = adicao_historico(msg_user, historico)
195
+ return '', historico
196
+ msg.submit(atualizar_historico, inputs=[msg, chatbot], outputs=[msg, chatbot], queue= False)
197
+ limpeza.click(lambda: None, inputs=None, outputs=chatbot, queue=False)
198
+
199
+ demo.queue()
200
+ demo.launch()
ecommerce.db ADDED
Binary file (28.7 kB). View file
 
requirements.txt ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ pandas==2.2.2
2
+ sqlalchemy==2.0.36
3
+ llama-cloud==0.1.5
4
+ llama-index==0.12.1
5
+ llama-index-agent-openai==0.4.0
6
+ llama-index-cli==0.4.0
7
+ llama-index-core==0.12.1
8
+ llama-index-embeddings-adapter==0.3.0
9
+ llama-index-embeddings-huggingface==0.4.0
10
+ llama-index-embeddings-openai==0.3.0
11
+ llama-index-experimental==0.5.0
12
+ llama-index-finetuning==0.3.0
13
+ llama-index-indices-managed-llama-cloud==0.6.2
14
+ llama-index-legacy==0.9.48.post4
15
+ llama-index-llms-azure-openai==0.3.0
16
+ llama-index-llms-groq==0.3.0
17
+ llama-index-llms-mistralai==0.3.0
18
+ llama-index-llms-openai==0.3.1
19
+ llama-index-llms-openai-like==0.3.0
20
+ llama-index-multi-modal-llms-openai==0.3.0
21
+ llama-index-postprocessor-cohere-rerank==0.3.0
22
+ llama-index-program-openai==0.3.0
23
+ llama-index-question-gen-openai==0.3.0
24
+ llama-index-readers-file==0.4.0
25
+ llama-index-readers-llama-parse==0.4.0
26
+ llama-parse==0.5.14
27
+ gradio==5.6.0