Chatbot de RH com LLM e RAG
Assistente conversacional que responde perguntas sobre políticas de RH, benefícios e carreira usando Retrieval-Augmented Generation com GPT-4.
Demonstração do projeto
O time de RH do Banco BV recebia mais de 800 perguntas mensais repetitivas sobre benefícios, políticas, processos de promoção e férias — tópicos com respostas claras na documentação interna, mas que consumiam 40% do tempo dos HRBPs. Desenvolvemos um chatbot baseado em RAG que indexa toda a base de documentos de RH e responde perguntas em linguagem natural, com citação das fontes, histórico de conversa e fallback humano quando a confiança é baixa.
Impacto & Métricas
800+
Perguntas respondidas/mês
73%
Taxa de resolução automática
4.7 / 5
CSAT médio
< 2s
Tempo de resposta
40%
Redução de carga HRBP
Arquitetura RAG
O sistema usa Retrieval-Augmented Generation (RAG) em vez de fine-tuning por dois motivos:
1. As políticas de RH mudam com frequência — RAG permite atualização sem retreinar o modelo
2. RAG cita as fontes, aumentando confiança e auditabilidade das respostas
Pipeline de Ingestão
1. Extração: PDFs e DOCXs de políticas de RH são extraídos com `pdfplumber` e `python-docx`
2. Chunking: documentos são divididos em chunks de 512 tokens com overlap de 50 tokens,
preservando contexto entre partes
3. Embeddings: `text-embedding-3-small` da OpenAI gera vetores de 1536 dimensões
4. Indexação: FAISS como vector store local (migração para Azure AI Search planejada)
Estratégias de Qualidade
- MMR Retrieval: reduz redundância nos documentos recuperados
- Score de confiança: se o score de similaridade do retriever for < 0.65,
o chatbot escala para um HRBP automaticamente
- Guardrails: o prompt proíbe explicitamente invenção de informações e
orienta o tom formal mas acessível
Próximos Passos
- Migração do índice vetorial para Azure AI Search (escala enterprise)
- Multimodalidade: responder com base em tabelas e fluxogramas de documentos
- Analytics de conversas para identificar gaps na documentação de RH
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
from langchain.chains import ConversationalRetrievalChain
from langchain.memory import ConversationBufferWindowMemory
from langchain.prompts import PromptTemplate
SYSTEM_PROMPT = """Você é o Assistente de RH do Banco BV. Responda perguntas dos
colaboradores com base EXCLUSIVAMENTE nos documentos fornecidos como contexto.
Regras:
- Seja direto e use linguagem simples
- Cite sempre a fonte (nome do documento)
- Se não souber, diga: "Não encontrei essa informação. Entre em contato com o RH."
- Nunca invente informações sobre políticas, valores ou processos
Contexto dos documentos:
{context}
Histórico da conversa:
{chat_history}
"""
def create_hr_chatbot(documents_path: str) -> ConversationalRetrievalChain:
"""
Cria pipeline RAG para chatbot de RH.
Args:
documents_path: caminho para pasta com PDFs e DOCXs de RH
Returns:
Chain conversacional com memória de janela (últimas 5 trocas)
"""
# Embeddings e índice vetorial
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = FAISS.load_local(documents_path, embeddings)
retriever = vectorstore.as_retriever(
search_type="mmr", # Maximal Marginal Relevance — reduz redundância
search_kwargs={"k": 5, "fetch_k": 20},
)
# LLM com temperatura baixa para respostas factuais
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.1)
# Memória de janela: mantém contexto das últimas 5 trocas
memory = ConversationBufferWindowMemory(
memory_key="chat_history",
return_messages=True,
k=5,
)
chain = ConversationalRetrievalChain.from_llm(
llm=llm,
retriever=retriever,
memory=memory,
combine_docs_chain_kwargs={
"prompt": PromptTemplate.from_template(SYSTEM_PROMPT)
},
return_source_documents=True,
verbose=False,
)
return chainfrom langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
from langchain.chains import ConversationalRetrievalChain
from langchain.memory import ConversationBufferWindowMemory
from langchain.prompts import PromptTemplate
SYSTEM_PROMPT = """Você é o Assistente de RH do Banco BV. Responda perguntas dos
colaboradores com base EXCLUSIVAMENTE nos documentos fornecidos como contexto.
Regras:
- Seja direto e use linguagem simples
- Cite sempre a fonte (nome do documento)
- Se não souber, diga: "Não encontrei essa informação. Entre em contato com o RH."
- Nunca invente informações sobre políticas, valores ou processos
Contexto dos documentos:
{context}
Histórico da conversa:
{chat_history}
"""
def create_hr_chatbot(documents_path: str) -> ConversationalRetrievalChain:
"""
Cria pipeline RAG para chatbot de RH.
Args:
documents_path: caminho para pasta com PDFs e DOCXs de RH
Returns:
Chain conversacional com memória de janela (últimas 5 trocas)
"""
# Embeddings e índice vetorial
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = FAISS.load_local(documents_path, embeddings)
retriever = vectorstore.as_retriever(
search_type="mmr", # Maximal Marginal Relevance — reduz redundância
search_kwargs={"k": 5, "fetch_k": 20},
)
# LLM com temperatura baixa para respostas factuais
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.1)
# Memória de janela: mantém contexto das últimas 5 trocas
memory = ConversationBufferWindowMemory(
memory_key="chat_history",
return_messages=True,
k=5,
)
chain = ConversationalRetrievalChain.from_llm(
llm=llm,
retriever=retriever,
memory=memory,
combine_docs_chain_kwargs={
"prompt": PromptTemplate.from_template(SYSTEM_PROMPT)
},
return_source_documents=True,
verbose=False,
)
return chain