# Factory Droid 커스텀 모델 설정: 내 API 키로 Claude와 GPT 쓰기

> Factory Droid의 settings.json에 customModels를 더해 내 API 키로 Claude와 GPT를 쓰는 설정을 정리합니다.

- Canonical HTML: https://omniakey.com/ko/blog/factory-droid-custom-models
- Markdown: https://omniakey.com/ko/blog/factory-droid-custom-models.md
- Published: 2026-10-30 (updated 2026-10-30)
- Author: Kiki, COO at OmniaKey
- Language: ko
- Category: API setup
- Reading time: 9 min
- All posts: https://omniakey.com/blog/llms.txt

---

Droid 1.0.0에서는 커스텀 모델을 `~/.factory/settings.json`의 `customModels`에 적습니다. 항목마다 `model`, `baseUrl`, `apiKey`, `provider` 네 가지가 필요합니다. Claude는 `anthropic`에 호스트 이름만 넣고, GPT는 `openai`, 나머지는 `generic-chat-completion-api`를 씁니다. 같은 버그를 세 모델이 고쳤고 걸린 시간은 33.7초, 77.4초, 30.7초였습니다.

세 번 모두 OmniaKey의 같은 키로 실행했습니다. 쓴 모델은 [Claude Sonnet 5.5](https://omniakey.com/ko/claude-sonnet-5-5), [GPT-6.1 Terra](https://omniakey.com/ko/gpt-6-1-terra), [MiniMax M3.1 Flash](https://omniakey.com/ko/minimax-m3-1-flash)입니다. 셋 다 같은 망가진 `median()` 함수를 받았고, 셋 다 고쳤습니다.

## 먼저 결론

- **어디에 쓰나.** `~/.factory/settings.json`의 `customModels`입니다. 항목은 `model`, `baseUrl`, `apiKey`, `provider` 네 개입니다(Factory 설정 문서, 2026년 10월 30일 확인).
- **provider 선택.** Claude는 `anthropic`, GPT 모델은 `openai`, Chat Completions를 쓰는 나머지 모델은 `generic-chat-completion-api`입니다.
- **`/v1`을 붙이나.** `anthropic`은 호스트 이름만 넣습니다. Droid가 `/v1/messages`를 붙이기 때문입니다. `openai`와 `generic-chat-completion-api`는 `/v1`로 끝나는 URL을 넣습니다.
- **`droid exec`의 id.** `custom:` 뒤에 공백을 하이픈으로 바꾼 표시 이름, 그 뒤에 0부터 시작하는 위치를 붙입니다: `custom:Claude-Sonnet-5.5-[OmniaKey]-0`.
- **실행 결과.** 세 모델 모두 버그를 고쳤습니다. Flash 30.7초, Claude 33.7초, GPT-6.1 Terra 77.4초입니다.

## provider에는 어떤 값을 넣나

모델 이름이 아니라 엔드포인트가 쓰는 API로 고릅니다.

- `anthropic`은 Anthropic Messages API 요청을 보냅니다. Claude에 씁니다. Anthropic의 URL은 `https://api.anthropic.com`입니다.
- `openai`는 OpenAI Responses API 요청을 보냅니다. GPT 모델에 씁니다. OpenAI의 URL은 `https://api.openai.com/v1`입니다.
- `generic-chat-completion-api`는 OpenAI Chat Completions 요청을 보냅니다. 나머지 대부분의 모델과 게이트웨이, 로컬 서버에 쓰고 각 서비스의 `/v1` URL을 넣습니다.

Factory는 `generic-chat-completion-api`를 OpenRouter, Fireworks, Together AI, Ollama, vLLM과 대부분의 오픈소스 모델 서비스에 권합니다. OpenAI나 Anthropic 공식 API를 호출할 때를 빼면 이 값을 쓰라고 안내합니다(Factory의 BYOK 문서, 2026년 10월 30일 확인).

Messages API나 Responses API도 지원하는 게이트웨이라면 `anthropic`이나 `openai`를 쓸 수 있습니다. OmniaKey로 설정한 Claude와 GPT-6.1 Terra 항목이 그랬고, 둘 다 동작했습니다. OmniaKey의 GPT 모델은 `POST /v1/responses`로 제공합니다(OmniaKey의 OpenAI 호환 문서, 2026년 10월 30일 확인).

네 번째 값 `bedrock-converse`는 AWS Bedrock의 Converse API에 있는 모델용입니다. Factory는 공식 API를 쓰는 Anthropic과 OpenAI 모델만 충분한 테스트와 벤치마크를 거쳤다고 알립니다. 파라미터가 300억 개 미만인 모델은 에이전트 코딩 작업에서 눈에 띄게 나쁩니다(Factory의 BYOK 문서, 2026년 10월 30일 확인).

## 우리가 쓴 settings.json

Droid는 처음 실행할 때 `~/.factory/settings.json`을 만듭니다. 이미 있는 파일에 `customModels`를 더하면 됩니다(Factory 설정 문서, 2026년 10월 30일 확인). 저희 파일은 이렇습니다:

```json
{
  "customModels": [
    {
      "model": "claude-sonnet-5-5",
      "displayName": "Claude Sonnet 5.5 [OmniaKey]",
      "baseUrl": "https://api.omniakey.com",
      "apiKey": "${OMNIAKEY_API_KEY}",
      "provider": "anthropic",
      "maxOutputTokens": 16000
    },
    {
      "model": "gpt-6.1-terra",
      "displayName": "GPT-6.1 Terra [OmniaKey]",
      "baseUrl": "https://api.omniakey.com/v1",
      "apiKey": "${OMNIAKEY_API_KEY}",
      "provider": "openai",
      "maxOutputTokens": 16000
    },
    {
      "model": "minimax-m3.1-flash",
      "displayName": "MiniMax M3.1 Flash [OmniaKey]",
      "baseUrl": "https://api.omniakey.com/v1",
      "apiKey": "${OMNIAKEY_API_KEY}",
      "provider": "generic-chat-completion-api",
      "maxOutputTokens": 16000
    }
  ]
}
```

- `model`은 API로 보내는 id입니다. 서비스의 모델 목록에서 그대로 복사합니다. `displayName`은 직접 붙이는 이름으로, `/model`에 보이고 `custom:` id를 만들 때도 쓰입니다.
- `baseUrl`은 `anthropic`이면 호스트 이름만, 나머지 둘은 `/v1`로 끝납니다.
- `apiKey: "${OMNIAKEY_API_KEY}"`는 환경 변수에서 키를 읽습니다. 키가 파일에 남지 않습니다(Factory의 BYOK 문서, 2026년 10월 30일 확인).
- `provider`는 어떤 API를 쓸지 정합니다. 여기를 잘못 쓰면 아래 "Invalid provider" 오류가 납니다.
- `maxOutputTokens: 16000`은 답변 한 번의 길이를 제한합니다.

키 하나와 [접속 URL](https://docs.omniakey.com/en/api/overview) 두 개로 세 모델을 모두 쓸 수 있습니다. Claude는 OmniaKey의 호스트 이름 URL, 나머지 둘은 `/v1` URL입니다. [OmniaKey의 코딩 에이전트 설정 문서](https://docs.omniakey.com/en/coding)를 따라 설정했다면 같은 키를 그대로 쓰면 됩니다.

Factory는 키가 로컬에 남고 Factory 서버로 업로드되지 않는다고 설명합니다(Factory의 BYOK 문서, 2026년 10월 30일 확인). 예전 안내서는 모델을 `~/.factory/config.json`에 적었습니다. Factory의 BYOK 문서는 지금도 Droid가 시작할 때 이 파일을 `settings.json`으로 복사한다고 적고 있습니다. Factory 저장소의 pull request(#76)는 2026년 10월 15일에 병합된 변경으로 이 복사가 없어졌다고 밝힙니다. 새 모델은 `settings.json`에 바로 적으세요.

## Droid에서 커스텀 모델을 고르는 방법

앱에서는 `/model`을 열고 Custom Models 항목을 봅니다. 명령줄에서는 `droid exec`에 `custom:`으로 시작하는 id를 넘깁니다.

Factory 문서에 따르면 저장한 모델은 `displayName`과 함께 그곳에 나타납니다. `/settings` > Custom models에서 추가할 수도 있고 `/model` > Manage custom models에서도 추가할 수 있습니다(2026년 10월 30일 확인).

`droid exec`의 id는 세 부분입니다. `custom:`, 공백을 하이픈으로 바꾼 표시 이름, 그리고 `customModels`에서 0부터 세는 위치입니다(Factory의 `droid exec` 문서, 2026년 10월 30일 확인). 저희는 `custom:Claude-Sonnet-5.5-[OmniaKey]-0`, `custom:GPT-6.1-Terra-[OmniaKey]-1`, `custom:MiniMax-M3.1-Flash-[OmniaKey]-2`가 나왔습니다.

위치는 배열 순서를 따릅니다. 중간에 모델을 하나 끼우면 그 아래 id가 모두 밀립니다. 파일을 고친 뒤 id를 다시 복사하세요.

`droid exec`의 `-r` / `--reasoning-effort`는 커스텀 모델에 적용되지 않습니다(Factory의 `droid exec` 문서, 2026년 10월 30일 확인). 대신 항목에 `reasoningEffort`를 적으세요.

## 세 모델이 같은 버그를 고치다

같은 파일 두 개, 같은 명령, 모델마다 한 번씩 실행했습니다. `stats.py`:

```python
def median(values):
    """Return the median of a non-empty list of numbers."""
    ordered = sorted(values)
    mid = len(ordered) // 2
    return ordered[mid]
```

`test_stats.py`:

```python
from stats import median

assert median([3, 1, 2]) == 2
assert median([4, 1, 3, 2]) == 2.5
assert median([5]) == 5
assert median([1.5, 2.5]) == 2.0
print("all tests passed")
```

명령은 `--model` 값만 바꿨습니다:

```bash
droid exec --auto medium -o json --model "custom:Claude-Sonnet-5.5-[OmniaKey]-0" "python3 test_stats.py fails. Fix the bug in stats.py without changing the tests, run python3 test_stats.py again, and tell me in one sentence what you changed."
```

|모델|시간|턴|출력 토큰|
|-|-|-|-|
|Claude Sonnet 5.5|33.7 s|3|702|
|GPT-6.1 Terra|77.4 s|4|451|
|MiniMax M3.1 Flash|30.7 s|4|525|

숫자는 Droid가 직접 보고한 값입니다(`duration_ms`, `num_turns`, `output_tokens`). Flash가 30.7초로 가장 빨랐고, Claude는 턴 수가 가장 적었고, GPT-6.1 Terra는 77.4초로 가장 느렸습니다. 첫 토큰까지 걸린 시간은 Claude 8.7초, Terra 17.8초, Flash 7.0초입니다. 셋 다 `test_stats.py`를 건드리지 않고 버그를 고쳤고, 테스트는 `all tests passed`를 출력했습니다.

Claude의 변경:

```diff
-    return ordered[mid]
+    if len(ordered) % 2:
+        return ordered[mid]
+    return (ordered[mid - 1] + ordered[mid]) / 2
```

GPT-6.1 Terra는 기존 return 줄 위에 같은 분기를 넣었고, MiniMax M3.1 Flash는 `% 2 == 1`로 썼습니다. 세 답변 모두 같은 고침을 설명했습니다. 길이가 짝수일 때 가운데 두 값의 평균을 돌려주는 방식입니다. [MiniMax M3.1 Flash 리뷰](https://omniakey.com/ko/blog/minimax-m3-1-flash-review)에서 이 모델을 더 자세히 다룹니다.

Droid의 JSON 결과는 매번 `factory_credits`도 출력했습니다. 그런데 저희는 한 번도 로그인하지 않았습니다. 값은 Claude Sonnet 5.5가 31,534, GPT-6.1 Terra가 4,830, MiniMax M3.1 Flash가 835였습니다. 이 숫자가 무엇을 재는지, BYOK 한도와 어떻게 관계되는지는 Factory 문서에 없습니다(2026년 10월 30일 확인).

## Factory 계정이나 요금제가 필요한가

저희 실행에서는 `custom:` 모델을 쓰는 `droid exec`에 Factory 계정이 필요 없었습니다. Factory 자체 모델과 대화형 앱은 계정이 필요했습니다.

Droid CLI 1.0.0은 2026년 10월 29일에 나왔습니다(Factory 변경 기록, 2026년 10월 30일 확인). Factory에 로그인하지 않은 깨끗한 홈 폴더에서 `custom:` 모델을 쓴 `droid exec`는 모두 저희 키로 동작했습니다. 같은 명령에서 `--model`만 빼면 곧바로 멈추고 "Authentication failed. Please log in using /login or set a valid FACTORY\_API\_KEY environment variable."(인증에 실패했습니다. /login으로 로그인하거나 유효한 FACTORY\_API\_KEY 환경 변수를 설정하세요.)가 나왔습니다. Factory의 v0.236.0 변경 기록(2026년 10월 8일)에는 이렇게 적혀 있습니다: "Droid exec now resumes a session on your own model credentials without a Factory sign-in."(Droid exec는 Factory 로그인 없이도 내 모델 자격 정보로 세션을 이어갈 수 있습니다.)

같은 폴더에서 인자 없이 `droid`를 실행하면 "Please login with your Factory account to continue."(계속하려면 Factory 계정으로 로그인하세요.)에서 멈췄습니다. 로그인 없이는 대화형 앱과 데스크톱 앱에서 커스텀 모델을 써 볼 수 없었습니다. 이미지 입력, Bedrock, `apiKeyHelper`, `reasoningEffort`와 thinking 설정, Windows, 작업 하나보다 긴 세션, 예전 `config.json`은 시험하지 않았습니다.

Factory의 Individual 요금제는 월 $20(Pro), $100(Plus), $200(Max)입니다. 가격 페이지에는 팀 요금제도 있는데 팀당 월 $60에 좌석당 $40이 붙습니다. 개인용 무료 요금제는 없습니다(Factory 요금 문서와 가격 페이지, 2026년 10월 30일 확인).

Individual 요금 문서에는 이렇게 적혀 있습니다: "BYOK is free up to an allowance on all Individual plans. After that, usage is charged according to your specific plan."(BYOK는 모든 Individual 요금제에서 정해진 한도까지 무료이고, 그 뒤에는 이용 중인 요금제에 따라 과금됩니다.) Factory는 그 한도가 얼마인지, 초과 후 요금이 어떻게 매겨지는지는 밝히지 않습니다.

개인 커스텀 모델은 CLI와 데스크톱 앱에서 동작합니다. Factory가 운영하는 웹과 모바일 앱에는 나오지 않습니다(Factory의 BYOK 문서, 2026년 10월 30일 확인).

## 어떤 오류가 나고, 어떻게 고치나

모두 나머지는 정상인 설정에서 값 하나가 틀린 경우였습니다. 환경은 Droid 1.0.0입니다.

1. `anthropic`의 `baseUrl`에 `/v1`을 붙인 경우. Droid는 0.9초 뒤 "Requested model was not found on the API provider"(API 제공자에서 요청한 모델을 찾지 못했습니다)를 출력했고, 로그에는 `404`와 `Invalid URL (POST /v1/v1/messages)`가 남았습니다. Droid가 `/v1/messages`를 직접 붙이므로 저희가 넣은 `/v1`과 겹칩니다. 고치는 방법은 호스트 이름만 넣는 것입니다. `https://api.anthropic.com` 또는 `https://api.omniakey.com`입니다.

2. `openai`에 호스트 이름만 넣은 경우. 1.4초 뒤 Droid는 `404`와 nginx의 "404 Not Found" 페이지를 출력했습니다. Responses API는 `/v1` 아래에 있습니다. 고치는 방법은 `https://api.openai.com/v1` 또는 `https://api.omniakey.com/v1`입니다.

3. 모델 id에 점을 넣은 `claude-sonnet-5.5`를 쓴 경우. 맞는 표기는 `claude-sonnet-5-5`입니다. 엔드포인트는 `503`과 오류 코드 `model_not_found`를 돌려주고, 메시지는 "No available channel for model claude-sonnet-5.5"(이 모델을 처리할 채널이 없습니다)였습니다. Droid 로그는 실패마다 "overloaded"로 적고 259.7초(약 4분 20초) 동안 10번 시도한 뒤 끝났습니다. 문구는 게이트웨이 것이고, 재시도는 Droid가 한 것입니다. 고치는 방법은 서비스의 모델 목록에서 정확한 id를 복사하는 것입니다.

4. Droid를 실행한 셸에서 `OMNIAKEY_API_KEY`가 비어 있던 경우. 2.8초 뒤 Droid는 `401`과 "Invalid token"(토큰이 유효하지 않습니다)을 받았습니다. 고치는 방법은 `droid`를 실행하는 셸에서 키를 export하고 새 세션을 여는 것입니다.

Factory의 문제 해결 문서에는 두 가지가 더 있습니다. "Invalid provider"는 값의 철자나 대소문자가 다를 때 나오며, `anthropic`, `openai`, `generic-chat-completion-api`, `bedrock-converse` 중 하나와 정확히 같아야 합니다. 모델이 선택 목록에 없을 때는 `~/.factory/settings.json`의 JSON 문법을 보고 각 항목에 필수 필드가 있는지 확인하라고 안내합니다(2026년 10월 30일 확인).

## 자주 묻는 질문

### Windows에서 Droid 설정 파일은 어디에 있나?

`%USERPROFILE%\.factory\settings.json`입니다. macOS와 Linux의 `~/.factory/settings.json`과 같은 파일입니다(Factory 설정 문서, 2026년 10월 30일 확인). `customModels`를 여기에 적습니다.

### 커스텀 모델이 `/model`에 안 보이는 이유는?

먼저 `~/.factory/settings.json`의 JSON 문법을 보고, 다음으로 `model`, `baseUrl`, `provider` 필드를 봅니다. Droid는 파일 감시로 저장된 변경을 알아챕니다(Factory의 BYOK 문서, 2026년 10월 30일 확인). Desktop 0.184.0과 CLI 0.227.0 조합에서 커스텀 모델이 데스크톱 선택 목록에 잠깐 나타났다 사라지고, `droid exec --help`에는 14개가 모두 나왔다는 보고가 있었습니다. 그 이슈는 지금 닫혀 있습니다(Factory-AI issue #40, 2026년 10월 30일 확인).

### 커스텀 모델이 이미지를 읽을 수 있나?

`anthropic`과 `openai`는 기본으로 켜져 있고, `generic-chat-completion-api`는 기본으로 꺼져 있습니다. `noImageSupport`의 기본값이 `true`입니다(Factory의 BYOK 문서, 2026년 10월 30일 확인). generic 항목에서 `noImageSupport: false`로 두면 켜집니다. CLI v0.205.1에서 그렇게 설정해도 이미지가 빠졌다는 보고가 한 건 있었습니다(Factory-AI issue #24, 2026년 10월 30일 확인).

### 커스텀 모델에 reasoning effort를 설정할 수 있나?

`droid exec`의 `-r` / `--reasoning-effort`는 커스텀 모델에 적용되지 않습니다. 항목에 `reasoningEffort`를 적으세요. Droid가 모르는 모델의 기본 강도를 정하고 선택 목록에 off, low, medium, high를 더합니다(Factory의 BYOK 문서, 2026년 10월 30일 확인).

### 데스크톱 Droid 앱에서도 커스텀 모델을 쓸 수 있나?

됩니다. 개인 커스텀 모델은 CLI와 데스크톱 앱에서 쓸 수 있고, Factory가 운영하는 웹과 모바일 앱에는 나오지 않습니다. CLI와 데스크톱 앱의 모델 편집기는 모두 `~/.factory/settings.json`에 저장합니다(Factory의 BYOK 문서, 2026년 10월 30일 확인).

## 확인한 출처

- [Factory BYOK 문서](https://docs.factory.com/model-independence/byok.md), 2026년 10월 30일 확인
- [Factory 설정 문서](https://docs.factory.com/droid-cli/settings.md), 2026년 10월 30일 확인
- [Factory droid exec 문서](https://docs.factory.com/droid-exec/overview.md), 2026년 10월 30일 확인
- [Factory 릴리스 노트](https://docs.factory.com/changelog/release-notes.md), 2026년 10월 30일 확인
- [Factory Individual 요금제](https://docs.factory.com/pricing/individuals.md), 2026년 10월 30일 확인
- [Factory 가격](https://factory.com/pricing), 2026년 10월 30일 확인
- [Factory-AI issue #40: 데스크톱 선택 목록에서 커스텀 모델이 사라짐](https://github.com/Factory-AI/factory/issues/40), 2026년 10월 30일 확인
- [Factory-AI issue #24: 이미지가 빠짐](https://github.com/Factory-AI/factory/issues/24), 2026년 10월 30일 확인
- [Factory-AI pull request #76: config.json 마이그레이션](https://github.com/Factory-AI/factory/pull/76), 2026년 10월 30일 확인

OmniaKey 자체 문서(2026년 10월 30일 확인): [API 개요](https://docs.omniakey.com/en/api/overview), [OpenAI 호환 API](https://docs.omniakey.com/en/api/openai-compatible).
