How to Pick GPT-6.1 Sol Reasoning Effort for Each Task
Your team probably has a dial that can quietly multiply the output bill, and nobody owns it. GPT-6.1 Sol reasoning effort sets how much hidden thinking the model does before it answers, and you pay for that thinking. By the end of this guide you will have a default effort for each task class, the Responses API code to apply it, and a one-page policy your leads can sign.
What GPT-6.1 Sol reasoning effort controls
Sol takes five levels in reasoning.effort: low, medium (the default), high, xhigh and max. none and minimal are not supported, per the GPT-6.1 Sol model page.
Reasoning tokens never appear in the response, but they fill the context window and are billed as output tokens, according to OpenAI's reasoning guide. Sol costs $2 per million input tokens, $0.10 cached and $10 output, with a 1,050,000-token context window. Effort is therefore mostly an output decision, and output costs five times input.
Step 1: Sort tasks into classes and pick a starting effort
Start from OpenAI's guidance for each level, then let your own evals overrule it:
low: tool use, planning, search, data analysis, support chat.medium: most workloads, including agentic coding and research.high: hard reasoning, complex debugging, high-value work where quality beats latency.xhigh: deep research and long-running agentic work, only when evals show a clear benefit.max: the most complex tasks, only after you compare it againstxhigh.
Set effort per task class, not per engineer. Five or six classes cover most teams.
Step 2: Set the effort in a Responses API tool-calling loop
On Sol, tool calling works through the Responses API, not Chat Completions. This loop maps a task class to an effort, caps output and feeds tool results back, following the function calling guide.
import json
from openai import OpenAI
client = OpenAI()
EFFORT_BY_TASK = {
'support_triage': 'low',
'code_review': 'medium',
'incident_debugging': 'high',
}
TOOLS = [{
'type': 'function',
'name': 'get_ticket',
'description': 'Fetch a support ticket by ID.',
'parameters': {
'type': 'object',
'properties': {'ticket_id': {'type': 'string'}},
'required': ['ticket_id'],
'additionalProperties': False,
},
'strict': True,
}]
def run(task_class: str, prompt: str):
input_list = [{'role': 'user', 'content': prompt}]
while True:
response = client.responses.create(
model='gpt-6.1-sol',
reasoning={'effort': EFFORT_BY_TASK[task_class]},
max_output_tokens=25000,
tools=TOOLS,
input=input_list,
)
if response.status == 'incomplete':
raise RuntimeError(response.incomplete_details.reason)
input_list += response.output
calls = [item for item in response.output if item.type == 'function_call']
if not calls:
return response
for call in calls:
args = json.loads(call.arguments)
input_list.append({
'type': 'function_call_output',
'call_id': call.call_id,
'output': json.dumps(lookup_ticket(args['ticket_id'])),
})
lookup_ticket is your own function. max_output_tokens counts reasoning tokens too, so if the cap hits first you get an incomplete response and have paid for thinking with no answer. OpenAI suggests reserving at least 25,000 tokens while you experiment. Appending response.output also carries the reasoning items back, which the docs say to keep during tool calls.
Step 3: Judge effort by cost per accepted result
Cheapest per call is the wrong scoreboard. A level that fails and gets retried, or reviewed by a human, costs more than it looks. Divide total spend by the results that passed your own acceptance check: tests green, reviewer approves, customer does not reopen.
def cost_usd(usage) -> float:
details = usage.input_tokens_details
cached, written = details.cached_tokens, details.cache_write_tokens
uncached = usage.input_tokens - cached - written
long_prompt = usage.input_tokens > 272_000
in_mult, out_mult = (2.0, 1.5) if long_prompt else (1.0, 1.0)
return (
uncached * 2.00 * in_mult
+ cached * 0.10 * in_mult
+ written * 2.50 * in_mult
+ usage.output_tokens * 10.00 * out_mult # includes reasoning tokens
) / 1_000_000
The long-prompt branch follows the model page: over 272K input tokens, input and cache rates double and output is 1.5x for the whole request. The function ignores Fast, Batch, Flex and regional modifiers.
Replay about 50 real tasks per class at two neighboring levels. With toy numbers: if medium costs $0.09 per task and passes 70%, that is $0.129 per accepted result. If high costs $0.20 and passes 90%, it is $0.222. Medium wins, unless a failure costs you more than the gap. Log usage.output_tokens_details.reasoning_tokens as well to see where the money went.
Step 4: Escalate one hard step without breaking the cache
Instead of rerunning a whole conversation at high, add a configuration_update item before the next user message. Leave the request-level effort unchanged so the prompt prefix stays cacheable, as the reasoning guide describes.
input_list.append({
'type': 'configuration_update',
'reasoning': {'effort': 'high'},
})
input_list.append({'role': 'user', 'content': 'Find the root cause of the failing deploy.'})
The update holds until another one replaces it. The limits: GPT-6 family only, standard single-agent mode, no two updates back to back, and no automatic compaction or truncation alongside it.
Step 5: Write the one-page effort policy
Put the decisions where your leads can see and challenge them. This format is our own, not an OpenAI API.
# llm-effort-policy.yaml (team format, not an OpenAI API)
model: gpt-6.1-sol
owner: <engineering-lead>
review_every: quarter
unsupported_efforts: [none, minimal]
task_classes:
support_triage:
default: low
escalate_to: medium
accepted_when: customer does not reopen within 7 days
code_review:
default: medium
escalate_to: high
accepted_when: reviewer keeps the suggestion
incident_debugging:
default: high
escalate_to: xhigh
accepted_when: on-call confirms the root cause
xhigh_or_max_requires:
evidence: eval run comparing cost per accepted result with the level below
approver: <engineering-lead>
Re-run the Step 3 comparison each quarter, and whenever you change the prompt or the tools.
Gotchas
- If you omit the parameter you get
medium, so every unconfigured service is already making a policy decision for you. - Old
noneorminimalsettings are unsupported on Sol. OpenAI says to start withlowand compare results on representative tasks. - The response's
reasoning.effortreports the request-level setting, not aconfiguration_update, so log the effort you intended. - A prompt over 272K input tokens reprices the whole request, not just the overflow.
- Treat
xhighandmaxas exceptions that need eval evidence, not as a default for important work.
A written effort default per task class turns an invisible token bill into a decision someone can defend, which is what production AI spend needs.