Customization
LangChain's Deep Agents customization page centers on one Python entry point, create_deep_agent(...). BeamWeaver exposes the same agent-building concerns through two Elixir surfaces:
-
use BeamWeaver.Agentfor stable application modules. -
BeamWeaver.Agent.build/1for runtime or config-driven agents.
This page is a map, not a replacement for the detailed guides. Use it when you are porting examples from the official Deep Agents docs and need to know which BeamWeaver option, macro, or guide owns each concept.
Option Map
Python create_deep_agent option
| BeamWeaver surface | Details |
|---|---|---|
model
|
model / :model, model_opts, BeamWeaver.Models.init_chat_model!/2
| Agents , Models |
tools
|
tools / :tools, %BeamWeaver.Core.Tool{}, use BeamWeaver.Tool
| Tools |
system_prompt
|
system_prompt / :system_prompt
| Agents , Profiles |
middleware
|
middleware / :middleware, BeamWeaver.Agent.Middleware
| Middleware , Custom Middleware , Prebuilt Middleware |
subagents
|
subagents, async_subagents
| Subagents , Async Subagents |
skills
|
skills
| Skills |
memory
|
memory, checkpoint-backed short-term memory, store-backed long-term memory
| Memory , Short-Term Memory , Long-Term Memory |
permissions
|
filesystem_permissions; runtime alias :permissions
| Filesystem Permissions |
backend
|
filesystem; runtime alias :backend
| Filesystem , Sandboxes |
interrupt_on
|
interrupt_on, graph interrupts, BeamWeaver.Agent.Middleware.HumanInTheLoop
| Human-In-The-Loop |
response_format
|
response_format / :response_format
| Structured Output |
context_schema
|
context_schema / :context_schema; invocation context:
| Runtime , Agents |
checkpointer
|
checkpointer / :checkpointer
| Persistence , Durable Execution |
store
|
store / :store, BeamWeaver.Memory.Store adapters
| Persistence , Long-Term Memory |
debug
|
debug / :debug; typed debug events and logging
| Event Streaming , Tracing |
name
|
name / :name
| Agents |
cache
|
cache / :cache, BeamWeaver.Cache adapters
| Adapters |
BeamWeaver also exposes agent options that are not a direct Python parameter: model_opts, validate_tools, input_schema, output_schema, interrupt_before, interrupt_after, recursion_limit, compact_conversation, overflow_recovery, prompt_caching, exclude_tools, and tool_descriptions.
Configuration Areas
The official customization page is organized around the knobs below. In BeamWeaver, each knob is an agent field, a runtime BeamWeaver.Agent.build/1 option, or a middleware/backend choice.
Model
Pass either a provider-prefixed model string or an initialized chat model:
model "openai:gpt-5.4", timeout: 120_000
# or
model BeamWeaver.Models.init_chat_model!("anthropic:claude-sonnet-4-6")
Runtime agents use the matching options:
BeamWeaver.Agent.build(
model: "openai:gpt-5.4",
model_opts: [timeout: 120_000]
)
See Models and the provider pages for supported provider strings and model-specific options.
Tools
Pass tool modules, %BeamWeaver.Core.Tool{} structs, or functions converted through the tool APIs:
tools do
tool MyApp.Tools.SearchDocs
tool MyApp.Tools.CreateTicket
end
Use Tools for tool schemas, injected runtime values, artifacts, and provider normalization.
System Prompt
Use system_prompt for task and product instructions. Middleware that contributes special tools, such as filesystem, skills, or memory middleware, adds its own model guidance around that prompt during the model request.
system_prompt "You are a release-risk analyst. Cite concrete evidence."
For provider/model-specific prompt changes, prefer explicit agent config, middleware, or profiles instead of copying the built-in Deep Agents prompt into every agent.
Middleware
BeamWeaver middleware is the extension point for lifecycle hooks, dynamic prompt edits, retry/fallback behavior, PII handling, tool-call limits, and human review:
middleware do
use BeamWeaver.Agent.Middleware.ModelRetry, max_attempts: 3
use BeamWeaver.Agent.Middleware.TodoList, tool_name: "write_todos"
end
See Middleware , Prebuilt Middleware , and Custom Middleware .
Interpreters And Code Execution
BeamWeaver does not ship Python QuickJS middleware or a default unsafe local runtime. Code execution remains explicit:
-
Custom tools for narrow, application-owned computation.
-
BeamWeaver.Filesystem.LocalShellor another executable filesystem backend when the agent needs anexecutetool. -
Sandbox-backed filesystems for isolated command execution.
-
BeamWeaver.Sandbox.Interpreter.Sessionwhen your application provides an explicit interpreter adapter.
Interpreter adapters implement BeamWeaver.Sandbox.Interpreter and are owned by a supervised session process. The session handles timeout/cancel behavior, adapter crash normalization, tagged snapshots, restore, close, and native telemetry. The adapter owns the language runtime:
{:ok, session} =
BeamWeaver.Sandbox.Interpreter.Session.start(
adapter: MyApp.SafeInterpreter,
timeout: 5_000,
max_snapshot_bytes: 1_000_000
)
{:ok, result} =
BeamWeaver.Sandbox.Interpreter.Session.eval(session, "state.answer = 42")
{:ok, snapshot} =
BeamWeaver.Sandbox.Interpreter.Session.snapshot(session)
See Filesystem , Sandboxes , Tracing , and Composed Agent Capabilities .
Subagents
Use subagents for synchronous task delegation and async_subagents for remote Agent Protocol work:
subagents do
subagent MyApp.Agents.Researcher
end
The child agent module owns its prompt, tools, middleware, and schema.
See Subagents and Async Subagents .
Backends And Filesystems
Official Deep Agents calls this layer "backends." BeamWeaver's public agent field is filesystem; runtime backend: remains accepted as a compatibility alias.
filesystem BeamWeaver.Filesystem.State.new()
Use BeamWeaver.Filesystem.Composite when different virtual path prefixes should route to different storage backends. Use sandbox filesystem adapters when the agent should run commands outside the host process.
Human-In-The-Loop
Set interrupt_on to pause before sensitive tool calls:
interrupt_on %{
"edit_file" => true,
"send_email" => %{allowed_decisions: [:approve, :reject]}
}
Human review requires checkpointing so the interrupted run can be resumed. See Human-In-The-Loop .
Skills
Use skills to expose SKILL.md metadata stored in the configured filesystem. Skills are progressively disclosed: the startup prompt lists available skills, and the model reads full skill files only when relevant.
skills ["/skills"]
See Skills .
Memory
Use memory true to load /AGENTS.md, or pass explicit memory file paths:
memory ["/AGENTS.md", "/project/AGENTS.md"]
This is filesystem-backed agent memory. It is separate from short-term graph state and long-term application stores. See Memory , Short-Term Memory , and Long-Term Memory .
Profiles
BeamWeaver separates profiles by concern:
-
Model profiles describe model capabilities and tokenizer defaults.
-
Provider profiles supply model-construction defaults.
-
Capability profiles package capability defaults for custom composed agents.
See Profiles .
Structured Output
Use response_schema/2 for the agent's final structured result:
response_schema MyApp.Schemas.Contact,
name: "contact",
strategy: :tool
Final parsed data is returned as :structured_response in the agent state. See
Structured Output
.
Runtime-Built Agent
Use BeamWeaver.Agent.build/1 when the agent is assembled from configuration, tenant data, or another runtime source:
alias BeamWeaver.Agent
alias BeamWeaver.Agent.Middleware
alias BeamWeaver.Agent.Subagent
alias BeamWeaver.Checkpoint
alias BeamWeaver.Core.Message
alias BeamWeaver.Filesystem
alias BeamWeaver.Filesystem.Permission
alias BeamWeaver.Memory
{:ok, agent} =
Agent.build(
name: "research_agent",
model: "anthropic:claude-sonnet-4-6",
model_opts: [
timeout: 120_000,
max_output_tokens: 2_000
],
tools: [MyApp.Tools.Search],
system_prompt: "You are a careful research assistant.",
middleware: [
{Middleware.ModelRetry, max_attempts: 3},
{Middleware.TodoList, tool_name: "write_todos"}
],
filesystem: Filesystem.State.new(),
filesystem_permissions: [
Permission.new(operations: [:read, :write], paths: ["/secrets/**"], mode: :deny),
Permission.new(operations: [:read, :write], paths: ["/workspace/**"], mode: :allow)
],
skills: ["/skills"],
memory: ["/AGENTS.md"],
subagents: [
Subagent.Spec.new(
name: "evidence_collector",
description: "Collect source-backed facts without editing files.",
system_prompt: "Return concise findings with file paths."
)
],
interrupt_on: %{"edit_file" => true},
response_format: MyApp.Schemas.ResearchSummary.schema(),
context_schema: %{
user_id: %{type: :string, required: true}
},
checkpointer: Checkpoint.ETS.new(),
store: Memory.ETS.new(),
debug: true,
recursion_limit: 10_000
)
Agent.invoke(
agent,
%{messages: [Message.user("Summarize the release risk.")]},
context: %{user_id: "user-123"},
config: %{"configurable" => %{"thread_id" => "thread-123"}}
)
The model_opts[:timeout] value is important for long model calls. It sets the generated agent model node's graph timeout and also flows into provider model construction when the model is specified as a provider string. Without an explicit model timeout, the generated model node falls back to the graph node default. See
Agents
and
Fault Tolerance
for the timeout precedence.
Module-Defined Agent
Use a module-defined agent for stable application code. It exposes the same fields as macros:
defmodule MyApp.ResearchAgent do
use BeamWeaver.Agent
alias BeamWeaver.Agent.Middleware
alias BeamWeaver.Checkpoint
alias BeamWeaver.Filesystem
alias BeamWeaver.Filesystem.Permission
alias BeamWeaver.Memory
name "research_agent"
model "anthropic:claude-sonnet-4-6", timeout: 120_000, max_output_tokens: 2_000
tools do
tool MyApp.Tools.Search
end
system_prompt "You are a careful research assistant."
middleware do
use Middleware.ModelRetry, max_attempts: 3
use Middleware.TodoList, tool_name: "write_todos"
end
filesystem Filesystem.State.new()
filesystem_permissions [
Permission.new(operations: [:read, :write], paths: ["/secrets/**"], mode: :deny),
Permission.new(operations: [:read, :write], paths: ["/workspace/**"], mode: :allow)
]
skills ["/skills"]
memory ["/AGENTS.md"]
subagents do
subagent MyApp.Agents.EvidenceCollector
end
interrupt_on %{"edit_file" => true}
response_schema MyApp.Schemas.ResearchSummary
context_schema do
field :user_id, :string, required: true
end
checkpointer Checkpoint.ETS.new()
store Memory.ETS.new()
debug true
recursion_limit 10_000
end
Module agents and runtime-built agents compile through the same BeamWeaver.Agent.Spec and graph compiler. Prefer modules when the agent shape belongs to application code; use BeamWeaver.Agent.build/1 when the shape is data.
Prompt And Profiles
The normal customization path is direct configuration:
-
Put product or task instructions in
system_prompt. -
Use
tool_descriptionsandexclude_toolswhen you need to adjust the model-visible tool surface. -
Use
middlewarefor dynamic prompts, model retries, fallbacks, call limits, PII handling, context editing, and custom lifecycle hooks.
BeamWeaver also has profiles, but they are intentionally split by concern:
-
Provider profiles apply model-construction defaults for provider/model strings.
-
Model profiles describe model capabilities such as context window, tool calling, streaming, and structured output support.
-
Capability profiles mirror Deep Agents profile data for custom composed agent code, but normal agent builds do not automatically overlay them.
See Profiles for the exact behavior and differences from the official Deep Agents profile API.
Differences From Python Examples
| Python docs pattern | BeamWeaver shape |
|---|---|
One create_deep_agent(...) call
|
use BeamWeaver.Agent module macros or BeamWeaver.Agent.build/1 options.
|
| Provider packages installed independently | Use documented native providers: OpenAI, Anthropic, Google, xAI, Z.ai, fake, and replay-backed tests. |
Python decorators such as @wrap_model_call
|
Implement BeamWeaver.Agent.Middleware callbacks or use prebuilt middleware modules.
|
Dataclass or typed Runtime[Context]
|
Pass context: maps and validate with context_schema.
|
Python BaseStore and checkpointers
|
Pass BeamWeaver.Memory.Store and BeamWeaver.Checkpoint.Saver adapters explicitly.
|
LangChain stream_events(..., version="v3") projection object
|
Use versionless typed envelope streams from BeamWeaver.Agent.stream_events/3.
|
| QuickJS interpreter middleware |
Provide an explicit BeamWeaver.Sandbox.Interpreter adapter for supervised interpreter sessions, or use tools/executable filesystem/sandbox-backed execution.
|
| Automatic hosted deployment infrastructure | Configure checkpointers, stores, cache, tracing exporters, auth boundaries, and sandbox lifecycle in Elixir. |