Remotion LabRemotion Lab
AI使用 LLM 生成 Remotion 程式碼

使用 LLM 生成 Remotion 程式碼

本指南示範如何使用 Vercel AI SDK,從自然語言提示生成 Remotion 元件程式碼。

使用 LLM 生成 Remotion 程式碼

本指南示範如何使用 Vercel AI SDK 從自然語言提示生成 Remotion 元件程式碼的範例。

安裝

npm i --save-exact ai @ai-sdk/openai zod
pnpm i ai @ai-sdk/openai zod
bun i ai @ai-sdk/openai zod
yarn --exact add ai @ai-sdk/openai zod

基礎範例

這個簡單的系統提示完全依賴模型對 Remotion 的既有知識——這並不理想,但是一個很好的起點。

generate.ts
import {generateText} from 'ai';
import {openai} from '@ai-sdk/openai';
 
const systemPrompt = `
You are a Remotion component generator. Generate a single React component that uses Remotion.
 
Rules:
- Export the component as a named export called "MyComposition"
- Use useCurrentFrame() and useVideoConfig() from "remotion"
- Animate values with interpolate() or spring() as appropriate
- Only output the code, no markdown or explanations
`.trim();
 
const {text: code, usage} = await generateText({
  model: openai('gpt-5.2'),
  system: systemPrompt,
  prompt: 'Create a countdown from 5 to 1 with smooth motion',
});
 
console.log(code);
// "import {useCurrentFrame, ...} export const MyComposition ..."
 
console.log(usage);
// { inputTokens: 89, outputTokens: 205, totalTokens: 294 }

回傳結果包含用於追蹤 token 消耗量的 usage 元數據。text 屬性包含生成的程式碼字串。格式化後的結果看起來像這樣:

import {useCurrentFrame, useVideoConfig, interpolate, AbsoluteFill} from 'remotion';
 
export const MyComposition: React.FC = () => {
  const frame = useCurrentFrame();
  const {fps} = useVideoConfig();
 
  // ... 元件其餘部分
};

請注意,原始輸出通常包含 Markdown 程式碼圍欄(例如 ```jsx),這需要額外的提示或後處理才能移除。關於後處理實作的範例,請參閱 Prompt to Motion Graphics 模板

使用 Zod 的結構化輸出

現在大多數主流的 LLM 供應商都為其 API 端點提供了結構化輸出模式,你可以精確定義你期望的屬性。為了更好地控制輸出,請使用帶有 output 屬性的 generateText() 來獲取帶有驗證的結構化輸出。

通常這已足以讓模型理解你實際上期望 code 屬性是字串化的程式碼,但你仍然可以在系統提示中再加上一條說明。

generate-structured.ts
import {generateText, Output} from 'ai';
import {openai} from '@ai-sdk/openai';
import {z} from 'zod';
 
const systemPrompt = `
You are a Remotion component generator. Generate a React component that uses Remotion.
For the code property, ALWAYS directly output the code as string without any markdown tags.
 
Rules:
- The component should be a named export called "MyComposition"
- Use useCurrentFrame() and useVideoConfig() from "remotion"
- Animate with interpolate() (and Easing from "remotion" when needed) or spring() as appropriate
- Keep it self-contained with no external dependencies
`.trim();
 
const {output} = await generateText({
  model: openai('gpt-5.2'),
  system: systemPrompt,
  prompt: 'Create a text animation that types out "Hello World" letter by letter',
  maxRetries: 3,
  output: Output.object({
    schema: z.object({
      code: z.string().describe('The complete React component code'),
      title: z.string().describe('A short title for this composition'),
      durationInFrames: z.number().describe('Recommended duration in frames'),
      fps: z.number().min(1).max(120).describe('Recommended frames per second'),
    }),
  }),
});
 
console.log(output.code);
console.log(`Recommended: ${output.fps}fps`);

結構化輸出保證你能收到包含所有必填欄位的有效 JSON,讓配置 Player 或渲染管線更加容易。如果 schema 不匹配,AI SDK 會自動重試最多 maxRetries 次(預設為 2)。

找到合適的系統提示

找到完美的系統提示是複雜的。根據你想要建立的內容,你可以針對特定動畫類型甚至企業品牌進行最佳化。

不過,一個很好的起點是使用 Remotion 的系統提示,它能教導通用 LLM Remotion 的 API 和最佳實踐。你可以從那裡開始迭代,生成幾個元件並根據需求調整。

請注意**上下文腐化(context rot)**的問題——隨著上下文增長,輸出品質和指令跟隨能力會下降。

技能(Skills)

與其使用一個龐大的系統提示,不如使用技能(Skills)——根據使用者的請求注入的模組化知識單元。這種方式保持基礎提示輕量化,並提高特定領域的輸出品質(例如:圖表、排版、過場效果、時間設定、3D)。

以下是技能偵測機制的最小範例:

skill-detection.ts
import {generateText, Output} from 'ai';
import {openai} from '@ai-sdk/openai';
import {z} from 'zod';
 
const SKILL_NAMES = [
  'charts',
  'typography',
  'transitions',
  'spring-physics',
  '3d',
] as const;
 
// 第 1 步:偵測需要哪些技能
const {output: detectedSkills} = await generateText({
  model: openai('gpt-5-mini'), // 使用快速、低成本的模型進行分類
  prompt: 'Create a bouncy bar chart showing quarterly sales data',
  output: Output.object({
    schema: z.object({
      skills: z
        .array(z.enum(SKILL_NAMES))
        .describe('Matching skill categories'),
    }),
  }),
});
 
console.log(detectedSkills.skills);
// ["charts", "spring-physics"]
 
// 第 2 步:只載入相關的技能內容
const skillContent = detectedSkills.skills
  .map((skill) => loadSkillMarkdown(skill)) // 你自己載入技能檔案的函式
  .join('\n\n');
 
// 第 3 步:使用有針對性的上下文生成程式碼
const {output} = await generateText({
  model: openai('gpt-5.2'),
  system: baseSystemPrompt + '\n\n' + skillContent,
  prompt: 'Create a bouncy bar chart showing quarterly sales data',
  output: Output.object({
    schema: z.object({
      code: z.string().describe('The complete React component code'),
      // 元數據、你的其他屬性...
    }),
  }),
});

完整的實作範例請參閱 Prompt to Motion Graphics 模板

下一步

生成程式碼後,你需要編譯並渲染它:

  • 動態編譯:了解如何在瀏覽器中將程式碼字串轉換為即時預覽——請參閱 Dynamic Compilation
  • 系統提示:Remotion 官方的系統提示,用於教導 LLM Remotion 的 API——請參閱 System Prompt
  • Prompt to Motion Graphics 模板:完整的實作範例——請參閱模板頁面

相關連結