从写代码,到创作下一幕

探索 字节跳动 - 火山方舟 的 AI 编程与视频创作活动。

火山方舟 Agent Plan 与 Coding Plan 活动,价格 ¥9.9 起

Agent Plan & Coding Plan

一站体验多款热门模型,为 AI 编程与智能体开发提供更多选择。新用户可联系(微信: goo_lvyouyou)免费体验 9.9 agent plan。

查看套餐优惠
Seedance 2.5 视频创作活动:30 秒视频、多模态参考、局部编辑

Seedance 2.5

让创意,跃然成片。探索 30 秒视频、多模态参考与局部编辑,把脑海中的画面变成下一支作品。

探索视频创作

工具

Function Calling

查看 Markdown

定义模型可在对话期间调用的自定义工具。模型请求调用后,由你在本地执行并返回结果。借此可集成数据库、API 和任何外部系统。

  1. 使用名称、说明和参数 JSON Schema 定义 tool

  2. 在请求中包含 tool

  3. 模型会返回 tool_call,表示需要外部数据

  4. 在本地执行函数并返回结果

  5. 模型会根据你的结果继续执行


工作原理

Developer
Grok
执行工具
{ temp: "73", condition: "sunny" }
用户查询与工具定义
"Is it warm in Palo Alto?"
get_weather(location)
工具调用
get_weather("PA")
工具结果
...之前的所有消息
{ temp: "73", condition: "sunny" }
模型响应
"It's a nice 73 °F in PA!"

快速入门

import { xai } from '@ai-sdk/xai';
import { streamText, tool, stepCountIs } from 'ai';
import { z } from 'zod';

const result = streamText({
  model: xai.responses('grok-4.7'),
  tools: {
    getTemperature: tool({
      description: 'Get current temperature for a location',
      inputSchema: z.object({
        location: z.string().describe('City name'),
        unit: z.enum(['celsius', 'fahrenheit']).default('fahrenheit'),
      }),
      execute: async ({ location, unit }) => ({
        location,
        temperature: unit === 'fahrenheit' ? 59 : 15,
        unit,
      }),
    }),
  },
  stopWhen: stepCountIs(5),
  prompt: 'What is the temperature in San Francisco?',
});

for await (const chunk of result.fullStream) {
  if (chunk.type === 'text-delta') {
    process.stdout.write(chunk.text);
  }
}

使用 Pydantic 定义 tool

使用 Pydantic 模型创建类型安全的参数 Schema:

from typing import Literal
from pydantic import BaseModel, Field

class TemperatureRequest(BaseModel):
    location: str = Field(description="City and state, e.g. San Francisco, CA")
    unit: Literal["celsius", "fahrenheit"] = Field("fahrenheit", description="Temperature unit")

class CeilingRequest(BaseModel):
    location: str = Field(description="City and state, e.g. San Francisco, CA")

tools = [
    {
        "type": "function",
        "name": "get_temperature",
        "description": "Get current temperature for a location",
        "parameters": TemperatureRequest.model_json_schema(),
    },
    {
        "type": "function",
        "name": "get_ceiling",
        "description": "Get current cloud ceiling for a location",
        "parameters": CeilingRequest.model_json_schema(),
    },
]

处理 tool call

当模型要使用 tool 时,执行函数并返回结果:

import json

def get_temperature(location: str, unit: str = "fahrenheit") -> dict:
    temp = 59 if unit == "fahrenheit" else 15
    return {"location": location, "temperature": temp, "unit": unit}

tools_map = {"get_temperature": get_temperature}

# Process function calls
for item in response.output:
    if item.type == "function_call":
        name = item.name
        args = json.loads(item.arguments)

        if name not in tools_map:
            output = json.dumps({"error": f"Unknown function: {name}"})
        else:
            output = json.dumps(tools_map[name](**args))

        response = client.responses.create(
            model="grok-4.7",
            input=[{"type": "function_call_output", "call_id": item.call_id, "output": output}],
            tools=tools,
            previous_response_id=response.id,
        )

for item in response.output:
    if item.type == "message":
        print(item.content[0].text)

结合内置 tool

function calling 可与内置智能体 tool 配合使用。模型可以先使用 Web Search,再调用你的自定义函数:

tools = [
    {"type": "web_search"},          # Built-in
    {"type": "x_search"},            # Built-in
    {                                # Custom
        "type": "function",
        "name": "save_to_database",
        "description": "Save research results to the database",
        "parameters": {
            "type": "object",
            "properties": {
                "data": {"type": "string", "description": "Data to save"}
            },
            "required": ["data"]
        },
    },
]

混合使用 tool 时:

  • 内置 tool在 SpaceXSI 服务器上自动执行

  • 自定义 tool 会暂停执行并返回给你处理

完整的 tool loop 示例请参阅 高级用法。


tool 选择

控制模型何时使用 tool:

值行为
"auto"模型决定是否调用 tool(默认)
"required"模型必须调用至少一个 tool
"none"禁用 function calling
{"type": "function", "function": {"name": "..."}}强制使用指定 tool

并行 function calling

默认启用并行函数调用,模型可在单个响应中请求多个工具调用。继续前请处理全部调用:

Python

# response.tool_calls may contain multiple calls
for tool_call in response.tool_calls:
    result = tools_map[tool_call.function.name](**json.loads(tool_call.function.arguments))
    # Append each result...

在请求中设置 parallel_tool_calls: false 可禁用。


tool Schema 参考

字段必需说明
name是唯一标识符(每个请求最多 350 个工具)
description否说明工具的用途。省略时按空描述处理;清晰的描述有助于模型判断何时使用该工具
parameters是定义函数输入的 JSON Schema

参数 Schema

JSON

{
  "type": "object",
  "properties": {
    "location": {
      "type": "string",
      "description": "City name"
    },
    "unit": {
      "type": "string",
      "enum": ["celsius", "fahrenheit"],
      "default": "celsius"
    }
  },
  "required": ["location"]
}

某个 parameters Schema 的根必须是对象("type": "object");请将其他类型嵌套在 properties 中。根 anyOf 或 oneOf 也可用,但每个分支本身都必须是对象,因此可定义接受多个对象变体之一的 tool:

JSON

{
  "oneOf": [
    {
      "type": "object",
      "properties": {
        "kind": { "const": "email" },
        "address": { "type": "string" }
      },
      "required": ["kind", "address"]
    },
    {
      "type": "object",
      "properties": {
        "kind": { "const": "sms" },
        "phone": { "type": "string" }
      },
      "required": ["kind", "phone"]
    }
  ]
}

完整 Vercel AI SDK 示例

Vercel AI SDK 会自动处理 tool 定义、执行和请求/响应循环:

JavaScript

import { xai } from '@ai-sdk/xai';
import { streamText, tool, stepCountIs } from 'ai';
import { z } from 'zod';

const result = streamText({
  model: xai.responses('grok-4.7'),
  tools: {
    getCurrentTemperature: tool({
      description: 'Get current temperature for a location',
      inputSchema: z.object({
        location: z.string().describe('City and state, e.g. San Francisco, CA'),
        unit: z.enum(['celsius', 'fahrenheit']).default('fahrenheit'),
      }),
      execute: async ({ location, unit }) => ({
        location,
        temperature: unit === 'fahrenheit' ? 59 : 15,
        unit,
      }),
    }),
    getCurrentCeiling: tool({
      description: 'Get current cloud ceiling for a location',
      inputSchema: z.object({
        location: z.string().describe('City and state'),
      }),
      execute: async ({ location }) => ({
        location,
        ceiling: 15000,
        ceiling_type: 'broken',
        unit: 'ft',
      }),
    }),
  },
  stopWhen: stepCountIs(5),
  prompt: "What's the temperature and cloud ceiling in San Francisco?",
});

for await (const chunk of result.fullStream) {
  switch (chunk.type) {
    case 'text-delta':
      process.stdout.write(chunk.text);
      break;
    case 'tool-call':
      console.log(`Tool call: ${chunk.toolName}`, chunk.input);
      break;
    case 'tool-result':
      console.log(`Tool result: ${chunk.toolName}`, chunk.output);
      break;
  }
}

最后更新:2026 年 10 月 10 日