Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

0
respostas

[Projeto] Minha implementação (usando ainda o Llama 8b)

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)