Orchestration and Recovery
Read only when the source uses subagents, grading loops, approvals, checkpoints, retries, durable execution, or streaming.
Import SubAgent and SubAgents from pydantic_ai_harness.subagents. Harness can load its Markdown agent format from configured folders, but it does not consume a Deep Agents YAML roster. Parse and validate retained application configuration into explicit Agent and SubAgent objects, or intentionally convert it: YAML system_prompt becomes Agent.instructions or the Markdown body, description remains the description, and tools become explicit toolsets or a tool_resolver. Set the child model explicitly or through AgentOverride; a model key in Harness Markdown is parsed but not applied.
| Deep Agents feature | Pydantic AI and Harness candidate | Important difference |
|---|---|---|
| synchronous named children | SubAgents |
Inspect the automatic general-purpose child and disablement, isolated versus forked context, declarative versus compiled children, tools, skills, permissions, approvals, state, structured results, and streaming inheritance. Harness does not transfer mutable parent capability state implicitly; use explicit dependencies or state transfer, shared_capabilities, or an application repository, then test child write visibility. |
| model-written fan-out or chaining | DynamicWorkflow |
This is a redesign, not an API port: Deep Agents generates JavaScript for QuickJS and calls task(...); Harness generates Python for Monty and calls child agents from run_workflow. Verify structured results, interpreter and thread state, nesting, and tool boundaries. Neither is a durable background task service. |
AsyncSubAgent background work |
an application queue/worker and narrow agent tools | Preserve graph ID, transport and authentication, start/check/update/cancel/list operations, task/thread/run identity, pending state, stale reads, steering, cancellation, and result durability. Harness synchronous delegation and generated workflows are not background-task services. |
RubricMiddleware grading loop |
an explicit evaluator/revision loop or focused capability | Preserve the invocation rubric, grader model and tools, revision feedback, iteration limit, terminal verdict, callbacks, and progress events. TrajectoryJudge provides cadence-based mid-run steering, so use it only when that different lifecycle is accepted. |
approval or interrupt_on |
Pydantic AI DeferredToolRequests, DeferredToolResults, ToolApproved, and ToolDenied |
Include DeferredToolRequests in output_type. When returned, persist result.all_messages(), resolve the request with build_results(...), then call run(message_history=..., deferred_tool_results=...). Use HandleDeferredToolCalls only for an in-process handler whose lifecycle is sufficient. The LangGraph Command(resume=...) protocol is not reproduced. |
| provider-valid run snapshots | StepPersistence |
It records step events, continuable snapshots, lineage, and tool effects; it is not arbitrary LangGraph graph-state checkpointing. |
| durable model and tool execution | TemporalDurability, DBOSDurability, PrefectDurability, AWSLambdaDurability, AbsurdDurability, PGTaskDurability, or another matching integration |
Select by the deployment contract and install its extra. Wire the integration's workflow or handler boundary, not only its capability; verify crash and redeploy recovery, replay, timers, signals, and side-effect idempotency in that runtime. |
| retries, fallbacks, and call limits | Pydantic AI tool/output retries, provider or model transport retries, pydantic_ai.models.fallback.FallbackModel, UsageLimits, and application or durable-workflow policy |
Classify expected versus unexpected errors and retry scope. Match backoff, fallback order, tool-error visibility, counters, terminal propagation, and side-effect idempotency. |
| LangGraph and Deep Agents event streaming | Pydantic AI streaming APIs plus Harness event handlers | Translate the application's selected modes and projections. Namespaced graphs and Deep Agents subagent handles with child identity, status, messages, tool calls, nested work, and output are not preserved automatically. |
Explicit designs for gaps
- Forked child context or compiled LangGraph children: pass selected context explicitly, rebuild the child with Pydantic AI primitives, or retain it behind a typed tool boundary during migration.
- Background subagents: keep the queue and worker in the host. Give the agent narrow start, list, inspect, steer, and cancel tools with tenant checks, idempotency keys, bounded retries, and durable results.
- Approvals: test approve, deny, changed arguments, stale decisions, authorization changes, crash before and after execution, replay, and side-effect idempotency.
- Checkpoints: separate message continuation, capability state, plans, files, approvals, domain state, and side effects. Do not replace a LangGraph checkpointer keyed by
thread_idwithStepPersistencewithout designing thread identity,message_historycontinuation, and ownership of the remaining state. UseStepPersistenceonly for its documented snapshot contract. - Streaming: verify lineage, ordering, backpressure, redaction, child and tool events, error termination, and final-output timing.
Primary sources: Deep Agents subagents, async subagents, grading rubrics, human-in-the-loop, fault tolerance, event streaming, Pydantic AI deferred tools, and durable execution.