For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
기본 탐색 메뉴
Theme

프롬프트 생성

Playground에서 프롬프트와 스키마를 생성하세요.

Generate 버튼을 사용하면 Playground에서 작업 설명만으로 프롬프트, 함수, 스키마를 생성할 수 있습니다. 이 가이드에서는 각 항목이 어떻게 생성되는지 살펴봅니다.

개요

프롬프트와 스키마를 처음부터 작성하려면 시간이 걸립니다. Generate 버튼으로 초안을 생성하면 빠르게 시작할 수 있습니다. 생성 방식은 크게 두 가지입니다.

  1. 프롬프트: 모범 사례를 반영한 메타 프롬프트로 프롬프트를 생성하거나 개선합니다.
  2. 스키마: 메타 스키마를 사용해 유효한 JSON과 문법에 맞는 함수 정의를 생성합니다.

현재는 메타 프롬프트와 메타 스키마를 사용하지만, 향후 DSPy나 “경사 하강법”과 같은 고급 기법을 도입할 수도 있습니다.

프롬프트

메타 프롬프트는 작업 설명에 맞는 프롬프트를 작성하거나 기존 프롬프트를 개선하도록 모델에 지시합니다. Playground의 메타 프롬프트에는 OpenAI의 프롬프트 엔지니어링 모범 사례와 실제 사용자와 함께 작업하며 얻은 경험이 반영되어 있습니다.

생성된 프롬프트가 예상 형식에 맞도록 오디오 등 출력 유형에 따라 다른 메타 프롬프트를 사용합니다.

메타 프롬프트

텍스트용 메타 프롬프트
import OpenAI from "openai";

const client = new OpenAI();

const metaPrompt = `Given a task description or existing prompt, produce a detailed system prompt to guide a language model in completing the task effectively.

# Guidelines

- Understand the Task: Grasp the main objective, goals, requirements, constraints, and expected output.
- Minimal Changes: If an existing prompt is provided, improve it only if it's simple. For complex prompts, enhance clarity and add missing elements without altering the original structure.
- Reasoning Before Conclusions**: Encourage reasoning steps before any conclusions are reached. ATTENTION! If the user provides examples where the reasoning happens afterward, REVERSE the order! NEVER START EXAMPLES WITH CONCLUSIONS!
    - Reasoning Order: Call out reasoning portions of the prompt and conclusion parts (specific fields by name). For each, determine the ORDER in which this is done, and whether it needs to be reversed.
    - Conclusion, classifications, or results should ALWAYS appear last.
- Examples: Include high-quality examples if helpful, using placeholders [in brackets] for complex elements.
   - What kinds of examples may need to be included, how many, and whether they are complex enough to benefit from placeholders.
- Clarity and Conciseness: Use clear, specific language. Avoid unnecessary instructions or bland statements.
- Formatting: Use markdown features for readability. DO NOT USE \`\`\` CODE BLOCKS UNLESS SPECIFICALLY REQUESTED.
- Preserve User Content: If the input task or prompt includes extensive guidelines or examples, preserve them entirely, or as closely as possible. If they are vague, consider breaking down into sub-steps. Keep any details, guidelines, examples, variables, or placeholders provided by the user.
- Constants: DO include constants in the prompt, as they are not susceptible to prompt injection. Such as guides, rubrics, and examples.
- Output Format: Explicitly the most appropriate output format, in detail. This should include length and syntax (e.g. short sentence, paragraph, JSON, etc.)
    - For tasks outputting well-defined or structured data (classification, JSON, etc.) bias toward outputting a JSON.
    - JSON should never be wrapped in code blocks (\`\`\`) unless explicitly requested.

The final prompt you output should adhere to the following structure below. Do not include any additional commentary, only output the completed system prompt. SPECIFICALLY, do not include any additional messages at the start or end of the prompt. (e.g. no "---")

[Concise instruction describing the task - this should be the first line in the prompt, no section header]

[Additional details as needed.]

[Optional sections with headings or bullet points for detailed steps.]

# Steps [optional]

[optional: a detailed breakdown of the steps necessary to accomplish the task]

# Output Format

[Specifically call out how the output should be formatted, be it response length, structure e.g. JSON, markdown, etc]

# Examples [optional]

[Optional: 1-3 well-defined examples with placeholders if necessary. Clearly mark where examples start and end, and what the input and output are. User placeholders as necessary.]
[If the examples are shorter than what a realistic example is expected to be, make a reference with () explaining how real examples should be longer / shorter / different. AND USE PLACEHOLDERS! ]

# Notes [optional]

[optional: edge cases, details, and an area to call or repeat out specific important considerations]`;

async function generatePrompt(taskOrPrompt) {
  const completion = await client.chat.completions.create({
    model: "gpt-6-astra",
    messages: [
      { role: "system", content: metaPrompt },
      {
        role: "user",
        content: "Task, Goal, or Current Prompt:\n" + taskOrPrompt,
      },
    ],
  });

  return completion.choices[0].message.content;
}

console.log(
  await generatePrompt("Write a concise product launch announcement.")
);

프롬프트 수정

프롬프트를 수정할 때는 메타 프롬프트를 조금 바꿔 사용합니다. 수정 사항이 명확하면 쉽게 반영할 수 있지만, 요청이 포괄적이면 무엇을 바꿔야 할지 판단하기 어렵습니다. 이를 위해 응답 앞부분에 추론 섹션을 둡니다. 여기서 모델은 기존 프롬프트의 명확성, 추론 과정의 순서, 전체 구조, 구체성 등을 검토해 필요한 변경 사항을 판단하고 개선안을 제시합니다. 응답을 파싱할 때는 이 섹션을 최종 응답에서 제외합니다.

텍스트 프롬프트 수정용 메타 프롬프트
import OpenAI from "openai";

const client = new OpenAI();

const metaPrompt = `Given a current prompt and a change description, produce a detailed system prompt to guide a language model in completing the task effectively.

Your final output will be the full corrected prompt verbatim. However, before that, at the very beginning of your response, use <reasoning> tags to analyze the prompt and determine the following, explicitly:
<reasoning>
- Simple Change: (yes/no) Is the change description explicit and simple? (If so, skip the rest of these questions.)
- Reasoning: (yes/no) Does the current prompt use reasoning, analysis, or chain of thought?
    - Identify: (max 10 words) if so, which section(s) utilize reasoning?
    - Conclusion: (yes/no) is the chain of thought used to determine a conclusion?
    - Ordering: (before/after) is the chain of though located before or after
- Structure: (yes/no) does the input prompt have a well defined structure
- Examples: (yes/no) does the input prompt have few-shot examples
    - Representative: (1-5) if present, how representative are the examples?
- Complexity: (1-5) how complex is the input prompt?
    - Task: (1-5) how complex is the implied task?
    - Necessity: ()
- Specificity: (1-5) how detailed and specific is the prompt? (not to be confused with length)
- Prioritization: (list) what 1-3 categories are the MOST important to address.
- Conclusion: (max 30 words) given the previous assessment, give a very concise, imperative description of what should be changed and how. this does not have to adhere strictly to only the categories listed
</reasoning>

# Guidelines

- Understand the Task: Grasp the main objective, goals, requirements, constraints, and expected output.
- Minimal Changes: If an existing prompt is provided, improve it only if it's simple. For complex prompts, enhance clarity and add missing elements without altering the original structure.
- Reasoning Before Conclusions**: Encourage reasoning steps before any conclusions are reached. ATTENTION! If the user provides examples where the reasoning happens afterward, REVERSE the order! NEVER START EXAMPLES WITH CONCLUSIONS!
    - Reasoning Order: Call out reasoning portions of the prompt and conclusion parts (specific fields by name). For each, determine the ORDER in which this is done, and whether it needs to be reversed.
    - Conclusion, classifications, or results should ALWAYS appear last.
- Examples: Include high-quality examples if helpful, using placeholders [in brackets] for complex elements.
   - What kinds of examples may need to be included, how many, and whether they are complex enough to benefit from placeholders.
- Clarity and Conciseness: Use clear, specific language. Avoid unnecessary instructions or bland statements.
- Formatting: Use markdown features for readability. DO NOT USE \`\`\` CODE BLOCKS UNLESS SPECIFICALLY REQUESTED.
- Preserve User Content: If the input task or prompt includes extensive guidelines or examples, preserve them entirely, or as closely as possible. If they are vague, consider breaking down into sub-steps. Keep any details, guidelines, examples, variables, or placeholders provided by the user.
- Constants: DO include constants in the prompt, as they are not susceptible to prompt injection. Such as guides, rubrics, and examples.
- Output Format: Explicitly the most appropriate output format, in detail. This should include length and syntax (e.g. short sentence, paragraph, JSON, etc.)
    - For tasks outputting well-defined or structured data (classification, JSON, etc.) bias toward outputting a JSON.
    - JSON should never be wrapped in code blocks (\`\`\`) unless explicitly requested.

The final prompt you output should adhere to the following structure below. Do not include any additional commentary, only output the completed system prompt. SPECIFICALLY, do not include any additional messages at the start or end of the prompt. (e.g. no "---")

[Concise instruction describing the task - this should be the first line in the prompt, no section header]

[Additional details as needed.]

[Optional sections with headings or bullet points for detailed steps.]

# Steps [optional]

[optional: a detailed breakdown of the steps necessary to accomplish the task]

# Output Format

[Specifically call out how the output should be formatted, be it response length, structure e.g. JSON, markdown, etc]

# Examples [optional]

[Optional: 1-3 well-defined examples with placeholders if necessary. Clearly mark where examples start and end, and what the input and output are. User placeholders as necessary.]
[If the examples are shorter than what a realistic example is expected to be, make a reference with () explaining how real examples should be longer / shorter / different. AND USE PLACEHOLDERS! ]

# Notes [optional]

[optional: edge cases, details, and an area to call or repeat out specific important considerations]
[NOTE: you must start with a <reasoning> section. the immediate next token you produce should be <reasoning>]`;

async function generatePrompt(taskOrPrompt) {
  const completion = await client.chat.completions.create({
    model: "gpt-6-astra",
    messages: [
      { role: "system", content: metaPrompt },
      {
        role: "user",
        content: "Task, Goal, or Current Prompt:\n" + taskOrPrompt,
      },
    ],
  });

  return completion.choices[0].message.content;
}

console.log(
  await generatePrompt("Make this support prompt more concise and empathetic.")
);

스키마

구조화된 출력값 스키마와 함수 스키마는 그 자체가 JSON 객체이므로, 두 스키마 모두 구조화된 출력값 기능을 사용해 생성합니다. 이때 원하는 출력의 스키마를 정의해야 하는데, 여기서는 출력 자체가 스키마입니다. 따라서 스키마 자체를 기술하는 메타 스키마를 사용합니다.

함수 스키마의 parameters 필드도 스키마이므로 같은 메타 스키마로 함수를 생성합니다.

제약 조건을 반영한 메타 스키마 정의

구조화된 출력값은 strict=true와 strict=false 두 가지 모드를 지원합니다. 두 모드 모두 주어진 스키마를 따르도록 학습된 동일한 모델을 사용합니다. 다만 “엄격 모드”에서만 샘플링에 제약을 적용해 출력이 스키마를 정확히 따르도록 보장합니다.

목표는 엄격 모드 자체를 사용해 엄격 모드용 스키마를 생성하는 것입니다. 하지만 JSON 스키마 명세의 공식 메타 스키마는 엄격 모드에서 현재 지원하지 않는 기능에 의존합니다. 이로 인해 입력 스키마와 출력 스키마 모두에 제약이 생깁니다.

  1. 입력 스키마: 입력 스키마에서 지원되지 않는 기능을 사용해 출력 스키마를 기술할 수 없습니다.
  2. 출력 스키마: 생성된 스키마에는 지원되지 않는 기능이 포함되어서는 안 됩니다.

출력 스키마에 새 키를 생성하려면 입력 메타 스키마에서 additionalProperties를 사용해야 합니다. 이 때문에 현재는 엄격 모드로 스키마를 생성할 수 없습니다. 그래도 생성된 스키마는 엄격 모드의 제약 조건을 충족해야 합니다.

이 한계를 극복하기 위해 의사 메타 스키마를 정의합니다. 이 메타 스키마는 엄격 모드에서 지원하지 않는 기능을 사용하되, 엄격 모드에서 지원하는 기능만 기술합니다. 이렇게 하면 메타 스키마를 정의할 때는 엄격 모드의 제약을 벗어나면서도 생성된 스키마는 엄격 모드의 제약 조건을 따르도록 할 수 있습니다.

Deep dive
의사 메타 스키마 설계 과정

출력 정리

엄격 모드에서는 출력이 스키마를 정확히 따르도록 보장합니다. 하지만 생성 단계에서는 엄격 모드를 사용할 수 없으므로 생성 후 출력을 검증하고 변환해야 합니다.

스키마를 생성한 뒤에는 다음 단계를 수행합니다.

  1. 모든 객체에서 additionalProperties를 false로 설정합니다.
  2. 모든 속성을 필수로 지정합니다.
  3. 구조화된 출력값 스키마는 json_schema 객체로 감쌉니다.
  4. 함수는 function 객체로 감쌉니다.

Realtime API의 함수 객체는 Chat Completions API의 함수 객체와 조금 다르지만 같은 스키마를 사용합니다.

메타 스키마

각 메타 스키마에는 퓨샷 예시가 포함된 프롬프트가 하나씩 대응합니다. 이 프롬프트와 구조화된 출력값 기능을 함께 사용한 결과, 엄격 모드 없이도 안정적으로 스키마를 생성할 수 있었습니다.

구조화된 출력값 메타 스키마
import OpenAI from "openai";

const client = new OpenAI();

const schemaDefinition = {
  type: "object",
  properties: {
    description: { type: "string" },
    type: {
      type: "string",
      enum: ["object", "array", "string", "number", "boolean", "null"],
    },
    properties: {
      type: "object",
      additionalProperties: { $ref: "#/$defs/schema_definition" },
    },
    items: {
      anyOf: [
        { $ref: "#/$defs/schema_definition" },
        { type: "array", items: { $ref: "#/$defs/schema_definition" } },
      ],
    },
    required: { type: "array", items: { type: "string" } },
    additionalProperties: { type: "boolean" },
    enum: { type: "array", minItems: 1, uniqueItems: true },
    $ref: { type: "string" },
    $defs: {
      type: "object",
      additionalProperties: { $ref: "#/$defs/schema_definition" },
    },
    anyOf: {
      type: "array",
      minItems: 1,
      items: { $ref: "#/$defs/schema_definition" },
    },
  },
  additionalProperties: false,
  if: { required: ["type"], properties: { type: { const: "object" } } },
  then: { required: ["properties"] },
};

const metaSchema = {
  name: "metaschema",
  schema: {
    ...schemaDefinition,
    required: ["type"],
    properties: {
      name: { type: "string", description: "The name of the schema" },
      ...schemaDefinition.properties,
    },
    $defs: {
      schema_definition: {
        ...schemaDefinition,
        anyOf: [
          { required: ["type"] },
          { required: ["$ref"] },
          { required: ["anyOf"] },
        ],
      },
    },
  },
};

const metaPrompt = `# Instructions
Return a valid schema for the described JSON.

You must also make sure:
- all fields in an object are set as required
- I REPEAT, ALL FIELDS MUST BE MARKED AS REQUIRED
- all objects must have additionalProperties set to false
    - because of this, some cases like "attributes" or "metadata" properties that would normally allow additional properties should instead have a fixed set of properties
- all objects must have properties defined
- field order matters. any form of "thinking" or "explanation" should come before the conclusion
- $defs must be defined under the schema param

Notable keywords NOT supported include:
- For objects: unevaluatedProperties, propertyNames, minProperties, maxProperties
- For arrays: unevaluatedItems, contains, minContains, maxContains, uniqueItems

Other notes:
- definitions and recursion are supported
- only if necessary to include references e.g. "$defs", it must be inside the "schema" object

# Examples
Input: Generate a math reasoning schema with steps and a final answer.
Output: {
    "name": "math_reasoning",
    "type": "object",
    "properties": {
        "steps": {
            "type": "array",
            "description": "A sequence of steps involved in solving the math problem.",
            "items": {
                "type": "object",
                "properties": {
                    "explanation": {
                        "type": "string",
                        "description": "Description of the reasoning or method used in this step."
                    },
                    "output": {
                        "type": "string",
                        "description": "Result or outcome of this specific step."
                    }
                },
                "required": [
                    "explanation",
                    "output"
                ],
                "additionalProperties": false
            }
        },
        "final_answer": {
            "type": "string",
            "description": "The final solution or answer to the math problem."
        }
    },
    "required": [
        "steps",
        "final_answer"
    ],
    "additionalProperties": false
}

Input: Give me a linked list
Output: {
    "name": "linked_list",
    "type": "object",
    "properties": {
        "linked_list": {
            "$ref": "#/$defs/linked_list_node",
            "description": "The head node of the linked list."
        }
    },
    "$defs": {
        "linked_list_node": {
            "type": "object",
            "description": "Defines a node in a singly linked list.",
            "properties": {
                "value": {
                    "type": "number",
                    "description": "The value stored in this node."
                },
                "next": {
                    "anyOf": [
                        {
                            "$ref": "#/$defs/linked_list_node"
                        },
                        {
                            "type": "null"
                        }
                    ],
                    "description": "Reference to the next node; null if it is the last node."
                }
            },
            "required": [
                "value",
                "next"
            ],
            "additionalProperties": false
        }
    },
    "required": [
        "linked_list"
    ],
    "additionalProperties": false
}

Input: Dynamically generated UI
Output: {
    "name": "ui",
    "type": "object",
    "properties": {
        "type": {
            "type": "string",
            "description": "The type of the UI component",
            "enum": [
                "div",
                "button",
                "header",
                "section",
                "field",
                "form"
            ]
        },
        "label": {
            "type": "string",
            "description": "The label of the UI component, used for buttons or form fields"
        },
        "children": {
            "type": "array",
            "description": "Nested UI components",
            "items": {
                "$ref": "#"
            }
        },
        "attributes": {
            "type": "array",
            "description": "Arbitrary attributes for the UI component, suitable for any element",
            "items": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string",
                        "description": "The name of the attribute, for example onClick or className"
                    },
                    "value": {
                        "type": "string",
                        "description": "The value of the attribute"
                    }
                },
                "required": [
                    "name",
                    "value"
                ],
                "additionalProperties": false
            }
        }
    },
    "required": [
        "type",
        "label",
        "children",
        "attributes"
    ],
    "additionalProperties": false
}`;

async function generateSchema(description) {
  const completion = await client.chat.completions.create({
    model: "gpt-5.6-terra",
    response_format: { type: "json_schema", json_schema: metaSchema },
    messages: [
      { role: "system", content: metaPrompt },
      { role: "user", content: "Description:\n" + description },
    ],
  });

  const content = completion.choices[0].message.content;
  if (!content) throw new Error("The model did not return a schema.");
  return JSON.parse(content);
}

console.log(
  JSON.stringify(await generateSchema("Describe a calendar event."), null, 2)
);