Run limits and agent loops
- Bound run duration — Set
WithTimeoutand/or a context deadline onRunandStream. Context deadline always wins over agent timeout. - Approval timeouts — When tools require approval, set
WithApprovalTimeoutless than the run timeout. Default is agent timeout − 30s. - Max iterations — Set
WithMaxIterationsto cap LLM rounds (default 5). Runs finish withfinish_reason: max_iterationswhen hit. - Sub-agent depth — Set
WithMaxSubAgentDepthwhen using delegation (default 2). - Agent mode — Use
AgentModeInteractive(5 min default) for user-facing apps;AgentModeAutonomous(60 min default) for background pipelines. See Timeouts & Modes.
LLM provider fallback strategy
- No built-in failover — The SDK calls a single
LLMClientper agent. Failover is your responsibility at the client layer. - Implement a wrapper — Wrap multiple provider clients with your own retry and fallback logic, implementing
interfaces.LLMClient. On429or5xx, switch to the secondary provider. - Circuit breaker — Track consecutive LLM errors and open a circuit to avoid hammering a degraded provider. Re-probe after a backoff window.
- Sticky provider per session — For conversation continuity, route the same conversation ID to the same provider. Provider-switching mid-conversation can cause context drift.
- Test fallback paths — Add an integration test that injects a failing LLM client and confirms the agent returns a clean error rather than hanging.
LLMClient interface and built-in clients.
Error handling patterns
- Always check errors —
RunandStreamreturn start errors;Get/ stream events surface run failures. A failedGetmeans the run did not complete successfully — do not accessresult.Content. - Typed errors —
context.DeadlineExceededmeans a timeout fired.ErrMaxIterationsReachedmeans the agent hitWithMaxIterations. Log both with the run context (agent name, conversation ID). - Non-blocking
Run— Wait onAgentRun.Done(), then callGet. Cancelling theGetcontext only unblocks the waiter — useAgentRun.Cancelto cancel the run. Streamerrors — AnAgentEventTypeRunErrorevent carries the error message. Drain the channel to completion even after an error event; close from the producing side.- Surface errors to users clearly — Distinguish timeout errors (“request took too long”), provider errors (“AI service unavailable”), and logic errors (“agent reached its step limit”) in your UI layer.
- Retries — Retrying
Runwith the sameConversationOptions.IDwill continue from the saved conversation history (if conversation is enabled). Beware of idempotency if tools have side effects.
Tool and delegation risk
- Approval policy — Choose
WithToolApprovalPolicyper agent — main and each specialist. Default is require-all; useAutoToolApprovalPolicy()only when you fully trust the agent surface. - Human review — Require approval for dangerous tools, MCP-exposed capabilities, and sub-agent delegation where policy demands it.
- Tool authorization — Implement
ToolAuthorizerfor programmatic gates (scopes, tenancy, feature flags) before approval or execution. - Parallel vs sequential tools — Use
WithAgentToolExecutionModeconsistently acrossNewAgent,NewAgentWorker, and sub-agents when order or shared state matters.
MCP and external tools
- Attack surface — Remote MCP servers widen what the LLM can invoke. Audit connected servers and use
ToolFilterto allowlist tools. - TLS — Prefer TLS for streamable HTTP MCP in production. Avoid
SkipTLSVerifyoutside local development. - Secrets — Protect bearer tokens, OAuth credentials, and custom headers. Never commit them to source control.
- Runtime registration — Dynamic MCP changes on the client do not propagate to remote workers automatically — see Dynamic Capabilities.
Split processes and Temporal
- Distributed execution — When using
DisableLocalWorker, runNewAgentWorkerwith matching configuration on a separate process. Streaming and approvals work across processes with no extra option — the agent subscribes to the run’s event stream directly through the Temporal client. - Distributed conversation — Use Redis (not in-memory) for conversation when client and worker are split. Same config on both processes.
- Config fingerprint — Keep task queue, tools, MCP/A2A setup, memory, hooks, and observability config aligned. Avoid
WithDisableFingerprintCheckin production. - Integration tests — Exercise approval and streaming paths with split processes before deploy.
- Workflow replay — After upgrading the SDK module, confirm existing workflows still replay in your Temporal environment.
Rate limiting awareness
- LLM provider rate limits — Most providers enforce requests-per-minute (RPM) and tokens-per-minute (TPM) limits. A
429from the provider surfaces as an LLM activity error in Temporal (which retries it) or a run error in-process (which does not retry by default). - Implement exponential backoff — In your
LLMClientwrapper, catch429responses and back off before retrying. Do not let unbounded retries exhaust your Temporal workflow timeout. - Track token usage — Monitor
agent.llm.tokens.inputandagent.llm.tokens.outputOTLP metrics. Set alerts when per-minute token totals approach your provider limit. See Metrics. - Cap concurrent runs — A burst of concurrent
Runcalls multiplies LLM load. Use a semaphore or rate limiter in your API layer before calling the agent. - Autonomous vs interactive mode —
AgentModeAutonomous(60 min timeout) can queue many long-running workflows. Size your Temporal workers and provider quota to match expected concurrency.
Cost controls
- Token budget per run — Set
WithLLMSampling(&LLMSampling{MaxTokens: N})to cap completion tokens per LLM call. Prevents runaway costs from unexpectedly long responses. - Cap iteration count —
WithMaxIterations(default 5) directly caps how many LLM calls a single run makes. Reduce it for cost-sensitive workloads. - Monitor token usage — Read
result.LLMUsage.TotalTokenson every run and aggregate by user/tenant. See Token Usage. - OTLP token metrics —
agent.llm.tokens.inputandagent.llm.tokens.outputhistograms let you alert on token spend in dashboards. See Metrics. - Sub-agent token multiplication — Each sub-agent delegation triggers its own LLM calls. Monitor sub-agent trees carefully — a 3-level deep tree with 3 tools per level can multiply token spend significantly.
- Estimate before production — Run the Benchmarks harness with real provider clients and
mock_tokenstuned to your expected prompt size to estimate cost at target load.
Prompt Caching
- Enable per provider — Prompt caching is opt-in on Anthropic via
llm.WithPromptCaching(true). OpenAI caches automatically server-side with no client option. Gemini and DeepSeek ignoreWithPromptCaching— this SDK does not configure prompt caching for them. - Message order matters — SDK builds context in stable-to-dynamic order automatically: system prompt and tools as separate request fields, then memory → RAG → conversation history (including the user message). Do not inject volatile content into stable prefixes.
- Data residency — Anthropic stores prefix KV state server-side. Leave caching disabled (default) or use
llm.WithPromptCaching(false)for sensitive data workloads. - Write cost — Anthropic charges 1.25x base input rate on cache writes for the default 5-minute TTL (2x for the 1-hour TTL). At low request volume the write cost may exceed read savings. Enable only when request volume justifies it.
- Sanitization — SDK strips timestamps and volatile IDs (session, conversation, run, request IDs, and UUIDs) from conversation history before sending to the provider to maximize cache hit rate. Original stored messages are unchanged.
Secrets and data handling
- Credentials — Keep LLM API keys and Temporal credentials in environment variables or a secrets manager — not in source control.
- Untrusted I/O — Treat tool arguments and model output as untrusted at your application boundary.
- Prompt safety — Validate and sanitize prompts, tool args, and model output in your integration layer. Consider Hooks for guardrails and PII scrubbing.
- Conversation and memory — You own
Clearon conversation and memory stores. Scope memory with tenant and user context — see Memory.
Observability
- OTLP wiring — Use
WithObservabilityConfigon bothNewAgentandNewAgentWorkerso traces, metrics, and logs from worker activities reach your collector. - Collector reachability — Confirm your OTLP endpoint is reachable before deploying. Use
Insecure: trueonly in development. - Run telemetry — Log
AgentTelemetryfrom results for operational insight — LLM call count, tool breakdown, finish reason. - Structured logging — Set
WithLogLevelappropriately; useWithLoggerto integrate with your log pipeline. - Temporal UI — Use workflow history and the Temporal Web UI to debug individual runs.
Temporal worker scaling
- Workers are stateless — Temporal holds all workflow state. Scale workers horizontally by adding replicas; each polls the same task queue and picks up available work.
- Stable agent names — Keep
WithNamestable for an agent type across client and worker processes. Do not reuse one name for different agent types. - Scale sub-agent workers independently — Run a
NewAgentWorkerper specialist when using remote workers. A high-delegation workload may require more sub-agent workers than root agent workers. - Size worker concurrency — Each worker runs multiple workflow goroutines concurrently. Tune via Temporal worker options (max concurrent workflow tasks, activity tasks). Match to your LLM provider’s concurrency quota to avoid throttling.
- Worker health checks — Probe that workers are polling before accepting traffic.
AgentModeInteractivewithDisableLocalWorkerperforms a pre-check automatically — ensure at least one worker is registered on the task queue. - Rolling deploys — Temporal workflows replay on new workers. After an SDK upgrade, verify workflow replay compatibility in staging before rolling out to production workers.
Operations
- Graceful shutdown — Call
Agent.Close()to flush OTLP exporters. CallAgentWorker.Stop()on worker processes. - Streaming UX — Live stream events are not automatically backfilled after disconnect. On the Temporal runtime, use
GetAgentStreamwith the savedrunIDand last event offset (Events(..., WithOffset(...))) to resume the stream after a process crash. PersistrunID(stream.ID()) and offset before consuming each event. See Reconnect example and Temporal streaming. - Health checks — Verify Temporal connectivity, worker availability, Redis/Postgres backends, and OTLP collector health in your deployment probes.
Pre-deploy checklist
Validate before deploy
Run these against your target environment to confirm configuration:Related
Distributed Execution
Split client and worker processes
Approvals
Tool and delegation approval flows