Streaming de herramientas de grano fino
Transmite las entradas de herramientas sin almacenamiento en búfer de JSON del lado del servidor para aplicaciones sensibles a la latencia.
El "fine-grained tool streaming" (streaming de herramientas de grano fino) entrega la entrada de una herramienta a tu cliente a medida que Claude la genera, sin almacenamiento en búfer ni validación de JSON del lado del servidor. 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.
Cómo usar el streaming de herramientas de grano fino
Todos los modelos admiten el streaming de herramientas de grano fino en la API de Claude, Amazon Bedrock, Claude Platform en AWS, Google Cloud y Microsoft Foundry. Para usarlo, establece eager_input_streaming en true en cualquier herramienta definida por el usuario en la que quieras habilitar el streaming de grano fino, y habilita el streaming en tu solicitud.
El campo eager_input_streaming es opcional. Establecerlo en true activa el streaming de grano fino para esa herramienta, y omitirlo te da el streaming estándar con búfer, en el que 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 todavía envía el encabezado beta heredado fine-grained-tool-streaming-2025-05-14, que activa el streaming de grano fino 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 todavía lo envía. El encabezado heredado no se puede combinar con una entrada de conjunto de herramientas de uso de computadora o uso de navegador: la API rechaza una solicitud que envía ambos, así que elimina el encabezado y establece eager_input_streaming en las herramientas definidas por el usuario que lo necesiten. Consulta la Referencia de herramientas para ver la definición del campo.
El siguiente ejemplo activa el streaming de grano fino 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 llegar por streaming:
client = anthropic.Anthropic()
with client.messages.stream(
max_tokens=65536,
model="claude-opus-5-5",
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 de grano fino para la herramienta make_file. Las pestañas de los SDK imprimen cada fragmento de entrada en el momento en que llega y luego imprimen la entrada acumulada completa una vez que termina el stream. La pestaña de cURL muestra el flujo 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 normalmente son más largos, con menos cortes a mitad de palabra.
Acumulación de deltas de entrada de herramientas
El contrato de acumulación es el mismo que para el streaming de uso de herramientas estándar, por lo que esta sección se aplica con y sin eager_input_streaming. Consulta Delta de JSON de entrada en Streaming de mensajes para ver el formato del evento. El streaming de herramientas de grano fino cambia lo que puedes suponer 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 por streaming, 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 asistente acumulador (como lo hacen las pestañas de Python, TypeScript, Go, Java y Ruby en el ejemplo anterior), este se encarga de ello por ti. El patrón manual es para los SDK sin un asistente, o para cuando quieres control total sobre cómo se ensambla la entrada.
El contrato de acumulación:
- En
content_block_startcontype: "tool_use", inicializa una cadena vacía:input_json = "" - Para cada
content_block_deltacontype: "input_json_delta", agrega:input_json += event.delta.partial_json - En
content_block_stop, analiza la cadena acumulada
Protege el análisis, 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 motivo de detención y decide si reintentar la solicitud con un max_tokens más alto o reparar la entrada parcial.
La discrepancia de tipos 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-5-5",
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}")Manejo de JSON inválido en respuestas de herramientas
Con el streaming de herramientas de grano fino, la entrada acumulada para una llamada a herramienta podría ser JSON inválido o incompleto. Cuando lo es, no puedes ejecutar la herramienta, así que en su lugar informa el fallo a Claude. 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 para Claude, sin ambigüedad, que recibiste JSON inválido, y conserva la entrada original para la depuración:
{
"INVALID_JSON": "<the unparseable input you received>"
}Devuelve el envoltorio, serializado como 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>\"}"
}Próximos pasos
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 crecen las conversaciones.
Transmite las respuestas de la API de Messages de forma incremental con eventos enviados por el servidor, incluidos los deltas de texto, uso de herramientas y pensamiento extendido.
Analiza bloques tool_use, da formato a respuestas tool_result y maneja errores con is_error.
Directorio de herramientas proporcionadas por Anthropic y referencia de las propiedades opcionales de definición de herramientas.
Was this page helpful?