Gemini Blog Generation Skill
SkillCloud & infraConfigure or debug LLM blog post generation using Vercel AI SDK and Google Gemini. Use when updating blog generation prompts, fixing AI integration issues, modifying content generation logic, or working with structured output schemas.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Gemini Blog Generation Skill skill
What this skill tells your AI
The instructions your AI receives, as published by motormetrics/motormetrics in .agents/skills/gemini-blog/SKILL.md and read by ahel’s review.
Blog generation package: packages/ai/
Architecture
packages/ai/
├── src/
│ ├── generate-post.ts # 2-step generation (analysis → structured output)
│ ├── config.ts # System instructions
│ ├── schemas.ts # Zod schemas (postSchema, highlightSchema)
│ ├── tags.ts # Tag constants (CARS_TAGS, COE_TAGS)
│ ├── hero-images.ts # Hero image URLs
│ └── save-post.ts # Post persistence with idempotency
2-Step Flow
- Step 1 (Analysis):
generateText()+ Code Execution Tool + Extended Thinking → Accurate calculations - Step 2 (Generation):
generateObject()+ Zod schema → Type-safe structured output
Key Functions
// Generate and persist (returns saved-post metadata, not the raw Zod object)
import { generateBlogContent } from "@motormetrics/ai";
const post = await generateBlogContent({
data: tokenisedData, // Pipe-delimited data
month: "October 2024",
dataType: "cars", // "cars" or "coe"
});
// post.postId, post.title, post.slug, post.excerpt
Schemas
// postSchema
z.object({
title: z.string().max(100), // SEO title, max 60 chars preferred
excerpt: z.string().max(500), // Meta description, under 300 chars
content: z.string(), // Markdown (no H1)
tags: z.array(z.string()).min(1).max(10), // 3-5 tags, first is dataType
highlights: z.array(highlightSchema), // 3-6 key statistics
});
// highlightSchema
z.object({
value: z.string(), // "52.60%", "$125,000"
label: z.string(), // "Electric Vehicles Lead"
detail: z.string(), // "2,081 units registered"
});
Tag Constants
export const CARS_TAGS = ["Cars", "Registrations", "Fuel Types", "Market Trends", ...] as const;
export const COE_TAGS = ["COE", "Quota Premium", "1st Bidding Round", "PQP", ...] as const;
Updating Prompts
Edit packages/ai/src/config.ts:
ANALYSIS_INSTRUCTIONS: For calculation logicGENERATION_INSTRUCTIONS: For output format
Debugging
Low Quality Output: Check Step 1 analysis logs, verify Code Execution Tool runs Python
Schema Validation Errors: Check Zod constraints (max lengths, array bounds)
API Errors: Verify AI_GATEWAY_API_KEY, check Gateway quota/billing
Environment Variables
AI_GATEWAY_API_KEY=... # Required (Vercel AI Gateway)
DATABASE_URL=... # Required for generate-and-save (Neon/Postgres)
BLOB_READ_WRITE_TOKEN=... # Required for local hero-image upload
LANGFUSE_PUBLIC_KEY=pk-lf-... # Optional telemetry
LANGFUSE_SECRET_KEY=sk-lf-...
Best Practices
- Always use 2-step flow: Separate analysis from generation
- Never skip Code Execution: Required for accurate calculations
- Use tag constants: Maintain vocabulary consistency
- Enable telemetry: Track costs and quality
References
packages/ai/AGENTS.mdfor full package documentation- Vercel AI SDK: Use Context7 for latest docs
Signals
- GitHub stars
- 22
- Forks
- 2
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
gemini-blog- Source
- github.com/motormetrics/motormetrics