# How to Configure System Prompts for Different Task Contexts in Needle

> Learn how to configure system prompts in Needle to provide factual context for user queries. This guide explains the process for different task contexts.

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

---

**You configure system prompts in Needle by passing a formatted string to the `system` parameter of the `Needle` class or `needle.extract` function, which encodes the text as UTF-8 and injects it as a factual context turn before the user query.**

Needle, the open-source tool-calling engine maintained by `cactus-compute/needle`, relies on **system turns** to ground model inference in environmental facts. These prompts provide contextual data—such as current dates, locales, and device types—that the model uses to resolve relative expressions like "tomorrow at 7" without receiving explicit instructions. Properly configuring these system prompts for different task contexts ensures your agents interpret user queries relative to the correct environmental state.

## How Needle Processes System Prompts

When you initialize a Needle agent, the system prompt is immediately encoded and passed to the native C library for injection into the inference context.

### Internal Storage and Initialization

In [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py), the constructor handles the `system` argument by encoding it to UTF-8 bytes:

```python
self._system = (system or "").encode("utf-8")          # needle/__init__.py:L61

```

This byte buffer is then passed to the native library during initialization:

```python
_lib().needle_init(self._system, self._tools_json, self._tool_index_path)   # needle/__init__.py:L89

```

The native engine treats this buffer as a **system turn**—a single message containing facts only, never instructions. During inference, the engine inserts this turn before the user query, allowing the model to reference the supplied environmental data while generating tool calls.

## Recognized System Keys and Format

Needle parses specific key-value pairs from the system string to establish grounding context. According to the API documentation in [`doc/apis.md`](https://github.com/cactus-compute/needle/blob/main/doc/apis.md), the engine recognizes the following factual keys:

- **`date`** – Current timestamp (e.g., `date: 2026-07-21 Tue 14:30`)
- **`locale`** – Language and region (e.g., `locale: en-US`)
- **`device`** – Hardware type (e.g., `device: phone`)
- **`battery`** – Battery level percentage (e.g., `battery: 62%`)
- **`network`** – Connectivity status (e.g., `network: wifi`)
- **`location`** – Geolocation string
- **`user`** – End-user identifier
- **`assistant`** – Identity the model should adopt

The parser ignores free-form text that does not match these keys, effectively preventing prompt-injection attacks while ensuring only vetted factual context reaches the model.

## Methods for Configuring System Prompts

You can configure system prompts at instantiation or dynamically change them per-task by creating new agent instances.

### Setting a Default System Prompt

Supply the `system` argument when creating a `Needle` instance to establish a fixed context for all queries:

```python
import needle

@needle.tool
def get_weather(city: str):
    """Return a dummy weather forecast."""
    return {"city": city, "forecast": "sunny"}

agent = needle.Needle(
    tools=[get_weather],
    system="date: 2026-07-21 Tue 14:30; locale: en-US; device: phone; battery: 78%"
)

response = agent.run("What’s the weather in Paris tomorrow?")
print(response["results"])

```

### One-Shot System Prompts with needle.extract

For extraction tasks that require different contexts without persistent agent state, use the `system` parameter in `needle.extract`:

```python
import needle
from pydantic import BaseModel

class WeatherReport(BaseModel):
    city: str
    forecast: str

result = needle.extract(
    text="Tomorrow at 9am in Berlin, will it be rainy?",
    schema=WeatherReport,
    system="date: 2026-07-21 Tue 14:30; locale: en-US; device: laptop"
)

print(result)  # → WeatherReport(city='Berlin', forecast='rainy')

```

### Dynamic Context Switching

To configure system prompts for different task contexts, instantiate separate agents or reinitialize the engine with updated system strings:

```python
def make_agent(context: str) -> needle.Needle:
    return needle.Needle(
        tools=[reminder_tool],
        system=context
    )

# Context for mobile user on July 21

agent_a = make_agent("date: 2026-07-21 Tue 14:30; device: phone")
print(agent_a.run("Set a reminder for tomorrow at 7"))

# Context for desktop user on August 10

agent_b = make_agent("date: 2026-08-10 Wed 09:00; device: laptop")
print(agent_b.run("Set a reminder for tomorrow at 7"))

```

## Security and Safety Considerations

The system turn mechanism is designed to carry **facts only**, not instructions. Because the parser in the native engine strictly validates keys against the recognized list, arbitrary instructions or prompt-injection attempts embedded in the system string are discarded. This architecture ensures that system prompts cannot override the tool-calling grammar or manipulate model behavior beyond providing environmental grounding data.

## Summary

- **System prompts** in Needle are configured via the `system` parameter as formatted key-value strings containing factual context.
- The Python wrapper encodes the string to UTF-8 in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py) and passes it to `_lib().needle_init()` for injection as a system turn.
- Recognized keys include `date`, `locale`, `device`, `battery`, `network`, `location`, `user`, and `assistant`.
- You can configure different contexts per task by creating new `Needle` instances or using the `system` argument in `needle.extract`.
- Free-form text in system prompts is ignored by the parser, preventing prompt-injection while maintaining factual grounding.

## Frequently Asked Questions

### What is the difference between a system turn and instructions in Needle?

A **system turn** carries factual environmental data (like dates and device status) that the model uses to resolve references, while **instructions** direct the model's behavior or reasoning style. Needle's architecture specifically restricts system prompts to factual keys, preventing them from being used as behavior instructions that could conflict with the tool-calling grammar.

### Can I use free-form text in the Needle system prompt?

While you can include free-form text in the `system` string you pass to Needle, the native parser ignores any content that does not match the recognized factual keys (such as `date:` or `locale:`). This design prevents prompt injection attacks and ensures only structured environmental facts influence the model's grounding context.

### How do I change the system context between different user queries?

To change system contexts, create a new `Needle` instance with the updated `system` string for each context, or use the `needle.extract` function with a specific `system` argument for one-shot operations. The system prompt is set at initialization time in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py), so you must reinitialize the agent or engine to apply different environmental facts.

### Does the system prompt affect tool calling in Needle?

The system prompt does not affect the **tool-calling grammar** or the availability of functions. It only provides grounding information that the model may reference to resolve relative expressions (like "tomorrow" or "here") within the user's query before selecting the appropriate tool and parameters according to the defined schema.