# GPT-6.1 Terra vs GPT-6.1 Sol: Which to Choose for Work, Code, and API

> AI Release · @ai_release1 · https://ai-release.org/guides/gpt-6-1-terra-ili-gpt-6-1-sol-chto-vybrat-dlya-raboty-k_en.html

## TL;DR

- Time to complete: 45 minutes
- Difficulty level: Intermediate
- You will need: macOS 13+/Windows 11/Ubuntu 22.04 with a terminal, Python 3.10+, `pip install openai`, `curl`, `jq`, an OpenAI API key with access to both model strings, ~1 GB free disk

- The two source posts publish **no price and no speed figures** for GPT-6.1 Terra, so the only honest way to choose is to measure both models on your own task before you commit a budget.
- Terra is positioned as a **desktop-app agent**: OpenAI scores it on OSWorld 2.1, a benchmark where the model has to perform multi-step tasks inside ordinary applications (the published example is assembling a 3D model from a technical drawing).
- GPT-6.1 Sol is the model our channel covers for **API work, automation scenarios and cost/access** — see the [full GPT-6.1 Sol overview](https://ai-release.org/guides/gpt-6-1-sol-polnyy-obzor.html?utm_source=tg&utm_medium=channel&utm_campaign=guide_inline&utm_content=guide_to_guide).
- Keep both model strings in environment variables: the switch between Terra and Sol then costs one line of code, not a refactor.

## Requirements and setup
![Illustration: Requirements and setup](https://ai-release.org/guides/img/gpt-6-1-terra-ili-gpt-6-1-sol-chto-vybrat-dlya-raboty-k-en-1.jpg?v=1794645955)


- Operating system: macOS 13+, Windows 11, or Ubuntu 22.04 with a POSIX shell.
- Python 3.10 or newer with `pip`.
- The official OpenAI SDK: `pip install --upgrade openai`.
- An API key whose account has access to **both** models. The GPT-6.1 Terra announcement at `openai.com/index/introducing-gpt-6-1-terra/` does not publish an API model string — take the exact strings from your account dashboard or the docs, and do not guess them.
- `curl` and `jq` for the account check below.
- One real input file from your own workflow (for example `tasks/task_01.txt`) — a benchmark on someone else's prompt tells you nothing about your job.

Prepare the workspace and the checklist:

```bash
mkdir -p gpt61-pick/{tasks,results} && cd gpt61-pick
python3 --version && jq --version && curl --version | head -1
```

Expected output — three lines, versions only, no errors:

```
Python 3.10.13
jq-1.7.1
curl 8.5.0
```

- [ ] `python3 --version` prints 3.10 or higher
- [ ] `pip show openai` returns a package entry
- [ ] Your API key is exported as `OPENAI_API_KEY`
- [ ] Both model strings are written down from the docs, not from memory
- [ ] `tasks/task_01.txt` contains a real task from your workflow
- [ ] `results/` exists and is writable

Confirm that your key actually sees both models before writing any code — this is the step most people skip and then spend an hour debugging a 404:

```bash
curl -s https://api.openai.com/v1/models \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  | jq -r '.data[].id' | sort | grep -iE 'sol|terra'
```

**Example:** if your account has both, you see two lines — one containing `sol`, one containing `terra`. An empty result means the key or the plan is wrong, not the script.

**Why this works:** `/v1/models` lists the model strings your key is allowed to call, so it separates "I typed the name wrong" from "my account has no access" in one command.

## Step 1. Write the two-model harness and capture one baseline per model

**What to do:** create one `.env`, one prompt file per task class, and one script that sends the identical prompt to both models and writes a JSON record for each.

**Why:** a comparison only means something if the prompt, temperature settings and machine are identical. A harness enforces that and gives you timings you can re-run later.

Create `.env`:

```bash
OPENAI_API_KEY="sk-..."
SOL_MODEL="<model-string-from-docs-for-sol>"
TERRA_MODEL="<model-string-from-docs-for-terra>"
```

The two `<…>` values are placeholders: replace each with the exact string your dashboard shows. The Terra announcement page publishes none, so do not invent one.

Create `bench.py`:

```python
import json, os, time
from pathlib import Path
from openai import OpenAI

client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
MODELS = {"sol": os.environ["SOL_MODEL"], "terra": os.environ["TERRA_MODEL"]}
PROMPT = Path("tasks/task_01.txt").read_text()

for key, model in MODELS.items():
    t0 = time.perf_counter()
    try:
        # If the docs specify a different endpoint or a reasoning setting
        # (the Terra description mentions a "medium reasoning" mode),
        # change only this call — the measurement stays valid.
        r = client.chat.completions.create(
            model=model,
            messages=[{"role": "user", "content": PROMPT}],
        )
        out = r.choices[0].message.content
    except Exception as e:
        out = f"ERROR: {type(e).__name__}: {e}"
    dt = time.perf_counter() - t0
    rec = {"model_key": key, "model": model,
           "seconds": round(dt, 2), "chars": len(out), "output": out}
    Path(f"results/{key}.json").write_text(json.dumps(rec, indent=2, ensure_ascii=False))
    print(f"{key:6s} {dt:6.2f}s chars={len(out)}")
```

**How to check:** load the environment, then run it.

```bash
set -a; source .env; set +a
python bench.py
ls -l results/
```

Expected screen output — two lines, one per model, plus two files:

```
sol     4.12s chars=1830
terra  11.87s chars=2140
-rw-r--r-- 1 user staff  4211 results/sol.json
-rw-r--r-- 1 user staff  4870 results/terra.json
```

The seconds above are what your own run prints, not a published benchmark: OpenAI published no speed figures for Terra in the announcement.

**Why this works:** both calls read from the same `task_01.txt` and the same process, so the only variable left is the model itself.

## Step 2. Route each task class to Terra or Sol
![Illustration: Step 2. Route each task class to Terra or Sol](https://ai-release.org/guides/img/gpt-6-1-terra-ili-gpt-6-1-sol-chto-vybrat-dlya-raboty-k-en-2.jpg?v=1794645963)


**What to do:** decide per **task class**, not per model, and encode the decision in one dictionary. Then pick the right execution path: API for text-shaped work, desktop product for GUI work.

**Why:** Terra is announced around OSWorld 2.1 — an agent that must drive normal desktop applications through several steps. A single API prompt cannot exercise that. Sol is what our channel's API and automation guides cover (text processing, service integration). Mixing the two up produces a "bad" benchmark that only reflects the wrong execution path.

| Model | What differs (per the source posts) | Price |
|---|---|---|
| GPT-6.1 Terra | OpenAI's desktop-agent model, announced at `openai.com/index/introducing-gpt-6-1-terra/`; scored on OSWorld 2.1 with multi-step tasks in desktop apps (example: build a 3D model from a technical drawing); a "medium reasoning" mode is mentioned | Not published in the announcement — check the docs |
| GPT-6.1 Sol | Covered by our API how-to, automation-scenarios guide, pricing/access guide, and a Sol-vs-GPT-4o comparison | Not stated in these posts — see the [Sol overview](https://ai-release.org/guides/gpt-6-1-sol-polnyy-obzor.html?utm_source=tg&utm_medium=channel&utm_campaign=guide_inline&utm_content=guide_to_guide) |

Routing table for the code:

```python
import os
from openai import OpenAI

client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])

ROUTES = {
    "desktop_multi_step":  os.environ["TERRA_MODEL"],  # GUI tasks, OSWorld 2.1 style
    "text_batch":          os.environ["SOL_MODEL"],    # text processing
    "service_integration": os.environ["SOL_MODEL"],    # calls into your services
    "code_task":           os.environ["SOL_MODEL"],    # unverified, measure first
}

def run(task_class: str, prompt: str) -> str:
    model = ROUTES[task_class]
    r = client.chat.completions.create(
        model=model,
        messages=[{"role": "user", "content": prompt}],
    )
    return r.choices[0].message.content

print(run("text_batch", "Summarise tasks/task_01.txt in 5 bullets."))
```

**Example:** run `python routes.py` and you get a five-bullet summary back, produced by whichever string sits in `SOL_MODEL`. Change one line in `ROUTES` and the same call goes to Terra — no other edit.

**Where this does NOT work:** if your task is "open the CAD app, read the drawing, place the parts", the API harness cannot score it. Run that task in the desktop product and keep the API numbers for text-shaped work only. If you are still choosing the surrounding stack for agent runs, compare the workflow options in [Jujutsu or Git for AI agent workflows](https://ai-release.org/guides/jujutsu-ili-git-chto-vybrat-dlya-raboty-s-ii-agentami-i.html?utm_source=tg&utm_medium=channel&utm_campaign=guide_inline&utm_content=guide_to_guide) and the model-selection article [GPT-6 Astra vs GPT-6.1 Sol](https://ai-release.org/guides/gpt-6-astra-ili-gpt-6-1-sol-chto-vybrat-dlya-raboty-cha.html?utm_source=tg&utm_medium=channel&utm_campaign=guide_inline&utm_content=guide_to_guide).

**Why this works:** the model string lives in exactly one place, so an A/B switch is a one-token change and your logs keep the `model_key` label.

## Step 3. Aggregate the runs, compare, and lock the decision
![Illustration: Step 3. Aggregate the runs, compare, and lock the decision](https://ai-release.org/guides/img/gpt-6-1-terra-ili-gpt-6-1-sol-chto-vybrat-dlya-raboty-k-en-3.jpg?v=1794645969)


**What to do:** repeat the harness over 5–10 real tasks per class, aggregate with `jq`, then write the decision down.

**Why:** one run is noise. A written decision log stops the team from re-litigating the choice every sprint.

```bash
jq -s 'map({model_key, seconds, chars})' results/*.json
```

**Example output from your own run:**

```
[
  { "model_key": "sol",   "seconds": 4.12, "chars": 1830 },
  { "model_key": "terra", "seconds": 11.87, "chars": 2140 }
]
```

Success looks like this:

- [ ] Each model produced 5–10 recorded runs per task class
- [ ] No `ERROR:` string inside any `results/*.json`
- [ ] Quality judged blind: rename files to `a.json` / `b.json` before scoring so the model name does not bias you
- [ ] A cost line in your decision log, filled from your account's billing page, not from an announcement
- [ ] `ROUTES` committed with a comment naming the date of the last measurement

**Why this works:** `jq -s` merges all result files into one array, so time and output size sit side by side and you compare like with like.

## Troubleshooting

**Problem. One of the two calls returns 404 while the other works.**
- Error: `openai.NotFoundError: Error code: 404 - The model '<your-model-string>' does not exist or you do not have access to it.`
- Cause: the Terra announcement page publishes no API model string, so a guessed name fails; or the key's plan does not include that model.
- Solution: run the `/v1/models` check from Requirements. Still empty? Keep Sol on the API path and perform Terra's GUI tasks in the desktop product. Fix the string in `.env`, then re-run `python bench.py`.

**Problem. The script crashes before any request is sent.**
- Error: `KeyError: 'TERRA_MODEL'`
- Cause: `.env` was never loaded into the shell, so `os.environ` has no entry.
- Solution: load it and confirm, then re-run.
```bash
set -a; source .env; set +a
python -c "import os; print(os.environ['TERRA_MODEL'])"
```
On PowerShell, set `$env:SOL_MODEL` and `$env:TERRA_MODEL` in the session instead.

**Problem. The second model in the loop fails immediately.**
- Error: `openai.RateLimitError: Error code: 429 - Rate limit reached for requests`
- Cause: both calls fire back to back and hit your organisation's request limit.
- Solution: add a retry with backoff around the call, and run the loop sequentially.
```python
import time
for attempt in range(4):
    try:
        r = client.chat.completions.create(model=model, messages=[{"role": "user", "content": PROMPT}])
        break
    except Exception:
        time.sleep(2 ** attempt)
```

## Summary and next steps

Run one identical prompt through GPT-6.1 Sol and GPT-6.1 Terra with the harness above, keep both model strings in `.env`, and route per task class — API work to Sol, multi-step desktop-app work to Terra. Next, repeat the measurement on ten real tasks and record the winning route with the date, since no price or speed figure for Terra was published in the announcement.

## FAQ

**Is GPT-6.1 Terra better than GPT-6.1 Sol for coding?**
Not answerable from the source posts: neither the Terra announcement nor our Sol guides publish a code-specific benchmark, and Terra's published evaluation is OSWorld 2.1 desktop tasks. Put your own repo task into `tasks/task_01.txt` and measure both.

**How much does GPT-6.1 Terra cost?**
The announcement publishes no price and no country list — it only describes the OSWorld 2.1 evaluation and a mention of a "medium reasoning" mode. Take the current figure from your account's pricing page or the docs.

**Which model should I use for desktop automation?**
Terra, because that is the capability OpenAI chose to demonstrate: multi-step tasks inside ordinary desktop applications, such as assembling a 3D model from a technical drawing. For text batches and service integrations, route to Sol.

**Do I need to rewrite my code to switch models?**
No. With the `ROUTES` dictionary and the two environment variables, switching is a one-line change; only the execution path differs when a task is GUI-driven and has to run in the desktop product instead of the API.
