AI Engineering Primer | From Basics to Advanced | 2026
Building Agentic Workflow for Personalized LinkedIn Posts via Few-Shot Prompting
This chapter explores how to construct an agentic workflow using LangChain and LangGraph that automatically summarizes technical articles, research papers, and newsletter posts into personalized LinkedIn content. By utilizing dynamic few-shot prompting, the agent learns to mirror an author's unique voice, formatting preferences, and thematic focus without needing expensive fine-tuning pipelines.
1. Context & Problem Statement: The Personalization Gap
Generative AI models excel at summarization out of the box. However, standard zero-shot summarization outputs suffer from a generic, robotic tone that fails to reflect individual authorship.
When domain experts, software engineers, or technical writers share insights on social platforms (such as LinkedIn or Twitter/X), their writing relies on specific stylistic nuances:
- Tone and Formality: Balanced technical depth without feeling overly formal or salesy.
- Visual Structure: Bullet points, concise hooks, and selective emoji placement.
- Domain Focus: Tailored hashtags (
#GenerativeAI,#LangChain,#SoftwareEngineering) and targeted calls to action.
Writing personalized social media posts for every published newsletter or research paper creates a repetitive workflow bottleneck. An agentic pipeline addresses this by fetching content directly from an article link and applying historical writing patterns to generate ready-to-post summaries.
2. Core Mental Model: Few-Shot Prompting vs. Fine-Tuning
To capture stylistic preferences, engineers typically choose between two paradigms: Fine-Tuning and In-Context Few-Shot Prompting.
Few-shot prompting conditions a Large Language Model (LLM) by providing a small set of input-output examples directly inside the prompt context before sending the actual query.
Real-Life Analogy
Imagine hiring a freelance copywriter to write posts in your style. Instead of sending them to a multi-week training course (Fine-Tuning), you hand them a reference card with three past articles alongside the exact social media posts you wrote for them (Few-Shot Examples). By analyzing those reference pairs, the copywriter immediately captures your tone, emoji usage, and layout rules.
Why Few-Shot Prompting Fits Social Media Generation
- Data Availability: Individual creators rarely possess the thousands of historical post-article pairs needed for effective fine-tuning. A collection of 10 to 20 past posts is typically all that exists.
- Contextual In-Memory Learning: Modern LLMs possess strong pre-trained capabilities; they only need brief context to align their output voice.
- Dynamic Adaptability: Modifying the target voice simply requires updating a JSON example file rather than re-training model weights.
3. High-Level Architecture & Workflow Design
The agentic pipeline is built as a stateful directed execution graph using LangGraph. The workflow accepts a target article URL, extracts its raw text, pairs it with structured historical examples, and routes the context to an LLM to generate the final post.
4. Context Window Constraints & Practical Edge Cases
While passing numerous examples improves stylistic alignment, it introduces a key constraint: LLM Context Window Limits.
During development, providing too many full-text article examples can quickly exhaust the model's token context limit.
Total Token Footprint = (Article Context Length × Example Count) + Target Article Length + System Prompt
Context Budgeting Strategy
If an example dataset contains 7 complete article-to-post pairs, feeding all 7 examples alongside a long target article can exceed limits like GPT-3.5 Turbo's token window, triggering API errors.
Strategic Recommendations:
- Cap Maximum Examples: Limit context examples to a strict threshold (e.g.,
MAX_FEW_SHOT_EXAMPLES = 3). - Diversify Example Themes: Ensure the selected 3-4 examples cover distinct content types (e.g., technical deep-dives, architectural overviews, framework releases) to maximize stylistic coverage across subjects.
5. Few-Shot Dataset Schema & Structural Anatomy
The few-shot dataset is stored as a structured JSON file (dataset.json). Each example entry maps a source article URL to the author's manually crafted LinkedIn post.
Dataset Schema (dataset.json)
{
"dataset_name": "training_dataset_langpost",
"examples": [
{
"url": "https://newsletter.example.com/posts/tool-calling-langchain",
"post_content": "Excited to share insights on tool calling with LangChain! 🛠️\n\nLearn how LLMs can leverage external APIs and functions to expand their capabilities. Let's dive into integrating tools into workflows for efficient AI agents.\n\n#AI #LangChain #ToolCalling"
},
{
"url": "https://newsletter.example.com/posts/parallel-execution-langgraph",
"post_content": "Speed up your graph workflows using parallel execution in LangGraph! ⚡\n\nBy leveraging fan-out and fan-in mechanisms, you can significantly lower response latencies in multi-agent workflows.\n\n#LangGraph #AIEngineering #Performance"
}
]
}
6. LangGraph State Management & Shared State Schema
LangGraph relies on a centralized State dictionary or TypedDict that flows sequentially through every graph node. Nodes receive the current state, perform operations, and return updated state attributes.
from typing import List, Dict, Any, TypedDict
class AgentState(TypedDict):
"""
Centralized state container shared across all workflow nodes in LangGraph.
"""
post_url: str # Target article URL passed by user
post_content: str # Scraped full-text content of target URL
few_shot_examples: List[Dict[str, str]] # Formatted historical pairs (article + post)
linkedin_post_content: str # Final LLM-generated social media output
7. Node Implementations: Web Content Ingestion & Data Preparation
The graph consists of three discrete nodes responsible for text extraction, context loading, and LLM inference.
Auxiliary Ingestion Helper
Uses LangChain's WebBaseLoader to parse HTML content from arbitrary web pages.
from langchain_community.document_loaders import WebBaseLoader
def get_content_from_url(url: str) -> str:
"""
Fetches and concatenates page content from a given web URL.
"""
try:
loader = WebBaseLoader(url)
docs = loader.load()
full_text = " ".join([doc.page_content for doc in docs])
return full_text
except Exception as e:
print(f"Error fetching URL {url}: {e}")
return ""
Node 1: Fetch Target Article Content
Parses the target input URL stored in post_url and populates post_content.
def get_article_content_for_post(state: AgentState) -> AgentState:
"""
Node 1: Extract article text for the target post URL.
"""
print("--- [NODE 1] FETCHING TARGET ARTICLE CONTENT ---")
target_url = state["post_url"]
extracted_text = get_content_from_url(target_url)
state["post_content"] = extracted_text
return state
Node 2: Load & Structure Few-Shot Context
Reads the JSON dataset, caps entries to MAX_FEW_SHOT_EXAMPLES, extracts historical article text for each example link, and formats them into contextual reference pairs.
import json
MAX_FEW_SHOT_EXAMPLES = 3
def prepare_few_shot_data(state: AgentState) -> AgentState:
"""
Node 2: Load historical JSON dataset and construct dynamic few-shot context pairs.
"""
print("--- [NODE 2] PREPARING FEW-SHOT DATASETS ---")
with open("dataset.json", "r") as f:
raw_data = json.load(f)
all_examples = raw_data.get("examples", [])
selected_examples = all_examples[:MAX_FEW_SHOT_EXAMPLES]
formatted_few_shots = []
for item in selected_examples:
example_url = item["url"]
example_post = item["post_content"]
# Scrape source content for the historical post
example_article_text = get_content_from_url(example_url)
formatted_few_shots.append({
"article_content": example_article_text,
"post_content": example_post
})
state["few_shot_examples"] = formatted_few_shots
return state
8. Prompt Construction & Interleaved Conversation Engineering
Rather than dumping example text into a single system message block, the workflow uses an Interleaved Chat Message Structure.
By alternating between HumanMessage (source article text) and AIMessage (author's matching post), the model learns through conversation history formatting.
System Base Prompt Definition
BASE_PROMPT = """
You are writing as a technical domain expert in Generative AI and Software Engineering.
Your goal is to write a concise, compelling LinkedIn post summarizing a provided article.
Guidelines:
- Match the precise writing style, formatting, and tone demonstrated in the examples below.
- Use exclamation points and technical emojis (e.g., 🛠️, ⚡, 🚀) appropriately without being overly enthusiastic.
- Avoid sounding overly formal, generic, or salesy.
- Keep content relevant, technical, and crisp.
- Include 2-4 relevant topic hashtags at the end of the post.
Pay close attention to the human/AI message context pairs below. Generate future posts matching this exact style.
"""
Node 3: LLM Invocations & Prompt Assembly
from langchain_core.messages import SystemMessage, HumanMessage, AIMessage
from langchain_openai import ChatOpenAI
def summarize_linkedin_post(state: AgentState) -> AgentState:
"""
Node 3: Assemble interleaved system/few-shot prompt and generate the LinkedIn post.
"""
print("--- [NODE 3] GENERATING PERSONALIZED POST VIA LLM ---")
# 1. Initialize system instruction
messages = [SystemMessage(content=BASE_PROMPT)]
# 2. Interleave historical context examples
for example in state["few_shot_examples"]:
messages.append(HumanMessage(content=f"Article Content:\n{example['article_content']}"))
messages.append(AIMessage(content=example["post_content"]))
# 3. Append actual target query
target_content = state["post_content"]
messages.append(HumanMessage(content=f"Summarize the following article into a LinkedIn post:\n{target_content}"))
# 4. Invoke LLM
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.0)
response = llm.invoke(messages)
# 5. Extract output and persist to state
state["linkedin_post_content"] = response.content.strip()
return state
9. State Graph Compilation & Execution Workflow
With all three nodes defined, we connect them into a LangGraph graph using explicit directed edges.
from langgraph.graph import StateGraph, START, END
def build_graph():
"""
Constructs, links, and compiles the agentic workflow state graph.
"""
workflow = StateGraph(AgentState)
# Register Nodes
workflow.add_node("get_article_content", get_article_content_for_post)
workflow.add_node("prepare_few_shot", prepare_few_shot_data)
workflow.add_node("summarize_post", summarize_linkedin_post)
# Define Directed Edges
workflow.add_edge(START, "get_article_content")
workflow.add_edge("get_article_content", "prepare_few_shot")
workflow.add_edge("prepare_few_shot", "summarize_post")
workflow.add_edge("summarize_post", END)
# Compile Graph
app = workflow.compile()
return app
# Main Execution Routine
if __name__ == "__main__":
app = build_graph()
initial_input = {
"post_url": "https://newsletter.example.com/posts/parallel-execution-langgraph"
}
final_state = app.invoke(initial_input)
print("\n================ GENERATED LINKEDIN POST ================\n")
print(final_state["linkedin_post_content"])
10. Real-World Execution Walkthrough & Results Analysis
When executing this pipeline on technical newsletter entries, the few-shot prompting setup successfully translates detailed technical prose into dynamic social media content.
Comparative Execution Matrix
Sample Agent Output
Learn how to enhance the performance of your graph workflows with parallel execution of nodes in LangGraph! ⚡
By utilizing fan-out and fan-in mechanisms, you can significantly speed up your graph operations and cut execution latencies.
Check out the performance comparison between serial and parallel execution in this insightful article!
#AI #LangGraph #PerformanceEnhancement #SoftwareEngineering
Summary and Key Takeaways
- Solves Voice Neutrality: Zero-shot LLM summaries produce generic outputs. Dynamic few-shot prompting preserves an individual author's unique writing voice, structural style, and emoji preferences.
- In-Context Learning Over Fine-Tuning: Fine-tuning requires large datasets and expensive retraining loops. Few-shot prompting works effectively with just 3 to 4 historical examples.
- Context Budget Awareness: Sending large datasets can exceed LLM context windows. Setting a strict threshold (e.g.,
MAX_FEW_SHOT_EXAMPLES = 3) prevents context overflow errors while preserving quality. - Modular LangGraph Architecture: Separating the pipeline into modular state nodes (
get_article_contentprepare_few_shotsummarize_post) makes the agent easier to extend and maintain. - Interleaved Message Formatting: Structuring few-shot context as alternating
HumanMessageandAIMessagehistory pairs guides the model's chat completions more effectively than dense system prompts. - Production Ingestion Capabilities: Combining web scrapers (such as
WebBaseLoader) with LangGraph state nodes allows users to generate customized social media summaries directly from source URLs.