How to Fine-Tune LLM Parameters for Specific Providers Like OpenAI and Gemini

Fine-tune LLM parameters in Prompt-Optimizer by declaring provider-specific values in the llmParams configuration object, which each provider's adapter class translates into native API fields for OpenAI, Gemini, and other supported vendors.

The Prompt-Optimizer repository abstracts LLM interactions through a flexible adapter pattern that normalizes provider-specific APIs. To fine-tune LLM parameters for specific providers, you populate the llmParams field in your model configuration, allowing the OpenAIAdapter or GeminiAdapter to map generic keys to provider-native request payloads.

Understanding the Adapter Architecture

The system routes all LLM requests through provider-specific adapter classes located in packages/core/src/services/llm/adapters/. Each adapter extends the base AbstractAdapter class defined in abstract-adapter.ts and implements the applyOverrides method to transform generic configuration into vendor-specific API calls.

  • OpenAIAdapter (openai-adapter.ts): Maps llmParams to OpenAI's chat completions format.
  • GeminiAdapter (gemini-adapter.ts): Translates parameters into the Gemini SDK's request structure.

These adapters consume a standardized model configuration object and extract the llmParams record to build the final HTTP request payload.

Configuring the llmParams Object

All model definitions in Prompt-Optimizer follow the interface defined in packages/core/src/services/model/types.ts. The optional llmParams field accepts a free-form key-value map that persists across the application layer until the adapter transforms it.

{
  "name": "Production GPT-4o",
  "providerId": "openai",
  "modelName": "gpt-4o-mini",
  "llmParams": {
    "temperature": 0.7,
    "maxTokens": 2048,
    "topP": 0.9
  }
}

The repository passes this object unchanged through the validation layer before handing it to the provider-specific adapter for translation.

OpenAI-Specific Parameter Mapping

When targeting OpenAI models, the OpenAIAdapter maps the following llmParams keys to OpenAI API fields:

  • temperature → temperature (0–2 float)
  • maxTokens → max_tokens (integer, 1–8192)
  • topP → top_p (0–1 float)
  • presencePenalty → presence_penalty (-2 to 2)
  • frequencyPenalty → frequency_penalty (-2 to 2)
  • stop → stop (string or array of strings)

The adapter extracts these values in packages/core/src/services/llm/adapters/openai-adapter.ts and constructs the JSON payload sent to the OpenAI chat completions endpoint.

OpenAI Configuration Example

import { createTextModelConfig } from '@/services/model/factory';

const openaiModel = createTextModelConfig(
  'GPT-4o Config',
  'OpenAI',
  true,
  process.env.VITE_OPENAI_API_KEY!,
  'openai',
  {
    model: 'gpt-4o-mini',
    llmParams: {
      temperature: 0.6,
      maxTokens: 1500,
      topP: 0.9,
      presencePenalty: 0.1,
      frequencyPenalty: 0.0,
      stop: ['\n\n']
    }
  }
);

Gemini-Specific Parameter Mapping

The Gemini API uses distinct field names and supports unique parameters for candidate generation and safety filtering. The GeminiAdapter handles the following mappings:

  • temperature → temperature (0–2 float)
  • maxOutputTokens → max_output_tokens (integer, 1–8192) — Note: Use maxOutputTokens for Gemini instead of maxTokens
  • candidateCount → candidate_count (1–5) — Number of parallel completions to generate
  • topP → top_p (0–1 float)
  • stopSequences → stop_sequences (array of strings)
  • safetySettings → safety_settings (object)

These translations occur in packages/core/src/services/llm/adapters/gemini-adapter.ts, where the adapter reads the generic keys and builds the Gemini-specific request body.

Gemini Configuration Example

import { createTextModelConfig } from '@/services/model/factory';

const geminiModel = createTextModelConfig(
  'Gemini Flash Config',
  'Google Gemini',
  true,
  process.env.VITE_GEMINI_API_KEY!,
  'gemini',
  {
    model: 'gemini-1.5-flash',
    llmParams: {
      temperature: 0.7,
      maxOutputTokens: 1024,
      candidateCount: 1,
      topP: 0.95,
      stopSequences: ['\n---']
    }
  }
);

Validation and Parameter Safety

Before any adapter processes the request, the validation service in packages/core/src/services/model/validation.ts sanitizes the llmParams object against provider-specific whitelists defined in advancedParameterDefinitions.ts.

The validateLlmParams function performs three checks:

  1. Verifies every key exists in the provider's parameter whitelist
  2. Validates type safety (e.g., ensuring temperature is a number)
  3. Enforces range constraints (e.g., 0–2 for temperature)

Unknown keys are rejected with errors surfaced in the UI through localization files in packages/ui/src/i18n/locales/. This prevents invalid parameters from reaching the provider API and wasting tokens.

Runtime Configuration Updates

The Vue-based UI layer exposes these parameters through the Model Settings panel implemented in packages/ui/src/components/ModelSettings.vue. When you adjust sliders or input fields in the interface, the component serializes the form data into the same llmParams structure, runs synchronous validation, and commits the updated configuration to the model store.

This allows you to fine-tune LLM parameters dynamically without restarting the application or editing configuration files directly.

Summary

  • Fine-tune LLM parameters by populating the llmParams object in your model configuration.
  • Provider adapters in packages/core/src/services/llm/adapters/ translate generic keys to native API fields.
  • OpenAI uses maxTokens, while Gemini requires maxOutputTokens for token limits.
  • The validation layer in validation.ts whitelists parameters and enforces type safety before API transmission.
  • Adjust parameters at runtime through the Model Settings UI component.

Frequently Asked Questions

What is the difference between maxTokens and maxOutputTokens?

maxTokens is the OpenAI-specific parameter controlling response length, mapped to max_tokens in the API. maxOutputTokens is the Gemini-specific equivalent mapped to max_output_tokens. The GeminiAdapter ignores maxTokens if you mistakenly use the OpenAI convention, so you must use provider-specific keys as defined in advancedParameterDefinitions.ts to ensure the limits apply correctly.

How does Prompt-Optimizer prevent invalid parameters from reaching the API?

The validateLlmParams function in packages/core/src/services/model/validation.ts checks every key in llmParams against a provider-specific whitelist imported from advancedParameterDefinitions.ts. If you include an unsupported parameter like candidateCount in an OpenAI configuration, the validator rejects the request before the OpenAIAdapter processes it, displaying an error in the UI.

Can I use the same parameter set for multiple providers?

No, you should define provider-specific llmParams for each model configuration. While some parameters like temperature and topP share names across providers, others like maxOutputTokens (Gemini) versus maxTokens (OpenAI) or candidateCount (Gemini only) are vendor-specific. The adapter architecture expects you to declare the correct keys for each providerId.

Where do I add support for a new LLM provider's parameters?

To extend support for a new provider, add the parameter whitelist to packages/core/src/services/model/advancedParameterDefinitions.ts, then implement a new adapter class in packages/core/src/services/llm/adapters/ following the pattern in openai-adapter.ts. The adapter should extract values from llmParams and map them to the new provider's SDK or REST API fields.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →