|
| 1 | +--- |
| 2 | +title: "Choosing models" |
| 3 | +description: "Find the exact model IDs a provider offers your account, pick the adapter for its endpoint, and check a model before a sweep." |
| 4 | +--- |
| 5 | + |
| 6 | +behaviors takes a provider's model ID as given: it has no catalog of models, and it passes the |
| 7 | +string to the provider's endpoint without checking it against a list or translating it. Choose |
| 8 | +the provider and endpoint first, then get the exact model ID from that provider's listing API. |
| 9 | +Use the returned `id`, not a display name; the same model can have different IDs at different |
| 10 | +providers. When you've been asked for a particular model, keep it, and verify its ID rather than |
| 11 | +substituting another. |
| 12 | + |
| 13 | +The examples below use `curl` and `jq`, with API keys already set in the named environment |
| 14 | +variables. They only list model metadata. Use the same credentials and endpoint as the |
| 15 | +experiment, since a listing shows what that account can use. An authentication or permission |
| 16 | +error does not mean that no models exist. |
| 17 | + |
| 18 | +## OpenAI |
| 19 | + |
| 20 | +[List models](https://developers.openai.com/api/reference/resources/models/methods/list) |
| 21 | +with `GET https://api.openai.com/v1/models`: |
| 22 | + |
| 23 | +```bash |
| 24 | +curl --fail-with-body --silent --show-error https://api.openai.com/v1/models \ |
| 25 | + -H "Authorization: Bearer $OPENAI_API_KEY" \ |
| 26 | + -o /tmp/openai-models.json && |
| 27 | +jq -r '.data[].id' /tmp/openai-models.json | sort |
| 28 | +``` |
| 29 | + |
| 30 | +Use a returned ID with `OpenAIResponsesAPI(model_id)` for models supporting the Responses API, or |
| 31 | +`OpenAICompatibleAPI(model_id)` for Chat Completions. The listing includes models for other |
| 32 | +tasks too; check a model's supported endpoints and features in the |
| 33 | +[model catalog](https://developers.openai.com/api/docs/models) before choosing an adapter. |
| 34 | + |
| 35 | +## Anthropic |
| 36 | + |
| 37 | +[List models](https://platform.claude.com/docs/en/api/models/list) |
| 38 | +with `GET https://api.anthropic.com/v1/models`: |
| 39 | + |
| 40 | +```bash |
| 41 | +curl --fail-with-body --silent --show-error 'https://api.anthropic.com/v1/models?limit=1000' \ |
| 42 | + -H "x-api-key: $ANTHROPIC_API_KEY" \ |
| 43 | + -H 'anthropic-version: 2023-06-01' \ |
| 44 | + -o /tmp/anthropic-models.json && |
| 45 | +jq -r '.data[] | [.id, .display_name] | @tsv' /tmp/anthropic-models.json && |
| 46 | +jq '{has_more, last_id}' /tmp/anthropic-models.json |
| 47 | +``` |
| 48 | + |
| 49 | +This is one page, even with `limit=1000`. While `has_more` is true, request the next page with |
| 50 | +`after_id` set to the returned `last_id`, and collect its models before advancing again. |
| 51 | +Pass a returned `id` to `AnthropicMessagesAPI(model_id)`; `display_name` is only for presentation. |
| 52 | + |
| 53 | +## OpenRouter |
| 54 | + |
| 55 | +OpenRouter serves models from multiple vendors through an OpenAI-compatible endpoint. Its |
| 56 | +[general catalog API](https://openrouter.ai/docs/api/api-reference/models/list-all-models-and-their-properties) |
| 57 | +is `GET https://openrouter.ai/api/v1/models`; the |
| 58 | +[account-filtered listing](https://openrouter.ai/docs/api/api-reference/models/list-models-filtered-by-user-provider-preferences-privacy-settings-and-guardrails) |
| 59 | +also applies your provider preferences, privacy settings, and guardrails: |
| 60 | + |
| 61 | +```bash |
| 62 | +curl --fail-with-body --silent --show-error https://openrouter.ai/api/v1/models/user \ |
| 63 | + -H "Authorization: Bearer $OPENROUTER_API_KEY" \ |
| 64 | + -o /tmp/openrouter-models.json && |
| 65 | +jq -r '.data[] | [.id, .name] | @tsv' /tmp/openrouter-models.json |
| 66 | +``` |
| 67 | + |
| 68 | +For the general catalog, change `/models/user` to `/models`. The |
| 69 | +[model browser](https://openrouter.ai/models) is useful for interactive search. Inspect |
| 70 | +`architecture`, `context_length`, and `supported_parameters` in the JSON for candidate models. |
| 71 | +Use the full returned `id`, including its vendor prefix and any suffix, with: |
| 72 | + |
| 73 | +```python |
| 74 | +import os |
| 75 | + |
| 76 | +from behaviors.implementations.models.openai_compatible import OpenAICompatibleAPI |
| 77 | + |
| 78 | +api = OpenAICompatibleAPI( |
| 79 | + model_id, # Exact id selected from the OpenRouter listing. |
| 80 | + base_url="https://openrouter.ai/api/v1", |
| 81 | + api_key=os.environ["OPENROUTER_API_KEY"], |
| 82 | +) |
| 83 | +``` |
| 84 | + |
| 85 | +The OpenAI SDK does not read `OPENROUTER_API_KEY` by itself, so pass it explicitly as above. |
| 86 | +Close the adapter with `await api.aclose()` when finished, as in the |
| 87 | +[conversation step](language-models.mdx#a-conversation-as-a-step). |
| 88 | + |
| 89 | +## Search and validate a candidate |
| 90 | + |
| 91 | +Search a saved response by ID or display name, changing the file and search text as needed: |
| 92 | + |
| 93 | +```bash |
| 94 | +jq -r --arg query 'claude' ' |
| 95 | + .data[] |
| 96 | + | select(([.id, (.name // .display_name // "")] | join(" ") | ascii_downcase) |
| 97 | + | contains($query | ascii_downcase)) |
| 98 | + | .id |
| 99 | +' /tmp/openrouter-models.json |
| 100 | +``` |
| 101 | + |
| 102 | +For paginated responses, search every collected page. A catalog entry does not establish that |
| 103 | +the model supports every feature the experiment needs. Check its support for the endpoint, |
| 104 | +streaming, tools, and reasoning, then try the chosen adapter and sampling settings with a small |
| 105 | +request before launching a sweep. Without credentials, the providers' published catalogs and |
| 106 | +documentation give candidate IDs, but not whether your account can use them. |
| 107 | + |
| 108 | +Keep the chosen provider, model ID, and request settings in the experiment's configuration |
| 109 | +inputs, so that each run records what was selected (see |
| 110 | +[A conversation as a step](language-models.mdx#a-conversation-as-a-step)). |
0 commit comments