POST /v1/messages
Tools are declared with a flat input_schema (no outer type: "function" wrapper). The model returns tool_use content blocks.
tools = [{
"name": "get_weather",
"description": "Get the weather for a city",
"input_schema": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
}]
Full loop
from anthropic import Anthropic
client = Anthropic(base_url="https://api.abliteration.ai", auth_token=os.environ["ABLIT_KEY"])
messages = [{"role": "user", "content": "What's the weather in Lagos?"}]
resp = client.messages.create(
model="abliterated-model",
max_tokens=1024,
tools=tools,
messages=messages,
)
messages.append({"role": "assistant", "content": resp.content})
tool_results = []
for block in resp.content:
if block.type == "tool_use":
result = get_weather(block.input["city"]) # your function
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": str(result),
})
messages.append({"role": "user", "content": tool_results})
final = client.messages.create(
model="abliterated-model",
max_tokens=1024,
tools=tools,
messages=messages,
)
print(final.content[0].text)
Streaming
Stream with stream=True. Tool-use blocks arrive as content_block_start with type: "tool_use", followed by input_json_delta events. stop_reason: "tool_use" signals the turn needs a follow-up with tool_result.
tool_choice={"type": "tool", "name": "get_weather"}
{type: "any"} forces some tool; {type: "auto"} is the default.
Multiple tool_use blocks can appear in the same response. Return one tool_result block per tool_use_id in the next user turn.Last modified on April 21, 2026