Skip to main content

Someone wanted to learn this too, so Grasp built them a personal learning path.

You can keep exploring this one or create your own

Agent Communication: Parent to Child Context Transfer

Introduction

In our previous lesson, we focused on the art of prompting a supervisor agent, teaching it how and when to delegate tasks. We established that the supervisor's role is to be an intelligent router, not an executor. Now, we'll shift our focus from the decision to delegate to the mechanics of the handoff itself. This lesson directly addresses how to pass context and instructions from a parent agent to its child agents, a critical step in building a functional agent hierarchy.

A worker agent, no matter how specialized, is inert without the proper information. It needs to know not only what task to perform but also the surrounding context necessary to perform it correctly. Today, you'll learn the patterns and Vercel AI SDK features for structuring this information flow, ensuring your worker agents receive everything they need to succeed. This is the bridge between the supervisor's plan and the worker's execution.

1. The Handoff: From Simple Tasks to Structured Data

The simplest way to pass information is through a single string, as we've implicitly done before. A supervisor might delegate with an instruction like "Research the market for AI-powered CRMs". This instruction is passed as an argument to the tool's execute function, which then invokes the child agent.

The AI SDK documentation provides a clear example of this basic pattern.

Subagents - Agents - AI SDK

This documentation from the Vercel AI SDK shows the fundamental pattern for creating and invoking a subagent.

Focus on the code block under the heading Basic Subagent Without Streaming. Notice how the researchTool defines an inputSchema that accepts a single task string. The execute function then passes this task as the prompt to the researchSubagent. This is the most direct form of instruction passing.

This works for simple, self-contained tasks. But what happens when the task is more complex? Consider our medical clinic's Booking Agent. An instruction like "Book an appointment" is insufficient. The agent needs to know:

  • Who is the patient? (e.g., patientId)
  • Which doctor or specialty? (doctorId or specialty)
  • What is the requested date and time? (requestedSlot)
  • Are there any specific notes for the appointment?

Passing this as a single, unstructured string would force the child agent to re-parse the information, introducing ambiguity and potential errors. The solution is to define a structured data contract between the parent and child.

2. The inputSchema: Your Data Contract

The inputSchema in your delegation tool is the formal contract for the data passed from the parent to the child. By using Zod, you can define a rich, typed object that ensures the child agent receives exactly the information it needs in a predictable format.

Let's expand on this idea with the "Orchestrator-Worker" pattern. This is a common and powerful hierarchical model where a primary orchestrator agent plans the work and delegates the execution to specialized worker agents.

A typical orchestrator-worker hierarchy. The Main Orchestrator Agent breaks down a task and passes structured context and instructions to specialized sub-agents like the Search, Content, and Analysis agents.

The AI SDK documentation provides a fantastic code example of this pattern in action.

Workflow Patterns - Agents

This documentation page showcases advanced agentic workflows. The "Orchestrator-Worker" pattern is directly relevant to passing structured context.

Carefully study the code block under the Orchestrator-Worker heading. Observe how the orchestrator first generates a structured implementationPlan. It then iterates through this plan, invoking a worker for each file change. Crucially, it passes a structured prompt to each worker, containing the specific file.filePath, file.purpose, and the overall featureRequest. This is a perfect example of a parent passing both specific instructions and broader context to its children.

This pattern demonstrates a key principle: the supervisor's job often involves first using an LLM call to extract structured data from an unstructured user request, and then passing that structured data to the appropriate worker.

For our booking agent, the tool definition would evolve from a simple string to a structured object:

// /lib/tools/delegation/create-booking-tool.ts
import { tool } from 'ai';
import { z } from 'zod';
import { bookingAgent } from '@/lib/agents/worker/booking-agent';

export const createBookingTool = () => tool({
  description: 'Schedules, cancels, or reschedules a patient appointment.',
  
  // The structured data contract
  inputSchema: z.object({
    patientId: z.string().describe('The unique identifier for the patient.'),
    action: z.enum(['SCHEDULE', 'CANCEL', 'RESCHEDULE']),
    slot: z.object({
      doctorId: z.string(),
      startTime: z.string().datetime(),
      endTime: z.string().datetime(),
    }),
    notes: z.string().optional().describe('Any additional notes for the booking.'),
  }),

  // The execute function now receives a structured object
  execute: async ({ patientId, action, slot, notes }) => {
    // Construct a precise prompt for the booking agent
    const task = `Perform the following booking action:
    - Action: ${action}
    - Patient ID: ${patientId}
    - Doctor ID: ${slot.doctorId}
    - Start Time: ${slot.startTime}
    - End Time: ${slot.endTime}
    - Notes: ${notes || 'N/A'}`;

    const result = await bookingAgent.generate({
      prompt: task,
    });
    
    // In a real scenario, you'd parse the result to confirm success/failure
    return result.text;
  },
});

With this inputSchema, the supervisor is now responsible for providing a complete, validated object. This makes the entire system more robust and predictable.

3. Passing Ambient and Implicit Context

Sometimes, the necessary context isn't in the user's immediate request but is part of the broader environment. This "ambient context" can include the full conversation history or session-level data like a user's ID or subscription tier.

Passing Conversation History

By default, a subagent starts with a clean slate—it has no knowledge of the parent's conversation. This isolation is a feature, as it prevents the subagent's context window from being cluttered. However, there are times when you need to provide this history. The AI SDK makes this possible within the execute function.

Subagents - Agents - AI SDK

This section of the documentation explains the isolated nature of subagent context and how to override it.

Read the section Subagent Context is Isolated. The code example shows how the execute function receives a messages object, which represents the parent agent's conversation history. You can then selectively pass this history to the subagent's generate call.

This technique should be used judiciously, as passing the full history can negate the context-saving benefits of using subagents.

Passing Dynamic Call Options

A more elegant way to handle session-level data is through the Vercel AI SDK's "dynamic call options". This feature allows you to define a typed schema for data that will be provided every time an agent is invoked. It's perfectly suited for the kind of tenant-specific context you aim to implement.

Build an Agent with Vercel

This video from Vercel introduces a powerful feature for passing structured, per-request context to an agent.

Watch the segment from dynamic call options. The speaker explains how you can define an input schema for the agent itself (e.g., userId and accountType). This data is then available in a prepareCall hook, allowing you to dynamically modify the agent's behavior—such as altering its system prompt or available tools—based on the incoming context.

This is an extremely powerful pattern. In your target architecture, the orchestrator could receive a request, identify the tenant, and then invoke a supervisor agent using dynamic call options to pass the tenantId. The supervisor's prepareCall hook could then use this tenantId to load the correct set of tools and prompts from your stores, ensuring every action is scoped to the correct tenant.

4. Managing the Return Context: toModelOutput

Passing context is a two-way street. A child agent might perform extensive work, involving multiple tool calls and thousands of tokens of reasoning. If all of that work were passed back to the parent's context window, it would quickly become bloated and expensive.

The toModelOutput function is the AI SDK's solution to this problem. It allows you to define a transformation that runs on the child agent's final output, summarizing it before it's added to the parent's message history.

Subagents - Agents - AI SDK

This part of the documentation covers the crucial concept of managing what the parent model sees versus what the user sees.

Read the sections Controlling What the Model Sees and Write Subagent Instructions for Summarization. This explains how toModelOutput intercepts the subagent's full output and returns only a concise summary to the parent model's context. It also correctly points out that this relies on prompting the subagent to create a good summary in the first place.

With this pattern:

  1. The UI can still receive and display the subagent's full, step-by-step work for transparency.
  2. The parent agent, however, only "sees" the concise summary (e.g., "Successfully booked appointment for patient 123 with Dr. Smith on Tuesday at 2 PM.").

This keeps the parent agent's context clean, focused, and cost-effective, which is essential for building scalable, production-ready systems.

Conclusion

Today, we've gone under the hood of agent delegation, exploring the specific mechanisms for passing information between parent and child agents. You've learned that effective context passing is about creating clear, structured data contracts and managing the flow of information in both directions.

Key Takeaways:

  • Structured inputSchema is Key: Use Zod to define a rich, typed object in your delegation tool's inputSchema. This creates a robust and predictable data contract.
  • The Orchestrator Plans and Prepares: A common pattern is for the parent agent to first parse an unstructured request into a structured object, which it then passes to the worker.
  • Pass Ambient Context Explicitly: Use the messages parameter in the execute function to pass conversation history, or leverage "dynamic call options" to inject session-level data like a tenant or user ID.
  • Control the Return Journey with toModelOutput: Prevent context bloat in your parent agent by using toModelOutput to summarize the child agent's work before adding it to the parent's history.
  • Prompting and Structure Work Together: Your ability to pass structured data is directly tied to your ability to prompt the parent agent to generate that structured data in the first place.

We now have a supervisor that knows when to delegate and how to pass the necessary information for a single task. In our next lesson, we will tackle more complex scenarios as we learn to "Aggregate and synthesize responses from multiple child agents into a unified result," enabling the supervisor to manage workflows that require the coordinated effort of several workers.

Can't find a good explanation? Sign up and we'll make it for you

Sign up