Gemini 3.6 Flash 这类模型本身不会主动触发外部工具,真正可落地的方式是让模型在对话中产出结构化的工具调用请求,再由你写的宿主代码去执行并回传结果。这个流程通常被称为 function calling / tool use。如果你的目标是让模型去查订单、写工单、调用内部 API,走这条路比在提示词里反复要求“请调用”要可靠得多。
可以基于函数调用实现联动,但模型不负责执行外部操作。正确边界是:模型只生成调用参数,宿主代码负责执行,然后在下一轮把工具结果带回模型。建议先定义清晰的工具 schema,设置最小权限、超时与错误处理。如果你的平台尚未暴露 tool use 能力,可临时用提示词约束 JSON 输出,但稳定性需结合环境验证。
先确认联动的技术接口
第一步不是写代码,而是确认你拿到的模型访问方式是否支持 tools 参数。通常通过 API 访问的 Gemini 系列模型会支持 function calling;如果你用的是某些聚合平台或私有化部署,可能暴露方式不同。你需要查看当前可用的请求体里能否传入 tools 或 functions 字段。如果不能,则只能走“输出 JSON + 解析”的方案。
如果只是外挂搜索、文档问答等非执行类工具,也可以考虑检索增强生成;但如果要写入数据、触发流程,必须走工具调用链路。注意,工具调用不等于让模型自己发起 HTTP 请求,而是由你的服务端统一执行,这样权限和审计才留在你手里。
函数调用式联动的最小闭环
下面是一个以 HTTP API 为假设的接入骨架。重点是循环:发送带 tools 的请求,模型返回 functionCall,执行工具,再把结果作为新的消息发给模型,模型给出最终回复。你可以把这个循环封装成一个函数,后面接入任何工具都复用。
# 伪代码,仅演示工具调用循环
def run_with_tools(user_input, tools):
messages = [{'role': 'user', 'parts': [{'text': user_input}]}]
for _ in range(3): # 限制循环次数
resp = post_chat(messages, tools)
if resp.has_function_call():
call = resp.function_call
result = dispatch_tool(call.name, call.arguments) # 宿主代码执行
messages.append({'role': 'model', 'parts': [{'functionCall': call}]})
messages.append({'role': 'user', 'parts': [{'functionResponse': {
'name': call.name,
'response': {'result': result}
}}]})
else:
return resp.text
return '工具调用次数超限'
这里 post_chat 和 dispatch_tool 需要你自己实现。post_chat 负责把 messages 和 tools 发给模型接口;dispatch_tool 根据函数名分发到具体外部服务。模型名在你发请求时以实际可用为准,建议先做一次 list models 确认。
定义工具时,描述要具体,因为模型决定是否调用主要依赖描述。常用工具定义类似这样:
tools = [
{
'functionDeclarations': [
{
'name': 'query_order',
'description': '按订单号查询订单状态,只在用户询问订单进度时调用',
'parameters': {
'type': 'object',
'properties': {
'order_id': {'type': 'string', 'description': '用户提供的订单号'}
},
'required': ['order_id']
}
}
]
}
]
参数表与验证清单
工具定义和调用流程都完成后,建议做一组小范围验证。下面这几个点最容易出问题,值得优先检查。
- 工具 name 使用英文小写加下划线,避免中文和空格。
- 描述用动词开头,说明何时调用,例如“只在……时调用”。
- 参数只放必需字段,减少模型补无关值的概率。
- 工具返回结果要尽量简短,太长会挤占上下文窗口,也容易让模型忽略关键字段。
验证时至少覆盖四类场景:单次工具调用、连续多次调用、工具返回错误、工具服务超时。如果发现模型没有发起调用,先检查工具描述是否清晰;如果调用参数不对,改为在参数描述中给出格式示例。
常见问题
模型会自动调用外部工具吗?
不会。模型只有在请求中收到 tools,且判断确实需要时,才会返回 functionCall。它不能主动发起外部请求,最终执行权始终在你的宿主代码里。
工具结果回传后,模型仍然回答“查不到”怎么办?
优先检查 messages 中 functionCall 和 functionResponse 是否配对,以及返回结果是否以文本形式放入 response 字段。也可以试着把工具返回错误信息一并写入 response,让模型向用户转达原因。
如果接口不支持 function calling,还有什么替代方案?
可以让模型输出 JSON,你解析后执行外部调用。这种方式也能跑通,但需要你在提示词中严格规定 JSON 格式,并做好缺少字段、解析失败的兜底。建议只把它当作临时方案。