技术博客
硬件教程

【三分钟看懂Needle 2】14MB 塞进树莓派:Needle 2 把 Agent 的“工具调用”压到了极致

yiwan-cat2026-08-19 21:38
【三分钟看懂Needle 2】14MB 塞进树莓派:Needle 2 把 Agent 的“工具调用”压到了极致

项目地址: https://github.com/cactus-compute/needle

图1 Needle 2 项目概览:45M 参数、14MB 体积与端侧工具调用

如果我们把今天的大模型 Agent 拆开,会发现很多端侧场景其实根本不需要一个“什么都知道、什么都能聊”的大模型。

智能灯只需要听懂:

“把客厅灯调暗一点。”

机器人只需要听懂:

“向前走两米,然后回到充电座。”

手表只需要听懂:

“下午三点提醒我开会。”

真正需要解决的问题往往只有两个:

该调用哪个函数?参数应该填什么?

Cactus Compute 开源的 Needle 2,就是沿着这个思路一路做减法。

它不是试图把 ChatGPT 塞进微控制器,而是干脆把“聊天、百科知识、长篇写作”这些能力砍掉,把模型集中训练成一个极小的 Tool Calling / Device Control 模型

最终得到的东西相当激进:

指标 Needle 2
参数量 45M
部署文件 约 14MB
Session RAM 约 28MB
量化 CQ2-bit
上下文 256 tokens 滑动窗口
主要能力 Tool Calling / Device Use / Structured Extraction
Raspberry Pi 5 解码 官方给出 500+ tok/s
部署形式 Python / CLI / C 静态库 / WebAssembly 等

Needle 2 的目标设备包括手机、可穿戴设备、智能家居、机器人,以及具备足够外部内存的 MCU 级硬件。

这篇文章不准备深挖网络里的数学细节。

我们直接回答三个问题:

Needle 2 到底是什么?为什么能这么小?以及怎样在自己的项目里把它跑起来?


一、先别把 Needle 2 当成一个迷你 ChatGPT

理解 Needle 2 最重要的一步,是把“LLM”的传统印象先扔掉。

它更接近这样一个组件:

自然语言
   ↓
Needle 2
   ↓
选择工具
   ↓
提取参数
   ↓
生成合法结构化调用
   ↓
你的程序执行动作

例如用户说:

把卧室空调调到 24 度

系统里提前注册了:

set_temperature(room, temperature)

Needle 真正需要干的事情只有:

{
  "room": "bedroom",
  "temperature": 24
}

剩下真正操作空调的事情,由你的程序完成。

这就是 Needle 2 能压到 45M 参数的重要前提。

它没有必要记住大量世界知识,也没必要特别擅长写文章。

智能家居、手机、手表和机器人本身已经把功能暴露成函数,模型只需要完成:

自然语言 → 正确函数 + 正确参数。


二、Needle 2 真正有意思的,是它把 Agent 变成了“端侧零件”

很多端侧大模型项目仍然遵循一个套路:

7B / 3B / 1B 大模型
      ↓
INT8 / INT4
      ↓
继续压缩
      ↓
想办法塞进设备

Needle 2 的路线完全相反:

先问设备真正需要什么
        ↓
只保留 Tool Calling
        ↓
模型、量化、推理引擎一起设计
        ↓
直接从目标硬件倒推架构

所以它不是“把一个大模型使劲压小”。

更准确地说,是:

从一开始就为了低内存、低功耗、离线工具调用重新造了一个模型。

这也是 Needle 最值得看的地方。

它讨论的不是:

如何让小设备也能聊天?

而是:

设备上的 AI 到底有没有必要聊天?


三、为什么只有 14MB?

Needle 2 背后使用的是 Cactus Compute 的 Simple Attention Network

这里不展开公式。对于项目博客来说,理解它做了哪些工程取舍,比推公式更重要。


图2 Needle 2 架构、核心特性与快速开始

看图时不需要盯数学细节,记住下面四件事情就够了。

1. Hadamard MLP:把最吃参数的一块砍掉

传统 Transformer 里的 FFN 往往是参数大户。

Needle 使用一种非常轻量的 Hadamard 变换完成通道混合,把大量传统全连接参数省掉。

直观理解就是:

传统模型

Attention
   ↓
一大坨可学习 FFN 参数
   ↓
下一层


Needle

Attention
   ↓
固定高效变换 + 少量参数
   ↓
下一层

对于 Tool Calling 来说,模型更依赖当前上下文里的工具定义和用户指令,而不是依赖庞大的参数去记忆世界知识。

2. Engram:知识不用全部塞进网络参数里

Needle 还增加了一种哈希 n-gram memory。

可以把它理解成:

模型主干
   +
一个非常便宜的快速记忆表

需要的时候查几行,而不是让所有知识都参与每一个 token 的矩阵计算。

3. 256-token 滑动窗口:内存不跟着聊天无限长

普通大模型一个麻烦是:

对话越来越长
↓
KV Cache 越来越大
↓
RAM 越吃越多

Needle 直接把窗口限制在 256 tokens

超过窗口以后,旧信息逐步滑走。

但工具定义不能忘,所以 system/tool 信息会被保留下来。

结果就是:

普通模型:

聊天越久
████████████████████████████ → RAM 持续增加


Needle 2:

████████
████████
████████

RAM 基本维持固定上限

这也是它能把 session RAM 控制在约 28MB 的关键设计之一。

4. Byte-level Grammar:不是让模型“尽量输出 JSON”

这是 Needle 2 特别实用的一点。

普通大模型 Tool Calling 很像:

请你一定按照 JSON 格式回答。

然后模型可能会先来一句:

好的!以下是您需要的 JSON:

接着 JSON parser 当场翻车。

Needle 走的是另一条路。

工具的 schema 会直接被编译成 byte-level grammar,模型生成时非法路径本身就不能走。

例如定义:

brightness: 0 ~ 100

那么结构约束会直接进入生成过程。

这不是:

“希望模型别犯格式错误。”

而是:

把错误出口焊死。


四、快速开始:5 分钟跑起来

好了,原理到此为止。

下面进入这篇文章真正重要的部分。

1. 安装

最简单就是:

pip install cactus-needle

建议先创建一个虚拟环境:

python -m venv .venv

Linux / macOS:

source .venv/bin/activate
pip install cactus-needle

Windows:

.\.venv\Scripts\activate
pip install cactus-needle

第一次初始化时,Needle 会自动获取当前平台对应的 engine 并缓存。

之后真正执行 inference 时不需要联网。

**注意:**网上有些文章会把 cactus-needle[gpu]cactus-needle[metal] 当成普通推理安装方式。实际上它们主要服务于 JAX 微调训练。普通 Tool Calling 推理直接安装 cactus-needle 即可。


2. 第一个例子:让 Needle 调天气工具

新建:

demo.py

写入:

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]
)

result = agent.run(
    "what's it like in Lagos right now?"
)

print(result["results"])

运行:

python demo.py

模型会先理解:

what's it like in Lagos right now?

然后选择:

get_weather

自动抽取:

city = Lagos

执行你的 Python 函数,再把执行结果带回来。

整个过程可以理解为:

“Lagos 现在天气怎么样?”
             ↓
        Needle 2
             ↓
       get_weather
             ↓
      city="Lagos"
             ↓
       Python function
             ↓
 {27°C, clear}

到这里,一个最小 Agent 就跑起来了。


五、实际项目里,更推荐把“模型判断”和“真实执行”分开

上面的 run() 很适合 Demo。

但如果工具会产生真实副作用,例如:

删除文件
打开门锁
发送消息
转账
启动机器人
关闭设备

更稳妥的做法是把模型和执行器分开。

先使用:

response = agent.complete(...)

拿到候选 Tool Call,再决定要不要执行。

例如:

import needle


@needle.tool
def set_light(room: str, brightness: int):
    """Set room light brightness."""
    return {
        "room": room,
        "brightness": brightness
    }


agent = needle.Needle(
    tools=[set_light]
)

response = agent.complete(
    "dim the bedroom light to 30"
)

print(response)

Needle 的返回对象中可以包含类似:

function_calls
confidence
prefill_tps
decode_tps
peak_ram_mb

因此生产环境可以进一步增加:

CONFIDENCE_THRESHOLD = 0.90

response = agent.complete(
    "dim the bedroom light to 30"
)

if response["confidence"] >= CONFIDENCE_THRESHOLD:
    print("允许执行")
    print(response["function_calls"])
else:
    print("置信度不足,转人工或云端模型")

更完整一点的流程应该是:

Needle
   ↓
confidence gate
   ↓
schema validator
   ↓
权限检查
   ↓
用户确认
   ↓
真正执行设备动作

需要特别强调:

置信度不是权限系统。

对于门锁、机器人运动、支付、删除数据之类的高风险动作,仍然需要独立的权限校验或人工确认。


六、第二种玩法:直接做结构化数据提取

Needle 还有一个非常实用的能力:

Structured Extraction。

例如一段杂乱文本:

Invoice from Acme Corp,
$1,200.00,
due 2026-09-01

我们想把它转换成:

公司
金额
日期

定义一个 Pydantic Model:

from pydantic import BaseModel
import needle


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)
print(invoice.total)
print(invoice.due_date)

得到一个真正的类型化 Python 对象。

本质上:

Tool Calling

用户文本
↓
函数参数


Structured Extraction

文档文本
↓
数据字段

其实是同一类问题。

这个能力很适合:

  • 发票字段提取
  • 设备日志解析
  • 传感器记录整理
  • OCR 后处理
  • 表单录入
  • 本地隐私数据结构化

而且不需要把这些文本发到云端。


七、第三种玩法:Playground

如果暂时不想写代码,Needle 自带 Web Playground。

安装以后直接:

needle playground

浏览器访问:

http://127.0.0.1:7860

就能看到交互界面。

你可以:

  • 编辑 Prompt
  • 添加工具
  • 修改 Schema
  • 测试 Tool Calling
  • 连续对话
  • 测试数据
  • 启动 Fine-tuning

如果准备评估 Needle 是否适合自己的硬件项目,我建议第一步不是研究论文。

就是:

pip install cactus-needle
needle playground

然后把自己设备的 5~10 个真实工具 schema 丢进去。

十几分钟基本就能判断:

它到底有没有用。


八、真正部署到树莓派,不一定要带 Python

这也是 Needle 2 很工程化的一点。

Python 只是开发入口。

官方还提供独立运行的二进制和 C/C++ embedding library。

例如:

pip install cactus-needle
needle download linux-arm64

当前支持的平台覆盖 ARM、x86、RISC-V、Android、iOS、WebAssembly 等多种目标。

下载后可以直接运行:

./needle \
  --tools tools.json \
  --prompt "dim the living room to 30"

也可以将其作为本地服务运行,再由自己的应用调用。

于是整个系统可以变成:

手机 App
机器人 ROS 节点
智能家居程序
浏览器
嵌入式上层逻辑
          ↓
      Needle Engine
          ↓
    Tool Call JSON
          ↓
      真实硬件

这也是为什么 Needle 2 不应该仅仅被理解成一个 Python 小模型。

更准确地说,它是一个可以嵌入设备软件栈里的 轻量自然语言控制组件


九、树莓派到底跑多快?

官方给出的 Raspberry Pi 5 数据已经到了几百 token/s 的量级。

这组速度放到聊天模型上可能没那么重要。

但放到 Tool Calling 场景里完全是另一回事。

因为它通常只需要输出类似:

{
  "room": "living_room",
  "brightness": 30
}

一共没几个 token。

换句话说,Needle 追求的不是:

每秒吐一大段文章。

而是:

设备命令下来以后,迅速给出动作。

这对机器人、穿戴设备和 IoT 才是关键指标。


十、普通 ESP32 真能直接跑吗?

这里需要稍微泼一点冷水。

网上很容易看到一句:

Needle 2 可以跑 ESP32。

这句话不能简单理解成:

随便拿块普通 ESP32 开发板 pip install 一下就行。

更准确的理解是:

Needle 2 已经把 LLM-style Tool Calling 推进到了 MCU 级硬件预算,但目标板仍然需要满足对应的 RAM、外部存储和运行库条件。

例如带较大 PSRAM / SDRAM 的 MCU 平台会更现实。

所以“可以运行在 ESP32 级设备”与“任何 ESP32 开发板都能直接运行”并不是一回事。


十一、如果有几十、几百个工具怎么办?

假设智能家居里有:

set_light
set_temperature
play_music
open_curtain
lock_door
start_robot
find_phone
send_message
set_alarm
...

几十上百个工具全部塞给模型,会占上下文,也会让工具选择变难。

Needle 使用了 Tool Retrieval 思路:

用户 Query
   ↓
Tool Retrieval
   ↓
挑出最相关 Top-K 工具
   ↓
只在这些工具中生成

这样做有两个好处。

第一,减少上下文压力。

第二,grammar 只需要针对候选工具构建。

对于真正的 IoT 或机器人系统来说,这比让一个模型面对整个 API 海洋要实用得多。


十二、还不够准?再考虑微调

45M 参数的另一个好处就是:

它已经小到普通开发环境也能比较轻松地做领域微调。

训练数据可以围绕:

用户指令
+
当前工具集合
+
正确工具
+
正确参数

进行组织。

最终你可以得到:

智能家居 Needle
机器人 Needle
工业设备 Needle
实验室仪器 Needle
车载 Needle

它们不需要拥有全部世界知识。

只需要特别熟悉:

自己的几十个动作。

这里有一个很重要的工程顺序:

先用原版模型测试
↓
收集真实失败案例
↓
分析到底是 Tool Schema 还是模型问题
↓
最后再决定是否微调

不要一上来就训练。

很多 Tool Calling 的问题,其实首先应该从工具命名、描述、参数定义和业务流程上解决。


十三、性能不错,但别被“14MB”三个字冲昏头

Needle 的优势很明确:

  • 模型足够小
  • 内存预算低
  • Tool Calling 是核心任务
  • 结构化约束强
  • 可以离线
  • 易于嵌入设备

但它并不是 14MB 的 ChatGPT。

它也不应该被拿去和通用大模型比:

长文写作
百科问答
复杂推理
长上下文总结
通用聊天

Needle 的核心目标不是:

用 45M 参数战胜所有大模型。

而是:

在一个非常窄但极有价值的端侧 Tool Calling 场景里,把模型压到设备真正能够承受的尺寸。


十四、14MB 也不等于整个 Python 环境只有 14MB

这一点做项目时一定要区分。

官方强调的:

14MB

主要指 Needle 2 的模型 / engine artifact。

如果你:

pip install cactus-needle

开发环境本身还可能包含 Python 依赖、训练组件以及其他工具链。

因此真正做嵌入式产品时,更应该关注:

Needle Native Engine
+
自己的应用代码
+
设备驱动
+
运行时 RAM

而不是拿整个 Python 虚拟环境的磁盘大小去理解那个 14MB。


十五、Needle 2 最适合拿来做什么?

1. 智能家居

“晚上十点把卧室灯调到 20%”
        ↓
set_light()

这类任务根本不需要一个十几亿参数的大模型。


2. 可穿戴设备

“十五分钟后提醒我”
       ↓
set_timer()

真正有价值的是:

低延迟、本地执行、没有网络也能工作。


3. 机器人

例如:

“去厨房检查一下”
        ↓
navigate()
        ↓
capture_image()
        ↓
return_home()

Needle 可以放在:

语音识别
   ↓
Needle
   ↓
ROS Service / Action
   ↓
机器人控制器

它不是负责机器人的视觉感知和运动规划。

它负责:

把人的语言翻译成机器人 API。


4. 离线隐私设备

例如:

  • 医疗记录字段提取
  • 实验室数据录入
  • 本地发票解析
  • 企业内部结构化信息

都可以:

文本
↓
Needle
↓
结构化数据

不用先把敏感文本上传云端。


5. Edge-Cloud 混合 Agent

我认为这甚至可能是 Needle 最现实的生产用法:

用户请求
   ↓
Needle 2 本地处理
   ↓
confidence 足够?
   ├── Yes → 本地执行
   │
   └── No → 云端大模型 / 人工

于是日常的:

开灯
调温
播放音乐
设置提醒
设备控制

全部本地完成。

真正复杂的问题才去云端。

这比让一个 7B 模型常驻在小设备里合理得多。


十六、它不适合什么?

Needle 2 不适合拿来做:

  • 写公众号长文
  • 回答大量百科知识
  • 复杂数学推理
  • 长文总结
  • 长上下文 RAG
  • 通用聊天机器人

所以不要问:

14MB 的 Needle 能不能替代 ChatGPT?

应该问:

我的产品里,真的需要 ChatGPT 吗?

如果设备的 AI 工作只是:

理解一句话
→
选择一个动作
→
填几个参数

那么答案可能真的是:

不需要。


十七、如果是我做项目,我会这样上 Needle 2

我不会一开始就微调。

我会按照下面这条路线:

第一阶段
pip install cactus-needle
↓
Playground 测真实工具


第二阶段
@needle.tool
↓
Python 原型


第三阶段
complete()
↓
confidence gate
↓
权限与参数校验


第四阶段
ARM / C library
↓
真正上树莓派或设备


第五阶段
收集真实失败样本
↓
再考虑 LoRA 微调
↓
导出自己的模型

尤其不要反过来:

先训练模型
↓
再想它到底有什么用

Needle 本身已经够小,真正决定它是否有价值的,是你的 Tool Schema 和实际设备接口设计


写在最后

Needle 2 最吸引我的其实不是:

45M 参数。

也不是:

14MB。

甚至不是树莓派上的几百 tok/s。

而是它重新问了一个长期被大模型热潮掩盖的问题:

一个智能设备真正需要多大的模型?

如果手机只需要设置闹钟,手表只需要调用几个 App,机器人只需要理解十几个动作,智能家居只需要操作灯、空调、窗帘和门锁,那么一个拥有庞大世界知识的大模型,很可能是在拿大炮替你按开关。

Needle 2 选择了另一条路:

不要把整个 AI 世界塞进设备。

只把设备真正需要的那一点智能塞进去。

对于正在做 IoT、机器人、智能家居、可穿戴设备、离线 AI 或资源受限端侧 Agent 的开发者来说,Needle 2 很值得先花十分钟跑一次:

pip install cactus-needle
needle playground

然后把自己产品里的真实工具扔进去。

能不能用,一试便知。


参考链接

点赞收藏
// 评论0
0 / 500
还没有评论,快来抢沙发