Hello! Welcome back.
In our last lesson, we built a generateLinkedInPost function, a specialized tool for creating short, punchy posts designed for engagement. We focused on crafting powerful hooks and using proven frameworks to structure content for that specific platform.
Now, we're going to level up. While short posts are excellent for capturing attention, long-form articles are where you establish deep authority and explore topics with the nuance they deserve. This brings a new set of challenges, primarily maintaining narrative coherence and brand voice over a much longer piece of text.
This lesson directly addresses the learning outcome: Generate a long-form LinkedIn article from a content outline, applying brand voice and narrative refinement.
We'll move beyond single-shot generation and design a more sophisticated, multi-step process. This approach will allow us to create comprehensive, well-structured articles that are consistently on-brand from the first paragraph to the last.
The Challenge of Long-Form Generation
Generating a 1,500-word article is fundamentally different from generating a 150-word post. A single, simple prompt is likely to result in:
- Instruction Drift: The model starts strong but gradually "forgets" the brand voice and structural rules, reverting to a generic, neutral tone.
- Lack of Narrative Cohesion: The article may feel like a collection of disconnected paragraphs rather than a single, flowing argument.
- Superficial Content: The model might not effectively weave in the specific data points, anecdotes, or contrarian angles that make for compelling thought leadership.
To overcome this, we need to think less like a person writing a prompt and more like an engineer designing a system. The solution lies in a structured, programmatic process.
A Conceptual Model for High-Quality Content
Before we write any code, let's look at a powerful conceptual workflow for generating high-quality, long-form content. The following video demonstrates how to create a custom "skill" in Claude, but the principles are universal and directly applicable to our TypeScript automation.
How I Built a Claude Skill That Writes Perfect SEO Content (Step-by-Step Tutorial)
The video 'How I Built a Claude Skill That Writes Perfect SEO Content' from Nico | AI Ranking provides an excellent mental model for the process we are about to build. Pay close attention to the components he prepares beforehand and the steps the AI follows.
As you watch, focus on these key ideas: Required Assets (00:58 - 04:31): Note the three types of documents he prepares: a tone of voice guide, a sitemap (which we can think of as a list of sources or internal topics), and an experience document (case studies, wins, personal insights). These are the raw materials for genuine thought leadership. Generation Workflow (06:56 - 10:59): Observe the multi-step interaction. The AI doesn't just write. It first asks clarifying questions, proposes an outline, plans how to integrate sources, and then generates the full text, weaving in personal experience. We will programmatically replicate this structured approach.
This workflow—combining brand rules, external knowledge, and personal experience in a structured, multi-step process—is exactly what we need to build to ensure our long-form articles are both high-quality and authentic.
Our Strategy: A Multi-Step Article Generator
Inspired by the video, we'll design a generateLinkedInArticle function that breaks the task into manageable steps. This approach directly combats instruction drift and allows for greater narrative control.
1. The Master Prompt: Defining the Rules of the Game
First, we need a comprehensive "master prompt" that consolidates all our requirements. This goes beyond the prompt we used for short posts. It needs to be extremely specific about structure, style, and vocabulary for long-form content.
The article below provides a brilliant framework for creating such a prompt.
Creating a Brand Voice Prompt for AI: Complete Template
The article 'Creating a Brand Voice Prompt for AI: Complete Template' from Atom Writer offers a detailed, actionable template for codifying your brand voice. We will use its principles to build our master prompt.
Please read the following sections: The Voice DNA Framework: Understand the 'Structural', 'Emotional', and 'Semantic' layers. This is how we move from vague adjectives to concrete, machine-readable rules. The Complete Brand Voice Prompt Template: Study the structure of the template. We will adapt this for our code. Content-Type Modifiers: Pay close attention to the 'Blog modifier'. This provides specific rules for long-form content, such as using subheadings (H2, H3) and ending with actionable takeaways. The Honest Limitation: This section explains why challenges like 'instruction drift' occur. Understanding the problem helps clarify why our multi-step solution is necessary.
2. Section-by-Section Generation to Combat Drift
As noted in the Atom Writer article, instruction drift is a major issue in long-form generation. The most effective way to solve this is to not generate the entire article at once.
Instead, our generateLinkedInArticle function will iterate through the sections defined in our content outline (which we created in Module 3). For each section, it will make a separate call to the LLM, asking it to write just that part. This approach re-establishes the context and instructions with each call, ensuring the brand voice remains strong from start to finish.
3. Iterative Refinement for a Polished Narrative
Simply generating text isn't enough. The learning outcome specifies "narrative refinement." This means actively shaping the story, integrating evidence, and ensuring the final piece is compelling.
How to Train AI to Match Your Brand Voice: A Guide to Personalized ...
The article 'How to Train AI to Match Your Brand Voice' provides further techniques for ensuring the output is authentic and refined.
Please focus on these two parts: Prompt Engineering Techniques That Actually Work: Review the concepts of Iterative Refinement and Role Play. This reinforces the idea that generation is a conversation, not a one-off command. Component 2: Custom Prompt Templates: Look at the 'Voice Audit' template. This introduces the idea of using the AI to check its own work, a powerful technique for refinement.
We can build this refinement into our process in two ways:
- In-flight Instructions: In each section-generation prompt, we'll explicitly direct the LLM to use specific data points or anecdotes from our outline.
- Post-Generation Polish: After assembling the sections, we can add a final step that asks the LLM to write a compelling introduction and conclusion for the now-complete article, ensuring a strong opening and a memorable finish.
Activity: Building the ArticleGenerator
Let's translate this strategy into code. We'll create a new file, src/generateLinkedInArticle.ts, and build our generator. This function will take the structured outline from Module 3 as its primary input.
// src/generateLinkedInArticle.ts
import OpenAI from 'openai';
import { systemRole, voiceRules, fewShotExamples } from './brandVoice'; // Reuse your brand voice assets
// Assume ContentOutline and Section are types you have defined
// import { ContentOutline, Section } from './createOutline';
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
/**
* Creates the master system prompt for generating a long-form article.
* This incorporates brand voice, structural rules, and content-type modifiers.
*/
function getArticleSystemPrompt(): string {
// Adapted from the Atom Writer 'Blog Modifier' and 'Voice DNA' concepts
const longFormRules = `
**Content Type: Long-Form LinkedIn Article**
* **Structure:** Use Markdown for formatting. The main title will be added later. Use H2 (##) for main section titles and H3 (###) for sub-section titles.
* **Paragraphs:** Keep paragraphs short, around 2-4 sentences maximum.
* **Sentence Length:** Average 12-18 words. Mix shorter, punchy sentences with slightly longer ones for rhythm.
* **Tone:** Maintain a balance between authoritative expertise and accessible, clear explanation. Your tone rating is: Funny: 2/5, Formal: 2/5, Respectful: 4/5, Enthusiastic: 3/5.
* **Vocabulary:** Do NOT use generic business jargon like 'leverage', 'synergy', 'streamline', 'robust', or 'delve'.
* **Engagement:** End each major section with a thought-provoking transition or a rhetorical question to keep the reader engaged.
`;
return `
${systemRole}
You are an expert thought-leadership writer, specializing in creating in-depth articles for a technical audience on LinkedIn. Your writing is clear, authoritative, and engaging.
**Core Brand Voice Rules:**
${voiceRules}
**Article-Specific Rules:**
${longFormRules}
**Writing Style Examples:**
${fewShotExamples}
`;
}
/**
* Generates a single section of the article.
*/
async function generateSectionContent(
systemPrompt: string,
section: any, // Use your Section type
articleTitle: string,
fullOutline: any // Use your ContentOutline type
): Promise<string> {
const sectionPrompt = `
You are writing a long-form article titled "${articleTitle}".
You have been tasked with writing the content for the following section: "## ${section.title}".
This section should cover these key points:
${section.key_points.map((p: string) => `- ${p}`).join('\n')}
To make this section compelling, you MUST weave in the following specific details, data, or anecdotes:
${section.supporting_details.map((d: string) => `- ${d}`).join('\n')}
The full outline of the article is provided for context, but you are ONLY to write the content for the "${section.title}" section. Do not write the title itself; just the body content.
Full Article Outline:
\`\`\`json
${JSON.stringify(fullOutline, null, 2)}
\`\`\`
Write the content for the "## ${section.title}" section now.
`;
const response = await openai.chat.completions.create({
model: "gpt-4-turbo",
messages: [
{ role: "system", content: systemPrompt },
{ role: "user", content: sectionPrompt },
],
temperature: 0.7,
});
return response.choices[0].message.content ?? '';
}
/**
* Generates a long-form LinkedIn article from a content outline.
* @param outline - The structured content outline for the article.
* @returns The full article as a Markdown string.
*/
export async function generateLinkedInArticle(
outline: any // Use your ContentOutline type
): Promise<string | null> {
try {
const systemPrompt = getArticleSystemPrompt();
let fullArticle = `# ${outline.title}\n\n`;
// Generate introduction
console.log("Generating introduction...");
const introSection = { title: "Introduction", key_points: outline.introduction_points, supporting_details: [] };
const introContent = await generateSectionContent(systemPrompt, introSection, outline.title, outline);
fullArticle += `${introContent}\n\n`;
// Generate each body section iteratively
for (const section of outline.sections) {
console.log(`Generating section: "${section.title}"...`);
const sectionContent = await generateSectionContent(systemPrompt, section, outline.title, outline);
fullArticle += `## ${section.title}\n\n${sectionContent}\n\n`;
}
// Generate conclusion
console.log("Generating conclusion...");
const conclusionSection = { title: "Conclusion", key_points: outline.conclusion_points, supporting_details: [] };
const conclusionContent = await generateSectionContent(systemPrompt, conclusionSection, outline.title, outline);
fullArticle += `## Conclusion\n\n${conclusionContent}\n\n`;
console.log("Article generation complete.");
return fullArticle;
} catch (error) {
console.error("Error during LinkedIn article generation:", error);
return null;
}
}
Deconstructing the Code
This implementation directly reflects our strategy:
getArticleSystemPrompt: This function creates our "master prompt." It combines your generalbrandVoicewith new, specific rules for long-form articles, such as using Markdown headers and adhering to stricter paragraph limits.generateSectionContent: This is the workhorse function. It receives instructions to write only one section, but it also gets the full outline for context. Crucially, the prompt explicitly commands the model to integrate thesupporting_detailsfor that section, achieving the "narrative refinement" we need.generateLinkedInArticle: This is the orchestrator. It initializes the article with a title, then loops through the introduction, body sections, and conclusion, callinggenerateSectionContentfor each. It assembles the results into a single, cohesive Markdown document. This iterative process is our solution to instruction drift.
This programmatic, multi-step approach gives you a reliable factory for producing high-quality, long-form articles that stay on-brand and are rich with detail.
Conclusion
In this lesson, we tackled the complex challenge of generating long-form content. We moved from a single-prompt approach to a sophisticated, multi-step generation process orchestrated in TypeScript. This method not only produces better, more coherent articles but also gives you far more control over the final narrative.
Key Takeaways:
- Long-form requires a process, not just a prompt. A multi-step strategy is essential for quality and consistency.
- Section-by-section generation is the key to defeating "instruction drift." It keeps the model focused and the brand voice strong throughout the article.
- A "master prompt" should be highly detailed, incorporating structural, stylistic, and vocabulary rules specific to the content format (e.g., a blog/article).
- True narrative refinement comes from explicitly directing the LLM to weave in specific data, anecdotes, and examples within each section.
Preview of the next lesson:
We've covered short posts and long-form articles for LinkedIn. Now, we'll shift our focus to a different platform with a completely different cadence: X (formerly Twitter). In the next lesson, "Design prompts for concise, engaging X posts derived from trend insights," you'll learn to distill complex ideas into the bite-sized, high-impact format that thrives on X.