К основному содержанию
правило

openai — правило для Cursor: рекомендации по OpenAI API

Правило помогает вести проект с OpenAI API: хранить промпты отдельно, правильно создавать клиент и задавать модели чёткие инструкции. Пригодится при разработке на Python.

Установить в Cursor · Вручную: положить файлы Все способы и платформы ↓
.cursor/rules/openai.mdc
Открыть на GitHub

Что делает openai

Правило применяется ко всем файлам проекта через маску **/*. Оно советует использовать библиотеку openai для Python и создавать клиент один раз при запуске приложения, получая ключ из переменной окружения OPENAI_API_KEY, а не записывая его в код. Без настроенного ключа пример с клиентом остановится с ошибкой.

Промпты предлагается хранить отдельно от логики приложения и версионировать. В запросе стоит задавать роль, контекст, задачу, формат и ограничения; инструкции размещать перед текстом, отделяя его разделителями. Для структурированных ответов правило показывает режим JSON, а для сложных задач — примеры входа и результата. Это рекомендации по работе с OpenAI API, а не готовый клиент или скрипт.

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

  • создать клиент OpenAI один раз при запуске приложения
  • вынести промпты из кода и хранить их отдельно
  • сформулировать запрос с ролью, контекстом и ограничениями
  • получать структурированные ответы в формате JSON
  • добавить примеры входа и результата к сложному запросу

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

  • Проверь, что клиент OpenAI создаётся один раз, а ключ берётся из OPENAI_API_KEY.
  • Вынеси текст промпта из логики приложения и предложи структуру для prompts.py.
  • Перепиши запрос для извлечения сущностей так, чтобы ответ возвращался в JSON.

Как установить openai

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

.cursor/rules/openai.mdc

Во frontmatter: description, globs, alwaysApply

По шагам, с командами для каждой платформы: Cursor rules: файлы .mdc, четыре режима и замена .cursorrules

Вопросы о openai

Как установить openai в Cursor?

Добавь файл правила по пути .cursor/rules/openai.mdc. Правило охватывает файлы по маске **/*.

Что делает правило openai?

Оно задаёт рекомендации по работе с OpenAI API: настройке Python-клиента, хранению промптов и составлению запросов. Также описывает JSON-ответы и примеры для сложных задач.

Что нужно для работы с OpenAI API по этому правилу?

В примерах используется библиотека openai для Python и ключ в переменной окружения OPENAI_API_KEY. Клиент предлагается создавать один раз при запуске приложения.

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

openai.mdc · CC0-1.0
---
description: This guide provides definitive, actionable best practices for developing with the OpenAI API, covering prompt engineering, robust client usage, agent design, and testing.
globs: **/*
---
# openai Best Practices

This document outlines the definitive best practices for interacting with OpenAI APIs, ensuring your applications are reliable, maintainable, and performant. Adhere to these guidelines for all OpenAI-powered development.

## 1. Code Organization and Structure

Always use the official `openai` Python client library. It handles authentication, request formatting, and error handling, allowing you to focus on business logic.

### 1.1 Client Initialization

Initialize the OpenAI client once, ideally at application startup or as a singleton. Never hardcode API keys.

❌ **BAD**: Hardcoding API key and re-initializing client
```python
import os
from openai import OpenAI

def get_response_bad(prompt: str):
    # API key hardcoded and client re-initialized on every call
    client = OpenAI(api_key="sk-YOUR_HARDCODED_KEY") 
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": prompt}]
    )
    return response.choices[0].message.content
```

✅ **GOOD**: Environment variable for API key, single client instance
```python
import os
from openai import OpenAI

# Initialize client once, leveraging OPENAI_API_KEY environment variable
client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))

def get_response_good(prompt: str) -> str:
    if not client.api_key:
        raise ValueError("OPENAI_API_KEY environment variable not set.")
    
    response = client.chat.completions.create(
        model="gpt-4o", # Always use the latest, most capable model
        messages=[{"role": "user", "content": prompt}]
    )
    return response.choices[0].message.content
```

### 1.2 Prompt Management

Treat prompts as first-class code artifacts. Store them in separate files, constants, or configuration, and version-control them. This improves readability, reusability, and testability.

❌ **BAD**: Inline, unstructured prompts
```python
def process_user_query(query: str):
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": "You are a helpful assistant."},
            {"role": "user", "content": f"Summarize this text: {query}"}
        ]
    )
    # ...
```

✅ **GOOD**: Externalized, structured prompts
```python
# prompts.py
SYSTEM_PROMPT_SUMMARIZER = "You are a concise summarization bot. Extract key information only."
USER_PROMPT_SUMMARIZE_TEXT = "Summarize the following text, focusing on main arguments:\n\n---\n{text}\n---"

# main.py
from prompts import SYSTEM_PROMPT_SUMMARIZER, USER_PROMPT_SUMMARIZE_TEXT

def process_user_query(query: str):
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT_SUMMARIZER},
            {"role": "user", "content": USER_PROMPT_SUMMARIZE_TEXT.format(text=query)}
        ]
    )
    # ...
```

## 2. Common Patterns and Anti-patterns

### 2.1 Prompt Engineering

Effective prompting is paramount. Follow the "Five-Element Prompt Template" for consistency and optimal results: **Role/Persona, Context, Task, Format, Constraints.**

#### 2.1.1 Model Selection

Always target the **latest, most capable model** (e.g., `gpt-4o`). Newer models are generally more intelligent, easier to prompt, and offer better performance.

#### 2.1.2 Clear Instructions and Delimiters

Place instructions at the beginning of the prompt. Use clear delimiters (e.g., `###`, `"""`) to separate instructions from context.

❌ **BAD**: Ambiguous instruction placement
```python
prompt = f"Summarize the text below as a bullet point list of the most important points. {text_input}"
```

✅ **GOOD**: Instructions first, context delimited
```python
prompt = f"""Summarize the text below as a bullet point list of the most important points.
Text: \"\"\"
{text_input}
\"\"\""""
```

#### 2.1.3 Be Specific and Detailed

Provide explicit details about the desired context, outcome, length, format, and style.

❌ **BAD**: Vague request
```python
prompt = "Write a poem about AI."
```

✅ **GOOD**: Highly specific request
```python
prompt = """Write a short, inspiring poem about the future of AI,
focusing on ethical development and human-AI collaboration.
Adopt the style of a modern, optimistic futurist.
"""
```

#### 2.1.4 Articulate Output Format with Examples

Show, don't just tell. Provide examples of the desired output format, especially for structured data. Use JSON mode for reliable parsing.

❌ **BAD**: Text-based format description
```python
prompt = """Extract company names, people names, and topics from the text.
Company names: <list>
People names: <list>
Topics: <list>
Text: {text}
"""
```

✅ **GOOD**: JSON Mode for structured output
```python
response = client.chat.completions.create(
    model="gpt-4o",
    response_format={"type": "json_object"}, # Crucial for structured output
    messages=[
        {"role": "system", "content": "You are an entity extraction bot. Output JSON."},
        {"role": "user", "content": f"""Extract the following entities from the text:
        - company_names (list of strings)
        - people_names (list of strings)
        - topics (list of strings)
        
        Text: \"\"\"{text}\"\"\"
        
        Example Output:
        ```json
        {{
            "company_names": ["OpenAI", "Microsoft"],
            "people_names": ["Sam Altman"],
            "topics": ["AI research", "LLMs"]
        }}
        ```
        """}
    ]
)
# response.choices[0].message.content will be a valid JSON string
```

#### 2.1.5 Few-Shot Learning

For complex tasks, provide a few high-quality input-output examples to guide the model.

```python
few_shot_prompt = f"""Extract keywords from the corresponding texts below.

Text 1: Stripe provides APIs that web developers can use to integrate payment processing into their websites and mobile applications.
Keywords 1: Stripe, payment processing, APIs, web developers, websites, mobile applications
---
Text 2: OpenAI has trained cutting-edge language models that are very good at understanding and generating text. Our API provides access to these models and can be used to solve virtually any task that involves processing language.
Keywords 2: OpenAI, language models, text processing, API.
---
Text 3: {user_text}
Keywords 3:"""

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": few_shot_prompt}]
)
```

#### 2.1.6 Role/Persona and Constraints

Define the AI's role and explicitly state what it should *not* do.

❌ **BAD**: Only negative constraints
```python
system_message = "DO NOT MENTION PRICES. DO NOT BE OVERLY FORMAL."
```

✅ **GOOD**: Clear role, positive instructions, and specific constraints
```python
system_message = """You are a friendly, helpful customer support agent for a SaaS product.
Your goal is to diagnose user issues and suggest solutions.
NEVER ask for Personally Identifiable Information (PII) like passwords or credit card numbers.
Instead, refer users to our secure help portal at `https://support.example.com/security`.
"""
```

### 2.2 Agent Design

For building autonomous agents, follow OpenAI's "Practical Guide to Building Agents" framework.

#### 2.2.1 Core Components

Agents require:
1.  **Model**: The LLM for reasoning and decision-making.
2.  **Tools**: External functions/APIs the agent can use.
3.  **Instructions**: Explicit guidelines and guardrails.

#### 2.2.2 Function Calling

Use function calling for agents to reliably interact with external tools and APIs. Define tools with clear schemas.

```python
from openai import OpenAI
import json

client = OpenAI()

def get_current_weather(location: str, unit: str = "fahrenheit") -> str:
    """Get the current weather in a given location"""
    # In a real app, this would call an external weather API
    if "san francisco" in location.lower():
        return json.dumps({"location": location, "temperature": "72", "unit": unit})
    return json.dumps({"location": location, "temperature": "unknown"})

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Get the current weather in a given location",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city and state, e.g. San Francisco, CA",
                    },
                    "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
                },
                "required": ["location"],
            },
        },
    }
]

def run_agent_with_tool(user_message: str):
    messages = [{"role": "user", "content": user_message}]
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=messages,
        tools=tools,
        tool_choice="auto", # Let the model decide if it needs to call a tool
    )
    response_message = response.choices[0].message

    if response_message.tool_calls:
        tool_call = response_message.tool_calls[0]
        function_name = tool_call.function.name
        function_args = json.loads(tool_call.function.arguments)
        
        if function_name == "get_current_weather":
            function_response = get_current_weather(**function_args)
            messages.append(response_message) # Extend conversation with assistant's reply
            messages.append(
                {
                    "tool_call_id": tool_call.id,
                    "role": "tool",
                    "name": function_name,
                    "content": function_response,
                }
            )
            second_response = client.chat.completions.create(
                model="gpt-4o",
                messages=messages,
            )
            return second_response.choices[0].message.content
    return response_message.content

# Example usage:
# print(run_agent_with_tool("What's the weather like in San Francisco?"))
```

#### 2.2.3 Guardrails and Workflow Orchestration

Implement explicit guardrails (e.g., input validation, content moderation, safety checks) and design clear workflows. For complex tasks, split into smaller, orchestratable agents (Manager Pattern).

### 2.3 Code Generation (Codex)

When using models for code generation, provide ample context and verification steps.

#### 2.3.1 Clear Code Pointers

Include specific file paths, greppable identifiers, or full stack traces to narrow the model's focus.

#### 2.3.2 Verification Steps

Ask the model to include steps to reproduce an issue, validate a feature, or run tests/linters. This improves output quality.

```python
code_gen_prompt = """
Refactor the `calculate_total` function in `src/utils.py` to use `Decimal` for currency calculations to avoid floating-point inaccuracies.
Ensure all existing unit tests in `tests/test_utils.py` still pass after your changes.
Provide the updated `src/utils.py` file and the command to run the tests.
"""
```

## 3. Performance Considerations

### 3.1 Model Choice

Balance model capability with cost and latency. Start with `gpt-4o` for prototyping, then consider `gpt-3.5-turbo` for simpler tasks where cost/speed is critical.

### 3.2 Token Usage

Be concise. Avoid sending unnecessary context or overly verbose prompts. Every token costs money and adds latency.

### 3.3 Streaming Responses

For user-facing applications, use streaming responses to improve perceived latency.

```python
def stream_response(prompt: str):
    stream = client.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": prompt}],
        stream=True,
    )
    for chunk in stream:
        if chunk.choices[0].delta.content is not None:
            print(chunk.choices[0].delta.content, end="")
    print() # Newline at the end
```

## 4. Common Pitfalls and Gotchas

*   **Hardcoding API Keys**: Security vulnerability. Use environment variables.
*   **Vague Prompts**: Leads to inconsistent, irrelevant, or hallucinated outputs. Be specific.
*   **Ignoring System Message**: The system message is your primary control for persona and behavior. Use it.
*   **Parsing Freeform Text**: Unreliable. Always use `response_format={"type": "json_object"}` for structured data.
*   **Over-reliance on Single-Turn Prompts**: For complex, multi-step tasks, design agents with tool use and iterative reasoning.

## 5. Error Handling

Implement robust error handling, especially for API calls.

### 5.1 API Exceptions

Catch specific OpenAI API exceptions and implement retry logic.

```python
from openai import OpenAI, APIError, RateLimitError, AuthenticationError
import time

def safe_api_call(prompt: str, retries: int = 3) -> str | None:
    for i in range(retries):
        try:
            response = client.chat.completions.create(
                model="gpt-4o",
                messages=[{"role": "user", "content": prompt}]
            )
            return response.choices[0].message.content
        except RateLimitError:
            delay = 2 ** i  # Exponential backoff
            print(f"Rate limit hit. Retrying in {delay} seconds...")
            time.sleep(delay)
        except AuthenticationError:
            print("Authentication failed. Check your API key.")
            return None
        except APIError as e:
            print(f"OpenAI API error: {e}")
            return None
        except Exception as e:
            print(f"An unexpected error occurred: {e}")
            return None
    print("Max retries exceeded.")
    return None
```

## 6. Request/Response Patterns

### 6.1 Chat Completions API

This is the primary endpoint for most LLM interactions. Always use the `messages` array for conversational context.

### 6.2 Structured Output (JSON Mode)

For any task requiring data extraction or structured responses, enforce JSON output.

```python
response = client.chat.completions.create(
    model="gpt-4o",
    response_format={"type": "json_object"},
    messages=[
        {"role": "system", "content": "You are a JSON-generating assistant."},
        {"role": "user", "content": "Generate a JSON object with 'name' and 'age' for a person named 'Alice' who is 30."}
    ]
)
data = json.loads(response.choices[0].message.content)
# data will be {'name': 'Alice', 'age': 30}
```

## 7. Rate Limiting

The `openai` Python client includes built-in retry logic for rate limits. However, for high-throughput applications, implement custom exponential backoff and jitter, or use a dedicated rate-limiting library.

## 8. Testing Approaches

Treat prompts and LLM interactions as critical code.

### 8.1 Prompts as Code

Version control your prompts alongside your application code.

### 8.2 Unit-Style Tests (Evals)

Write tests for your prompt outputs. Define expected outcomes and evaluate model responses against them.

```python
# test_summarizer.py
import pytest
from your_app import get_response_good # Assuming get_response_good uses your structured prompt

@pytest.mark.parametrize("input_text, expected_keywords", [
    ("The quick brown fox jumps over the lazy dog.", ["fox", "dog", "jumps"]),
    ("OpenAI released GPT-4o, a new multimodal model.", ["OpenAI", "GPT-4o", "multimodal model"]),
])
def test_keyword_extraction(input_text, expected_keywords):
    # This assumes get_response_good is adapted for keyword extraction with JSON output
    prompt = f"""Extract 3-5 keywords from the following text as a JSON array.
    Text: \"\"\"{input_text}\"\"\"
    Example: ["keyword1", "keyword2"]
    """
    response_json_str = get_response_good(prompt)
    actual_keywords = json.loads(response_json_str)
    
    assert isinstance(actual_keywords, list)
    assert len(actual_keywords) >= 3 # Check length
    for keyword in expected_keywords:
        assert any(keyword.lower() in actual.lower() for actual in actual_keywords) # Check for presence
```

### 8.3 Iterative Refinement

Continuously test, analyze outputs, and refine your prompts and model parameters. Use OpenAI's Evals framework or similar tools for systematic evaluation.

© sanjeed5 · CC0-1.0 · sanjeed5/awesome-cursor-rules-mdc

Похожие правила IDE

Все правила IDE по теме «Бэкенд и API» →
openai-api-troubleshooting официальный OpenAI Классифицирует сбои при вызовах OpenAI API в Codex и подсказывает точное действие для исправления. Пригодится, когда запрос падает с сетевой ошибкой, 401, 403 или исчерпанным балансом. CX Codex GP ChatGPT 13установок openai-agents-sdk laguagu Скилл помогает писать агентов на Python-библиотеке openai-agents: настраивать передачу контекста между агентами, инструменты через @function_tool, стриминг и сессии в SQLite. CX Codex +1 2 200установок openai-docs официальный openai Скилл ищет актуальные материалы OpenAI и помогает отвечать по API, Codex, моделям и обновлению промптов с опорой на официальную документацию. CX Codex +1 6 100установок openai-image-gen swarmclawai Скилл генерирует изображения через OpenAI Images API: GPT Image, DALL-E 3 и DALL-E 2. Собирает пакет картинок и HTML-галерею для просмотра. CX Codex +1 ★ 701звёзд репо openai-api-development Mindrally Скилл для разработки на OpenAI API: подсказывает, как писать вызовы GPT, function calling, эмбеддинги и Assistants API на Python. CX Codex +1 864установок extension-openai caffeinelabs Задаёт правила интеграции OpenAI в канистры Motoko через пакет openai-client. Защищает API-ключ от утечки при реплицированных вызовах. CX Codex +1 28 400установок

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

Весь набор →
peewee Задаёт стандарты работы с ORM Peewee в Python: настройку BaseModel, внешние ключи с backref, транзакции atomic и защиту от проблемы N+1. ★ 3 580звёзд репо pdoc Правило задаёт формат docstring и type hints в Python-коде, который документируется через pdoc. Пригодится, когда нужно привести описание публичного API к единому виду. ★ 3 580звёзд репо pandas Правило для Cursor задаёт стиль работы с pandas: векторизация вместо циклов, явные .loc и .iloc, экономные типы данных. Пригодится, если агент часто пишет медленный код. ★ 3 580звёзд репо opencv-python Набор инструкций для Cursor, нацеленный на быстрый код компьютерного зрения на Python. Правило запрещает циклы по пикселям и требует векторизации. ★ 3 580звёзд репо nuxt Правило для Cursor задаёт агенту стиль кода в Nuxt-проекте: структура каталогов, Composition API, Pinia, useFetch. Пригодится, если агент уже начал плодить миксины и onMounted вместо SSR-фетча. ★ 3 580звёзд репо numpy Правило заставляет Cursor генерировать векторизованный код NumPy без медленных циклов Python. Помогает писать быстрые модульные функции с явным указанием dtype. ★ 3 580звёзд репо numba Правило задаёт практики для Numba-кода на Python: CPU-ускорение, CUDA-ядра и работу с массивами. Пригодится для численных задач в .py. ★ 3 580звёзд репо notion-api Правило для Cursor задаёт, как писать код интеграций с Notion API: модули, токены в переменных окружения, официальные SDK и пагинация. ★ 3 580звёзд репо

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

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