Frameworks differ; the lifecycle does not
Agent frameworks use different language for human involvement. A graph pauses at an interrupt. A crew asks for feedback. A function tool can be wrapped before it runs. Those are useful integration points, but they are not a complete approval system by themselves.
The durable lifecycle is consistent: capture intent, create an external approval, persist the workflow correlation, wait without holding an in-memory process open, verify the decision event, and resume exactly the work that requested it. Treating that lifecycle as an adapter boundary keeps policy and audit behavior consistent when teams change frameworks.
LangGraph: correlate the approval with the checkpoint
A durable graph already has a useful primitive: a checkpointed thread that can pause and resume. The integration should create the approval at the interrupt boundary and attach the thread identifier as correlation data. The process can then stop; it does not need to poll or keep a worker alive.
When the signed decision event arrives, load the stored correlation, verify that the approval is terminal and applies to the expected action, then resume that exact thread. Avoid resolving a thread by email address or display text. Those values are helpful to people but are not durable workflow identifiers.
- Persist the approval ID beside the graph checkpoint before returning control.
- Use an idempotency key derived from the thread and interrupt so a retry returns the same approval.
- Resume only after the webhook signature and replay window have been verified.
CrewAI: keep feedback outside the execution loop
Human feedback in a crew can shape planning, review intermediate work, or authorize a tool. Only the last case is a security boundary. If the feedback decides whether a consequential action may happen, move it to an external provider that records a durable request and returns a structured decision.
The crew should not infer approval from free-form prose such as 'looks good.' Feed a typed approved or rejected outcome back into the flow and preserve the approval ID in the task output. That makes later behavior explainable and prevents another agent from reinterpreting the human response.
AutoGen: guard the function that owns the side effect
For function-oriented agents, place the checkpoint around the narrowest tool that can cause the side effect. A deploy function, refund function, or outbound-message function should not be callable through an unguarded alias elsewhere in the tool registry.
The wrapper can create the approval from validated function arguments and return a pending result to the conversation. After approval, a trusted worker executes the original function using the stored arguments. This prevents the model from changing parameters between the human decision and execution.
intent = validate(tool_arguments)
approval = request_approval(intent, correlation_id)
persist(checkpoint, approval.id, intent)
# Later, after a verified decision event
state = load_checkpoint(approval.id)
assert decision.action == state.intent.action
resume_or_execute(state, decision)Keep one policy surface across every adapter
Framework-specific adapters should be intentionally thin. They should know how to extract a summary, correlation ID, and resume handle. They should not each invent expiry behavior, recipient rules, signature verification, or audit semantics.
Centralizing those concerns gives platform teams one place to answer operational questions: Who approved this? Which version of the action did they see? Did a retry create another request? Which event resumed the workflow? A consistent control plane turns three framework integrations into one governable system instead of three special cases.
- Use the same action vocabulary across frameworks for reporting and policy.
- Keep sensitive credentials in the application boundary, never in agent state.
- Test every adapter against the same duplicate, expiry, rejection, and cancellation scenarios.
- Expose the approval ID in logs so framework traces and decision history can be joined.
Build a checkpoint your application can trust.
Start with one approval request, then connect the signed outcome to your workflow.