通义千问3-14B从零开始:Python调用函数接口代码实例
1. 引言
1.1 业务场景描述
在当前大模型应用快速落地的背景下,开发者对高性能、低成本、易部署的开源模型需求日益增长。通义千问 Qwen3-14B 正是在这一趋势下推出的“守门员级”模型——148亿参数、单卡可运行、支持双模式推理,并具备强大的函数调用与Agent能力。尤其适合需要长上下文理解、多语言翻译、逻辑推理和结构化输出的企业级轻量部署场景。
然而,尽管官方提供了qwen-agent库和 Ollama 集成方案,许多开发者仍面临如何从零开始调用其函数接口的实际挑战。本文将基于Ollama + Ollama-WebUI 双重部署环境,手把手实现 Python 环境下调用 Qwen3-14B 的函数接口完整流程。
1.2 痛点分析
现有文档多集中于命令行启动或 WebUI 操作,缺乏系统性的 API 调用示例,尤其是:
- 如何定义并注册自定义函数?
- 如何触发模型进行函数调用而非普通回复?
- 如何解析返回结果中的函数参数?
这些问题导致开发者难以将其集成到自动化系统中。
1.3 方案预告
本文将以天气查询函数为例,演示如何通过本地 Ollama 服务暴露的 REST API,在 Python 中完成以下任务:
- 启动并配置 Qwen3-14B 支持函数调用;
- 定义 OpenAI 兼容格式的 function schema;
- 发送包含 function hint 的 prompt;
- 解析模型返回的 function_call 字段;
- 执行实际函数并返回结果给模型生成最终回答。
2. 技术方案选型
2.1 为什么选择 Ollama + Ollama-WebUI?
| 方案 | 优点 | 缺点 |
|---|---|---|
| 直接加载 HuggingFace 模型 + Transformers | 控制精细,灵活性高 | 显存占用大,需手动管理量化、KV Cache |
| vLLM 部署 | 高吞吐、低延迟 | 配置复杂,不支持所有功能(如 Thinking 模式) |
| Ollama + Ollama-WebUI | 单命令启动、自动量化、支持 function call、可视化调试 | 功能依赖 Ollama 实现程度 |
Ollama 对 Qwen3-14B 提供了开箱即用的支持,且已兼容 OpenAI 格式的 function calling,配合 Ollama-WebUI 可实时查看<think>推理过程,非常适合开发调试阶段。
2.2 核心技术栈
- 模型:
qwen3:14b(可通过ollama pull qwen3:14b下载) - 运行时: Ollama(v0.3+),启用 gRPC 和 OpenAI 兼容 API
- 前端交互: Ollama-WebUI(可选,用于可视化验证)
- 客户端: Python 3.9+,使用
requests调用/v1/chat/completions - 协议支持: OpenAI-style function calling(非原生 JSON mode)
注意:Qwen3-14B 的 function calling 基于特殊 token
<tool_call>和<tool_response>实现,Ollama 自动处理编解码。
3. 实现步骤详解
3.1 环境准备
确保已安装以下组件:
# 安装 Ollama curl -fsSL https://ollama.com/install.sh | sh # 拉取 Qwen3-14B 模型(FP8 量化版,约 14GB) ollama pull qwen3:14b # 启动 Ollama 服务(默认监听 11434 端口) ollama serve安装 Ollama-WebUI(可选):
git clone https://github.com/ollama-webui/ollama-webui.git cd ollama-webui && docker-compose up -d访问http://localhost:3000即可进入图形界面测试模型。
3.2 定义函数 Schema
我们以一个简单的天气查询函数为例,模拟外部工具调用。
{ "name": "get_weather", "description": "获取指定城市的当前天气信息", "parameters": { "type": "object", "properties": { "city": { "type": "string", "description": "城市名称,如北京、上海" }, "unit": { "type": "string", "enum": ["celsius", "fahrenheit"], "description": "温度单位,默认为 celsius" } }, "required": ["city"] } }该 schema 符合 OpenAI 函数调用规范,Ollama 能正确识别并引导模型输出<tool_call>。
3.3 Python 调用代码实现
以下是完整的 Python 示例代码,展示如何发起一次带函数提示的对话请求。
import requests import json # Ollama OpenAI 兼容 API 地址 OLLAMA_API = "http://localhost:11434/v1/chat/completions" # 自定义函数定义 functions = [ { "name": "get_weather", "description": "获取指定城市的当前天气信息", "parameters": { "type": "object", "properties": { "city": {"type": "string", "description": "城市名称"}, "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]} }, "required": ["city"] } } ] # 请求头 headers = { "Content-Type": "application/json" } # 用户输入 user_message = { "role": "user", "content": "北京今天天气怎么样?" } # 发送请求到 Ollama payload = { "model": "qwen3:14b", "messages": [user_message], "functions": functions, "function_call": "auto", # 允许模型自主决定是否调用函数 "stream": False } response = requests.post(OLLAMA_API, headers=headers, data=json.dumps(payload)) result = response.json() print("原始响应:") print(json.dumps(result, indent=2, ensure_ascii=False)) # 判断是否返回了函数调用 if "choices" in result and len(result["choices"]) > 0: message = result["choices"][0]["message"] if "function_call" in message: func_call = message["function_call"] print(f"\n检测到函数调用:{func_call['name']}") print(f"参数解析:{func_call['arguments']}") # 解析 arguments(注意:可能是字符串或对象) try: args = json.loads(func_call["arguments"]) except: args = func_call["arguments"] # 若无法解析则保留原样 # 模拟执行函数 if func_call["name"] == "get_weather": city = args.get("city", "未知城市") unit = args.get("unit", "celsius") temperature = "26°C" if unit == "celsius" else "78°F" weather_info = f"{city}当前气温{temperature},晴朗无云。" # 将结果回传给模型生成自然语言回答 final_payload = { "model": "qwen3:14b", "messages": [ user_message, { "role": "assistant", "content": "", "function_call": func_call }, { "role": "function", "name": "get_weather", "content": weather_info } ], "stream": False } final_response = requests.post(OLLAMA_API, headers=headers, data=json.dumps(final_payload)) final_result = final_response.json() print("\n最终回答:") print(final_result["choices"][0]["message"]["content"]) else: print("模型直接回复:") print(message["content"]) else: print("请求失败或无响应")3.4 代码解析
(1)关键字段说明
"functions":传入可用函数列表,模型据此判断是否需要调用。"function_call": "auto":由模型决定;也可设为"none"(禁用)或{"name": "get_weather"}(强制调用)。"role": "function":当函数执行完成后,必须以该角色将结果回传,以便模型继续生成回答。
(2)数据流图解
[用户提问] ↓ → Ollama (qwen3:14b) → 是否需调用函数? ↓ 是 返回 <tool_call> 结构 ↓ Python 解析并执行函数 ↓ 回传 <tool_response> 给模型 ↓ 生成最终自然语言回答(3)Thinking 模式的影响
若你在 Ollama 启动时设置了OLLAMA_QWEN_ENABLE_THINKING=1,你会看到类似如下输出:
<think> 用户询问北京天气 → 需要调用 get_weather 工具 → 参数 city=北京 </think> <tool_call>{"name": "get_weather", "arguments": {"city": "北京"}}</tool_call>这表明模型显式展示了推理路径,有助于调试 Agent 行为。
4. 实践问题与优化
4.1 常见问题及解决方案
| 问题 | 原因 | 解决方法 |
|---|---|---|
function_call字段未出现 | 模型未识别需调用函数 | 明确提示:“请使用工具获取信息” |
arguments为字符串而非 JSON 对象 | Ollama 输出格式不稳定 | 使用try-except安全解析 |
| 函数调用后模型无响应 | 缺少role=function回传 | 确保按顺序发送三段消息 |
| 中文 city 名称乱码 | 编码问题 | 设置Content-Type: application/json; charset=utf-8 |
4.2 性能优化建议
启用 FP8 量化:在资源有限设备上显著降低显存占用。
ollama run qwen3:14b-fp8限制上下文长度:除非必要,避免使用 128k 上下文以提升响应速度。
缓存函数结果:对于高频查询(如天气、汇率),增加本地缓存层减少重复计算。
异步处理 pipeline:使用 FastAPI 或 Celery 构建异步 Agent 流程。
5. 总结
5.1 实践经验总结
本文围绕 Qwen3-14B 在 Ollama 环境下的函数调用能力,完成了从环境搭建到 Python 实现的全流程实践。核心收获包括:
- Ollama 已良好支持 Qwen3-14B 的 function calling,无需额外训练或微调;
- 函数调用依赖特殊的 role 类型(
function)和<tool_call>标记; - Thinking 模式可增强可解释性,适用于复杂推理场景;
- 整体流程符合 OpenAI 兼容标准,便于迁移至其他平台。
5.2 最佳实践建议
- 优先使用 Ollama 管理模型生命周期,简化部署复杂度;
- 在生产环境中封装函数调用逻辑为统一中间件,提高复用性;
- 结合 qwen-agent 库构建更复杂的多工具协作 Agent。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。