通用工具调用 Demo


文档摘要

源文件:chapter2/localllmserving/README.md 通用工具调用 Demo 一个跨平台的 LLM 工具调用演示,使用标准 OpenAI 兼容 API。可在 Windows、macOS 和 Linux 上无缝运行,自动为你的系统选择最合适的后端。 🌟 特性 通用兼容:单一入口( )即可在所有平台上运行 自动后端选择: 在带 NVIDIA GPU 的 Linux/Windows 上使用 vLLM 在 macOS、Windows 或无 GPU 的 Linux 上使用 Ollama 标准工具调用:仅使用 OpenAI 兼容的工具调用格式 内置工具:天气、计算器、时间,且易于添加自定义工具 交互与示例模式:用示例测试或交互式聊天 🆕

源文件:chapter2/local_llm_serving/README.md

通用工具调用 Demo

一个跨平台的 LLM 工具调用演示,使用标准 OpenAI 兼容 API。可在 Windows、macOS 和 Linux 上无缝运行,自动为你的系统选择最合适的后端。

🌟 特性

  • 通用兼容:单一入口(main.py)即可在所有平台上运行
  • 自动后端选择
    • 在带 NVIDIA GPU 的 Linux/Windows 上使用 vLLM
    • 在 macOS、Windows 或无 GPU 的 Linux 上使用 Ollama
  • 标准工具调用:仅使用 OpenAI 兼容的工具调用格式
  • 内置工具:天气、计算器、时间,且易于添加自定义工具
  • 交互与示例模式:用示例测试或交互式聊天
  • 🆕 流式支持:实时展示思考过程、工具调用与响应

🚀 快速开始

# 1. Clone the repository git clone <repository> cd chapter2/local_llm_serving # 2. Install dependencies pip install -r requirements.txt # 3. Check your system compatibility python check_compatibility.py # 4. Run the main script (auto-detects best backend) python main.py

就这么简单!脚本会自动检测你的平台并使用合适的后端。

📋 前置条件

所有平台

  • Python 3.10+
  • pip install -r requirements.txt

各平台专属准备

🍎 macOS

# Install Ollama brew install ollama # Start Ollama service (in separate terminal) ollama serve # Download a model ollama pull qwen3:0.6b

🪟 Windows

带 NVIDIA GPU:

  • 已安装 CUDA 工具包
  • NVIDIA 驱动 452.39+
  • 将自动使用 vLLM

无 GPU:

# Download and install Ollama # From: https://ollama.com/download/windows # Pull a model ollama pull qwen3:0.6b

🐧 Linux

带 NVIDIA GPU:

  • 已安装 CUDA 工具包
  • 将自动使用 vLLM

无 GPU:

# Install Ollama curl -fsSL https://ollama.com/install.sh | sh # Start service systemctl start ollama # Pull a model ollama pull qwen3:0.6b

🎮 用法

基本用法

# Run with auto-detection (recommended) python main.py # Run examples only python main.py --mode examples # Run interactive mode only python main.py --mode interactive # Force specific backend python main.py --backend ollama # Force Ollama python main.py --backend vllm # Force vLLM (requires GPU) # Show system info python main.py --info

在你的代码中使用

from main import ToolCallingAgent # Initialize (auto-detects best backend) agent = ToolCallingAgent() # Send a message response = agent.chat("What's the weather in Tokyo?") print(response) # Disable tools for a query response = agent.chat("Tell me a joke", use_tools=False) # Reset conversation agent.reset_conversation()

添加自定义工具

from tools import ToolRegistry # Get the tool registry registry = ToolRegistry() # Define your tool function def my_custom_tool(param1: str, param2: int) -> str: return f"Processed {param1} with {param2}" # Register it registry.register_tool( name="my_custom_tool", function=my_custom_tool, description="My custom tool description", parameters={ "type": "object", "properties": { "param1": {"type": "string", "description": "First parameter"}, "param2": {"type": "integer", "description": "Second parameter"} }, "required": ["param1", "param2"] } )

📁 项目结构

local_llm_serving/ ├── main.py # Main entry point (auto-detects backend) ├── benchmark.py # Serving benchmark: throughput / TTFT / KV cache / batching ├── agent.py # vLLM agent implementation ├── ollama_native.py # Ollama native tool calling ├── tools.py # Tool implementations ├── config.py # Configuration settings ├── server.py # vLLM server manager ├── check_compatibility.py # System compatibility checker ├── requirements.txt # Python dependencies ├── env.example # Environment variables template └── README.md # This file

🛠️ 可用工具

  1. get_current_temperature:用 Open-Meteo API 获取实时天气信息(无需 API Key)
  2. get_current_time:获取不同时区的当前时间
  3. convert_currency:不同货币之间的换算(模拟汇率)
  4. parse_pdf:解析来自 URL 或本地文件的 PDF 文档
  5. code_interpreter:执行 Python 代码,完成复杂计算与数据处理

🎬 流式模式

Agent 现已支持流式响应,会展示:

  • 🧠 内部思考过程(灰色显示)
  • 🔧 实时发生的工具调用
  • ✓ 实时返回的工具结果
  • 📝 逐字符流式输出的最终响应

使用流式

交互模式(默认)

# Streaming is enabled by default python main.py # Disable streaming python main.py --no-stream # Toggle streaming during chat with /stream command

编程式用法

from main import ToolCallingAgent # Initialize agent agent = ToolCallingAgent() # Stream response for chunk in agent.chat("What's the weather in Tokyo?", stream=True): chunk_type = chunk.get("type") content = chunk.get("content", "") if chunk_type == "thinking": print(f"Thinking: {content}") elif chunk_type == "tool_call": print(f"Tool: {content['name']}") elif chunk_type == "tool_result": print(f"Result: {content}") elif chunk_type == "content": print(content, end="", flush=True)

测试流式

# Run streaming demo python demo_streaming.py # Compare streaming vs regular mode python test_streaming.py --mode compare

📈 服务基准(benchmark.py

benchmark.py 是实验 2-1 的配套基准,用于测量本地部署的小模型在 服务(serving) 层面的核心指标,帮助建立对吞吐 / 延迟 / 批处理 / KV Cache 的直觉。它通过 OpenAI 兼容接口工作,vLLM 与 Ollama 均可。

所有数字都来自真实服务端的实测,脚本本身不产生任何合成数据。 如果服务端尚未启动,可用 --dry-run 离线查看每个场景将要发出的请求配置。

场景(--scenario

场景 说明 对应书中要点
throughput 单流解码吞吐(tok/s)与首 token 延迟(TTFT) 实验 2-1 第 2 点:M2 上 >100 tok/s
kv-cache 前缀缓存 命中 vs 未命中 的 TTFT 对比 实验 2-1 第 5 点:改动系统提示词开头 → 缓存失效、需重算整个前缀
batching 不同并发度下的聚合吞吐(批处理权衡) 连续批处理如何提升系统吞吐
all 依次运行以上全部场景(默认)

用法

# 1. 先启动服务端(二选一) python server.py # vLLM(需要 NVIDIA GPU) ollama serve && ollama pull qwen3:0.6b # Ollama(Mac / 无 GPU) # 2. 运行基准 python benchmark.py --scenario all --output results.json # 跑全部并保存 python benchmark.py --scenario kv-cache --backend ollama # 只看 KV Cache TTFT 对比 python benchmark.py --scenario batching --concurrency 1,2,4,8 # 批处理吞吐扫描 # 离线查看计划(不访问服务端),可用于验证参数 python benchmark.py --dry-run python benchmark.py --help

主要参数

  • --backend {vllm,ollama}:推断默认地址与模型名(vLLM Qwen3-0.6B @ :8000/v1,Ollama qwen3:0.6b @ :11434/v1
  • --base-url / --model / --api-key:覆盖默认连接配置
  • --repeatsthroughput / kv-cache 的重复次数(默认 5)
  • --max-tokens / --temperature:生成参数
  • --prefix-tokenskv-cache 场景共享前缀的近似长度,越长缓存效果越明显(默认 1024)
  • --concurrencybatching 场景的并发度列表,逗号分隔(默认 1,2,4,8
  • --output:将结果写入 JSON 文件

说明:kv-cache 依赖服务端的前缀缓存(vLLM 的 automatic prefix caching 默认开启)。命中组保持系统提示词逐字节不变;未命中组每次只在系统提示词开头插入一个唯一计数串,前缀被改写导致缓存全部失效——这正是书中「系统提示词一旦定下来就不要改」的实测演示。

🔧 配置

env.example 复制为 .env 并自定义:

# For vLLM (if you have GPU) MODEL_NAME=Qwen/Qwen3-0.6B VLLM_HOST=localhost VLLM_PORT=8000 # Logging LOG_LEVEL=INFO

📊 工具调用格式

本项目使用标准 OpenAI 兼容工具调用

{ "tool_calls": [{ "id": "call_123", "type": "function", "function": { "name": "get_weather", "arguments": {"location": "Tokyo"} } }] }

没有临时解析或自定义格式——只是各平台通用的标准。

🐛 故障排查

"Ollama not found"

  • Macbrew install ollama && ollama serve
  • Windows:从 ollama.com 下载
  • Linuxcurl -fsSL https://ollama.com/install.sh | sh

"No models installed"

ollama pull qwen3:0.6b # Default model used by this project

"CUDA not available"(Linux/Windows)

  • 安装 NVIDIA 驱动与 CUDA 工具包
  • 否则脚本会自动改用 Ollama

检查系统兼容性

python check_compatibility.py

🤝 支持的模型

默认模型:

  • Qwen3(0.6B)— 本项目使用的默认模型。体积小,工具调用支持尚可。

其他兼容工具调用的模型:

  • Qwen3(8B+)— 工具支持良好
  • Llama 3.1/3.2(8B+)— 工具支持良好
  • Mistral Nemo — 工具调用出色

针对 vLLM:

  • 默认使用 Qwen3-0.6B
  • 可配置任何 vLLM 支持的模型

📚 工作原理

  1. 平台检测main.py 检测你的操作系统与 GPU 可用性
  2. 后端选择
    • 有 NVIDIA GPU?→ 使用 vLLM 获得最佳性能
    • 无 GPU 或在 Mac 上?→ 使用 Ollama 做本地推理
  3. 工具执行:两种后端都使用标准 OpenAI 工具调用格式
  4. 响应生成:执行工具并把结果回传给模型

🔗 参考资料

📄 许可证

本 demo 项目按"原样"提供,用于教学目的。


作者与出处
原作者: bojieli
来源:bojieli
许可证:Apache-2.0
整理: 灏天文库整理
由灏天文库结构化整理,提供目录导航、全文检索与在线阅读,便于系统化学习
发布者: 作者: bojieli 转发
评论区 (0)
U