跳至内容

API参考:批量推理

/batch_inference 端点允许用户利用LLM提供商提供的批量推理功能。这些推理通常比同步API便宜得多。通过此端点进行的推理的处理方式和最终数据模型与通过主/inference端点进行的推理基本相同,只有少数例外:

  • 批量采样会从被调用的函数中抽取单个变体。
  • 批处理函数没有回退或重试机制。
  • 仅支持类型为chat_completion的变体。
  • 不支持缓存。
  • 不支持 dryrun 设置。
  • 不支持流式传输。

在底层实现中,网关会验证所有请求,从被调用函数中采样单个变体,在适用时处理模板化,并将推理路由到适当的模型提供商。 批处理端点中没有回退机制,因为请求是异步处理的。

典型的工作流程是首先使用POST /batch_inference端点提交一批请求。之后,您可以轮询GET /batch_inference/{batch_id}GET /batch_inference/:batch_id/inference/:inference_id端点来检查批处理状态并获取结果。每次轮询将返回待处理状态、失败状态或批处理结果。即使批处理已完成并处理完毕,您仍可以继续轮询该端点作为获取结果的方式。当批处理首次完成并处理后,结果会像/inference端点一样存储在ChatInference、JsonInference和ModelInference表中。网关在完成后重复轮询时会将结果重新组装成预期结果。

POST /batch_inference

请求

additional_tools

  • 类型: 工具列表的列表(见下方)
  • 必填项: 否(默认:无额外工具)

推理时定义的允许模型调用的工具列表清单。 该字段支持动态工具使用,即在运行时定义工具。 外部列表中的每个元素对应批次中的单次推理。 内部列表包含对应推理可用的工具集。

如果可能的话,建议优先在配置文件中定义工具。 只有在您的使用场景需要动态工具调用时,才使用此字段。

每个工具都是一个包含以下字段的对象:descriptionnameparametersstrict

这些字段与配置文件中的字段相同,唯一的区别是parameters字段应包含JSON模式本身,而不是其路径。 详情请参阅配置参考

allowed_tools

  • 类型: 字符串列表的列表
  • 必填:

允许模型调用的工具名称列表的列表。 这些工具必须在配置文件中定义。 外层列表中的每个元素对应批次中的单次推理。 内层列表包含对应推理允许使用的工具名称。

无论此字段如何设置,additional_tools中提供的任何工具始终被允许使用。

credentials

  • 类型: object (从动态凭证名称到API密钥的映射)
  • 必填: 否(默认:无凭据)

在您的TensorZero配置中,每个模型提供商都可以通过使用dynamic位置(例如dynamic::my_dynamic_api_key_name)来配置为在推理时接受凭据。 更多详情请参阅配置参考。 网关期望凭据按照以下说明在请求体的credentials字段中提供。 如果未提供凭据且模型提供商已配置为使用动态凭据,网关将返回400错误。

Example
[models.my_model_name.providers.my_provider_name]
# ...
# Note: the name of the credential field (e.g. `api_key_location`) depends on the provider type
api_key_location = "dynamic::my_dynamic_api_key_name"
# ...
{
// ...
"credentials": {
// ...
"my_dynamic_api_key_name": "sk-..."
// ...
}
// ...
}

episode_ids

  • 类型: UUID列表
  • 必填:

要关联推理结果的现有情景ID列表。 列表中的每个元素对应批次中的单个推理。 对于需要开启全新情景的元素,可将情景ID设为null

仅使用由TensorZero网关返回的剧集ID。

function_name

  • 类型: string
  • 必填项:

要调用的函数名称。该函数对于批次中的所有推理都是相同的。

该函数必须在配置文件中定义。

inputs

  • 类型: input 对象列表(见下方)
  • 必填项:

函数的输入。

列表中的每个元素对应批次中的一次推理。

input[].messages
  • 类型: 消息列表(见下文)
  • 必填: 否(默认值:[]

提供给模型的消息列表。

每条消息都是一个包含以下字段的对象:

  • role: 消息的角色 (assistantuser)。
  • content: 消息的内容(见下文)。

content 字段可以包含以下类型之一:

  • string: 文本消息的内容文本(仅在该角色没有定义schema时允许使用)
  • 内容块列表:消息的内容块(见下文)

内容块是一个包含type字段的对象,并根据类型包含其他字段。

如果内容块的类型为text,则必须包含以下任一附加字段:

  • text: 内容块的文本内容。
  • arguments: 一个包含TensorZero函数参数的JSON对象,适用于带有模板和模式的函数(详见Prompt Templates & Schemas)。

如果内容块的类型为 tool_call,则必须包含以下附加字段:

  • arguments: 工具调用的参数。
  • id: 内容块的唯一标识符。
  • name: 内容区块的工具名称。

如果内容块的类型为 tool_result,则必须包含以下附加字段:

  • id: 内容块的ID。
  • name: 内容区块的工具名称。
  • result: 工具调用的结果。

如果内容块的类型为 image,则必须包含以下任一附加字段:

  • url: 远程图片的URL地址。
  • mime_type and data: The MIME type and base64-encoded data for an embedded image.
    • 我们支持以下MIME类型:image/png, image/jpeg, 以及 image/webp

有关如何在推理中使用图像的更多详情,请参阅多模态推理指南。

如果内容块的类型为raw_text,则必须包含以下附加字段:

  • value: 内容块的文本内容。 该内容块将忽略此函数相关的任何模板和模式。

如果内容块的类型为unknown,则必须包含以下额外字段:

  • data: 来自提供方的原始内容块,未经TensorZero的任何验证或转换。
  • model_provider_name (可选): 一个字符串,用于指定何时该内容块应包含在模型提供者的输入中。 如果设置,该内容块将仅提供给特定的模型提供者。 如果未设置,该内容块将传递给所有模型提供者。

例如,以下假设的未知内容块会将daydreaming内容块发送给针对your_model_provider_name模型提供商的推理请求。

{
"type": "unknown",
"data": {
"type": "daydreaming",
"dream": "..."
},
"model_provider_name": "tensorzero::model_name::your_model_name::provider_name::your_model_provider_name"
}

这是整个API中最复杂的字段。详情请参阅此示例。

Example
{
// ...
"input": {
"messages": [
// If you don't have a user (or assistant) schema...
{
"role": "user", // (or "assistant")
"content": "What is the weather in Tokyo?"
},
// If you have a user (or assistant) schema...
{
"role": "user", // (or "assistant")
"content": [
{
"type": "text",
"arguments": {
"location": "Tokyo"
// ...
}
}
]
},
// If the model previously called a tool...
{
"role": "assistant",
"content": [
{
"type": "tool_call",
"id": "0",
"name": "get_temperature",
"arguments": "{\"location\": \"Tokyo\"}"
}
]
},
// ...and you're providing the result of that tool call...
{
"role": "user",
"content": [
{
"type": "tool_result",
"id": "0",
"name": "get_temperature",
"result": "70"
}
]
},
// You can also specify a text message using a content block...
{
"role": "user",
"content": [
{
"type": "text",
"text": "What about NYC?" // (or object if there is a schema)
}
]
},
// You can also provide multiple content blocks in a single message...
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "Sure, I can help you with that." // (or object if there is a schema)
},
{
"type": "tool_call",
"id": "0",
"name": "get_temperature",
"arguments": "{\"location\": \"New York\"}"
}
]
}
// ...
]
// ...
}
// ...
}
input[].system
  • 类型: 字符串或对象
  • 必填:

系统消息的输入内容。

如果函数没有系统架构,该字段应为字符串。

如果函数有系统模式,此字段应为符合该模式的对象。

output_schemas

  • 类型: 可选对象列表(有效的JSON Schema)
  • 必填:

一个JSON模式列表,用于验证批次中每次推理的函数输出。 列表中的每个元素对应批次中的单次推理。 对于需要使用函数配置中定义的output_schema的元素,这些值可以为空。 该模式用于验证函数输出,并发送给支持结构化输出的提供方。

parallel_tool_calls

  • 类型: 可选的布尔值列表
  • 必填:

一个布尔值列表,用于指示批次中的每个推理是否允许在单次对话轮次中请求多个工具调用。 列表中的每个元素对应批次中的一个推理。 对于应使用被调用函数配置值的元素,您可以提供null。 如果完全不提供此字段,我们将默认使用被调用函数的配置值。

大多数模型提供商不支持并行工具调用。在这些情况下,网关会忽略此字段。 目前,只有Fireworks AI和OpenAI支持并行工具调用。

params

  • 类型: 对象(见下文)
  • 必填项: 否(默认值:{}

为特定变体类型覆盖推理时参数。 此字段支持动态推理参数,即在运行时定义参数。

该字段的格式为{ variant_type: { param: [value1, ...], ... }, ... }。 建议尽可能在配置文件中设置这些参数。 仅当需要在运行时动态设置这些参数时才使用此字段。 每个参数如果指定,应为一个可能为null的值列表,其长度与批次大小相同。

请注意,这些参数将应用于指定类型的每个变体。

目前,我们支持以下功能:

  • chat_completion
    • frequency_penalty
    • max_tokens
    • presence_penalty
    • seed
    • temperature
    • top_p

有关参数的更多详情,请参阅配置参考,下方示例展示了具体用法。

Example

例如,如果你想动态覆盖一批3次推理中首次调用的chat_completion变体的temperature参数,你需要在请求体中包含以下内容:

{
// ...
"params": {
"chat_completion": {
"temperature": [0.7, null, null]
}
}
// ...
}

tags

  • 类型: 可选的JSON对象列表,包含字符串键和值
  • 必填:

用户提供的标签,用于与推理相关联。

列表中的每个元素对应批次中的一次推理。

例如,[{"user_id": "123"}, null][{"author": "Alice"}, {"author": "Bob"}]

tool_choice

  • 类型: 可选字符串列表
  • 必填:

如果设置,将覆盖请求的工具选择策略。

列表中的每个元素对应批次中的一次推理。

支持的工具有以下选择策略:

  • none: 该函数不应使用任何工具。
  • auto: 模型自行决定是否使用工具。如果决定使用工具,还会选择具体使用哪些工具。
  • required: 模型必须使用工具。若存在多个可用工具,则由模型决定使用哪个工具。
  • { specific = "tool_name" }: 模型应使用特定工具。该工具必须在配置文件的tools部分定义或在additional_tools中提供。

variant_name

  • 类型: string
  • 必填:

如果设置此项,会将批量推理请求固定到特定变体(不推荐)。

通常您不应手动设置此字段,而应让TensorZero网关自动分配变体版本。 此字段主要用于测试或调试目的。

响应

对于向/batch_inference发送的POST请求,响应是一个包含元数据的JSON对象,这些元数据允许您引用该批次并在稍后进行轮询。 响应对象包含以下字段:

batch_id

  • 类型: UUID

批次的ID。

inference_ids

  • 类型: UUID列表

批次中推理的ID。

episode_ids

  • 类型: UUID列表

与批次中推理相关联的剧集ID。

示例

想象你有一个简单的TensorZero函数,它能用GPT-4o Mini生成俳句。

[functions.generate_haiku]
type = "chat"
[functions.generate_haiku.variants.gpt_4o_mini]
type = "chat_completion"
model = "openai::gpt-4o-mini-2024-07-18"

您可以提交批量推理任务,通过单次请求生成多首俳句。 inputs中的每个条目等同于常规推理请求中的input字段。

终端窗口
curl -X POST http://localhost:3000/batch_inference \
-H "Content-Type: application/json" \
-d '{
"function_name": "generate_haiku",
"variant_name": "gpt_4o_mini",
"inputs": [
{
"messages": [
{
"role": "user",
"content": "Write a haiku about artificial intelligence."
}
]
},
{
"messages": [
{
"role": "user",
"content": "Write a haiku about general aviation."
}
]
},
{
"messages": [
{
"role": "user",
"content": "Write a haiku about anime."
}
]
}
]
}'

响应中包含一个batch_id以及批次中每个推理对应的inference_idsepisode_ids

{
"batch_id": "019470f0-db4c-7811-9e14-6fe6593a2652",
"inference_ids": [
"019470f0-d34a-77a3-9e59-bcc66db2b82f",
"019470f0-d34a-77a3-9e59-bcdd2f8e06aa",
"019470f0-d34a-77a3-9e59-bcecfb7172a0"
],
"episode_ids": [
"019470f0-d34a-77a3-9e59-bc933973d087",
"019470f0-d34a-77a3-9e59-bca6e9b748b2",
"019470f0-d34a-77a3-9e59-bcb20177bf3a"
]
}

GET /batch_inference/:batch_id

此端点及随后的GET端点均可用于轮询批处理状态。 若仅使用批处理ID调用此端点,系统将尽可能返回完整的批处理信息。 返回格式取决于函数类型及轮询时的批处理状态。

待处理

{"status": "pending"}

失败

{"status": "failed"}

已完成

status

  • 类型: 字面字符串 "completed"

batch_id

  • 类型: UUID

inferences

  • 类型:与推理端点响应体完全匹配的对象列表,文档见此处

示例

扩展上面的示例:你可以使用batch_id来轮询此作业的状态:

终端窗口
curl -X GET http://localhost:3000/batch_inference/019470f0-db4c-7811-9e14-6fe6593a2652

当任务处于挂起状态时,响应将仅包含status字段。

{
"status": "pending"
}

任务完成后,响应将包含status字段和inferences字段。 每个推理对象与常规推理请求的响应相同。

{
"status": "completed",
"batch_id": "019470f0-db4c-7811-9e14-6fe6593a2652",
"inferences": [
{
"inference_id": "019470f0-d34a-77a3-9e59-bcc66db2b82f",
"episode_id": "019470f0-d34a-77a3-9e59-bc933973d087",
"variant_name": "gpt_4o_mini",
"content": [
{
"type": "text",
"text": "Whispers of circuits, \nLearning paths through endless code, \nDreams in binary."
}
],
"usage": {
"input_tokens": 15,
"output_tokens": 19
}
},
{
"inference_id": "019470f0-d34a-77a3-9e59-bcdd2f8e06aa",
"episode_id": "019470f0-d34a-77a3-9e59-bca6e9b748b2",
"variant_name": "gpt_4o_mini",
"content": [
{
"type": "text",
"text": "Wings of freedom soar, \nClouds embrace the lonely flight, \nSky whispers adventure."
}
],
"usage": {
"input_tokens": 15,
"output_tokens": 20
}
},
{
"inference_id": "019470f0-d34a-77a3-9e59-bcecfb7172a0",
"episode_id": "019470f0-d34a-77a3-9e59-bcb20177bf3a",
"variant_name": "gpt_4o_mini",
"content": [
{
"type": "text",
"text": "Vivid worlds unfold, \nHeroes rise with dreams in hand, \nInk and dreams collide."
}
],
"usage": {
"input_tokens": 14,
"output_tokens": 20
}
}
]
}

GET /batch_inference/:batch_id/inference/:inference_id

此端点可用于轮询批次中单个推理的状态。 由于轮询涉及拉取批次中所有推理的数据,我们也会将这些推理的状态存储在ClickHouse中。 响应格式取决于函数类型以及轮询时的批次状态。

待处理

{"status": "pending"}

失败

{"status": "failed"}

已完成

status

  • 类型: 字面字符串 "completed"

batch_id

  • 类型: UUID

inferences

  • 类型: 包含单个对象的列表,该对象与推理端点文档此处中记录的响应体完全匹配。

示例

与上述类似,我们也可以轮询特定的推理结果:

终端窗口
curl -X GET http://localhost:3000/batch_inference/019470f0-db4c-7811-9e14-6fe6593a2652/inference/019470f0-d34a-77a3-9e59-bcc66db2b82f

当任务处于待处理状态时,响应将仅包含status字段。

{
"status": "pending"
}

任务完成后,响应将包含status字段和inferences字段。 与上述不同,此请求将返回仅包含所请求推理的列表。

{
"status": "completed",
"batch_id": "019470f0-db4c-7811-9e14-6fe6593a2652",
"inferences": [
{
"inference_id": "019470f0-d34a-77a3-9e59-bcc66db2b82f",
"episode_id": "019470f0-d34a-77a3-9e59-bc933973d087",
"variant_name": "gpt_4o_mini",
"content": [
{
"type": "text",
"text": "Whispers of circuits, \nLearning paths through endless code, \nDreams in binary."
}
],
"usage": {
"input_tokens": 15,
"output_tokens": 19
}
}
]
}