Programa
Com o lançamento do GPT-5, a OpenAI expandiu a chamada de ferramentas/funções na API para incluir chamadas de ferramentas de formato livre (texto bruto, sem JSON), restrições gramaticais via Lark/CFG, listas de permissões de ferramentas e raciocínio aprimorado sobre o uso de ferramentas. Juntos, esses recursos fazem do GPT-5 um modelo realmente ágil; você pode conectar APIs, bancos de dados e ferramentas personalizadas à API Responses e gerar respostas fundamentadas ou até mesmo automatizar fluxos de trabalho.
Neste tutorial, vou falar sobre ferramentas de funçãoe ferramentas personalizadas, restrições gramaticais, listas de permissões de ferramentase preâmbulos, com exemplos de código e explicações claras sobre como funcionam e quando usá-los.
Chamada de função no GPT-5: O quê e por quê
A chamada de funções no GPT-5 permite que você melhore o modelo com os dados e ações do seu aplicativo. O modelo pode decidir quando usar uma ferramenta, enquanto você cuida da lógica e devolve os resultados para uma resposta final e fundamentada.
Tipos de chamadas de função:
- Ferramentas de função (esquema JSON): Eles oferecem entradas e saídas estruturadas que o modelo pode chamar com precisão.
- Ferramentas personalizadas (forma livre): Eles oferecem entradas e saídas de texto flexíveis para integrações não estruturadas.
O que é chamada de função?
O GPT-5 dá suporte tanto a ferramentas de função estruturadas (usando JSON Schema) quanto a ferramentas personalizadas que aceitam cargas de texto de formato livre (como SQL, scripts ou configurações) para integração perfeita com tempos de execução externos.
As ferramentas de função são definidas pelo JSON Schema, garantindo que o modelo entenda exatamente quais argumentos passar e permitindo uma validação rigorosa da entrada. Você pode ler mais em nosso tutorial sobre tutorial sobre chamadas de função OpenAI.
Por que usar chamadas de função?
- Flexibilidade: As ferramentas de formato livre permitem que o modelo produza o texto exato que seu sistema precisa, sem as limitações do JSON rígido, tornando-as ideais para códigos, consultas ou configurações.
- Confiabilidade e controle: As ferramentas de função fazem com que os argumentos sejam estruturados, o que melhora a previsibilidade e reduz os erros de análise.
- Fluxos de trabalho de agentes: O GPT-5 foi feito pra tarefas complexas de codificação e uso de ferramentas com várias etapas, fazendo da chamada de ferramentas uma característica principal.
Como funciona a chamada de função?
- Manda um prompt que inclua todas as ferramentas disponíveis.
- O modelo faz uma chamada de ferramenta (com argumentos ou texto livre).
- Seu aplicativo executa a ferramenta (executa a função Python).
- Manda a saída da ferramenta de volta pro modelo.
- O modelo então responde ou pode chamar ferramentas adicionais.

Fonte: Chamada de função - API OpenAI
Quando usar Função vs. Ferramentas personalizadas
- Use ferramentas de função quando quiser uma validação rigorosa e argumentos digitados previsíveis por meio do JSON Schema.
- Use ferramentas personalizadas (forma livre) quando seu tempo de execução precisar de texto bruto (como scripts, SQL ou configurações) ou quando você precisar de iterações rápidas sem esquemas.
Ferramentas de função (esquema JSON): Enviar dados estruturados
Usar as Ferramentas de Função com o Esquema JSON permite que você obtenha resultados previsíveis e estruturados a partir do modelo. O modelo avalia as ferramentas que você declarou, decide quando usar uma, sugere argumentos validados em JSON e, então, executa a função correspondente no seu código.
Depois disso, você pode pedir ao modelo para gerar uma resposta só com base nos dados que a ferramenta devolveu, garantindo que o resultado seja fundamentado, legível por máquina e fácil de integrar.
Esse exemplo mostra vários conceitos importantes:
- Descoberta de ferramentas e geração de argumentos: O modelo escolhe a ferramenta certa e preenche automaticamente seus argumentos do tipo JSON.
- Ciclo de execução da ferramenta: Seu aplicativo executa as ferramentas solicitadas e manda os resultados de volta para o modelo.
- Resposta final em forma de esquema: A resposta final é baseada estritamente nos resultados das ferramentas, o que minimiza imprecisões e garante a confiabilidade.
1. Configurando
- Crie uma conta OpenAI e gere uma chave API no painel da plataforma. No painel, abra a seção API, depois “Exibir chaves API” e clique em “Criar nova chave secreta”.
- Adicione um método de pagamento ou créditos à sua conta para que as chamadas de API possam ser executadas; o uso é deduzido do seu saldo pré-pago à medida que você faz solicitações.
- Salve sua chave API como uma variável de ambiente chamada OPENAI_API_KEY antes de iniciar seu aplicativo.
- Instale o SDK oficial do OpenAI Python com
pip install openai.
2. Defina ferramentas
Você fornece uma lista de ferramentas com um nome, descrição e esquema JSON para os parâmetros. O esquema ajuda o modelo a fornecer argumentos bem formados.
make_coffeeespera um parâmetro de string:coffee_type.random_coffee_factnão aceita parâmetros (objeto vazio). Essas definições são passadas por meio de um argumentotoolsna chamada da API para que o modelo saiba o que está disponível.
import os
from openai import OpenAI
import json
client = OpenAI(api_key = os.environ["OPENAI_API_KEY"])
tools = [
{
"type": "function",
"name": "make_coffee",
"description": "Gives a simple recipe for making a coffee drink.",
"parameters": {
"type": "object",
"properties": {
"coffee_type": {
"type": "string",
"description": "The coffee drink, e.g. espresso, cappuccino, latte"
}
},
"required": ["coffee_type"],
},
},
{
"type": "function",
"name": "random_coffee_fact",
"description": "Returns a fun fact about coffee.",
"parameters": {"type": "object","properties":{}}
}
]
3. Implementar ferramentas
Você implementa as funções Python que realmente fazem o trabalho:
make_coffee(coffee_type)retorna uma string concisa com a receita, identificada pela bebida solicitada.random_coffee_fact()retorna uma pequena carga útil de fatos.
Ambos retornam dicionários serializáveis em JSON, ideais para alimentar o modelo.
def make_coffee(coffee_type):
recipes = {
"espresso": "Grind fine, 18g coffee → 36g espresso in ~28s.",
"cappuccino": "Brew 1 espresso shot, steam 150ml milk, pour and top with foam.",
"latte": "Brew 1 espresso shot, steam 250ml milk, pour for silky texture.",
}
return {"coffee_type": coffee_type, "recipe": recipes.get(coffee_type.lower(), "Unknown coffee type!")}
def random_coffee_fact():
return {"fact": "Coffee is the second most traded commodity in the world, after oil."}
4. Comece uma conversa
Comece a conversa com a pergunta do usuário: {"role": "user", "content": "How do I make a latte?"}
O modelo pode retornar mensagens que incluem um item function_call, como make_coffee com {"coffee_type":"latte"}. Depois, você deve adicionar as mensagens do modelo de volta em input_list: input_list += response.output. Isso ajuda a manter o estado da conversa para a próxima rodada.
# Track used tools
used_tools = []
input_list = [{"role": "user", "content": "How do I make a latte?"}]
response = client.responses.create(
model="gpt-5",
tools=tools,
input=input_list,
)
input_list += response.output
5. Executar chamadas de ferramentas e anexar resultados
Você deve iterar sobre response.output e identificar os itens em que item.type é igual a "function_call". Para esses itens, analise item.arguments e envie as solicitações para suas funções Python.
Para a função ` make_coffee `, chame-a usando ` make_coffee(args["coffee_type"])`. Para a função random_coffee_fact, basta chamar random_coffee_fact().
Depois de executar as funções, acrescente uma mensagem “ function_call_output ” que inclua o seguinte:
call_id(que liga essa saída à solicitação do modelo)output(uma string JSON do resultado da sua função).
for item in response.output:
if getattr(item, "type", "") == "function_call":
used_tools.append(item.name)
args = json.loads(item.arguments or "{}")
if item.name == "make_coffee":
result = make_coffee(args["coffee_type"])
elif item.name == "random_coffee_fact":
result = random_coffee_fact()
else:
result = {"error": f"Unknown tool {item.name}"}
input_list.append({
"type": "function_call_output",
"call_id": item.call_id,
"output": json.dumps(result)
})
6. Gerar a resposta final
Você faz uma segunda chamada client.responses.create, passando o input_list atualizado, que agora inclui os resultados da ferramenta.
A variável ` used_tools ` pega os nomes das ferramentas que apareceram nas chamadas de função do modelo. Vamos usar isso pra mostrar quais ferramentas foram usadas.
final = client.responses.create(
model="gpt-5",
tools=tools,
input=input_list,
instructions="Answer using only the tool results."
)
print("Final output:\n", final.output_text)
print("\n--- Tool Usage ---")
for t in tools:
status = "USED ✅" if t["name"] in used_tools else "NOT USED ❌"
print(f"{t['name']}: {status}")
Como o usuário perguntou sobre um café com leite, o modelo escolheu make_coffee com coffee_type = "latte", seu código executou isso e a resposta final foi criada só a partir do resultado dessa ferramenta.
Final output:
{"coffee_type":"latte","recipe":"Brew 1 espresso shot, steam 250ml milk, pour for silky texture."}
--- Tool Usage ---
make_coffee: USED ✅
random_coffee_fact: NOT USED ❌
Ferramentas personalizadas (forma livre): Enviar texto bruto
Use as ferramentas personalizadas de formato livre do GPT-5 para permitir que o modelo envie texto bruto diretamente para sua ferramenta, como código, SQL, comandos shell ou CSV simples, sem precisar de JSON Schema.
Essa capacidade vai além das antigas chamadas de função só em JSON, dando a você mais flexibilidade pra integração com executores, mecanismos de consulta ou interpretadores de linguagem específica de domínio (DSL).
No modo de formato livre, o modelo gera uma chamada de ferramenta personalizada com uma carga útil de texto não estruturado que você pode encaminhar para o seu tempo de execução. Em seguida, você retorna o resultado para o modelo usar na finalização da resposta apresentada ao usuário.
Agora vamos escrever o código que permite ao modelo escolher as ferramentas certas e devolver texto bruto não estruturado como resultado. Essa saída vai ser passada para uma função Python para gerar um resultado. Assim, o usuário pode colocar os ingredientes que tem, e o modelo vai criar receitas que são perfeitas para o que ele precisa.
Neste código de exemplo, temos:
- Inicializei o cliente OpenAI e criei uma ferramenta personalizada chamada
meal_plannerque aceita texto bruto como entrada. - Criei o Python
plan_mealque pega uma sequência de ingredientes separados por vírgulas e dá uma ideia de refeição. - Comecei a conversa com uma mensagem de usuário listando os ingredientes disponíveis.
- Fiz uma chamada inicial ao modelo instruindo o GPT-5 a usar a ferramenta só com uma lista limpa de ingredientes e coloquei o resultado do modelo no histórico de conversas.
- Localizei a chamada da ferramenta personalizada emitida e extraí a string de entrada bruta separada por vírgulas.
- Executei a ferramenta passando a lista para
plan_meale, em seguida, enviei o resultado de volta para o modelo como umfunction_call_outputvinculado viacall_id. - Fiz uma chamada final ao modelo para transformar a ideia inicial da ferramenta numa receita concisa e passo a passo, e imprimi os detalhes da chamada à ferramenta e o resultado final.
from openai import OpenAI
import json
import random
client = OpenAI()
# --- Custom tool ---
tools = [
{
"type": "custom",
"name": "meal_planner",
"description": "Takes ONLY a comma-separated list of ingredients and suggests a meal idea."
}
]
# --- Fake meal planner ---
def plan_meal(ingredients: str) -> str:
ideas = [
f"Stir-fry: {ingredients} with garlic & soy sauce.",
f"One-pot rice: cook {ingredients} together in broth until fluffy.",
f"Soup: simmer {ingredients} in stock with herbs.",
f"Sheet-pan bake: roast {ingredients} at 200°C for ~20 min."
]
return random.choice(ideas)
# --- Start conversation ---
messages = [
{"role": "user", "content": "I only have chicken, rice, and broccoli. Any dinner ideas?"}
]
# 1) Ask model with clear instruction
resp = client.responses.create(
model="gpt-5",
tools=tools,
input=messages,
instructions="If the user mentions ingredients, call the meal_planner tool with ONLY a comma-separated list like 'chicken, rice, broccoli'."
)
messages += resp.output
# 2) Find the tool call
tool_call = next((x for x in resp.output if getattr(x, "type", "") == "custom_tool_call"), None)
assert tool_call, "No tool call found!"
# Get clean CSV input
ingredients_csv = tool_call.input.strip()
# 3) Run the tool
meal_result = plan_meal(ingredients_csv)
# 4) Send tool output back
messages.append({
"type": "function_call_output",
"call_id": tool_call.call_id,
"output": meal_result
})
# 5) Final model response
final = client.responses.create(
model="gpt-5",
tools=tools,
input=messages,
instructions="Turn the meal idea into a short recipe with 3-4 steps."
)
print("\n--- Tool Call ---")
print("Name:", tool_call.name)
print("Input:", ingredients_csv)
print("Output:", meal_result)
print("\n--- Final Output ---\n", final.output_text)
Como resultado, recebemos estatísticas sobre as ferramentas utilizadas, incluindo instalação, entrada e saída. Além disso, o resultado final traz uma receita completa sobre como preparar a refeição.
--- Tool Call ---
Name: meal_planner
Input: chicken, rice, broccoli
Output: One-pot rice: cook chicken, rice, broccoli together in broth until fluffy.
--- Final Output ---
One-Pot Chicken, Rice & Broccoli
- Season bite-size chicken pieces with salt and pepper; sear in a little oil in a pot until lightly browned.
- Add 1 cup rinsed rice and 2 cups broth (or water + salt). Bring to a boil, then cover and simmer on low for 12 minutes.
- Scatter 2 cups small broccoli florets on top, cover, and cook 5-7 more minutes until rice is fluffy and broccoli is tender.
- Rest 5 minutes off heat, fluff, and adjust seasoning. Optional: stir in a knob of butter or a splash of soy.
Restrições gramaticais (Lark): Limitar saídas da ferramenta
O GPT-5 agora suporta gramática livre de contexto (CFG) para garantir que os formatos de saída sejam rigorosamente controlados.
Ao aplicar uma gramática, como SQL ou uma linguagem específica de domínio (DSL), às suas respostas, o GPT-5 garante que os resultados sigam sempre a estrutura necessária. O CFG é especialmente importante para processos automatizados e fluxos de trabalho de alto risco.
O GPT-5 pode usar gramáticas definidas em formatos como Lark para limitar as saídas da ferramenta durante a geração. Essa abordagem de decodificação restrita aumenta a confiabilidade, evitando desvios de formato e garantindo a consistência estrutural.
Agora vamos escrever o código em que o modelo escolhe uma ferramenta e gera APENAS uma expressão aritmética gramaticalmente válida; essa expressão é então avaliada em Python, o resultado é devolvido à conversa e a resposta final é apresentada de forma clara em linguagem natural.
Neste código de exemplo, temos:
- Inicializei o cliente OpenAI e criei uma ferramenta personalizada
math_solverque só pode gerar expressões aritméticas com gramática válida (Lark CFG). - Comecei a conversa com uma pergunta matemática em linguagem natural do usuário.
- Fiz uma primeira chamada de modelo instruindo o GPT-5 a chamar
math_solvercom uma expressão que segue a gramática. - Localizei a chamada da ferramenta emitida e extraí a string da expressão bruta da carga útil da ferramenta.
- A gente avaliou a expressão localmente num ambiente restrito pra chegar num resultado concreto.
- Devolvi o resultado da execução da ferramenta para a conversa, conectado pelo link original
call_id. - Fiz uma chamada final ao modelo para apresentar o resultado avaliado de forma clara em linguagem natural.
from openai import OpenAI
import json
client = OpenAI()
# --- Local fake evaluator ---
def eval_expression(expr: str) -> str:
try:
# Evaluate safely using Python's eval on restricted globals
result = eval(expr, {"__builtins__": {}}, {})
return f"{expr} = {result}"
except Exception as e:
return f"Error evaluating expression: {e}"
# --- Custom tool with grammar constraint ---
tools = [
{
"type": "custom",
"name": "math_solver",
"description": "Solve a math problem by outputting ONLY a valid arithmetic expression.",
"format": {
"type": "grammar",
"syntax": "lark",
"definition": r"""
start: expr
?expr: term
| expr "+" term -> add
| expr "-" term -> sub
?term: factor
| term "*" factor -> mul
| term "/" factor -> div
?factor: NUMBER
| "(" expr ")"
%import common.NUMBER
%ignore " "
"""
},
}
]
# --- User asks ---
msgs = [
{"role": "user", "content": "What is (12 + 8) * 3 minus 5 divided by 5?"}
]
# 1) First model call: GPT-5 must emit a grammar-valid expression
resp = client.responses.create(
model="gpt-5",
tools=tools,
input=msgs,
instructions="Always call the math_solver tool with a grammar-valid arithmetic expression like '(12 + 8) * 3 - 5 / 5'."
)
msgs += resp.output
tool_call = next(
x for x in resp.output
if getattr(x, "type", "") in ("custom_tool_call", "tool_call", "function_call")
)
expr = getattr(tool_call, "input", "") or getattr(tool_call, "arguments", "")
print("\n=== Grammar-Constrained Expression ===")
print(expr)
# 2) Run the local evaluator
tool_result = eval_expression(expr)
print("\n=== Tool Execution Result ===")
print(tool_result)
# 3) Return tool output
msgs.append({
"type": "function_call_output",
"call_id": tool_call.call_id,
"output": tool_result
})
# 4) Final pass: GPT-5 presents answer nicely
final = client.responses.create(
model="gpt-5",
input=msgs,
tools=tools,
instructions="Present the evaluated result clearly in natural language."
)
print("\n=== Final Output ===")
print(final.output_text)
Como você pode ver, o modelo selecionou a ferramenta e, em seguida, gerou uma expressão com restrições gramaticais. Depois disso, passa pela função Python para gerar a resposta. No final, temos uma resposta adequada em linguagem natural.
=== Grammar-Constrained Expression ===
(12 + 8) * 3 - 5 / 5
=== Tool Execution Result ===
(12 + 8) * 3 - 5 / 5 = 59.0
=== Final Output ===
59
Listas de ferramentas permitidas: Limite com segurança o que o modelo pode usar
A configuração “ allowed_tools ” (Selecionar ferramentas) permite restringir o modelo a uma seleção segura de ferramentas do seu kit completo de ferramentas. Isso melhora a previsibilidade e evita chamadas de ferramentas não intencionais, ao mesmo tempo em que ainda dá flexibilidade ao modelo dentro do conjunto permitido.
Você pode deixar o modelo escolher entre as ferramentas permitidas ou exigir que ele use uma, refletindo os comportamentos de “ferramenta forçada” vistos em outras pilhas e alinhando-se às melhores práticas gerais para orquestração de chamada de ferramentas.
Agora vamos escrever o código onde permitimos uma única ferramenta, fazemos com que o modelo chame só essa ferramenta, a executa, alimenta os resultados de volta e, em seguida, produz um resumo conciso voltado para o usuário.
Observação: Crie uma conta gratuita no Firecrawl, crie uma conta gratuita, gere uma chave API, salve-a como uma variável de ambiente FIRECRAWL_API_KEY e instale o SDK Python do Firecrawl usando pip install firecrawl-py.
Neste código de exemplo, temos:
- Defini um conjunto completo de ferramentas com
dummy_web_searchefirecrawl_search. - Limitou o modelo a
firecrawl_searchapenas através detool_choice = { type: "allowed_tools", mode: "required", tools: [...] }. - Emitiu a primeira chamada de modelo, capturou o nome da chamada da ferramenta e os argumentos e os imprimiu para visibilidade.
- Quando
firecrawl_searché chamado, os argumentos são deserializados, o Firecrawl é executado, a resposta é convertida em um dicionário serializável em JSON e os dados seguros são extraídos. - Alimentei os resultados da ferramenta de volta para a conversa usando
function_call_outputvinculado porcall_ide, em seguida, fiz uma chamada final ao modelo para resumir em 3–4 pontos com links Markdown. - Incluí uma ramificação alternativa que executaria a ferramenta fictícia (embora a lista de permissões impeça isso nesta execução).
- Imprimiu a resposta final em linguagem natural.
from openai import OpenAI
from firecrawl import Firecrawl
import json
import os
client = OpenAI()
firecrawl = Firecrawl(api_key=os.environ["FIRECRAWL_API_KEY"])
# --- Full toolset ---
tools = [
{
"type": "function",
"name": "dummy_web_search",
"description": "A fake web search that always returns static dummy results.",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string"},
"limit": {"type": "integer"}
},
"required": ["query"]
},
},
{
"type": "function",
"name": "firecrawl_search",
"description": "Perform a real web search using Firecrawl.",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string"},
"limit": {"type": "integer"}
},
"required": ["query"]
},
},
]
# --- Dummy implementation ---
def dummy_web_search(query, limit=3):
return {
"query": query,
"results": [f"[Dummy] Result {i+1} for '{query}'" for i in range(limit)]
}
# --- User asks ---
messages = [
{"role": "user", "content": "Find me the latest info about the stock market."}
]
# --- Restrict to Firecrawl only ---
resp = client.responses.create(
model="gpt-5",
tools=tools,
input=messages,
instructions="Only the firecrawl_search tool is allowed. Do not use dummy_web_search.",
tool_choice={
"type": "allowed_tools",
"mode": "required", # force Firecrawl
"tools": [{"type": "function", "name": "firecrawl_search"}],
},
)
for item in resp.output:
if getattr(item, "type", "") in ("function_call", "tool_call"):
print("\n--- Tool Call ---")
print("Tool name:", item.name)
print("Arguments:", item.arguments)
if item.name == "firecrawl_search":
args = json.loads(item.arguments)
# Firecrawl returns a SearchData object → convert it
results_obj = firecrawl.search(
query=args["query"],
limit=args.get("limit", 3),
)
# 🔥 Convert to JSON-serializable dict
if hasattr(results_obj, "to_dict"):
results = results_obj.to_dict()
elif hasattr(results_obj, "dict"):
results = results_obj.dict()
else:
results = json.loads(results_obj.json()) if hasattr(results_obj, "json") else results_obj
print("\n--- Firecrawl Raw Results ---")
print(json.dumps(results, indent=2)[:500])
# ✅ Extract only the data portion for summarization
safe_results = results.get("data", results)
# Feed back to GPT
messages += resp.output
messages.append({
"type": "function_call_output",
"call_id": item.call_id,
"output": json.dumps(safe_results) # now safe
})
# Final pass
final = client.responses.create(
model="gpt-5",
tools=tools,
input=messages,
instructions="Summarize the Firecrawl search results into 3-4 bullet points with clickable [Title](URL) links."
)
print("\n--- Final Natural Language Answer ---")
print(final.output_text)
elif item.name == "dummy_web_search":
args = json.loads(item.arguments)
results = dummy_web_search(args["query"], args.get("limit", 3))
print("\n--- Dummy Web Search Results ---")
print(json.dumps(results, indent=2))
Ele escolheu a pesquisa Firecrawl e, usando isso, gerou a resposta final no formato markdown.

Preâmbulos: Diga ao modelo como chamar as ferramentas
Preâmbulos são explicações curtas que o modelo cria antes de usar uma ferramenta, deixando claro o motivo da chamada. Eles aumentam a transparência, criam confiança nos usuários e melhoram a clareza da depuração em fluxos de trabalho complexos. Você pode ativá-los usando uma instrução simples como “explique antes de chamar uma ferramenta”, normalmente sem adicionar latência perceptível.
Agora vamos escrever o código em que o modelo primeiro gera uma breve linha “Preâmbulo:” explicando por que está chamando uma ferramenta, depois chama a ferramenta, você a executa localmente, retorna o resultado e o modelo produz uma resposta final clara.
Neste código de exemplo, temos:
- Inicializei o cliente OpenAI e defini uma ferramenta de função de tipo estrito (
medical_advice) com JSON Schema. - Adicionada uma instrução do sistema dizendo ao modelo para gerar uma linha de “
“Preamble:”” antes de qualquer chamada de ferramenta. - Comece a conversa perguntando ao usuário sobre os sintomas dele.
- Fiz a primeira chamada ao modelo para pegar tanto o preâmbulo quanto a chamada à ferramenta com seus argumentos.
- Extraímos e executamos a ferramenta localmente para gerar recomendações.
- Devolvi a saída da ferramenta para o modelo, conectada por meio de
call_id. - Fiz uma chamada final ao modelo para que o GPT-5 mostrasse o resultado como uma resposta direta e fácil de entender.
from openai import OpenAI
import json
import random
client = OpenAI()
# --- Fake tool implementation ---
def medical_advice(symptom: str):
remedies = {
"headache": "You can take acetaminophen (paracetamol) or ibuprofen, rest in a quiet room, and stay hydrated.",
"cough": "Drink warm fluids, use honey in tea, and consider over-the-counter cough syrup.",
"fever": "Use acetaminophen to reduce fever, stay hydrated, and rest. See a doctor if >39°C.",
}
return {"advice": remedies.get(symptom.lower(), "Please consult a healthcare provider for guidance.")}
# --- Tool definition ---
tools = [{
"type": "function",
"name": "medical_advice",
"description": "Provide safe, general over-the-counter advice for common symptoms.",
"parameters": {
"type": "object",
"properties": {"symptom": {"type": "string"}},
"required": ["symptom"],
"additionalProperties": False
},
"strict": True,
}]
# --- Messages (system preamble instruction) ---
messages = [
{"role": "system", "content": "Before you call a tool, explain why you are calling it in ONE short sentence prefixed with 'Preamble:'."},
{"role": "user", "content": "What should I take for a headache?"}
]
# 1) First call: expect preamble + tool call
resp = client.responses.create(model="gpt-5", input=messages, tools=tools)
print("=== First Response ===")
for item in resp.output:
t = getattr(item, "type", None)
if t == "message":
# Extract just the model's text
content = getattr(item, "content", None)
text = None
if isinstance(content, list):
text = "".join([c.text for c in content if hasattr(c, "text")])
elif content:
text = str(content)
if text:
# ✅ Only print once
print(text)
if t in ("function_call", "tool_call", "custom_tool_call"):
print("Tool:", getattr(item, "name", None))
print("Args:", getattr(item, "arguments", None))
# Extract tool call
tool_call = next(x for x in resp.output if getattr(x, "type", None) in ("function_call","tool_call","custom_tool_call"))
messages += resp.output
# 2) Execute tool locally
args = json.loads(getattr(tool_call, "arguments", "{}"))
symptom = args.get("symptom", "")
tool_result = medical_advice(symptom)
# 3) Return tool result
messages.append({
"type": "function_call_output",
"call_id": tool_call.call_id,
"output": json.dumps(tool_result)
})
# 4) Final model call → natural answer
final = client.responses.create(model="gpt-5", input=messages, tools=tools)
print("\n=== Final Answer ===")
print(final.output_text)
Você pode ver que, antes de chamar a ferramenta, ela explica por que está chamando a ferramenta. Isso é bom para observabilidade e depuração.

Resumo
O GPT-5 é o modelo mais avançado da OpenAI até agora, sendo especialmente bom em programação e fluxos de trabalho baseados em agentes. Seus recursos API mais recentes permitem o desenvolvimento direto de sistemas de nível de produção do início ao fim.
Neste tutorial, você aprendeu como:
- Retorne resultados estruturados usando Ferramentas de Função e Esquema JSON para uma automação confiável a jusante.
- Habilite a execução de formato livre com as Ferramentas Personalizadas (texto bruto), permitindo que o modelo gere código, SQL, scripts shell e arquivos CSV além de apenas chamadas JSON.
- Formatos restritos usando restrições gramaticais do Lark quando a precisão é importante, como em matemática, SQL ou linguagens específicas de domínio (DSLs).
- Limite o acesso às ferramentas com listas de permissões (ou impondo o uso de uma única ferramenta) para aumentar a segurança, o controle e o determinismo.
- Melhore a transparência com breves preâmbulos, para que o modelo explique por que está chamando uma ferramenta específica, auxiliando na observabilidade e na depuração.
Pra saber mais sobre o que você pode fazer com as várias ferramentas da OpenAI, recomendo fazer nosso curso de habilidades OpenAI Fundamentals. curso básico sobre a OpenAI e o o curso Trabalhando com a API da OpenAI.

Sou um cientista de dados certificado que gosta de criar aplicativos de aprendizado de máquina e escrever blogs sobre ciência de dados. No momento, estou me concentrando na criação e edição de conteúdo e no trabalho com modelos de linguagem de grande porte.



