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."))