Skip to main content
Haystack is a Python framework for building pipelines and agents with language models. The neuraltrust-haystack package adds TrustGuard components that evaluate text or text-only chat messages at the points you connect them in a pipeline. Place an input guard before a generator and an output guard after it. Connect protected work to the guard’s content output so only accepted or validated transformed content reaches the next step.

Integration capabilities

Guards act at pipeline boundaries. They do not intercept an Agent’s internal model calls or tool execution. Output guards evaluate completed replies; they cannot withhold tokens already delivered through a streaming callback.

Before you start

Start with an Observe policy to review findings in Activity, then verify the intended block and transformation behavior in Enforce mode. See Policies.

1. Install

Import the components from the Haystack integration namespace:

2. Configure credentials

By default, both components use Secret.from_env_var("TRUSTGUARD_API_KEY"). The credential is resolved for each evaluation. Pass a Haystack Secret to use a different variable:
Use api_base="https://your-trustguard-host" for another deployment. The component appends /v1/evaluate. Other constructor settings do not read environment variables automatically.

3. Gate text in a pipeline

NeuralTrustGuard takes a nonempty text string and returns text and verdict when content can proceed. The default on_violation="raise" stops with NeuralTrustBlockedError for block or ask. Use on_violation="route" when the application should handle a denied request using the verdict output:
On block or ask, the guard emits only verdict: there is no text output, so the required input of AcceptText receives no value and the component does not run. Connect the protected component only through the guard and keep its content input required. Supplying the original content through another input path bypasses this gate. The example’s AcceptText component represents the protected downstream step. For a real text pipeline, connect guard.text to the next component’s required text or prompt input. To evaluate a completed text reply, use a separate NeuralTrustGuard(direction="output") instance and pass the reply to its text input.

4. Guard chat input and completed replies

NeuralTrustChatGuard takes messages: list[ChatMessage]. Use direction="input" for the conversation sent to a chat generator, and direction="output" for the generator’s completed replies:
In a pipeline, connect input_guard.messages to chat_generator.messages, then chat_generator.replies to output_guard.messages. Deliver only the output guard’s messages to the application. Route mode also omits the messages output entirely for block and ask. The chat guard accepts a nonempty list of system, user, and assistant messages with exactly one nonempty text part each. It preserves message order, names, and metadata in independent output copies. Tools, tool results, reasoning, multiple content parts, images, files, and audio are rejected before evaluation. Message metadata is preserved locally and is not sent as message content to TrustGuard.

Group evaluations for a conversation

Pass a stable session_id on every input and output call for one conversation. For a shared component, supply it per run so concurrent users have separate session identifiers. Send earlier turns in the chat guard’s messages list when the input evaluation needs their text; the component does not maintain conversation history itself. consumer_id can select a policy override configured in TrustGuard. attributes adds JSON-compatible request context:

5. Run asynchronously and manage client lifetime

Both components expose run_async with the same inputs and verdict behavior as run:
Haystack 3.x runs asynchronous pipelines with await Pipeline.run_async(...). Haystack 2.31 uses await AsyncPipeline.run_async(...), importing AsyncPipeline from haystack. Use an async with guard context around the asynchronous pipeline’s lifetime. Reuse guard instances across requests to reuse their HTTP connections. A guard can serve synchronous and asynchronous evaluations: synchronous calls share one pool, and asynchronous calls use a separate pool for each event loop. Credentials are resolved per evaluation rather than stored in the pool. For application-managed shutdown, close() closes the synchronous pool. await aclose() closes the synchronous pool and the asynchronous pool owned by the current event loop; call it in each owning loop before that loop stops. Context managers perform the corresponding cleanup automatically. Cleanup waits for active evaluations, is idempotent, and allows a later evaluation to create a new pool.

6. Verify enforcement

With a policy-triggering fixture for your collector, use route mode to inspect the outcome without forwarding denied content:
Match the correlation ID to the evaluation in Activity. Test a benign allow, a configured block, and a configured transformation in both policy directions. Verify that blocked content never reaches the next component and that transformed content replaces the original. The fixture and expected verdict depend on the assigned policy.

Reference

Configuration

All constructor parameters are keyword-only. Optional keyword-only run parameters are session_id, consumer_id, and attributes. Policies and detectors are configured in TrustGuard; the components do not accept per-request policy or detector IDs.

Verdicts and errors

verdict contains status and, when supplied, findings, trace_id, and request_id. Findings may include sensitive evidence; log only the fields your application needs. NeuralTrustBlockedError carries the status and a verdict limited to status and validated correlation IDs. Connection failures, timeouts, and HTTP 429/502/504 are retried with bounded backoff. Authentication failures, TLS failures, other HTTP errors, malformed verdicts, and unusable transformations stop execution. Route mode affects valid block and ask verdicts only; there is no fail-open mode. Import these errors from the same component namespace: A pipeline may wrap a component exception in its own execution error. Inspect the chained cause when handling a specific NeuralTrust exception there.

Save and restore pipelines

Both components support to_dict and from_dict for Haystack pipeline serialization:
Environment-based Secrets serialize the variable name, never the resolved credential. Set that variable in the restoring process before evaluation. Secret.from_token(...) works for direct use but cannot be serialized. Runtime HTTP clients are not serialized. The haystack_integrations namespace is compatible with Haystack 3.x’s default deserialization allowlist.

Coverage and limits

  • Text and supported text-only chat can be monitored, blocked, or transformed in either policy direction. Empty or whitespace-only content is rejected.
  • Transforms must map unambiguously to the original messages. Changes to message count, roles, or supported structure fail closed.
  • Document batches, tools, multimodal content, and Agent lifecycle hooks are outside these components’ contract.
  • Output evaluation begins after a reply completes. Buffer responses and deliver only the guard’s output when content must pass policy before the user receives it.
  • Each guarded stage adds an evaluation round trip. Detection and rewriting depend on the collector policy, policy direction, and TrustGuard service.