Hello! Welcome to the fifth module of our course.
In our last few lessons, we mastered text generation for both LinkedIn and X, culminating in a function to create structured X threads that break down complex topics. You learned how to use a detailed master prompt to orchestrate a sequence of connected text outputs.
Today, we pivot from purely textual platforms to the visual-first world of Instagram. While the principles of narrative sequencing remain, the format changes dramatically. Instead of a thread of text, we'll be planning a carousel of images. This lesson bridges our text generation skills with the visual generation we'll tackle next.
This lesson directly addresses the learning outcome: Design prompts to generate a narrative outline and per-slide content for an Instagram carousel from a trend analysis. We will break this into two parts:
- Defining a compelling narrative structure for the carousel.
- Designing a prompt that instructs an LLM to generate a structured content plan for each slide, ready for our automation pipeline.
The AIDA Framework: A Narrative Blueprint for Carousels
Just like a good X thread, an effective Instagram carousel tells a story. It can't just be a random collection of facts; it needs a narrative arc to pull the viewer from the first slide to the last. A classic marketing framework that is exceptionally well-suited for this is AIDA.
To get a firm grasp of this framework, please watch the following video from The Futur. It provides an excellent breakdown of how to structure content to maximize engagement.
Why Your Instagram Carousels Are Being Ignored— Use AIDA technique
This video, 'Why Your Instagram Carousels Are Being Ignored', explains the AIDA framework (Attention, Interest, Desire, Action) and how to apply it specifically to Instagram carousels.
Please watch from the beginning to 2:37 to understand the AIDA framework. Then, watch the segments on 'Attention' (2:37-4:03), 'Desire' and 'Action' (5:12-5:50), and the reasoning for using 8-10 slides (5:50-6:44).
As you saw, the AIDA framework gives us a powerful narrative structure:
- Attention (Slide 1): The hook. A provocative image, a bold statement, or an intriguing question. Its only job is to make someone stop scrolling and swipe.
- Interest & Desire (Slides 2-~8): The value. This is the core of your carousel. You build interest by educating the audience, sharing insights, or telling a story. You create desire by showing them how this information can transform their work or perspective.
- Action (Final Slide): The call to action (CTA). Tell the viewer exactly what to do next: leave a comment, save the post, or visit a link.
This structure should feel familiar; it's a more visual and paced version of the "Hook, Value, CTA" model we used for X threads.
To see how this strategic thinking translates directly into a prompt, let's review a short article that outlines best practices for prompting an LLM to create carousel content.
ChatGPT 5 Carousel Creation: Tips & Best Practices
The PostNitro article, 'ChatGPT 5 Carousel Creation: Tips & Best Practices', provides strategic advice on how to structure your prompts for generating carousel content.
Please read the sections 'The "Right Way": Strategic ChatGPT Prompting for Carousels' and 'Best Practices for High-Performing Carousels'. Pay close attention to the recommended structural format (hook, value, call-to-action) and the constraint of keeping slide text under 25-30 words.
The key insight here is that we can explicitly instruct the LLM to follow this narrative structure. For a quick, practical example, look at the "Instagram Carousel Script" prompt in this image.
From Narrative to Structured Data: The Engineering Approach
Asking an LLM for plain text that we have to manually copy-paste into a design tool is inefficient. For our automated system, we need a more robust approach. Given your background in system design, you'll appreciate the value of forcing the LLM to return a structured, machine-readable output.
Instead of asking for a block of text, we will design a prompt that instructs the LLM to generate a JSON array. Each object in the array will represent a slide, containing its content, type, and even suggestions for visuals.
This approach offers several advantages:
- Modularity: It separates content generation (today's lesson) from visual generation (future lessons).
- Reliability: Parsing JSON is far more reliable than parsing freeform text with regular expressions.
- Control: It gives us granular control over each element of the carousel.
The following tutorial, while focused on building an entire infographic deck generator, contains a brilliant section on this exact technique.
GLM Image Tutorial: Building an Infographic Deck Generator
The DataCamp tutorial 'GLM Image Tutorial: Building an Infographic Deck Generator' demonstrates a professional-grade pipeline for generating visual content. We'll focus on the step where it converts raw research into a structured JSON plan for the slides.
Please read Step 5: Phase 2 - Convert research into structured slide JSON. Analyze the system_prompt provided in the code block. Notice how it defines a strict JSON schema with different slide layouts ('title', 'stat', 'comparison', etc.) and enforces rules about content and structure. This is the blueprint for the robust prompting we want to achieve.
The power of the system_prompt in that tutorial is its specificity. It defines not just the what (a slide deck) but the precise how (a JSON array with a specific schema and content rules). This is the level of control we need for our automation agent.
Activity: Building the generateCarouselContentPlan Function
Let's apply these principles and build the core function for this lesson. We'll create a new file, src/generateCarouselContent.ts, and implement generateCarouselContentPlan. This function will take a trend analysis and produce a JSON object representing the content plan for an Instagram carousel.
The prompt will instruct the LLM to act as an expert social media strategist, applying the AIDA framework to generate a structured plan.
// src/generateCarouselContent.ts
import OpenAI from 'openai';
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
// We can reuse the TrendInsight type from previous lessons
interface TrendInsight {
narrative: string;
keywords: string[];
}
// Define the structure for a single slide's content plan
export interface CarouselSlide {
slide_number: number;
type: 'hook' | 'value' | 'cta';
headline: string; // The main text on the slide, max 25 words
notes?: string; // Optional speaker notes or extra context for the visual
visual_suggestion: string; // A text description of the visual for this slide
}
// Define the structure for the entire carousel plan
export interface CarouselPlan {
slides: CarouselSlide[];
}
/**
* Creates a prompt to generate a structured content plan for an Instagram carousel.
* @param insight - The trend data to base the carousel on.
* @returns A string containing the full prompt for the LLM.
*/
function getCarouselPlanPrompt(insight: TrendInsight): string {
const prompt = `
You are an expert social media strategist and content creator specializing in tech content for Instagram.
Your task is to create a content plan for a 7-slide Instagram carousel based on the provided trend analysis.
**CONTEXT (The Trend):**
"${insight.narrative}"
**FRAMEWORK (AIDA):**
- **Slide 1 (Attention/Hook):** A strong, scroll-stopping hook. Ask an intriguing question or state a bold fact.
- **Slides 2-6 (Interest/Value):** Break down the trend into digestible points. Each slide should build on the last and provide clear value.
- **Slide 7 (Action/CTA):** A clear call-to-action. Ask a question to encourage comments, or suggest saving the post.
**RULES:**
1. **JSON Output:** You MUST respond with ONLY a valid JSON object that adheres to the following structure: { slides: CarouselSlide[] }. Do not include any explanatory text or markdown formatting.
2. **Slide Interface:** Each slide object in the array must conform to this TypeScript interface:
\`\`\`typescript
interface CarouselSlide {
slide_number: number;
type: 'hook' | 'value' | 'cta';
headline: string; // The main text, MUST be under 25 words.
notes?: string; // Optional internal notes for context.
visual_suggestion: string; // A concise idea for the visual on this slide (e.g., "Minimalist icon of a neural network," "Chart showing user growth").
}
\`\`\`
3. **Concise Text:** The 'headline' for each slide must be extremely concise and impactful. Keep it under 25 words.
4. **Narrative Flow:** Ensure the slides tell a coherent story, flowing logically from the hook to the CTA.
Now, generate the JSON for the 7-slide carousel plan based on the trend context.
`;
return prompt;
}
/**
* Generates a structured content plan for an Instagram carousel from a trend insight.
* @param insight - An object containing the trend narrative and keywords.
* @returns A CarouselPlan object, or null on error.
*/
export async function generateCarouselContentPlan(
insight: TrendInsight
): Promise<CarouselPlan | null> {
const prompt = getCarouselPlanPrompt(insight);
try {
console.log(`Generating Instagram carousel content plan...`);
const response = await openai.chat.completions.create({
model: "gpt-4-turbo",
messages: [{ role: "user", content: prompt }],
response_format: { type: "json_object" }, // Enforce JSON output at the API level
temperature: 0.5,
max_tokens: 1500,
});
const rawContent = response.choices[0].message.content;
if (!rawContent) {
console.error("LLM returned empty content for the carousel plan.");
return null;
}
// Parse the JSON string into our CarouselPlan object
const plan = JSON.parse(rawContent) as CarouselPlan;
// Basic validation
if (!plan.slides || plan.slides.length === 0) {
console.error("Parsed plan is invalid or has no slides.");
return null;
}
console.log("Successfully generated carousel plan:", JSON.stringify(plan, null, 2));
return plan;
} catch (error) {
console.error("Error generating carousel plan:", error);
return null;
}
}
Deconstructing the Code
- TypeScript Interfaces (
CarouselSlide,CarouselPlan): We define the shape of our desired output directly in our code. This provides strong typing and serves as the "source of truth" for our prompt. getCarouselPlanPrompt: This function constructs a highly constrained prompt. It specifies the persona, the task, the AIDA framework, and most importantly, the exact JSON structure and TypeScript interface the output must conform to.response_format: { type: "json_object" }: This is a crucial parameter for the OpenAI API. It instructs the model to guarantee the output is a syntactically correct JSON object, which significantly increases the reliability of ourJSON.parse()call.generateCarouselContentPlan: This function orchestrates the API call and parses the response. Thanks to the structured prompt andjson_objectmode, the parsing is simple and robust. The output of this function is a cleanCarouselPlanobject, ready to be passed to the next stage of our pipeline: visual generation.
Conclusion
You have now designed a system to translate a raw trend analysis into a structured, narrative-driven content plan for an Instagram carousel. This is a critical step in automating content creation for visual platforms.
Key Takeaways:
- Effective carousels follow a narrative structure like AIDA (Attention, Interest, Desire, Action) to guide the viewer.
- For robust automation, it is best to prompt the LLM to return a structured format like JSON rather than plain text.
- A well-designed prompt for structured data generation defines the persona, task, framework, and the exact output schema (e.g., by providing a TypeScript interface).
- Separating content planning from visual generation creates a more modular, maintainable, and reliable automation pipeline.
Preview of the next lesson:
We now have a plan for what to say on each slide and a textual idea for the visuals. In the next lesson, we'll get more concrete about the visual aspect. We will learn to identify key data points from a trend analysis suitable for visual representation, figuring out how to turn statistics and timelines from our TrendInsight into compelling charts and diagrams for our carousel slides.