📋 部署前的准备

  • Python 环境:需要 Python 3.10 或更高版本。
  • 网络:首次运行需要联网,因为要从 Hugging Face 下载推理引擎。之后推理过程本身不访问网络。
  • 硬件:CPU 就能跑,不需要 GPU。如果要自己微调,有 NVIDIA GPU 或 Apple Silicon 会快很多。

🚀 方式一:Python 包部署(最直接)

这是官方主推的方式,适合在 Python 项目里集成工具调用能力。

第一步:安装

1
pip install cactus-needle

如果你只做推理,这样装就够了。需要微调或导出模型的话,加上 train 扩展:

1
pip install "cactus-needle[train]"

第二步:写你的第一个工具调用

Needle 的用法很简洁——用 @needle.tool 装饰一个普通 Python 函数,它的签名和文档字符串就自动变成了工具描述:

1
2
3
4
5
6
7
8
9
10
import needle

@needle.tool
def get_weather(city: str):
"""Get the current weather for a city."""
return {"city": city, "temp_c": 27, "sky": "clear"}

agent = needle.Needle(tools=[get_weather])
print(agent.run("what's it like in Lagos right now?")["results"])
# [{'city': 'Lagos', 'temp_c': 27, 'sky': 'clear'}]

agent.run() 会自动完成整个循环:模型决定调用 get_weather、Needle 执行这个函数、把结果喂回模型、返回最终响应。你不需要手动解析 JSON 或驱动多轮对话。

第三步(可选):结构化提取

如果你只是想从文本里抽取数据,可以用 extract(),传入一个 Pydantic 模型就能拿回类型化的对象:

1
2
3
4
5
6
7
8
9
from pydantic import BaseModel

class Invoice(BaseModel):
vendor: str
total: float
due_date: str

invoice = needle.extract("Invoice from Acme Corp, $1,200.00, due 2026-09-01", Invoice)
print(invoice.vendor, invoice.total) # -> Acme Corp 1200.0

🌐 方式二:浏览器 Playground(可视化调试)

如果你不想写代码,只想先感受一下这个模型能做什么,官方提供了一个 Web 界面。

1
needle playground

它会在本地 http://127.0.0.1:7860 启动一个页面,你可以在里面直接编辑工具描述、修改提示词、运行查询。它还带有一个 “Finetune on these tools” 按钮,可以直接在浏览器里触发微调流程,训练完后下载调好的 .cact 文件。

🐳 方式三:Docker + OpenAI 兼容 API(非官方)

Needle 官方并没有提供 OpenAI 兼容的 HTTP 服务,但社区有一个 needle-openai 项目填补了这个空缺。如果你想让现有的 OpenAI 客户端直接调用 Needle,可以用这个方案。

1
docker run -d -p 8000:8000 -v needle-cache:/cache ghcr.io/sirmmo/needle-openai:latest

启动后,用任何 OpenAI SDK 指向 http://localhost:8000/v1 即可。不过要注意几个关键限制:

  • 它不是一个聊天模型。当没有工具可调用时,它会把模型的推理痕迹作为 content 返回,而不是自由对话。
  • 一次只能处理一个请求。原生引擎是单会话的,并发请求会串行处理,否则可能崩溃。
  • 长输入会被静默截断。截断后它会返回一个看起来很自信但实际上是错误的答案,confidence 会是 0.0。所以一定要检查置信度分数

🔧 方式四:WebAssembly / Rust(边缘设备专用)

如果你的目标平台是浏览器、Cloudflare Workers 或嵌入式设备,needle-rs 提供了 413KB 的 WASM 运行时,整个模型(13.7MB)也能在浏览器标签页里跑起来,数据完全不出设备。

1
npm install needle-rs
1
2
3
4
5
6
7
8
import init, { NeedleV2Wasm } from "needle-rs";
await init();

const res = await fetch("https://huggingface.co/Cactus-Compute/needle2/resolve/main/needle2.cact");
const engine = NeedleV2Wasm.load(new Uint8Array(await res.arrayBuffer()));

const out = engine.run_json(query, toolsJson);
// [{"name":"get_weather","arguments":{"city":"Paris"}}]

🎯 微调:让它学会你的工具集

Needle 的基座模型在通用工具调用上表现不错,但如果你有一组特定的工具(比如公司内部 API),微调能显著提升准确率。流程分三步:

1. 准备数据(JSONL 格式,每行一个样本)

1
{"query": "dim the kitchen to 10", "tools": [{"name": "set_lights", ...}], "answers": [{"name": "set_lights", "arguments": {"room": "kitchen", "brightness": 10}}], "reasoning": "'kitchen' -> room; 'dim to 10' -> brightness 10"}

官方建议每个工具至少准备 120 个样本,否则会过拟合。数据里要包含约 1/8 的“离题样本”(answers: []),让模型学会什么时候不该调用工具。

2. LoRA 微调

1
needle finetune data.jsonl --epochs 10

3. 构建调优后的模型

1
needle build checkpoints/needle2.pkl --lora checkpoints/needle_lora.pkl --out my_needle.cact

生成的 my_needle.cact 依然是单文件,可以直接用同一个引擎运行,不需要重新编译。

⚠️ 几个需要留意的地方

  • 它不是聊天模型。官方反复强调这一点:Needle 只输出工具调用或什么都不输出,没有自由生成的能力。如果你需要对话,应该用别的模型。
  • 工具描述决定一切。官方原话是“describing them well is the whole game”——工具的名称、参数类型、文档字符串,直接决定了模型能不能正确调用。
  • 置信度要用起来。每个响应都带一个 0-1 的置信度分数。低置信度意味着模型“没把握”,这时候应该把请求转给人工或更大的模型处理。
  • 遥测默认开启。Cactus Compute 会收集匿名的使用数据(函数名、包版本、操作系统),不涉及你的提示词或输出。可以用 NEEDLE_TELEMETRY=0 关掉。

你打算把 Needle 用在什么场景?是想在 Python 项目里做工具调用,还是想在浏览器或嵌入式设备上跑?告诉我具体目标,我可以帮你看看哪种部署方式更合适。