函数调用及结构化JSON输出支持 Ollama
函数调用允许大语言模型(LLM)自主决定调用您代码中的函数——例如查询天气、查询数据库、发送邮件——并以正确的格式返回参数。Ollama 函数调用基于两个核心组件:用于确保 JSON 有效的 format 参数,以及用于声明可用函数的 API tools 字段。本指南用 Python 演示这两个组件的用法,介绍哪些本地模型真正可靠,以及如何通过模式验证和重试机制提高整个流程的稳健性。
#为什么要在本地使用函数调用
大语言模型(LLM)生成的是文本,而不是操作。函数调用弥合了这一差距:模型不再以普通文本回答,而是返回一个结构化对象,表示“调用 get_meteo 函数,城市参数为 Paris”。您的代码执行该函数,获取实际结果,再将结果传回模型,由模型撰写最终回复。这是智能体以及与外部世界交互的助手的基础机制。
在本地,挑战是双重的。首先,确保输出是 100% 可解析的 JSON——一个话多的模型如果添加“以下是 JSON:”就会破坏您的整个管道。其次,确保模型选择正确的函数和参数,这对小模型来说变得棘手。Ollama 通过其 API 处理这两点,但需要了解一些防护措施。
- 保证输出JSON格式
- format 参数对解码过程施加约束:模型只能生成语法有效的 JSON,甚至可以进一步限定其符合特定的模式。
- 函数调用
- tools字段声明以OpenAI格式定义的函数;模型会返回包含需传递参数的tool_calls。
- 100 % 本地
- 所有操作都通过位于 http://localhost:11434 的 Ollama 守护进程在您的电脑上运行,无需 API 密钥,也不会泄露数据。
#前置条件及兼容模型
JSON 模式(format 参数)适用于任何模型。而通过 tools 进行函数调用,则要求模型经过工具使用训练——否则 tool_calls 字段会保持为空。模型的表现并不都一样:一个纸面上“兼容”的 3B 模型常会弄错参数,而 14B 及以上模型在处理简单的结构规范时表现可靠。
- Ollama 已安装
- 守护进程已启动,可通过 http://localhost:11434 访问。请使用 ollama list 检查。
- Python SDK
- pip install ollama pydantic — le client officiel plus Pydantic pour la validation.
- 可靠的工具调用模型
- qwen3.5:9b、mistral-small (24B) 和 gpt-oss:20b 是 2026 年的绝佳起点。在 Q4 量化下:Qwen 3.5 9B ≈ 6.6 GB,24B 模型 ≈ 14 GB VRAM。
- 推荐 GPU
- RTX 3060 12GB 可以顺畅运行 Qwen 3.5 9B;若要让工具调用真正可靠,建议选择 20–24B 模型(RTX 4070/4080 16 GB)。
#通过 format 参数强制生成有效的 JSON
最简单的情况:您希望模型始终输出 JSON,而不是自由文本。在 chat 调用中传入 format: 'json'。Ollama 随后会在逐 token 解码时施加约束,以生成语法有效的 JSON 对象。重要提示:请在提示词中保留明确说明预期字段的指令,否则模型会自行编造结构。
#按模式约束的 JSON 结构化输出(structured outputs)
自2024年底起,Ollama也接受在format中传入完整的JSON Schema(而不只是字符串'json')。此时,解码会受到约束,必须遵守该模式规定的类型、必填字段和枚举值。这比单独使用'json'稳健得多,因为模型在结构上无法生成不符合该模式的对象。使用Pydantic可以自动生成该模式。
这里的解码被约束为符合 Personne 的结构,model_validate_json 会在 Python 端再执行一次验证。双重保障:确保输出既可解析,又符合声明的类型。这是本地生产环境中所有数据提取任务推荐采用的模式。
#用 Python 逐步使用 tools API
接下来介绍真正的函数调用。在 tools 字段中按 OpenAI 格式声明函数(包含 name、description,以及采用 JSON Schema 的 parameters)。模型读取这些定义后,如果认为调用函数有帮助,就会返回一个或多个 tool_calls,而不是文本消息。您需要执行函数并将结果返回。
- 01描述函数为每个函数提供清晰的 name、准确的 description(模型会据此选择函数),以及采用 JSON Schema 格式的 parameters,列出各个参数,并通过 required 指明哪些参数必填。
- 02发送带有 tools 的请求将tools列表传递给ollama.chat。模型将自行决定是调用函数还是直接回答。
- 03读取 tool_calls检查 resp['message'].get('tool_calls')。如果存在,说明模型希望调用一个带有指定参数的函数。
- 04执行并返回调用真正的 Python 函数,然后将结果作为 'tool' 角色消息传递给模型,由模型生成最终回复。
#调用 → 执行 → 响应的循环
函数调用涉及往返操作。第一次调用:模型返回一个tool_call,您执行该函数。第二次调用:您将结果返回给模型,模型随后生成自然语言响应。这是完整的循环,可重复用于多个函数。
#Schema 验证与重试策略
本地部署时,小模型有时会出现参数缺失、类型错误或函数不存在等问题。切勿依赖原始输出。每个 tool_call 均需通过 Pydantic 验证,若验证失败,则应结合错误信息重新调用——通常模型在第二次尝试时会自动修正。
- 执行前需验证
- 为每个函数定义一个 Pydantic 模型,就能在参数传入您的代码之前,检测出参数缺失或类型错误。
- 带反馈的重试
- 将错误消息重新加入上下文,可以引导模型进行修正。几乎总是尝试 2 至 3 次就足够了。
- 函数白名单
- 拒绝任何不在 dispatch 中的函数名。这既是一项安全措施,也是防止幻觉的保护机制。
- 优雅的降级
- 失败 N 次后,请向用户返回一条清晰的说明,而不是让程序崩溃——使用小模型时尤其如此。
#小模型在工具使用中的陷阱
工具使用对模型的认知能力要求较高:模型必须理解意图、选择合适的函数、映射参数并遵守格式。参数量低于 7B 时,结果往往不够可靠。以下是在本地运行时最常出现的问题及解决方法。
- tool_calls 为空
- 模型以文本形式响应,而非调用函数。通常是因为模型未经过工具使用训练,或函数描述过于模糊。请改用 Qwen 3.5 或 Mistral Small,并完善函数描述。
- 参数错误
- 模型会编造或遗漏字段。请在 schema 中用 required 将这些字段设为必填,减少同时提供给模型的函数数量,并在每次执行前进行验证。
- 模型虚构的函数
- 模型调用了一个不存在的函数。分发端必须配置白名单。
- JSON 中混入额外内容
- 未指定格式时,小型模型会在 JSON 前后添加其他文本。对于只需提取数据的任务,请始终使用 format='json' 或指定一个模式(schema)。
- 功能过多
- 工具数量超过5–6个时,小模型就容易混乱。请按子任务拆分,或采用两阶段路由。
#深入了解
函数调用是智能体和高级集成的基础组件。本网站的以下指南进一步延伸了本篇指南的内容:
- 用 Python 通过 REST API 集成 Ollama
- 在实际的 FastAPI/Flask 应用中使用 :11434 端口上的 OpenAI 兼容端点、流式传输和 JSON 模式。
- 使用 LangChain 和 Ollama 创建本地 AI 智能体
- 从基础的函数调用过渡到一个能够串联工具、记忆和推理的完整智能体。
- MCP 与本地 LLM:将 MCP 服务器连接到 Ollama
- 通过模型上下文协议(Model Context Protocol)统一对工具(文件、网络、数据库)的访问方式,而不是手动定义每个函数。
有反馈、发现了错误,或想补充说明?请告诉我们,让这份指南对每个人都更有帮助。