Behaviour for redacting sensitive data before it is sent to an LLM provider.
A redactor is invoked on outbound message text — user input and tool results — right before the conversation is handed to the LLM. Assistant output and the system prompt are left untouched: the LLM has already seen its own prior responses, and the system prompt is authored by the developer.
Redactors are configured per session at start_link/1 via the :redactor
option. The value can be a module or a {module, opts} tuple. When nil
(the default), no redaction is performed.
MyApp.Agent.start_link(redactor: Condukt.Redactors.Regex)
MyApp.Agent.start_link(redactor: {Condukt.Redactors.Regex, patterns: my_patterns})Implementing a redactor
defmodule MyApp.Redactor do
@behaviour Condukt.Redactor
@impl true
def redact(text, _opts) do
String.replace(text, ~r/\bsecret-[a-z0-9]+\b/, "[REDACTED]")
end
endRedaction in this version is outbound-only: the original text remains in the session's stored history. Each turn re-runs the redactor on the messages that are about to be sent, so secrets never leave the BEAM process.
Summary
Callbacks
Returns text with sensitive substrings replaced.
Functions
Applies a redactor spec to a single string.
Returns messages with redaction applied to user input and tool results.
Callbacks
Functions
Applies a redactor spec to a single string.
The spec is a module implementing the behaviour, a {module, opts} tuple, a
list of redactor specs, or nil. Returns text unchanged when spec is
nil or an empty list.
Returns messages with redaction applied to user input and tool results.
Assistant messages and any non-textual content blocks are returned unchanged. Tool result content that is not a binary is JSON-encoded before redaction so embedded secrets in structured output are still caught.