Systems Library / AI Model Setup / How to Create Temperature and Parameter Presets
AI Model Setup advanced

How to Create Temperature and Parameter Presets

Optimize model parameters for different tasks: creative, analytical, and factual.

Jay Banlasan

Jay Banlasan

The AI Systems Guy

Most people use the same AI parameters for every task. Temperature 0.7, max tokens 1000, done. That is leaving real quality on the table. The parameters that make a creative brainstorm session excellent will make a data extraction task unreliable. The settings that produce tight, factual summaries will make creative writing feel robotic. I use parameter presets matched to task types, and the quality difference is immediately obvious.

Temperature is the most important lever but not the only one. Top-p, frequency penalty, and presence penalty each affect output in measurable ways. Understanding what each does lets you dial in exactly the right behavior for each use case.

What You Need Before Starting

Step 1: Understand What Each Parameter Does

Before writing code, understand the controls:

"""
TEMPERATURE (0.0 - 2.0):
- 0.0: Fully deterministic. Same input = same output every time.
- 0.1-0.3: Highly consistent. Small variations. Best for: extraction, classification, factual Q&A.
- 0.5-0.7: Balanced. Good variation without chaos. Best for: summaries, explanations, general writing.
- 0.8-1.2: Creative and varied. Different outputs per run. Best for: brainstorming, creative writing, ideas.
- 1.3+: Increasingly random. Often degrades quality. Use only for specific creative tasks.

TOP_P (0.0 - 1.0) - nucleus sampling:
- Controls vocabulary diversity independently of temperature.
- 0.1: Only top 10% probability tokens. Very conservative.
- 0.9: Standard. Most common default.
- 1.0: Full vocabulary available.
- Lower top_p + low temperature = extremely predictable outputs.

FREQUENCY_PENALTY (-2.0 - 2.0):
- Positive values penalize tokens that have already appeared based on frequency.
- 0.5-1.0: Reduces word repetition in long outputs. Good for reports and documents.
- 0.0: No penalty. Normal behavior.

PRESENCE_PENALTY (-2.0 - 2.0):
- Positive values penalize any token that has appeared at all (regardless of count).
- 0.5-1.0: Encourages topic diversity. Good for brainstorming multiple angles.
- 0.0: No penalty. Normal behavior.

MAX_TOKENS:
- Hard limit on output length.
- Set to what you actually need plus 20% buffer.
- Too low = truncated outputs. Too high = wasted costs.
"""

Step 2: Define Your Task Presets

from dataclasses import dataclass
from typing import Optional

@dataclass
class ParameterPreset:
    name: str
    temperature: float
    max_tokens: int
    top_p: float = 1.0
    frequency_penalty: float = 0.0
    presence_penalty: float = 0.0
    description: str = ""

PRESETS = {
    # Factual, deterministic tasks
    "extraction": ParameterPreset(
        name="extraction",
        temperature=0.0,
        max_tokens=1000,
        top_p=0.9,
        description="Data extraction, classification, structured output. Zero variance."
    ),

    "factual_qa": ParameterPreset(
        name="factual_qa",
        temperature=0.1,
        max_tokens=500,
        top_p=0.9,
        description="FAQ answers, documentation Q&A. Consistent with slight variation."
    ),

    "summarization": ParameterPreset(
        name="summarization",
        temperature=0.2,
        max_tokens=800,
        top_p=0.95,
        frequency_penalty=0.3,
        description="Document summaries. Low variance, reduced repetition."
    ),

    # Balanced tasks
    "support_response": ParameterPreset(
        name="support_response",
        temperature=0.4,
        max_tokens=400,
        top_p=0.9,
        frequency_penalty=0.1,
        description="Customer support. Natural but consistent. Not robotic."
    ),

    "content_writing": ParameterPreset(
        name="content_writing",
        temperature=0.6,
        max_tokens=1500,
        top_p=0.95,
        frequency_penalty=0.4,
        presence_penalty=0.2,
        description="Blog posts, articles, emails. Natural writing, varied vocabulary."
    ),

    # Creative tasks
    "brainstorming": ParameterPreset(
        name="brainstorming",
        temperature=0.9,
        max_tokens=2000,
        top_p=1.0,
        presence_penalty=0.6,
        description="Idea generation, angles, concepts. Maximum variety per run."
    ),

    "ad_copy": ParameterPreset(
        name="ad_copy",
        temperature=0.8,
        max_tokens=600,
        top_p=1.0,
        presence_penalty=0.5,
        frequency_penalty=0.3,
        description="Ad hooks, headlines, creative copy. Varied, energetic."
    ),

    "code_generation": ParameterPreset(
        name="code_generation",
        temperature=0.1,
        max_tokens=2000,
        top_p=0.95,
        description="Code writing. Low temperature for logical consistency."
    ),
}

Step 3: Build a Preset-Aware Completion Function

import openai

client = openai.OpenAI(api_key="YOUR_API_KEY")

def complete(
    messages: list,
    task_type: str = "factual_qa",
    model: str = "gpt-4o-mini",
    preset_overrides: dict = None
) -> dict:
    preset = PRESETS.get(task_type, PRESETS["factual_qa"])

    params = {
        "temperature": preset.temperature,
        "max_tokens": preset.max_tokens,
        "top_p": preset.top_p,
        "frequency_penalty": preset.frequency_penalty,
        "presence_penalty": preset.presence_penalty,
    }

    if preset_overrides:
        params.update(preset_overrides)

    response = client.chat.completions.create(
        model=model,
        messages=messages,
        **params
    )

    return {
        "content": response.choices[0].message.content,
        "preset_used": task_type,
        "params": params,
        "tokens_used": response.usage.total_tokens
    }

# Usage
result = complete(
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Extract all dates from this document: The contract starts March 1, 2024 and expires December 31, 2025. Payment due January 15, 2024."}
    ],
    task_type="extraction"
)
print(result["content"])

Step 4: Build a Preset Comparison Tool

Test your presets against the same input to see the difference.

def compare_presets(
    messages: list,
    preset_names: list[str],
    model: str = "gpt-4o-mini"
) -> dict:
    results = {}

    for preset_name in preset_names:
        print(f"Running preset: {preset_name}...")
        result = complete(messages, task_type=preset_name, model=model)
        results[preset_name] = {
            "output": result["content"],
            "tokens": result["tokens_used"],
            "params": result["params"]
        }

    return results

# Compare extraction vs brainstorming on the same task
test_messages = [
    {"role": "system", "content": "Generate 5 marketing angles for a productivity app that saves teams 2 hours per day."},
    {"role": "user", "content": "Give me 5 distinct angles."}
]

comparison = compare_presets(test_messages, ["brainstorming", "content_writing", "factual_qa"])
for preset, result in comparison.items():
    print(f"\n=== {preset.upper()} ===")
    print(result["output"][:300])

Step 5: Auto-Detect Task Type from Content

Automatically select the right preset based on the input and system prompt.

TASK_CLASSIFIER_PROMPT = """Classify this AI task into one of these categories:
extraction, factual_qa, summarization, support_response, content_writing, brainstorming, ad_copy, code_generation

Return ONLY the category name. One word."""

def auto_detect_task_type(messages: list) -> str:
    # Build a description of the task from the messages
    task_description = ""
    for msg in messages:
        if msg["role"] in {"system", "user"}:
            task_description += f"{msg['role'].upper()}: {msg['content'][:200]}\n"

    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": TASK_CLASSIFIER_PROMPT},
            {"role": "user", "content": task_description}
        ],
        temperature=0,
        max_tokens=10
    )

    detected = response.choices[0].message.content.strip().lower()
    return detected if detected in PRESETS else "factual_qa"

def smart_complete(messages: list, model: str = "gpt-4o-mini") -> dict:
    task_type = auto_detect_task_type(messages)
    result = complete(messages, task_type=task_type, model=model)
    result["auto_detected_task"] = task_type
    return result

Step 6: Save Custom Presets for Your Use Case

import json
from pathlib import Path

CUSTOM_PRESETS_PATH = Path("./custom_presets.json")

def save_custom_preset(name: str, preset: ParameterPreset):
    existing = {}
    if CUSTOM_PRESETS_PATH.exists():
        existing = json.loads(CUSTOM_PRESETS_PATH.read_text())

    existing[name] = {
        "temperature": preset.temperature,
        "max_tokens": preset.max_tokens,
        "top_p": preset.top_p,
        "frequency_penalty": preset.frequency_penalty,
        "presence_penalty": preset.presence_penalty,
        "description": preset.description
    }
    CUSTOM_PRESETS_PATH.write_text(json.dumps(existing, indent=2))
    print(f"Preset '{name}' saved.")

def load_custom_presets():
    if not CUSTOM_PRESETS_PATH.exists():
        return
    data = json.loads(CUSTOM_PRESETS_PATH.read_text())
    for name, config in data.items():
        PRESETS[name] = ParameterPreset(name=name, **config)

load_custom_presets()

# Save a domain-specific preset
save_custom_preset("legal_review", ParameterPreset(
    name="legal_review",
    temperature=0.0,
    max_tokens=2000,
    top_p=0.9,
    description="Contract review, legal analysis. Zero variance required."
))

What to Build Next

Related Reading

Want this system built for your business?

Get a free assessment. We will map every system your business needs and show you the ROI.

Get Your Free Assessment

Related Systems