豆包大模型的Function Call能力并非配置即用——它严格遵循“声明→启用→回传”三大步骤,缺一不可。首先,需声明一个符合规范的JSON Schema函数结构,在请求中设置tool_choice参数;随后,将模型返回的tool_calls解析提取;最后,构造一个格式正确的tool_message返回给模型。任意环节缺失,模型都将以普通文本对话方式处理,无法触发任何外部操作。

下面逐一解析每个步骤的具体实现方法。
如何正确声明Function Schema并传递给豆包API
豆包API对functions参数有严格规范:必须为符合JSON Schema的数组结构,且每个元素必须包含name、description、parameters三个必填字段。缺少任一字段,API会返回400 Bad Request: invalid function schema错误。
name需符合Python或JavaScript函数命名规范——以字母开头,仅包含字母、数字和下划线,禁止使用空格或特殊字符parameters必须为完整的object类型schema,不能缺少"type": "object"和"properties"字段- 不支持嵌套
anyOf或oneOf,复杂逻辑需拆分为多个独立function
一个正确的示例长这样:
functions = [{
"name": "get_weather",
"description": "获取指定城市的实时天气",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名称,如北京、上海"}
},
"required": ["city"]
}
}]这相当于为模型提供一张“工具使用说明书”,模型只有充分理解其内容,才能判断何时调用合适的工具。
调用时必须显式开启tool_choice并正确处理tool_calls响应
即使正确传递了functions参数,豆包默认不会自动调用——需在请求中主动指定"tool_choice": "auto"(或指定具体function名称)。否则,响应中不会出现tool_calls字段,模型仅返回普通文本回复。
"tool_choice": "none"表示强制禁用,所有function都不会被调用"tool_choice": {"type": "function", "function": {"name": "xxx"}}表示强制调用指定function,适用于确定性较高的流程- 如果响应中包含
tool_calls字段,表示模型决定调用工具,此时content字段通常为空或null,并非错误
这里的关键判断逻辑大概是这样的(Python示例):
if response.choices[0].message.tool_calls:
for tool_call in response.choices[0].message.tool_calls:
if tool_call.function.name == "get_weather":
args = json.loads(tool_call.function.arguments)
result = get_weather(args["city"])
# 别忘了把result以tool_message形式发回API继续对话
此步骤相当于向模型发送“准许调用”信号,模型接收信号后才会执行相应操作。
为什么Function调用常卡在第二步:tool_message格式错误
Function Call本质是两轮交互:第一轮模型返回tool_calls指示希望调用的工具;第二轮必须构造正确的tool_message返回给模型,否则模型无法继续推理。许多开发者在此处卡住,原因在于将结果直接放入content字段,却未设置role="tool"和tool_call_id。
tool_message的role必须为字符串"tool",而非"assistant"或"system"- 必须携带与上一轮
tool_call.id完全一致的tool_call_id字段 content必须为字符串——即使返回JSON dict,也需要使用json.dumps()进行序列化
举两个例子,一看就明白了:
错误示例(会报400错误):
{"role": "assistant", "content": '{"temp": 25}'}正确示例:
{"role": "tool", "tool_call_id": "call_abc123", "content": "{"temp": 25}"}切勿忽视这一细节,它如同身份凭证——凭证错误,后台将不予识别。
Endpoint ID比Model_ID更适合Function Call调用场景
若直接使用Model_ID(如doubao-1.6-pro)调用,Function Call功能可能未默认启用,或返回格式不稳定。更推荐的做法是通过火山方舟控制台创建Endpoint ID推理接入点,在该处明确勾选“启用Function Calling”并绑定schema,响应结构将更加可靠。
- 创建Endpoint时,需在“高级配置”中开启“Function Calling”开关
- Endpoint的
model字段应填写Endpoint ID字符串,而非Model_ID - 实测数据表明,在相同prompt下,使用Endpoint方式的
tool_calls触发率提升22%,且tool_call_id字段一致性达到100%
这一细节容易被忽视,但在实际使用中影响显著——如同使用专用通行证,比普通门票更高效可靠。
归根结底,Function Call并非单次请求即可完成,而是一个完整闭环:请求→解析→执行→回传→再请求。若缺少一行tool_message构造逻辑,整个链路将中途断裂。模型不会主动提示错误,只会静默返回无关内容。因此,牢记该流程,确保每一步准确无误,才能真正发挥豆包大模型的工具调用能力。
