1+ # %%
2+ import os
3+ from dotenv import load_dotenv
4+ from langchain_google_genai import ChatGoogleGenerativeAI
5+
6+ load_dotenv ()
7+
8+ google_api_key = os .environ .get ("API_KEY" )
9+
10+ # %%
11+
12+ TRIAGEM_PROMPT = (
13+ "Você é um triador de Service Desk para políticas internas da empresa Carraro Desenvolvimento. "
14+ "Dada a mensagem do usuário, retorne SOMENTE um JSON com:\n "
15+ "{\n "
16+ ' "decisao": "AUTO_RESOLVER" | "PEDIR_INFO" | "ABRIR_CHAMADO",\n '
17+ ' "urgencia": "BAIXA" | "MEDIA" | "ALTA",\n '
18+ ' "campos_faltantes": ["..."]\n '
19+ "}\n "
20+ "Regras:\n "
21+ '- **AUTO_RESOLVER**: Perguntas claras sobre regras ou procedimentos descritos nas políticas (Ex: "Posso reembolsar a internet do meu home office?", "Como funciona a política de alimentação em viagens?").\n '
22+ '- **PEDIR_INFO**: Mensagens vagas ou que faltam informações para identificar o tema ou contexto (Ex: "Preciso de ajuda com uma política", "Tenho uma dúvida geral").\n '
23+ '- **ABRIR_CHAMADO**: Pedidos de exceção, liberação, aprovação ou acesso especial, ou quando o usuário explicitamente pede para abrir um chamado (Ex: "Quero exceção para trabalhar 5 dias remoto.", "Solicito liberação para anexos externos.", "Por favor, abra um chamado para o RH.").'
24+ "Analise a mensagem e decida a ação mais apropriada."
25+
26+ """
27+ decisao: AUTO_RESOLVER
28+ ugencia: BAIXA
29+ campos_faltantes: []
30+ """
31+ )
32+ # %%
33+
34+ from pydantic import BaseModel , Field
35+ from typing import Literal , List , Dict
36+
37+ class TriagemOut (BaseModel ):
38+ decisao : Literal ["AUTO_RESOLVER" , "PEDIR_INFO" , "ABRIR_CHAMADO" ]
39+ urgencia : Literal ["BAIXA" , "MEDIA" , "ALTA" ]
40+ campos_faltantes : List [str ] = Field (default_factory = list )
41+
42+ # %%
43+
44+ llm_triagem = ChatGoogleGenerativeAI (model = "gemini-2.5-flash" , temperature = 0.0 , api_key = google_api_key )
45+ # %%
46+
47+ from langchain_core .messages import SystemMessage , HumanMessage
48+
49+ triagem_chain = llm_triagem .with_structured_output (TriagemOut )
50+
51+ def triagem (mensagem : str ) -> Dict :
52+ saida : TriagemOut = triagem_chain .invoke ([SystemMessage (content = TRIAGEM_PROMPT ), HumanMessage (content = mensagem )])
53+ return saida .model_dump ()
54+ # %%
55+
56+ testes = ["posso reembolsar a internet?" , "Quero ter mais 5 dias remoto?" , "Como sacar o pino do coquilho traseiro do guindaste zunlaine 75" ]
57+
58+ for msg_test in testes :
59+ print (f"Pergunta: { msg_test } \n -> Resposta: { triagem (msg_test )} \n " )
60+
61+ # %%
62+
63+ from pathlib import Path
64+ from langchain_community .document_loaders import PyMuPDFLoader
65+
66+ docs = [];
67+
68+ for n in Path ("." ).glob ("*.pdf" ):
69+ try :
70+ loader = PyMuPDFLoader (str (n ))
71+ docs .extend (loader .load ())
72+ print (f"carregado arquivo com sucesso: { n .name } " )
73+ except Exception as a :
74+ print (f"Erro ao carregar arquivo { n .name } : { a } " )
75+ # %%
76+
77+ from langchain_text_splitters import RecursiveCharacterTextSplitter
78+
79+ splitter = RecursiveCharacterTextSplitter (chunk_size = 100 , chunk_overlap = 30 )
80+
81+ chunks = splitter .split_documents (docs )
82+
83+ # %%
84+
85+ for chunk in chunks :
86+ print (chunk );
87+ print ("--------------------------" )
88+ # %%
89+
90+ from langchain_google_genai import GoogleGenerativeAIEmbeddings
91+
92+ embedding = GoogleGenerativeAIEmbeddings (model = "models/gemini-embedding-001" , google_api_key = google_api_key )
93+
94+ # %%
95+
96+ from langchain_community .vectorstores import FAISS
97+
98+ vectorstoe = FAISS .from_documents (chunks , embedding )
99+
100+ retriever = vectorstoe .as_retriever (search_type = "similarity_score_threshold" , search_kwargs = {"score_threshold" : 0.3 , "k" : 4 })
101+ +
102+ # %%
103+
104+ from langchain_core .prompts import ChatPromptTemplate
105+ from langchain .chains .combine_documents import create_stuff_documents_chain
106+
107+ prompt_rag = ChatPromptTemplate .from_messages ([
108+ ("system" ,
109+ "Você é um Assistente de Políticas Internas (RH/IT) da empresa Carraro Desenvolvimento. "
110+ "Responda SOMENTE com base no contexto fornecido. "
111+ "Se não houver base suficiente, responda apenas 'Não sei'." ),
112+
113+ ("human" , "Pergunta: {input}\n \n Contexto:\n {context}" )
114+ ])
115+
116+ document_chain = create_stuff_documents_chain (llm_triagem , prompt_rag )
117+
118+ # %%
119+
120+ def askPolitic_rag (pergunta : str ) -> Dict :
121+
122+
123+
0 commit comments