Needle 2 Confidence Score: Post‑Hoc Head and Decoding Probability Signals Explained
Needle 2 calculates confidence scores using two signals—a learned neural confidence head and the token‑level decoding probability—taking the minimum of the two to ensure conservative, reliable tool‑calling decisions.
Needle 2, the open‑source tool‑calling framework from Cactus Compute, provides a calibrated confidence score for every generated function call. Understanding how this score works is essential for building reliable agent systems that can gate low‑confidence actions. This article breaks down the two signals used for confidence scoring in Needle 2, explains how they combine, and shows practical implementation patterns from the source code.
The Two Confidence Signals in Needle 2
Needle 2's confidence mechanism relies on two independent signals. The final reported value is the minimum of these two, ensuring that a call passes only when both sources agree on high confidence.
Signal 1: Post‑Hoc Confidence Head
The post‑hoc confidence head is a learned neural module named ConfidenceHead that evaluates the complete prompt together with the generated function call. It produces a calibrated probability reflecting how well the model's output matches the training distribution.
In needle/model/architecture.py, the confidence head is implemented as follows:
# Lines 63-75 in needle/model/architecture.py
class ConfidenceHead(nn.Module):
def __init__(self, hidden_size: int):
super().__init__()
self.dense = nn.Linear(hidden_size, 1)
self.sigmoid = nn.Sigmoid()
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
# Pool final hidden state and predict confidence
pooled = hidden_states[:, -1, :]
return self.sigmoid(self.dense(pooled)).squeeze(-1)
This head is trained only on the base model weights. When you load a fine‑tuned agent with LoRA adapters, the confidence head becomes unavailable and returns None—a warning is emitted at construction time in needle/__init__.py (lines 60-63).
Signal 2: Decoding Probability of Call Tokens
The decoding probability signal captures the token‑level likelihood that the model assigned while generating the JSON‑structured function call. This is derived directly from the model's softmax outputs during autoregressive decoding, representing the model's own certainty about each generated token.
This signal requires no additional training and remains available even with fine‑tuned adapters.
How Needle 2 Combines the Two Signals
According to the API documentation in doc/apis.md (lines 51-54), Needle 2 applies a conservative policy: the final confidence is the lower of the two signals. This design guarantees that:
- A call is accepted only when both the learned head and token‑level probability indicate reliability
- Downstream systems can implement hard gates (e.g., refusing calls below a threshold)
- False positives are minimized in production tool‑calling pipelines
Handling Fine‑Tuned Agents and Missing Confidence
Because the ConfidenceHead is tied to base model weights, fine‑tuned agents present a special case. The runtime logic in needle/__init__.py handles this:
# Lines 60-63 in needle/__init__.py
if self.using_lora:
warnings.warn(
"Confidence scores unavailable with fine-tuned weights; "
"head was trained on base model only."
)
self.confidence_head = None
When confidence_head is None, the confidence field in responses will be None. Your application code should handle this gracefully.
Practical Implementation: Gating Calls by Confidence
The following pattern demonstrates how to integrate confidence scoring into your Needle 2 application:
import needle
# Declare a simple tool
@needle.tool
def set_lights(room: str, on: bool, brightness: int = 0):
"""Control lights in a room."""
return {"room": room, "on": on, "brightness": brightness}
# Create an agent with a confidence gate of 0.7
agent = needle.Needle(tools=[set_lights])
# Run a query
response = agent.run("Turn on the kitchen lights to 50 percent")
# Inspect the confidence score
conf = response.get("confidence")
print("Confidence:", conf)
# Optionally reject low‑confidence calls
if conf is not None and conf < 0.7:
print("⚠️ Low confidence – you may want to re‑ask or fallback to a larger model.")
else:
print("✅ High confidence – safe to act on the result.")
Running Tests with Confidence Thresholds
The built‑in test harness in needle/environments/_harness.py (lines 28-33) supports filtering by minimum confidence:
from needle.environments import smart_home
# Run the built‑in test suite; set a minimum confidence of 0.5
smart_home.run_tests(min_confidence=0.5)
This allows systematic evaluation of model reliability across your tool set.
Summary
- Two signals drive Needle 2 confidence scoring: the learned
ConfidenceHeadpost‑hoc evaluator and the raw token‑level decoding probability. - Conservative combination: the final score is the minimum of the two signals, accepting calls only when both sources agree.
- Base model dependency: the confidence head requires base model weights and returns
Nonefor LoRA‑fine‑tuned agents. - Source locations:
ConfidenceHeadimplementation inneedle/model/architecture.py(lines 63-75), combination logic indoc/apis.md(lines 51-54), runtime handling inneedle/__init__.py(lines 60-63), and test filtering inneedle/environments/_harness.py(lines 28-33).
Frequently Asked Questions
What are the exact two signals used for confidence scoring in Needle 2?
Needle 2 uses a post‑hoc confidence head (a learned neural network that evaluates prompt‑plus‑call combinations) and the decoding probability of the generated call tokens (the token‑level softmax probabilities during generation). The final confidence is the minimum of these two values.
Why does Needle 2 take the minimum of the two confidence signals?
Taking the minimum implements a conservative reliability policy. A call receives high confidence only when both the trained head and the model's own generation probability agree. This reduces false positives in critical tool‑calling scenarios where incorrect actions could have significant consequences.
Why is confidence unavailable with fine‑tuned Needle 2 models?
The ConfidenceHead is trained only on base model weights. When you load a fine‑tuned agent with LoRA adapters, the head's predictions no longer align with the modified distribution. Needle 2 explicitly disables the head in this case and emits a warning, returning None for confidence scores to avoid misleading calibration.
How can I filter Needle 2 test results by confidence level?
Use the min_confidence parameter in the environment test harness as shown in needle/environments/_harness.py. Pass a float threshold (e.g., 0.5 or 0.7) to smart_home.run_tests() or equivalent environment runners to exclude low‑confidence predictions from your evaluation results.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →