Esta función es elegible para Zero Data Retention (ZDR). Cuando tu organización tiene un acuerdo de ZDR, los datos enviados a través de esta función no se almacenan después de que se devuelve la respuesta de la API.
El "fine-grained tool streaming" (streaming detallado de herramientas) entrega la entrada de una herramienta a tu cliente a medida que Claude la genera, sin almacenamiento en búfer del lado del servidor ni validación de JSON. Omitir el paso de almacenamiento en búfer reduce el tiempo hasta el primer fragmento de un parámetro grande, como un documento o un bloque de código, y los fragmentos llegan a través de los mismos eventos de Streaming de mensajes que el uso de herramientas estándar.
Debido a que la API no almacena en búfer ni valida la entrada de una herramienta antes de transmitirla, podrías recibir JSON parcial o inválido. Una respuesta que termina con el stop reason max_tokens también puede cortar un parámetro a la mitad. Acumula los fragmentos, protege el análisis sintáctico y consulta Manejo de JSON inválido en respuestas de herramientas para saber cómo devolver a Claude una entrada que no se puede analizar.
Todos los modelos admiten el streaming detallado de herramientas en la API de Claude, Claude Platform en AWS, Amazon Bedrock, Google Cloud y Microsoft Foundry. Para usarlo, establece eager_input_streaming en true en cualquier herramienta definida por el usuario donde quieras habilitar el streaming detallado, y habilita el streaming en tu solicitud.
El campo eager_input_streaming es opcional. Establecerlo en true activa el streaming detallado para esa herramienta, y omitirlo te da el streaming con búfer estándar, en el cual la API almacena en búfer y valida cada valor de parámetro antes de transmitirlo de vuelta. La excepción es una solicitud que aún envía el encabezado beta heredado fine-grained-tool-streaming-2025-05-14, el cual activa el streaming detallado para las herramientas que dejan el campo sin establecer. El campo por herramienta reemplaza ese encabezado, y un false explícito mantiene el streaming con búfer para una herramienta incluso cuando una solicitud aún lo envía. Consulta la Referencia de herramientas para la definición del campo.
El siguiente ejemplo activa el streaming detallado para una herramienta make_file y le pide a Claude un poema largo, de modo que la entrada de la herramienta sea lo suficientemente grande como para verla transmitirse:
client = anthropic.Anthropic()
with client.messages.stream(
max_tokens=65536,
model="claude-opus-4-8",
tools=[
{
"name": "make_file",
"description": "Write text to a file",
"eager_input_streaming": True,
"input_schema": {
"type": "object",
"properties": {
"filename": {
"type": "string",
"description": "The filename to write text to",
},
"lines_of_text": {
"type": "array",
"description": "An array of lines of text to write to the file",
},
},
"required": ["filename", "lines_of_text"],
},
}
],
messages=[
{
"role": "user",
"content": "Can you write a long poem and make a file called poem.txt?",
}
],
) as stream:
for event in stream:
if event.type == "input_json":
print(event.partial_json, end="", flush=True)
final_message = stream.get_final_message()
print()
for block in final_message.content:
if block.type == "tool_use":
print(f"Complete tool input: {block.input}")Cada pestaña activa el streaming detallado para la herramienta make_file. Las pestañas de SDK imprimen cada fragmento de entrada en el momento en que llega, y luego imprimen la entrada acumulada completa una vez que el stream termina. La pestaña de cURL muestra el stream de eventos sin procesar, y la pestaña de CLI usa jq para imprimir solo los fragmentos. Debido a que los fragmentos impresos se unen para formar la entrada completa de la herramienta, el poema llena tu terminal a medida que Claude lo escribe:
{"filename": "poem.txt", "lines_of_text": ["The Wanderer's Journey", "", "I.", "", "Beneath the vast and star-strewn sky,", "Where silver moonbeams softly lie,", ...
Complete tool input: {"filename": "poem.txt", "lines_of_text": ["The Wanderer's Journey", ...]}Sin eager_input_streaming, la API almacena en búfer y valida cada valor de parámetro antes de transmitirlo de vuelta, por lo que no se imprime nada para un parámetro grande hasta que Claude haya terminado de generarlo. Con él, los fragmentos comienzan a llegar tan pronto como Claude inicia el parámetro, y típicamente son más largos, con menos cortes a mitad de palabra.
El contrato de acumulación es el mismo que para el streaming estándar de uso de herramientas, por lo que esta sección aplica con y sin eager_input_streaming. Consulta Input JSON delta en Streaming de mensajes para el formato de evento. El streaming detallado de herramientas cambia lo que puedes asumir sobre el resultado: el servidor transmite fragmentos sin validarlos, por lo que la cadena acumulada podría no ser JSON válido.
Cuando un bloque de contenido tool_use se transmite, el evento inicial content_block_start contiene input: {} (un objeto vacío). Esto es un marcador de posición. La entrada real llega como una serie de eventos input_json_delta, cada uno con un fragmento de cadena partial_json. Para ensamblar la entrada completa, concatena estos fragmentos y analiza el resultado cuando el bloque se cierre.
Cuando tu SDK proporciona un helper acumulador (como lo hacen las pestañas de Python, TypeScript, Go, Java y Ruby en el ejemplo anterior), este lo maneja por ti. El patrón manual es para SDKs sin un helper, o cuando quieres control total sobre cómo se ensambla la entrada.
El contrato de acumulación:
content_block_start con type: "tool_use", inicializa una cadena vacía: input_json = ""content_block_delta con type: "input_json_delta", agrega: input_json += event.delta.partial_jsoncontent_block_stop, analiza la cadena acumuladaProtege el análisis sintáctico, como lo hacen los siguientes ejemplos de SDK. Una respuesta también puede detenerse en max_tokens a mitad de un parámetro. Verifica el stop reason y decide si reintentar la solicitud con un max_tokens más alto o reparar la entrada parcial.
La discrepancia de tipo entre el input: {} inicial (objeto) y partial_json (cadena) es intencional. El objeto vacío marca la posición en el arreglo de contenido. Las cadenas delta construyen el valor real.
client = anthropic.Anthropic()
tool_inputs: dict[int, str] = {} # index -> accumulated JSON string
with client.messages.stream(
model="claude-opus-4-8",
max_tokens=1024,
tools=[
{
"name": "get_weather",
"description": "Get current weather for a city",
"eager_input_streaming": True,
"input_schema": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
}
],
messages=[{"role": "user", "content": "Weather in Paris?"}],
) as stream:
for event in stream:
match event.type:
case "content_block_start" if event.content_block.type == "tool_use":
tool_inputs[event.index] = ""
case "content_block_delta" if event.delta.type == "input_json_delta":
tool_inputs[event.index] += event.delta.partial_json
case "content_block_stop" if event.index in tool_inputs:
raw_input = tool_inputs[event.index]
try:
parsed = json.loads(raw_input)
except json.JSONDecodeError:
# No se garantiza que la cadena acumulada sea JSON válido.
# Consulta "Handling invalid JSON in tool responses" en esta página.
print(f"Invalid tool input: {raw_input}")
else:
print(f"Tool input: {parsed}")Reaccionar a los fragmentos y ensamblarlos son preocupaciones separadas. El primer ejemplo reacciona a cada fragmento a medida que llega y aun así delega el ensamblaje al SDK en las pestañas que usan un helper acumulador. Usa el patrón manual cuando no estés usando un helper acumulador o cuando quieras control total sobre el ensamblaje.
Con el streaming detallado de herramientas, la entrada acumulada para una llamada de herramienta podría ser JSON inválido o incompleto. Cuando lo es, no puedes ejecutar la herramienta, así que reporta el fallo de vuelta a Claude en su lugar. El content de un resultado de herramienta no tiene que ser JSON, pero envolver la cadena sin procesar en un objeto JSON bajo una sola clave deja claro a Claude sin ambigüedad que recibiste JSON inválido, y preserva la entrada original para depuración:
{
"INVALID_JSON": "<the unparseable input you received>"
}Devuelve el envoltorio, serializado a una cadena, como el content de un bloque de contenido de resultado de herramienta con is_error establecido en true:
{
"type": "tool_result",
"tool_use_id": "toolu_01A09q90qw90lq917835lq9",
"is_error": true,
"content": "{\"INVALID_JSON\": \"<the unparseable input you received>\"}"
}Construye el envoltorio con tu biblioteca de JSON en lugar de concatenar cadenas, para que las comillas y otros caracteres especiales en la entrada inválida se escapen correctamente.
Comprende cómo funciona la ventana de contexto, cómo el pensamiento extendido y el uso de herramientas cuentan para ella, y cómo gestionar el contexto a medida que las conversaciones crecen.
Transmite respuestas de la API de Messages de forma incremental con eventos enviados por el servidor, incluyendo deltas de texto, uso de herramientas y pensamiento extendido.
Analiza bloques tool_use, formatea respuestas tool_result y maneja errores con is_error.
Directorio de herramientas proporcionadas por Anthropic y referencia de propiedades opcionales de definición de herramientas.
Was this page helpful?