Hello! Welcome back to our project on building an autonomous content creation system.
In our last lesson, we took a major step by teaching our system to think like a strategist. We moved beyond simple fact synthesis to generate unique, contrarian, and insightful angles on a given tech trend by simulating a debate between expert personas. You now have a factual TrendNarrative and a rich AnglesOutput containing diverse perspectives.
Today, we'll address the learning outcome: to produce structured content outlines from the trend analysis output. This is the crucial architectural step where we translate high-level analysis into a concrete blueprint for content. This blueprint will guide the final text and visual generation stages, ensuring the output is coherent, strategic, and tailored to the specific social media platform.
From Angles to Actionable Blueprints
An angle gives you a theme, but an outline gives you a plan. Without a structured outline, an LLM tasked with writing a post might wander off-topic or fail to structure its argument effectively. By creating a detailed, machine-readable outline first, we gain control over the narrative flow, ensuring the final content is logical, engaging, and achieves its strategic goal.
Different platforms require different narrative structures. A deep-dive LinkedIn article is structured very differently from a punchy X thread or a visual Instagram carousel. Our goal is to create a function that can generate the appropriate outline for a given platform.
Let's explore the anatomy of effective content on our target platforms.
Anatomy of a High-Performing X (Twitter) Thread
X threads excel at breaking down complex ideas into digestible, sequential chunks. They are built to create and sustain curiosity.
Twitter Thread Marketing: The Complete Guide to Creating Viral ...
The article 'Twitter Thread Marketing' provides an excellent breakdown of the structural components of a thread that consistently drives engagement. Understanding this anatomy is key to creating an effective outline.
Read the section titled 'Anatomy of a Viral Twitter Thread'. Focus on the six key components: The Hook Tweet, The Setup, The Value Delivery, The Social Proof Insert, The Summary/Recap, and The Call-to-Action. This structure will be the foundation for our X thread outline schema.
As you can see from the reading, a successful thread isn't just a series of random tweets. It's a carefully crafted narrative with a distinct beginning (Hook), middle (Value Delivery), and end (Summary + CTA).
Anatomy of an Engaging LinkedIn Carousel
LinkedIn carousels (often shared as PDF documents) are a powerful visual format for storytelling and education. They function like a mini-presentation.
The key takeaway from this resource is the slide-by-slide structure. An effective carousel outline won't just list points; it will map them to individual slides, considering both the text and the potential for visuals.
Engineering the Outline: Structured Output with Zod
To make our outlines programmatically useful, we must enforce a strict, predictable structure. As in our previous lessons, we'll use Zod to define schemas for our desired JSON output. This ensures the LLM's response is always in the format our downstream agents expect.
The concept of forcing an LLM to generate structured JSON is a powerful technique for building reliable AI systems.
Structured LLM Output with Pydantic and LangChain
This video, while using Python and Pydantic, perfectly illustrates the principle we'll use with TypeScript and Zod. It demonstrates how to combine a schema definition with a specific LLM call to get guaranteed JSON output.
Watch from 03:23 to 05:26. Pay attention to how a class is defined to specify the desired JSON structure and how the LLM is invoked with a special method (with_structured_output) to enforce that structure. The logic is identical to what we'll implement.
Now, let's define the Zod schemas for a LinkedIn article outline and an X thread outline.
import { z } from 'zod';
// Schema for a long-form LinkedIn Article Outline
export const LinkedInArticleOutlineSchema = z.object({
platform: z.literal("LinkedIn"),
title: z.string().describe("A compelling, SEO-friendly title for the article."),
hook: z.string().describe("The opening sentence or question designed to grab the reader's attention."),
introduction: z.string().describe("A short paragraph (2-3 sentences) that sets the context and states the article's main thesis, based on a chosen angle."),
sections: z.array(z.object({
title: z.string().describe("A clear and descriptive heading for a major section of the article."),
points: z.array(z.string()).describe("A list of key ideas, arguments, or data points to be discussed in this section.")
})).describe("The main body of the article, broken into logical sections."),
conclusion: z.string().describe("A summary of the key takeaways for the reader."),
cta: z.string().describe("A clear call-to-action, e.g., 'Follow me for more insights' or 'What are your thoughts on this trend?'")
});
// Schema for an X Thread Outline
export const XThreadOutlineSchema = z.object({
platform: z.literal("X"),
hookTweet: z.string().describe("Tweet 1: A powerful hook to stop the scroll and create an information gap."),
setupTweets: z.array(z.string()).min(1).max(2).describe("Tweets 2-3: Provide context, establish credibility, and deepen the hook's promise."),
valueTweets: z.array(z.object({
point: z.string().describe("The core message or step for this tweet."),
supportingDetail: z.string().optional().describe("An optional example, data point, or brief explanation to support the point.")
})).describe("The main body of the thread, delivering value in sequence."),
summaryTweet: z.string().describe("The penultimate tweet that recaps the main lessons or takeaways."),
ctaTweet: z.string().describe("The final tweet with a clear call-to-action.")
});
// A union type for any possible content outline
export const ContentOutlineSchema = z.union([LinkedInArticleOutlineSchema, XThreadOutlineSchema]);
export type ContentOutline = z.infer<typeof ContentOutlineSchema>;
These schemas are our "contracts" with the LLM. They transform a fuzzy creative task into a deterministic engineering problem.
Activity: Implementing the Outline Generation Service
It's time to build. We'll create a new function, createContentOutline, that takes the TrendNarrative and AnglesOutput from our previous steps and generates a structured outline.
The prompt is where we combine our context, goals, and structural requirements. A good prompt for this task has several key parts:
- Role: Define the LLM as an expert (e.g., "You are a master content strategist...").
- Context: Provide the raw materials—the trend narrative and the analytical angles.
- Task: Clearly state the goal—to create an outline for a specific platform.
- Instructions: Guide the LLM on how to use the context, such as selecting the most compelling angle.
- Format: Explicitly demand a JSON output that adheres to our Zod schema.
Here is the implementation. You can create a new file, createOutline.ts, in your project.
import { z } from 'zod';
import OpenAI from 'openai';
import { zodToJsonSchema } from 'zod-to-json-schema';
// Assume these types are imported from your other files
// import { TrendNarrative } from './synthesizeTrend';
// import { AnglesOutput } from './generateAngles';
// Paste the Zod schemas from above here
// export const LinkedInArticleOutlineSchema = z.object({...});
// export const XThreadOutlineSchema = z.object({...});
// ...
// Helper to convert Zod schema to JSON schema for the prompt
const linkedinJsonSchema = zodToJsonSchema(LinkedInArticleOutlineSchema, "LinkedInArticleOutlineSchema");
const xThreadJsonSchema = zodToJsonSchema(XThreadOutlineSchema, "XThreadOutlineSchema");
// Initialize your LLM client
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
// The main outline generation function
export async function createContentOutline(
trendNarrative: TrendNarrative,
anglesOutput: AnglesOutput,
platform: "LinkedIn" | "X"
): Promise<ContentOutline | null> {
const narrativeString = `Headline: ${trendNarrative.headline}\nNarrative: ${trendNarrative.narrative}`;
const anglesString = anglesOutput.perspectives.map(p =>
`- Persona: ${p.persona}\n Angle: ${p.angle}\n Key Questions: ${p.keyQuestions.join(', ')}`
).join('\n');
const targetSchema = platform === 'LinkedIn' ? linkedinJsonSchema : xThreadJsonSchema;
const systemPrompt = `
You are an expert content strategist and viral copywriter for the tech industry. Your task is to create a structured content outline for a given social media platform based on a trend analysis.
**Instructions:**
1. Review the provided Trend Narrative and the diverse Analytical Angles.
2. Select the single most compelling or contrarian angle to serve as the central thesis for the content piece.
3. Use the selected angle to create a detailed outline for the specified platform: ${platform}.
4. The outline must be engaging, logical, and provide clear value to a technical audience (developers, engineers, tech leads).
5. Your output MUST be a single JSON object that strictly adheres to the following JSON Schema. Do not include any other text or explanations outside of the JSON object.
**JSON Schema:**
\`\`\`json
${JSON.stringify(targetSchema, null, 2)}
\`\`\`
`;
try {
const response = await openai.chat.completions.create({
model: "gpt-4-turbo",
messages: [
{ role: "system", content: systemPrompt },
{
role: "user",
content: `
Here is the trend analysis:
**Trend Narrative:**
${narrativeString}
**Analytical Angles:**
${anglesString}
Please generate the content outline for the ${platform} platform.
`
}
],
response_format: { type: "json_object" },
});
const content = response.choices[0].message.content;
if (!content) {
throw new Error("Empty response from LLM.");
}
// Parse and validate the response against our Zod schema
const outline = (platform === 'LinkedIn' ? LinkedInArticleOutlineSchema : XThreadOutlineSchema).parse(JSON.parse(content));
console.log(`Successfully generated outline for ${platform}:`, outline);
return outline as ContentOutline;
} catch (error) {
console.error(`Error during outline generation for ${platform}:`, error);
return null;
}
}
This function is a reusable component in our content pipeline. By simply changing the platform parameter, we can generate a perfectly structured blueprint for different types of content, all derived from the same core analysis. This is the power of a modular, agentic architecture.
Conclusion
You have now created the essential bridge between strategic analysis and content creation. The structured outline is a powerful tool that ensures your automated system produces content that is not only well-written but also purposeful, coherent, and platform-aware.
Key Takeaways:
- A structured outline translates high-level angles into a concrete, machine-readable plan for content generation.
- Effective outlines are platform-specific, reflecting the unique narrative conventions of X, LinkedIn, and other channels.
- Using Zod to define output schemas and instructing the LLM to generate structured JSON is a robust technique for building reliable and predictable AI workflows.
- A well-designed prompt for outlining should provide the LLM with a clear role, the necessary context (narrative and angles), a specific task, and strict formatting requirements.
Preview of the next lesson:
With our structured outlines in hand, we are ready to generate the final text. The next module, "LLM-Powered Text Generation," begins with the lesson, "Apply brand voice constraints and few-shot examples to control LLM-generated content style." We will take the outlines you've just created and feed them to a new "Writer Agent," focusing on techniques to ensure the generated prose matches your unique brand voice and style.