К основному содержанию
скилл CX Codex GP ChatGPT официальный · OpenAI

ai-generation-persistence — скилл для Codex: сохранение генераций

Помогает сохранять результаты запросов к LLM, присваивать им ID и открывать по адресу. Подойдёт для проектов с историей чатов или генераций.

Установить в Codex · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add openai/plugins --skill ai-generation-persistence -a codex
Открыть на GitHub

Что делает ai-generation-persistence

Скилл предлагает создавать запись с ID до вызова модели, затем сохранять результат и метаданные: модель, расход токенов, оценочную стоимость, время и ID пользователя. Для изображений и файлов он описывает сохранение в Vercel Blob с записью постоянных URL в базу. Стриминг тоже должен завершаться сохранением результата.

В примерах используются nanoid, Drizzle и Postgres для записей, @vercel/blob для файлов, а Upstash Redis — для кэширования одинаковых запросов по хешу. Стандартный поток создаёт ресурс и перенаправляет пользователя на страницу с его ID. Конкретные сервисы хранения из примеров понадобятся, если вы будете повторять именно эту схему.

Ставьте скилл, если генерации должны переживать обновление страницы и открываться по ссылке; для приложения, которому не нужна история результатов, эти правила избыточны.

Какие задачи решает

  • сохранять результат генерации до завершения стриминга
  • открывать чат или генерацию по ID в URL
  • записывать расход токенов и оценочную стоимость
  • сохранять сгенерированные изображения по постоянным URL
  • кэшировать повторные запросы по модели и промпту

Примеры запросов агенту

  • Добавь сохранение истории чатов с отдельным URL для каждого чата.
  • Сохраняй результат и расход токенов после каждой генерации.
  • Сделай кэш одинаковых запросов по модели и промпту.

Как установить ai-generation-persistence

1Через Skills CLI (Vercel)

npx skills add openai/plugins --skill ai-generation-persistence -a codex

2Вручную: положить файлы

.agents/skills/ai-generation-persistence/SKILL.md

Для всех проектов — ~/.agents/skills/

Из того же набора201

Весь набор →
supabase официальный supabase Скилл помогает настраивать базу данных, аутентификацию и RLS в Supabase без скрытых дыр в безопасности. CX Codex GP ChatGPT 8установок remotion-render официальный Remotion Экспортирует видео и отдельные кадры из проектов Remotion через консольные команды. CX Codex GP ChatGPT 3установок figma-create-new-file официальный Figma Создаёт пустые файлы Figma, FigJam или Slides в черновиках нужной команды. Скилл готовит параметры и planKey перед запуском MCP-инструментов. CX Codex GP ChatGPT 6установок swiftui-performance-audit официальный OpenAI Находит причины просадок кадров, долгого рендеринга и утечек памяти в SwiftUI. Помогает разобрать код вьюшек или подготовить замеры для профилирования. CX Codex GP ChatGPT 109установок swiftui-liquid-glass официальный OpenAI Скилл помогает создавать и проверять интерфейсы SwiftUI с Liquid Glass для iOS 26+. Он нужен при внедрении эффекта, ревью и проверке fallback-сценариев. CX Codex GP ChatGPT 121установок swiftui-ui-patterns официальный OpenAI Скилл помогает собирать и рефакторить SwiftUI-интерфейсы: навигацию, состояние, компоновку и контролы. Подойдёт для новых экранов и правок существующего проекта. CX Codex GP ChatGPT 114установок swiftui-view-refactor официальный OpenAI Скилл наводит порядок в коде SwiftUI: делит разросшиеся экраны на отдельные структуры View и выносит побочные эффекты из body. CX Codex GP ChatGPT 113установок ios-memgraph-leaks официальный OpenAI Скилл захватывает и разбирает утечки памяти iOS из симулятора или .memgraph. Нужен для поиска удерживающих связей и проверки исправлений. CX Codex GP ChatGPT 1 054установок

Похожие

podcast-generation microsoft Генерирует озвучку текстов в формате подкаста через модель Azure OpenAI GPT Realtime Mini по WebSocket. Помогает настроить стриминг аудио от FastAPI до React. Claude Code GitHub Copilot 29установок skill-creator официальный anthropics Помогает создать новый скилл, доработать существующий и проверить результат через тестовые промпты и оценки. Claude Code Claude.ai 414 180установок writing-for-agents Matt Pocock Помогает писать скиллы и документы с инструкциями для агентов. Пригодится при правках AGENTS.md, CLAUDE.md и связанных справочных файлов. Claude Code 466 719установок media-use heygen-com Находит и генерирует ассеты для видео в HyperFrames — музыку, дикторский голос, аватары и эффекты. Сохраняет всё локально в assets. Claude Code CX Codex Cursor +1 1 100 000установок mcp-builder официальный anthropics Скилл проводит через создание MCP-сервера на TypeScript или Python: от изучения протокола до тестов и оценки качества. Claude Code Claude.ai 130 949установок subagent-driven-development Jesse Vincent Скилл выполняет план через отдельных субагентов для каждой задачи и проверяет результат после каждого шага. Подходит для независимых задач в одной сессии. Claude Code CX Codex 237 746установок orchestration stablyai Координирует воркеров Orca через DAG задач, циклы супервизора и цепочки сообщений. Пригодится для распределения сложной работы между агентами. Claude Code CX Codex Cursor +1 349 200установок

Вопросы о ai-generation-persistence

Как установить ai-generation-persistence в Codex?

Выполните npx skills add openai/plugins --skill ai-generation-persistence. Для установки с указанием агента используйте npx skills add openai/plugins --skill ai-generation-persistence -a codex.

Что делает ai-generation-persistence?

Подсказывает, как сохранять генерации с ID, результатами и метаданными, а затем открывать их по URL. Также описывает хранение изображений и кэширование повторных запросов.

Какие хранилища используются в примерах скилла?

Для текстовых данных и истории приведён Neon Postgres через Drizzle, для изображений и файлов — Vercel Blob, для кэша — Upstash Redis.

Исходный текст

SKILL.md · Apache-2.0
---
name: ai-generation-persistence
description: "AI generation persistence patterns — unique IDs, addressable URLs, database storage, and cost tracking for every LLM generation"
metadata:
  priority: 6
  docs:
    - "https://sdk.vercel.ai/docs/ai-sdk-ui/storing-messages"
  sitemap: "https://sdk.vercel.ai/sitemap.xml"
  pathPatterns:
    - "app/api/generate/**"
    - "app/api/generations/**"
    - "src/app/api/generate/**"
    - "src/app/api/generations/**"
    - "app/chat/[id]/**"
    - "app/generate/[id]/**"
    - "src/app/chat/[id]/**"
    - "src/app/generate/[id]/**"
    - "lib/generations/**"
    - "src/lib/generations/**"
  bashPatterns: []
  importPatterns:
    - "ai"
    - "@ai-sdk/*"
    - "@vercel/blob"
    - "nanoid"
    - "@paralleldrive/cuid2"
  promptSignals:
    phrases:
      - "save generations"
      - "persist generations"
      - "generation history"
      - "chat history"
      - "save chat"
      - "generation id"
      - "ai chat"
      - "chat app"
      - "chatbot"
      - "image generation"
      - "text generation"
      - "ai app"
    allOf:
      - [generate, save]
      - [generate, persist]
      - [generate, store]
      - [ai, persist]
      - [ai, history]
      - [ai, database]
      - [chat, persist]
      - [chat, database]
      - [chat, url]
      - [generation, url]
      - [generation, id]
      - [image, generate]
      - [stream, save]
      - [stream, persist]
    anyOf:
      - "shareable"
      - "retrievable"
      - "permalink"
      - "cost tracking"
      - "token usage"
      - "nanoid"
      - "cuid"
      - "openai"
      - "anthropic"
      - "llm"
      - "gpt"
      - "claude"
    noneOf:
      - "github actions"
      - "ci workflow"
    minScore: 6
---

# AI Generation Persistence

**AI generations are expensive, non-reproducible assets. Never discard them.**

Every call to an LLM costs real money and produces unique output that cannot be exactly reproduced. Treat generations like database records — assign an ID, persist immediately, and make them retrievable.

## Core Rules

1. **Generate an ID before the LLM call** — use `nanoid()` or `createId()` from `@paralleldrive/cuid2`
2. **Persist every generation** — text and metadata to database, images and files to Vercel Blob
3. **Make every generation addressable** — URL pattern: `/chat/[id]`, `/generate/[id]`, `/image/[id]`
4. **Track metadata** — model name, token usage, estimated cost, timestamp, user ID
5. **Never stream without saving** — if the user refreshes, the generation must survive

## Generate-Then-Redirect Pattern

The standard UX flow for AI features: create the resource first, then redirect to its page.

```ts
// app/api/chat/route.ts
import { nanoid } from "nanoid";
import { db } from "@/lib/db";
import { redirect } from "next/navigation";

export async function POST(req: Request) {
  const { prompt, model } = await req.json();
  const id = nanoid();

  // Create the record BEFORE generation starts
  await db.insert(generations).values({
    id,
    prompt,
    model,
    status: "pending",
    createdAt: new Date(),
  });

  // Redirect to the generation page — it handles streaming
  redirect(`/chat/${id}`);
}
```

```tsx
// app/chat/[id]/page.tsx
import { db } from "@/lib/db";
import { notFound } from "next/navigation";

export default async function ChatPage({ params }: { params: Promise<{ id: string }> }) {
  const { id } = await params;
  const generation = await db.query.generations.findFirst({
    where: eq(generations.id, id),
  });
  if (!generation) notFound();

  // Render with streaming if still pending, or show saved result
  return <ChatView generation={generation} />;
}
```

This gives you: shareable URLs, back-button support, multi-tab sessions, and generation history for free.

## Persistence Schema

```ts
// lib/db/schema.ts
import { pgTable, text, integer, timestamp, jsonb } from "drizzle-orm/pg-core";

export const generations = pgTable("generations", {
  id: text("id").primaryKey(),            // nanoid
  userId: text("user_id"),                // auth user
  model: text("model").notNull(),         // "openai/gpt-5.4"
  prompt: text("prompt"),                 // input text
  result: text("result"),                 // generated output
  imageUrls: jsonb("image_urls"),         // Blob URLs for generated images
  tokenUsage: jsonb("token_usage"),       // { promptTokens, completionTokens }
  estimatedCostCents: integer("estimated_cost_cents"),
  status: text("status").default("pending"), // pending | streaming | complete | error
  createdAt: timestamp("created_at").defaultNow(),
});
```

## Storage Strategy

| Data Type | Storage | Why |
|-----------|---------|-----|
| Text, metadata, history | Neon Postgres via Drizzle | Queryable, relational, supports search |
| Generated images & files | Vercel Blob (`@vercel/blob`) | Permanent URLs, CDN-backed, no expiry |
| Prompt dedup cache | Upstash Redis | Fast lookup, TTL-based expiry |

## Image Persistence

Never serve generated images as ephemeral base64 or temporary URLs. Save to Blob immediately:

```ts
import { put } from "@vercel/blob";
import { generateText } from "ai";

const result = await generateText({ model, prompt });

// Save every generated image to permanent storage
const imageUrls: string[] = [];
for (const file of result.files ?? []) {
  if (file.mediaType?.startsWith("image/")) {
    const ext = file.mediaType.split("/")[1] || "png";
    const blob = await put(`generations/${generationId}.${ext}`, file.uint8Array, {
      access: "public",
      contentType: file.mediaType,
    });
    imageUrls.push(blob.url);
  }
}

// Update the generation record with permanent URLs
await db.update(generations)
  .set({ imageUrls, status: "complete" })
  .where(eq(generations.id, generationId));
```

## Cost Tracking

Extract usage from every generation and store it. This enables billing, budgeting, and abuse detection:

```ts
const result = await generateText({ model, prompt });

const usage = result.usage; // { promptTokens, completionTokens, totalTokens }
const estimatedCostCents = estimateCost(model, usage);

await db.update(generations).set({
  result: result.text,
  tokenUsage: usage,
  estimatedCostCents,
  status: "complete",
}).where(eq(generations.id, generationId));
```

## Prompt Dedup / Caching

Avoid paying for identical generations. Cache by content hash:

```ts
import { Redis } from "@upstash/redis";
import { createHash } from "crypto";

const redis = Redis.fromEnv();

function hashPrompt(model: string, prompt: string): string {
  return createHash("sha256").update(`${model}:${prompt}`).digest("hex");
}

// Check cache before generating
const cacheKey = `gen:${hashPrompt(model, prompt)}`;
const cached = await redis.get<string>(cacheKey);
if (cached) return cached; // Return cached generation ID

// After generation, cache the result
await redis.set(cacheKey, generationId, { ex: 3600 }); // 1hr TTL
```

## Anti-Patterns

- **Streaming to client without saving** — generation lost on page refresh. Always write to DB as tokens arrive or on completion.
- **Routes without `[id]` segments** — `/api/chat` with no ID means generations aren't addressable. Use `/chat/[id]`.
- **Re-generating identical prompts** — check cache first. Same prompt + same model = same cost for no new value.
- **Ephemeral base64 images** — generated images served inline are lost when the component unmounts. Save to Vercel Blob.
- **Missing metadata** — always store model name, token counts, and timestamp. You need this for cost tracking and debugging.
- **Client-only state** — storing generations only in React state or localStorage. Use a database — generations must survive across devices and sessions.

© Vercel Labs · Apache-2.0 · openai/plugins

Смотрите также

Спонсоры проекта

Компании, которые помогают держать аналитику открытой