from langchain_openai import ChatOpenAI
from langchain_core.prompts import (
PromptTemplate,
ChatPromptTemplate,
MessagesPlaceholder
)
from langchain_core.messages import HumanMessage, AIMessage
from langchain_core.output_parsers import StrOutputParser
from dotenv import load_dotenv
from pydantic import BaseModel
import os
load_dotenv()
# CONFIGURAÇÃO DO MODELO
llm = ChatOpenAI(
base_url=os.getenv("BASE_URL"),
api_key=os.getenv("API_KEY"),
model=os.getenv("MODEL_ALTERNATIVO"),
temperature=0.7
)
# MODELO PYDANTIC
class CidadeRecomendada(BaseModel):
cidade: str
motivo: str
cidade_parser = llm.with_structured_output(
CidadeRecomendada
)
# HISTÓRICO - SINGLETON
class HistoricoChat:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance.historico = {}
return cls._instance
def adicionar(self, conversa, pergunta, resposta):
if conversa not in self.historico:
self.historico[conversa] = []
self.historico[conversa].append(
HumanMessage(content=pergunta)
)
self.historico[conversa].append(
AIMessage(content=resposta)
)
def obter(self, conversa):
return self.historico.get(conversa, [])
historico = HistoricoChat()
# CHAT PROMPT TEMPLATE
chat_prompt = ChatPromptTemplate.from_messages([
(
"system",
"""Você é um assistente especializado em
turismo brasileiro.
Responda de forma clara e objetiva.
Utilize o histórico da conversa para
manter o contexto das perguntas."""
),
MessagesPlaceholder(
variable_name="historico"
),
(
"human",
"{pergunta}"
)
])
# CADEIA DE CHAT
chat_chain = chat_prompt | llm | StrOutputParser()
# FUNÇÃO DE CHAT COM MEMÓRIA
def conversar(conversa, pergunta):
contexto = historico.obter(conversa)
resposta = chat_chain.invoke({
"historico": contexto,
"pergunta": pergunta
})
historico.adicionar(
conversa,
pergunta,
resposta
)
return resposta
# CADEIA DE CIDADE
cidade_prompt = PromptTemplate.from_template("""
Indique uma cidade brasileira para uma pessoa
interessada em {interesse}.
Responda contendo:
- cidade: nome da cidade
- motivo: explique por que ela é adequada
ao interesse informado.
Interesse: {interesse}
""")
cidade_chain = cidade_prompt | cidade_parser
# CADEIA DE RESTAURANTES
restaurante_prompt = PromptTemplate.from_template("""
Recomende 3 restaurantes em {cidade}.
O interesse do viajante é {interesse}.
Para cada restaurante, informe:
- nome
- tipo de culinária
- motivo da recomendação.
Responda apenas com texto.
""")
restaurante_chain = (
restaurante_prompt
| llm
| StrOutputParser()
)
# CADEIA CULTURAL
cultural_prompt = PromptTemplate.from_template("""
Sugira 3 atrações culturais em {cidade}
relacionadas ao interesse "{interesse}".
Explique brevemente cada atração.
Responda apenas com texto.
""")
cultural_chain = (
cultural_prompt
| llm
| StrOutputParser()
)
# PIPELINE DE RECOMENDAÇÃO
interesse = "história e cultura"
cidade = cidade_chain.invoke({
"interesse": interesse
})
print("\n=== CIDADE ===")
print("Cidade:", cidade.cidade)
print("Motivo:", cidade.motivo)
restaurantes = restaurante_chain.invoke({
"cidade": cidade.cidade,
"interesse": interesse
})
print("\n=== RESTAURANTES ===")
print(restaurantes)
cultural = cultural_chain.invoke({
"cidade": cidade.cidade,
"interesse": interesse
})
print("\n=== CULTURAL ===")
print(cultural)
# CHAT COM HISTÓRICO
print("\n=== CHAT COM HISTÓRICO ===")
conversa = "usuario1"
pergunta1 = "Quero viajar para uma cidade histórica."
resposta1 = conversar(conversa, pergunta1)
print("\nPergunta:", pergunta1)
print("Resposta:", resposta1)
pergunta2 = "Qual cidade brasileira você recomenda?"
resposta2 = conversar(conversa, pergunta2)
print("\nPergunta:", pergunta2)
print("Resposta:", resposta2)
pergunta3 = "E quais atrações culturais existem lá?"
resposta3 = conversar(conversa, pergunta3)
print("\nPergunta:", pergunta3)
print("Resposta:", resposta3)
# PROCESSAMENTO EM LOTE
print("\n=== PERGUNTAS EM LOTE ===")
perguntas = [
{
"historico": [],
"pergunta": "Qual cidade brasileira é famosa por suas praias?"
},
{
"historico": [],
"pergunta": "Qual cidade brasileira é famosa pela arquitetura colonial?"
},
{
"historico": [],
"pergunta": "Qual cidade brasileira é conhecida pela cultura nordestina?"
}
]
respostas = chat_chain.batch(perguntas)
for i, resposta in enumerate(respostas, 1):
print(f"\nPergunta {i}:")
print(resposta)