# Needle System Facts: How to Control Agent Behavior with Custom Directives

> Learn how Needle system facts control LLM agent behavior. Understand how to use custom directives to shape output, enforce rules, and manage confidence gating for better results.

- Repository: [Cactus Compute, Inc./needle](https://github.com/cactus-compute/needle)
- Tags: how-to-guide
- Published: 2026-09-06

---

**System facts in Needle are high-level instructions passed via the `system` parameter that shape every LLM response by constraining output format, enforcing mapping rules, and controlling confidence gating.**

The Needle agent uses **system facts** to provide persistent behavioral guidance to the underlying language model. These facts are plain strings that act as system-role messages, prepended to every LLM request to enforce domain-specific constraints. As implemented in the `cactus-compute/needle` repository, system facts directly influence prompt construction, decode grammar generation, and tool selection logic.

## What System Facts Can Be Provided to the Needle Agent

Needle accepts **any valid string** as a system fact. The repository provides six pre-built environments with rigorously tested system facts, or you can craft custom directives for specialized use cases.

### Built-In System Facts by Environment

Each environment module in `needle/environments/` defines a `SYSTEM` constant containing a tailored directive:

| Environment | Key Behavioral Constraint | Source File |
|-------------|---------------------------|-------------|
| **Wearable** | "Copy reply text verbatim, preserving capitalization. Map each explicit supported watch action to exactly one declared call. Do not guess missing values; values not explicitly stated must be omitted." | [[`wearable.py`](https://github.com/cactus-compute/needle/blob/main/wearable.py)](https://github.com/cactus-compute/needle/blob/main/needle/environments/wearable.py) |
| **Smart Home** | "Map each explicit supported home action to exactly one declared call; never duplicate an action. Do not guess missing targets or values; targets and values not explicitly stated must be omitted." | [[`smart_home.py`](https://github.com/cactus-compute/needle/blob/main/smart_home.py)](https://github.com/cactus-compute/needle/blob/main/needle/environments/smart_home.py) |
| **Productivity** | "Copy titles, messages, and date or time phrases verbatim from the user; never rephrase or resolve them. Map each explicit supported request to exactly one declared call." | [[`productivity.py`](https://github.com/cactus-compute/needle/blob/main/productivity.py)](https://github.com/cactus-compute/needle/blob/main/needle/environments/productivity.py) |
| **Media Player** | "Map each explicit supported media action to exactly one declared call; never duplicate an action. Do not guess missing values." | [[`media_player.py`](https://github.com/cactus-compute/needle/blob/main/media_player.py)](https://github.com/cactus-compute/needle/blob/main/needle/environments/media_player.py) |
| **Kitchen Appliance** | "Map each explicit supported appliance action to exactly one declared call; never duplicate an action. Do not guess missing values." | [[`kitchen_appliance.py`](https://github.com/cactus-compute/needle/blob/main/kitchen_appliance.py)](https://github.com/cactus-compute/needle/blob/main/needle/environments/kitchen_appliance.py) |
| **Data Capture** | "Copy names, merchants, and descriptions verbatim from the user. Record only values the user stated; never estimate. Map each explicit supported record to exactly one declared call." | [[`data_capture.py`](https://github.com/cactus-compute/needle/blob/main/data_capture.py)](https://github.com/cactus-compute/needle/blob/main/needle/environments/data_capture.py) |

### Custom System Facts

Beyond the built-in environments, you can provide **arbitrary strings** that encode any behavioral policy. Common patterns include:

- **Output format constraints**: Enforcing JSON-only responses or specific schema compliance
- **Content restrictions**: Prohibiting certain phrases, requiring verbatim copying, or blocking opinion generation
- **Reasoning controls**: Requiring step-by-step decomposition or preventing chain-of-thought elaboration
- **Safety boundaries**: Preventing action execution without explicit user confirmation

## How System Facts Affect Needle Agent Behavior

System facts influence three core mechanisms in the Needle runtime, as implemented in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py) and the underlying native library.

### 1. Prompt Construction

The system fact becomes the **system-role message** in every LLM request. In [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py), the `Needle` class initializes with:

```python
class Needle:
    def __init__(
        self,
        tools: Sequence[Tool],
        system: str,  # The system fact parameter

        model: str = "gpt-4",
        confidence_threshold: float = 0.7,
    ) -> None:
        # ...

        self._system = system.encode("utf-8")
        self._handle = lib.needle_init(
            self._model.encode("utf-8"),
            self._system,  # Passed to native library

            # ...

        )

```

The native library embeds this string at the start of the token sequence, giving it maximal attention weight in the model's context window.

### 2. Decode Grammar Generation

System facts participate in **grammar-constrained decoding**. The runtime compiles:

1. The system fact string
2. The JSON schema of registered tools
3. Confidence threshold parameters

Into a finite-state grammar that parses valid LLM outputs. This grammar enforces structural constraints like "exactly one call per explicit action" by rejecting token sequences that would violate the system fact's directives.

### 3. Confidence Gating and Tool Selection

System facts modulate the **confidence-threshold mechanism**. When the system fact includes explicit mapping instructions (e.g., "map each explicit supported action to exactly one declared call"), the runtime:

- Increases penalty scores for ambiguous or multi-call outputs
- Triggers the `confidence_threshold` check more aggressively for edge cases
- Returns `None` rather than emit a call when the system fact's constraints would be violated

## Practical Code Examples

### Using a Built-In Environment System Fact

```python
import needle
from needle.environments import wearable

# Automatically uses wearable.SYSTEM as the system fact

agent = needle.Needle(
    tools=wearable.TOOLS,
    system=wearable.SYSTEM,  # "Copy reply text verbatim..."

)

response = agent.invoke("Set a timer for 5 minutes", Context())

# Enforces: verbatim text, one timer call, no guessed duration units

```

### Creating a Custom System Fact

```python
import needle

finance_system = (
    "You are a financial assistant. "
    "Always express monetary values in USD with two decimal places. "
    "Never provide investment advice. "
    "If a transaction type is ambiguous, return NO_CALL rather than guess."
)

agent = needle.Needle(
    tools=[transfer_funds, check_balance, list_transactions],
    system=finance_system,
    confidence_threshold=0.85,  # Stricter threshold pairs with strict system fact

)

```

### Verifying the Active System Fact

```python

# Access the encoded system string stored in the agent

print(agent._system.decode())

# Output: "You are a financial assistant. Always express..."

```

### Combining System Facts with Context

```python
from needle import Needle, Context

# Runtime system fact override for specialized sub-tasks

base_system = needle.environments.productivity.SYSTEM
override_system = base_system + " Priority: scheduling over email when both mentioned."

agent = Needle(tools=productivity.TOOLS, system=override_system)

ctx = Context()  # Conversation state

result = agent.invoke("Meeting at 3pm and reply to John's message", ctx)

# System fact now weights scheduling higher

```

## Best Practices for System Facts in Needle

- **Be explicit about negatives**: Phrases like "never guess" and "do not estimate" carry stronger grammatical weight than "avoid guessing"
- **Use verbatim copy directives**: For structured data extraction, explicitly command "copy X verbatim from the user"
- **One-action-per-call mapping**: Include the exact phrase "map each explicit supported [domain] action to exactly one declared call" for optimal grammar compilation
- **Pair with confidence thresholds**: Strict system facts work best with elevated `confidence_threshold` values (0.8-0.9)
- **Test grammar validation**: System facts that contradict the tool schema can cause decode failures—validate with sample invocations

## Summary

- **System facts are strings** passed via the `system` parameter in `needle.Needle()` that act as persistent LLM instructions
- Needle provides **six built-in environments** (`wearable`, `smart_home`, `productivity`, `media_player`, `kitchen_appliance`, `data_capture`) with proven system facts in `needle/environments/`
- System facts affect **prompt construction**, **decode grammar generation**, and **confidence gating** to enforce behavioral constraints
- **Custom system facts** are fully supported for domain-specific requirements beyond the built-in environments
- The implementation in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py) encodes and passes system facts to the native library via `lib.needle_init()`

## Frequently Asked Questions

### How do I override a built-in system fact while keeping its tools?

Create a `Needle` instance with the environment's `TOOLS` but supply your own `system` string. The tools and system fact are independent parameters:

```python
from needle.environments import smart_home

agent = needle.Needle(
    tools=smart_home.TOOLS,  # Keep original tools

    system="Your custom directive here"  # Replace system fact

)

```

### Can system facts prevent hallucinated tool arguments?

Yes. Include explicit directives like "do not guess missing values; omit parameters not explicitly stated" and set a high `confidence_threshold`. The grammar compiler uses these phrases to penalize speculative token generation.

### What happens if my system fact conflicts with the tool schema?

The decode grammar may fail to compile or produce validation errors at runtime. Needle's native library intersects the system fact constraints with the tool schema—contradictions can cause `NeedleError` exceptions during initialization or inference.

### Are system facts tokenized separately from user messages?

Yes. According to the `needle` source code, system facts are encoded as distinct UTF-8 byte sequences and passed separately to `lib.needle_init()`, ensuring they receive consistent attention weighting regardless of conversation length.