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

[Sugestão] Se estiver usando com ollama e modelos recentes um alteração no código da aula resolve erros

No curso LangChain e Python: criando ferramentas com a OpenAI
aula: Orquestrando assistentes sem LangGraph

Quando esta usando ollama com a interface openai e typedict ou pydantic precisa fazer um ajuste numa instrução para informar que o roteador é um tool_calling

roteador = prompt_roteador | modelo.with_structured_output(Rota, method="function_calling")

import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.output_parsers import StrOutputParser

from typing import Literal, TypedDict

#para garantira que o destino seja sempre uma das opções especificadas
#isso aqui poderia ser substituido por pydantic
class Rota(TypedDict):
    destino: Literal["praia","montanha"]

def responda(pergunta: str):
    rota = roteador.invoke({"query": pergunta})["destino"]

    if rota == "praia":
        return cadeia_praia.invoke({"query": pergunta})
    return cadeia_montanha.invoke({"query": pergunta})

# Carrega as variáveis de ambiente do arquivo .env
load_dotenv()  

# O Ollama utiliza a base_url para se conectar ao serviço
OLLAMA_HOST = os.getenv("OLLAMA_BASE_URL", "http://localhost:11434/v1")
OLLAMA_API_KEY =  os.getenv("OLLAMA_API_KEY")
OLLAMA_MODEL_IN_USE = os.getenv("OLLAMA_MODEL_IN_USE")

# padrao OPENAI com OLLAMA
# Inicialização do modelo usando interface openAI inves de ollama
modelo = ChatOpenAI(
    model=OLLAMA_MODEL_IN_USE,
    openai_api_base=OLLAMA_HOST , # <--- O padrão OpenAI
    openai_api_key=OLLAMA_API_KEY, # O Ollama aceita qualquer texto como chave aqui
    temperature=0.5
)

# Prompt Consultor 1
prompt_consultor_praia = ChatPromptTemplate.from_messages(
    [
        ("system", "Apresente-se como Sra. Praias. Você é uma especialista em viagens com destinos para praias."),
        ("human", "{query}")
    ]
)

# Prompt Consultor 2
prompt_consultor_montanha = ChatPromptTemplate.from_messages(
    [
        ("system", "Apresente-se como Sra. High Mountain. Você é uma especialista em viagens destinos para montanhas e atividades radicais."),
        ("human", "{query}")
    ]
)

#configurando o prompt roteador pra decidir qual cadeia usar
#a cadeia recebe a pergunta do usuário e decidira para qual consultor irá praia ou montanha
prompt_roteador = ChatPromptTemplate.from_messages(
    [
        ("system", "Responda apenas com 'praia' ou 'montanha'"),
        ("human", "{query}")
    ]
)

#definindo o roteador
# Força o Gemma 4 a usar a estrutura de ferramentas/JSON do Pydantic
roteador = prompt_roteador | modelo.with_structured_output(Rota, method="function_calling")


#criando chains especificas para cada consultor
cadeia_praia    = prompt_consultor_praia | modelo | StrOutputParser()
cadeia_montanha = prompt_consultor_montanha | modelo | StrOutputParser()

print(responda("quero surfar em um lugar quente."))