Anonymous workflows are one-call agent runs. They are useful for scripts, notebooks, jobs, CI tasks, and callbacks where defining a named agent module would add ceremony without adding useful state.
Condukt.run/2 accepts a prompt as the first argument:
{:ok, text} =
Condukt.run("Summarize README.md in three bullets.",
model: "anthropic:claude-sonnet-4-20250514",
tools: [Condukt.Tools.Read]
)Condukt starts a transient Condukt.Session, runs the prompt, returns the
final text, and stops the session. No conversation history is kept across
calls.
Runtime options
Anonymous workflows accept the same run options as agent runs:
:timeoutcaps the synchronous call timeout in milliseconds:max_turnscaps tool-use loops:imagesattaches images to the user message
They also accept the same session options you would pass to an agent's
start_link/1, including :model, :api_key, :base_url,
:system_prompt, :thinking_level, :tools, :sandbox, :cwd,
:subagents, :session_store, :compactor, :redactor, and
:load_project_instructions.
Anonymous workflows default :load_project_instructions to false. Pass
load_project_instructions: true when you want AGENTS.md, CLAUDE.md, and
local skills to shape the transient run.
Typed input
Use :input when you want the prompt to be instructions and the arguments to
be a separate JSON payload:
{:ok, text} =
Condukt.run("Review the supplied pull request metadata.",
input: %{repo: "tuist/condukt", pr_number: 42},
input_schema: %{
type: "object",
properties: %{
repo: %{type: "string"},
pr_number: %{type: "integer"}
},
required: ["repo", "pr_number"]
}
)When :input_schema is present, Condukt validates the input with JSV before
making an LLM request. Input must be a map.
Structured output
Use :output to require a JSON Schema-shaped result:
{:ok, %{verdict: "approve", summary: summary}} =
Condukt.run("Decide a review verdict.",
input: %{repo: "tuist/condukt", pr_number: 42},
output: %{
type: "object",
properties: %{
verdict: %{type: "string", enum: ["approve", "request_changes", "comment"]},
summary: %{type: "string"}
},
required: ["verdict", "summary"]
}
)Structured mode appends a synthetic submit_result tool. The model calls that
tool with the final result, Condukt validates the submitted map with JSV, and
the validated value is returned.
If the schema's top-level properties keys are atoms, Condukt atomizes the
matching top-level result keys after validation.
Inline tools
For small workflow-specific tools, use Condukt.tool/1:
ls =
Condukt.tool(
name: "ls",
description: "Lists files under a glob.",
parameters: %{
type: "object",
properties: %{pattern: %{type: "string"}},
required: ["pattern"]
},
call: fn %{"pattern" => pattern}, context ->
Condukt.Sandbox.glob(context.sandbox, pattern)
end
)
{:ok, text} =
Condukt.run("List Elixir files under lib/.",
tools: [ls]
)Inline tool callbacks receive the same context map as module tools:
:agent, :sandbox, :cwd, and :opts. :opts is always [] for inline
tools.
Anonymous sub-agents
Anonymous workflows can register sub-agents inline with :subagents. Use
role: [opts] when the child does not need a named module:
{:ok, text} =
Condukt.run("Plan the release notes.",
subagents: [
researcher: [
model: "anthropic:claude-haiku-4-5",
system_prompt: "Find facts and return concise notes.",
tools: [Condukt.Tools.Read]
]
]
)Inline sub-agent opts are normal session opts plus the optional :input and
:output schemas documented in the sub-agents guide. Anonymous sub-agents
default :load_project_instructions to false; set it to true in the role
opts when the child should load project instructions.
Errors
Anonymous workflows return {:error, reason} for validation failures, LLM
errors, and session startup failures.
Common structured workflow reasons include:
{:invalid_input, %JSV.ValidationError{}}{:invalid_output, %JSV.ValidationError{}}{:invalid_input, :input_must_be_a_map}:no_result_submitted
Choosing an API
Use anonymous workflows when the task fits in one call and no module-level agent identity is useful.
Use operation/2 when you want a named compile-time entrypoint on an agent
module.
Use a supervised agent process when you need long-lived state, conversation history, streaming interaction, or OTP supervision.