本文研究对象是截至 2026 年 8 月 24 日公开的 cactus-compute/needle 主分支、其 API 与微调文档、README 中的 Needle 2 说明,以及项目明确链接的 Simple Attention Network 论文。123 仓库快速迭代,版本、引擎格式和基准数字可能继续变化;文中把“源码事实”“论文证据”“项目自述”和“工程推断”分开标注,不把单次跑通或 README 宣称视为生产保证。

先给结论

Needle 最准确的定位是:

一个把自然语言压缩成受 schema 约束的本地动作或结构化记录,并在低内存设备上执行的模型—运行时一体化系统。

它不是通用对话模型,也不是完整的自主 Agent。它把问题限定成一个更窄、但更可交付的契约:

自然语言 query
    -> 工具/记录 schema 选择
    -> 合法的 JSON function call
    -> 本地函数或设备 API 执行
    -> 执行结果回灌
    -> 下一步调用或结束

这个取舍带来四个直接结果:

  1. 结构可靠性优先于开放式表达:模型默认解决“调用什么、参数是什么”,不是写长篇自由文本。
  2. 设备约束优先于通用能力:内存、延迟、断网运行和可预测失败比世界知识覆盖重要。
  3. 安全边界在解码和外部策略两处同时存在:grammar 可以阻止非法格式和部分非法值,但不能判断一个合法动作是否有业务风险。
  4. 商业价值集中在执行层:智能家居、机器人、汽车座舱、可穿戴、工业设备和隐私结构化抽取,比开放式聊天更匹配它。

一、Needle 到底是什么:模型、SDK、引擎和格式的合体

1. 仓库表面是 Python 包,真正产品是跨层闭环

GitHub 仓库的 Python 层包含 needle/agent、needle/model、needle/playground 和文档;安装 cactus-needle 后,Python 会按当前平台寻找或下载动态库,然后通过 ctypes 调用 C engine。1

可以把仓库分成四层:

层级 关键文件/对象 职责
公开 Python API needle/init.py 的 Needle、extract、tool、Field 工具注册、会话、调用循环、结构化抽取
Agent/schema 层 needle/agent/tools.py、fetch.py Python 注解/docstring 到 JSON Schema;引擎下载与离线缓存
训练/导出层 needle/model/architecture.py、finetune.py、quantize.py、export.py JAX 模型、LoRA、量化感知、.cact 二进制导出
设备运行时 platform-specific libneedle 和 standalone runner 权重加载、prefill、受 grammar 约束的解码、KV cache、性能统计

因此,“Needle 是一个模型”只说对了一半。真正可部署的交付物是:

工具 schema + .cact 权重 + 对应 engine + Python/设备调用协议

.cact 不是普通的 safetensors。导出文件携带架构几何、量化码本、张量目录、tokenizer、KV 窗口和可选 probe head;运行时按固定张量顺序读取,不需要在设备上解析一套通用深度学习框架。源码还明确指出,导出格式与 engine 版本绑定,旧版本导出的 archive 可能无法被新运行时加载。1

2. 公开指标与其真正含义

README 将 Needle 2 描述为:

  • 45M 参数;
  • 单个约 14MB 二进制;
  • 完整会话约 28MB RAM;
  • CQ2-bit 压缩;
  • 约 256 token 的滑动窗口;
  • 支持工具调用、设备使用和结构化抽取;
  • 推理阶段不联网;
  • 工具超过 5 个时启用内置工具检索;
  • 每个基础模型响应带 confidence。

这些数字表达的是部署边界,不是通用智能水平。14MB 的价值在于把模型放进受限设备;它不意味着 14MB 模型能覆盖大模型的知识、语言和规划能力。工具描述本身是外部输入,模型更多是在一个动态 schema 空间里做选择与参数填充,而不是从庞大参数记忆中回答任意问题。

二、从源码看一次调用是如何发生的

1. Needle.init:绑定一次工具集和一组权重

needle/init.py 的 Needle 构造器接收:

Needle(
    tools=None,
    system=None,
    weights=None,
    tool_index_path=None,
    buffer_size=65536,
)

其核心动作是:

  1. 将 callable、Pydantic model、原始 JSON schema 统一转成 schema;
  2. 保存 Python 函数名到函数对象的映射;
  3. 把 system 编码成环境事实;
  4. 将工具 schema 序列化成 JSON;
  5. 通过 _bind() 初始化共享 engine;
  6. 如果给了 .cact,把整个二进制读入内存并调用 needle_load。

源码有一个容易被忽略的全局状态限制:engine 不能卸载已加载权重。基础模型和 tuned 模型在同一进程中的切换不是普通对象级切换;一旦 tuned 权重绑定,后续创建 base agent 可能直接抛错,防止程序“看似切换、实际仍使用旧权重”。生产系统应按模型类型分进程,或在进程启动阶段固定权重。1

2. tools.py:把 Python 类型变成模型可执行的契约

@needle.tool 并不执行函数,它给函数附加 _needle_tool schema。build_schema() 使用:

  • inspect.signature;
  • typing.get_type_hints(…, include_extras=True);
  • docstring 的 Google-style Args:;
  • Literal、Annotated;
  • Pydantic 的 model_json_schema()。

原生类型映射大致是:

str -> string
int -> integer
float -> number
bool -> boolean
list -> array
dict -> object

还支持:

  • Optional/union 的简化处理;
  • Python Enum;
  • Literal[…] 枚举;
  • list[T];
  • Pydantic model;
  • 可选默认值;
  • 参数 description。

needle.Field 把运行时约束挂到 schema 上,包括:

description
enum / const
ge / le / gt / lt
multiple_of
min_length / max_length
pattern / format
min_items / max_items / unique_items

这一步的工程意义是:工具的接口说明不再只是 prompt 文本,而成为后续 grammar 编译的机器可执行约束。不过 schema 推导不是完整的 Pydantic/JSON Schema 实现:复杂嵌套 union、任意 Python 类型、业务级交叉字段约束仍可能退化为字符串或需要手写 schema。实际项目应对生成后的 schema 做快照测试,而不能只看函数类型注解。

3. complete():一次模型轮次的协议

agent.complete(text) 调用 C engine 的 needle_complete,从固定 buffer 中读回 JSON envelope。文档给出的响应结构类似:

{
  "type": "call",
  "success": true,
  "error": null,
  "error_code": null,
  "function_calls": [
    {
      "name": "set_lights",
      "arguments": {
        "room": "living room",
        "on": true,
        "brightness": 30
      }
    }
  ],
  "reasoning": "'living room' -> room; 'dim' -> on true, brightness 30",
  "confidence": 0.94,
  "prefill_tps": 4300.0,
  "decode_tps": 850.0,
  "peak_ram_mb": 28.5
}

type 通常有两种语义:

  • call:需要外部执行 function_calls;
  • respond:本轮结束,没有后续调用。

一个重要边界是:function_calls 受 grammar 约束,而 reasoning 是另一路自由生成文本。reasoning 可以帮助审计参数来源,却不能被视为形式化证明;安全策略不能因为 reasoning 看起来合理就放行。

4. run():最小 Agent loop,而不是通用规划器

run(query, max_steps=8, max_new_tokens=256) 的逻辑非常直接:

  1. complete(query);
  2. 如果是 call,按名称找到 Python 函数;
  3. 用 fn(**arguments) 执行;
  4. 捕获异常并把错误对象放入结果;
  5. 将结果 JSON 序列化后再次 complete();
  6. 最多循环 max_steps 次;
  7. 最终把所有执行结果挂到 response[“results”]。

它支持多步依赖,例如先 search_for_contact,再使用返回的 contact_id 调 send_instant_message。文档明确给出“工具结果回灌后继续下一调用”的路径。4 但它没有内建:

  • 任务分解树;
  • 计划持久化;
  • 工具权限系统;
  • 幂等键;
  • 重试退避;
  • 超时隔离;
  • 人工确认;
  • 事务回滚;
  • 预算/成本管理;
  • 长期记忆。

所以 run() 更准确是受限工具循环,不是 LangGraph、OpenHands 或通用自主 Agent 的替代品。

三、Needle 的模型底层:为什么它能这么小

1. Simple Attention Network 论文解决了什么问题

Needle README 链接的论文是《A Controlled Study of Attention-Only Transformers》。论文研究一个很具体的问题:

Transformer 中占据约三分之二非 embedding 参数的 FFN,究竟是不可替代的计算原语,还是主要提供了可被 attention 重新承载的参数容量?2

论文对标准 Transformer 与 attention-only 的 Simple Attention Network(SAN)做了三种公平对照:

对照 控制变量 结果
iso-depth 深度相同,直接删 FFN 标准 Transformer 领先约 0.47 nats
iso-FLOP 训练 FLOPs 相同 标准 Transformer 领先约 0.26 nats
iso-param 参数量相同,把预算换成 attention 深度 差约 0.0055 nats,约 0.27% loss

论文还报告:

  • 差距随训练预算从 5B、30B 到 105B token 缩小;
  • QK-normalization 是 48 层 attention-only 可训练的关键;
  • sandwich normalization 有小幅收益;
  • residual gate 在测试设置下基本性能中性;
  • SAN 在上下文中已有证据的任务上更强;
  • 需要从参数记忆中召回知识的低上下文任务上更弱;
  • FFN 被删掉后,内容写入能力部分转移到 attention output projection;
  • 在相同参数量下,SAN 可能需要更多 FLOPs/token。

论文的结论不是“FFN 没用”,而是:

在小规模、推理密集、上下文提供证据的分布上,FFN 的功能很大程度可以被重新分配的 attention 参数替代;剩余差距主要是参数化知识存储,而不是所有非线性都消失。

论文的局限也必须保留:

  • 总规模不超过 87M 参数;
  • 主要训练语料是 reasoning-dense 的 SYNTH;
  • MMLU 等知识基准基本无法区分;
  • 只有一个 FineWeb-edu 知识密集控制点;
  • 结论不能外推为所有规模、所有语料和所有 Agent 任务。

2. Needle 2 不是论文 SAN 的原样复刻

README 对 Needle 2 的描述更丰富。它把 SAN 思路与端侧工具模型组件组合起来:

  • Hadamard MLP;
  • GQA;
  • engram hashed n-gram key-value memory;
  • multi-lane hyper-connections;
  • Sinkhorn 归一化的路由;
  • gated/sandwich-normalized attention 与 MLP residual;
  • 工具检索 contrastive head;
  • confidence head;
  • grammar-constrained decoding。

因此应区分三个概念:

  1. 论文 SAN:用于验证 attention-only 结构的受控研究模型;
  2. Needle 2:面向工具调用的具体 45M 产品模型;
  3. Needle Python SDK/engine:让模型在设备上真正完成 schema、解码和执行的运行时系统。

3. 架构组件的工程解释

GQA

Query heads 多于 KV heads,多个 Q head 共享 K/V,降低 KV cache 和内存带宽。它是移动端常见的空间—质量折中,尤其适合固定小窗口。

Hadamard MLP

README 称其以 Hadamard MLP 替代传统 FFN。源码中使用固定 Walsh-Hadamard 变换,并把主要可学习参数放在对角缩放和投影上。固定变换可以用 O(n log n) 算法执行,不需要存储一个完整 dense 矩阵,目标是减少参数和内存访问。

Engram

architecture.py 中的 engram 由 hashed n-gram 表、key/value 投影和卷积 taps 组成,并在指定层触发。它提供一种低成本的局部词组/模式记忆,弥补 attention-only 模型对参数化记忆的弱点,但 hash 冲突、词表分布和跨语言表现需要单独评估。

Multi-lane hyper-connections

配置中的 mhc_lanes=4 表示维护多条残差流,再通过路由混合。README 将混合矩阵 P 描述为通过 Sinkhorn iteration 得到的 doubly-stochastic normalization。直观上,它试图在很小模型中增加残差路径的表达和稳定性,同时保持总参数可控。

QK normalization 和 gated residual

论文的消融显示 QK normalization 是深层 attention-only 的 load-bearing 组件;删除后出现发散。residual gate 在论文设置里更多是诊断工具而不是稳定的性能来源。工程上不能把所有组件都宣传成“每个都有独立收益”,应以消融和部署指标为准。

四、约束解码:Needle 与普通函数调用模型最不一样的地方

1. 普通方案的缺陷

典型函数调用链路是:

模型输出 JSON
    -> JSON parser
    -> schema validator
    -> 错误则重试

问题包括:

  • JSON 可能少括号、错引号;
  • enum 输出未知值;
  • 数值越界;
  • 正则字段不符合格式;
  • 多轮重试增加延迟;
  • 模型可能调用未声明工具;
  • “验证通过”不等于业务语义正确。

2. Needle 的方案

Needle 把工具 schema 编译为 byte-level grammar,在 token 生成时屏蔽不允许的字节/路径:

Python 类型/docstring/Field
    -> JSON Schema
    -> grammar compiler
    -> 每一步解码的合法字节集合
    -> 合法 JSON call

它保证的主要是:

  • 结构合法;
  • 工具名称来自声明集合;
  • 参数字段符合 schema;
  • enum/const 合法;
  • 数值、字符串和数组约束尽可能在解码中执行。

这对设备控制特别重要,因为“后处理纠错”常常意味着额外延迟和不确定的动作重试。

如果想从形式语言和解码算法层面进一步理解这里的 GCD,推荐阅读《Grammar-Constrained Decoding:让语言模型输出合法的魔术5。该文从“可完成前缀”定义出发,推导合法 token 集合、logits 硬屏蔽和增量 parser 状态转移,并解释 tokenizer prefix tree 如何与字符 grammar 求交;同时比较 PICARD、Outlines、LM Format Enforcer、llama.cpp GBNF 和 XGrammar 等实现路线,讨论 grammar-induced distribution shift、tool-call abstention、dead-end 诊断、性能缓存和生产级 validator 分层。Needle 的 byte-level grammar 正是这些原理在端侧工具调用中的具体化:grammar 负责协议和结构边界,业务 validator、权限策略与执行沙箱仍负责语义和安全边界。

3. grammar 不能解决的安全问题

grammar 无法理解:

  • 用户是否有权限;
  • 转账金额是否符合账户策略;
  • 当前门是否应该打开;
  • 参数组合是否违反业务状态;
  • 工具结果是否可信;
  • 这个动作是否需要人工确认。

因此应采用双层安全架构:

模型层:schema / grammar / confidence
策略层:权限、额度、审计、幂等、人工确认、回滚

五、工具检索、置信度和有限记忆

1. 工具检索

文档说明,5 个或更少工具会直接进入上下文;超过 5 个时,Needle 使用内置 contrastive head 对 query 和工具 schema 做检索,只把 top-5 工具渲染进当前上下文,并重建 grammar。工具 schema embedding 可由 tool_index_path 持久化,schema 变化时按 fingerprint 处理。4

优势:

  • 小模型不必面对巨大 schema;
  • grammar 分支数下降;
  • 上下文和 KV cache 更小;
  • 大目录仍可保持端侧运行。

风险:

  • top-5 召回失败时,正确工具不可达;
  • 相似工具的描述质量直接决定检索;
  • 工具目录变化需要重新计算 fingerprint;
  • 召回指标不能由最终调用准确率替代。

大目录产品应分别测:

检索 Recall@5
工具选择准确率
参数 exact-match
离题空调用率
多步链路成功率

2. Confidence

基础模型的 confidence 是两个信号的最小值:

  1. 对 prompt + call 的 post-hoc confidence head;
  2. call token 的解码概率。

它支持“高置信度自动执行,低置信度升级”的产品策略。这个思想很适合真实设备,因为失败模式从“盲目执行错误动作”变成“拒绝或升级”。

但是官方微调文档明确说明:LoRA 不更新 confidence head,tuned .cact 的 confidence 被禁用并报告为 None。3 这意味着微调后必须:

  • 用独立分类器校准;
  • 依据 schema 完成率、参数校验和工具结果做外部置信度;
  • 或采用大模型复核;
  • 不能沿用基础模型阈值。

3. 256 token 滑动窗口与 KV sink

Needle 通过滑动窗口限制会话状态,并将工具描述固定为 KV sinks,使内存不随对话无限增长。适合短命令和设备控制,不适合:

  • 长文档阅读;
  • 多页合同;
  • 十几轮以上复杂规划;
  • 大规模历史记忆;
  • 需要完整保留所有工具返回值的任务。

“有界内存”是端侧优势,也是能力边界。要做长期会话,外部必须提供摘要、状态数据库或检索记忆;不能指望 Needle 内部自动成为长期记忆系统。

六、量化、.cact 和离线部署

1. Cactus Quants 的设计思路

quantize.py 提供普通 fake quant、CQ 量化、混合 bits map、QAT/STE 等路径。export.py 的格式说明显示:

  • 矩阵按 [out, in] 预转置;
  • 按 group 做 CQ2/CQ3/CQ4;
  • 使用 Lloyd-Max codebook;
  • 码本与 Walsh-Hadamard 变换结合;
  • norms 和少量非矩阵参数保留 FP16/FP32;
  • KV cache 可使用指定 bits;
  • tokenizer 作为 RAW blob 写进归档;
  • header 保存架构和量化几何;
  • 张量按 layer-major 固定顺序排列;
  • 64 字节对齐,便于内核顺序读取。

CQ 的核心不是简单“把每个权重四舍五入成 2 bit”,而是按组归一化后,用小码本近似向量,并利用固定 Hadamard 结构重建。这样做的目标是把极低 bit 宽度和可接受的矩阵误差结合起来。

2. 为什么 .cact 适合设备

.cact 将这些内容打包在一起:

架构几何
量化码本
张量目录
量化张量
KV cache 配置
可选 contrastive/confidence head
SentencePiece tokenizer

设备上不需要:

  • Python;
  • PyTorch;
  • Flax;
  • 一个通用模型加载器;
  • 多个外部 tokenizer 文件。

Python 包首次运行会从 Hugging Face 缓存平台动态库;推理本身不联网。NEEDLE_LIB_PATH 可以强制指定本地 library,HF_HUB_OFFLINE=1 可让缺失资源快速失败。1

3. 部署风险

量化部署必须单独验证:

  • CQ2 与 CQ4 的工具选择差异;
  • 低 bit 对数字、日期和长字符串的影响;
  • 多语言 token 变长后的窗口溢出;
  • 不同 CPU/NPU 的对齐和 SIMD 行为;
  • engine 与 .cact 版本兼容;
  • confidence head 在量化后是否仍校准;
  • 长会话 KV window 的真实峰值内存;
  • cold start、编译/加载时间和电池消耗。

README 的 14MB/28MB 是很有吸引力的产品指标,但应在目标硬件、目标语言、目标工具目录和真实数据上重测。

七、Needle 如何微调:从 JSONL 到可部署模型

1. 数据契约

每行一个 JSON 对象:

{
  "query": "把厨房灯调暗到 10",
  "tools": [
    {
      "name": "set_lights",
      "parameters": {
        "type": "object",
        "properties": {
          "room": {"type": "string"},
          "brightness": {"type": "integer"}
        },
        "required": ["room"]
      }
    }
  ],
  "answers": [
    {
      "name": "set_lights",
      "arguments": {
        "room": "厨房",
        "brightness": 10
      }
    }
  ],
  "reasoning": "'厨房' -> room;'调暗到 10' -> brightness 10"
}

文档强调的训练原则:

  1. 参数只能取自 query 中有证据的值;
  2. optional 字段没有证据时省略,不填空字符串;
  3. 需要 answers: [] 的离题样本,否则模型会对所有输入调用工具;
  4. 相似工具必须提供消歧 query;
  5. reasoning 建议写出字段与原文 span 的对应关系;
  6. 每个样本应适配 max-len;
  7. 可加入 system 环境事实。

2. LoRA 训练和导出

官方命令:

needle finetune data.jsonl --epochs 10 --out adapter.pkl
needle build checkpoints/needle2.pkl   --lora adapter.pkl   --out tuned.cact

默认参数包括:

  • LoRA rank 16;
  • alpha 32;
  • 学习率 1e-4;
  • batch size 16;
  • 默认 epochs 3;
  • max length 1024;
  • validation split 0.1;
  • warmup + cosine decay;
  • gradient clipping;
  • 冻结基础模型。

源码将 LoRA 放在每层的 q_proj、k_proj、v_proj、gate_proj、out_proj。这是一种成本很低的适配方案:注意力路由和内容写入路径可改变,但 embedding、engram 表、tokenizer、confidence head 和整体 engine 保持不变。

3. 如何判断训练是否有效

官方文档给出很实用的判断:

  • 几百条干净样本通常先改善工具选择;
  • 参数 grounding 往往需要数千条、多样化样本;
  • 训练 loss 降、validation loss 升,说明过拟合;
  • 小数据集 3 epochs 可能只有几十步,不足以改变 rank-16 adapter;
  • 如果工具选对但参数值错,优先增加真实、多样、带 reasoning 的样本;
  • grounding 很重时可试 rank 32;
  • 数据增强可通过 needle generate-data,但它依赖 OPENROUTER_API_KEY,生成样本必须人工抽检。3

4. LoRA 微调的硬边界

Needle 的微调不是“让模型学会任意新能力”:

  • 不更新 confidence head,微调后 confidence 为 None;
  • 不更新 tokenizer,中文、非英语和特殊符号可能变成更多 token;
  • 不改变基础模型的窗口和 engine 约束;
  • 不自动扩展长程规划能力;
  • 不保证新增工具的检索 head 校准;
  • 不保证业务函数异常处理;
  • 不等于安全策略训练;
  • 不等于继续预训练。

适合微调的是:

工具选择偏好
领域术语映射
参数 grounding
固定格式抽取
设备命令的自然语言变体

不适合只靠 LoRA 解决的是:

新语言 tokenizer 能力
大规模世界知识
长上下文推理
复杂规划
权限和合规
高风险动作决策

八、Needle 能不能变成通用 Agent

1. 单独改造成通用 Agent:不划算

通用 Agent 需要:

  • 开放式语言理解;
  • 世界知识和事实检索;
  • 长上下文;
  • 任务分解;
  • 多工具规划;
  • 失败恢复;
  • 成本/时间预算;
  • 权限管理;
  • 长期记忆;
  • 复杂结果综合;
  • 与用户自然对话。

Needle 的设计则是:

  • 无工具就返回空调用;
  • 不生成自由文本 fallback;
  • 工具 schema 是核心上下文;
  • 窗口很短;
  • loop 默认最多 8 步;
  • engine 共享全局状态;
  • confidence 依赖基础模型 head;
  • tuned 权重失去 confidence。

这两组目标相反。若强行把 Needle 改成通用 Agent,最可能发生的是:增加上下文、自由文本 head、规划状态、长期记忆和工具权限后,失去 14MB/28MB/低延迟的核心优势。

2. 作为通用 Agent 的端侧执行层:可行且合理

更好的架构是:

flowchart LR
    U["用户输入"] --> P["云端大模型或本地较大模型:理解、规划、对话"]
    P --> R["端侧路由:选择设备域"]
    R --> N["Needle:schema 检索、约束解码、结构化调用"]
    N --> G["权限/额度/审计/人工确认策略"]
    G --> X["设备 API、函数或机器人动作"]
    X --> N
    N --> P
    P --> U

Needle 在其中承担:

  • 本地 tool router;
  • 参数结构化器;
  • 低延迟执行器;
  • 大模型 fallback 前的第一道过滤;
  • 断网情况下的核心命令能力;
  • 隐私数据不出设备的抽取器。

这不是降低它的定位,而是把它放在最适合它的层:可预测的执行面,而不是开放式认知面

九、最佳商业潜力排序

1. 智能家居、机器人和可穿戴设备

这是第一优先级,原因是五项约束同时匹配:

  • 工具集合有限;
  • 指令短;
  • 参数 schema 清晰;
  • 设备端必须低延迟;
  • 断网也要工作;
  • 错误动作需要被拦截;
  • 内存和功耗比知识覆盖更重要。

可售卖的不是单一模型,而是:

Needle SDK
+ 设备工具 schema 模板
+ 权限/确认策略
+ 端侧 engine
+ 厂商 LoRA 适配
+ 远程模型版本管理

2. 汽车座舱和本地语音动作

车机可以用 Needle 处理:

  • 空调、座椅、车窗;
  • 导航意图结构化;
  • 媒体控制;
  • 本地电话簿查询;
  • 车辆状态查询。

高风险动作必须由策略层确认,例如开锁、远程启动、支付和隐私数据访问不能只依赖 confidence。

3. 工业和机器人控制

优势:

  • 本地运行;
  • 工具参数可验证;
  • 可接 PLC、ROS、设备 RPC;
  • 断网环境可工作;
  • 可记录每次调用 envelope、reasoning、结果和操作者。

但工业场景更需要 deterministic policy、权限、急停、状态机和审计;Needle 只能是语言入口,不能替代安全控制系统。

4. 隐私结构化抽取

适合:

  • 发票、收据、引用;
  • 工单、表格、设备日志;
  • 本地合规文档的字段提取;
  • 不能上传云端的企业文本。

Needle 将 extraction 视为“只有一个工具的调用”,因此 schema conformance 比生成漂亮摘要更重要。它可以作为传统 OCR/规则系统后的语义结构化层。

5. 芯片、NPU 和 OEM 授权

长期护城河可能不在公开权重,而在:

  • .cact 格式;
  • Cactus Quants;
  • 单一 engine;
  • grammar compiler;
  • 工具检索 head;
  • LoRA 到嵌入式归档的完整链路;
  • 多平台 runner。

如果 Cactus Compute 能将这些能力适配更多 NPU、DSP、MCU 或手机 SoC,商业模式可以从模型订阅扩展到 SDK 授权、设备出货分成和私有部署。

十、商业落地前必须补齐的验证

README 称 Needle 在某些 benchmark 上可以与 FunctionGemma、LFM2.5、Apple FM 竞争,但这是项目自述;不能直接当作独立复现实验。1 采购或集成前应建立自己的评测集:

能力指标

  • 工具选择 accuracy;
  • top-5 工具召回率;
  • 参数 exact-match;
  • 数字、日期、枚举、单位准确率;
  • 离题输入空调用率;
  • 多步链路完成率;
  • 工具异常后的恢复率;
  • schema 约束违规率;
  • 中文、英语和目标语言表现。

设备指标

  • 首次加载时间;
  • prefill/decode latency;
  • 峰值 RAM;
  • 每次调用能耗;
  • 不同 CQ bits 的质量退化;
  • CPU/NPU/SIMD 兼容性;
  • 256 token 窗口下的溢出率;
  • offline 缺失资源时是否 fail-fast。

安全指标

  • 低 confidence 的拒绝/升级率;
  • 高风险工具的人工确认覆盖率;
  • 重复调用和幂等性;
  • 权限越权;
  • schema 合法但业务非法的拦截率;
  • tool result 注入和错误回灌;
  • 审计日志完整性。

十一、与其他路线的本质差异

路线 核心目标 Needle 的不同
通用大模型函数调用 通过提示词生成工具调用 Needle 把 schema 编译进解码约束,并把模型缩到端侧
Toolformer 从语料自监督学习何时调用 API Needle 更关注固定工具契约、设备运行和可验证输出
ReAct 思考—行动—观察的文本轨迹 Needle 的 reasoning/调用 envelope 更窄,loop 更短,几乎不做开放式思考
LangGraph/Agent framework 状态、节点、重试和流程编排 Needle 只提供轻量模型调用循环,不替代工作流框架
llama.cpp/ONNX mobile 通用模型推理 Needle 用专用 .cact、engine 和 grammar 做垂直协同
传统规则/DSL 确定性强但语言覆盖弱 Needle 提供自然语言泛化,再由 schema 和策略层兜底

Needle 的创新不是每个组件都首创,而是把多个组件收束到一个很窄的产品问题:端侧、离线、低内存、受约束的工具调用

十二、最终判断

技术判断

Needle 2 最值得关注的不是“45M 是否打败更大的模型”,而是它展示了一条不同的工程路线:

小模型
+ 专用架构
+ 极低 bit 量化
+ 自描述权重格式
+ 专用 C engine
+ grammar constrained decoding
+ tool retrieval
+ confidence gating
+ LoRA 领域适配
= 端侧可执行 AI

产品判断

它最适合成为:

大模型负责理解和规划,Needle 负责端侧约束、调用和执行,策略系统负责安全与权限。

它不适合被包装成“通用本地 ChatGPT”,也不应在金融、医疗、工业和家庭高风险动作中被单独授权。

投资/商业判断

最佳商业潜力依次是:

  1. 智能家居、机器人、可穿戴;
  2. 汽车座舱和本地语音控制;
  3. 工业设备与隐私环境;
  4. 本地结构化抽取;
  5. NPU/OEM/嵌入式 AI SDK 授权。

一句话收束:

Needle 的护城河不是“它知道多少”,而是“它能否在很小的设备上,把自然语言稳定地变成合法、可审计、可升级、可离线执行的动作”。

参考文献

  1. Cactus Compute, Needle GitHub Repository, README 与源码,https://github.com/cactus-compute/needle  2 3 4 5 6

  2. Henry Ndubuaku et al., A Controlled Study of Attention-Only Transformers, arXiv:2607.18363, https://arxiv.org/abs/2607.18363  2

  3. Cactus Compute, Needle Fine-tuning Documentation, https://github.com/cactus-compute/needle/blob/main/doc/finetuning.md  2 3

  4. Cactus Compute, Needle API Documentation, https://github.com/cactus-compute/needle/blob/main/doc/apis.md  2

  5. 吴子豪,《Grammar-Constrained Decoding:让语言模型输出合法的魔术》,https://vortezwohl.github.io/ai/2026/08/24/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3Grammar-Constrained-Decoding.html