# OpenCode에서 MiniMax M3.1 Flash 사용하기: 설정과 도구 호출

> OpenCode v2.2.3에서 MiniMax M3.1 Flash 실측 설정입니다. Provider JSON, 모델 ID, 도구 호출, 오류 대처를 담았습니다.

- Canonical HTML: https://omniakey.com/ko/blog/minimax-m3-1-flash-opencode
- Markdown: https://omniakey.com/ko/blog/minimax-m3-1-flash-opencode.md
- Published: 2026-11-12 (updated 2026-11-12)
- Author: Kiki, COO at OmniaKey
- Language: ko
- Category: API setup
- Reading time: 9 min
- All posts: https://omniakey.com/blog/llms.txt

---

[MiniMax M3.1 Flash](https://omniakey.com/ko/minimax-m3-1-flash)는 OpenCode v2.2.3에서 [OpenAI 호환 사용자 Provider](https://opencode.ai/docs/providers/)로 동작합니다. OpenCode에 넣는 모델 이름은 `omniakey/minimax-m3.1-flash`이고 Base URL은 `https://api.omniakey.com/v1`입니다. 2026년 11월 12일, 아래 설정으로 실제 저장소 작업 하나를 끝냈습니다. 읽기 5회, 쓰기 1회, `node --test` 1회를 실행했고 테스트 12개가 모두 통과했습니다.

OpenCode의 사용자 Provider는 OpenAI Chat Completions 형식으로 통신하고 OmniaKey는 /v1에서 이 형식을 받습니다. 설정 파일은 프로젝트에 하나 두면 되지만, 실제로 갈리는 지점은 세 가지입니다. 모델 ID를 OmniaKey 표기와 똑같이 맞추는 것, Key를 OpenCode server 프로세스가 읽게 하는 것, 도구 호출을 거치는 동안 모델의 사고 필드를 보존하는 것입니다.

## 시작하기 전에 준비할 것

OpenCode는 V2를 사용합니다. 실측 버전은 v2.2.3입니다. V2는 사용자 Provider를 최상위 providers 객체에 넣고, V1 예제는 구조가 다릅니다. 설정을 복사하기 전에 [V2 Provider 문서](https://opencode.ai/docs/providers/)와 `opencode --version`으로 버전을 확인하십시오.

- OpenCode: v2.2.3, 2026년 11월 12일 실측
- OmniaKey 모델 ID: `minimax-m3.1-flash`
- OpenCode에서 쓰는 이름: `omniakey/minimax-m3.1-flash`

OmniaKey에서 Key를 만들고 `OMNIAKEY_API_KEY`에 넣습니다. 아래 JSON에는 변수 이름만 있고 Key 값은 없습니다. 테스트 명령이 이미 있는 작은 저장소를 준비하십시오. 실측에는 `src/normalize.js`, 테스트 파일 하나, 테스트 스크립트가 있는 Node 예제를 썼습니다.

MiniMax 자체 API의 모델 ID는 대소문자가 섞인 `MiniMax-M3.1-Flash`입니다. OmniaKey는 전부 소문자인 `minimax-m3.1-flash`를 씁니다. opencode.jsonc에서는 models 키와 `modelID`, 두 곳 모두에 OmniaKey의 소문자 ID를 넣으십시오. 대소문자가 다르면 OmniaKey의 ID와 일치하지 않습니다.

모델을 아직 고르는 중이라면 [MiniMax M3.1 Flash 리뷰](https://omniakey.com/ko/blog/minimax-m3-1-flash-review)에 벤치마크, 출시 정보, 항상 켜지는 사고 방식이 정리되어 있습니다.

## 실측한 OpenCode V2 설정

프로젝트 최상위에 opencode.jsonc로 저장합니다. 실행에 쓴 설정을 공개할 수 있는 형태로 그대로 옮긴 것입니다.

```json
{
  "$schema": "https://opencode.ai/config.json",
  "model": "omniakey/minimax-m3.1-flash",
  "share": "disabled",
  "update": "disable",
  "warming": false,
  "snapshots": false,
  "enabled_providers": ["omniakey"],
  "providers": {
    "omniakey": {
      "name": "OmniaKey",
      "env": ["OMNIAKEY_API_KEY"],
      "package": "@opencode/ai/providers/openai-compatible",
      "settings": {
        "baseURL": "https://api.omniakey.com/v1"
      },
      "models": {
        "minimax-m3.1-flash": {
          "modelID": "minimax-m3.1-flash",
          "name": "MiniMax M3.1 Flash",
          "body": {
            "reasoning_effort": "medium",
            "max_tokens": 4096,
            "stream_options": {"include_usage": true}
          },
          "limit": {
            "context": 1000000,
            "output": 4096
          },
          "capabilities": {
            "tools": true,
            "input": ["text"],
            "output": ["text"],
            "freeform": [],
            "reasoning": {
              "supported": true,
              "effort": ["low", "medium", "high", "xhigh", "max"]
            }
          },
          "compatibility": {
            "reasoningField": "reasoning_content",
            "requireReasoning": true,
            "maxTokensField": "max_tokens"
          }
        }
      }
    }
  },
  "permissions": [
    {"action": "*", "resource": "*", "effect": "deny"},
    {"action": "read", "resource": "*", "effect": "allow"},
    {"action": "glob", "resource": "*", "effect": "allow"},
    {"action": "grep", "resource": "*", "effect": "allow"},
    {"action": "edit", "resource": "src/normalize.js", "effect": "allow"},
    {"action": "shell", "resource": "node --test", "effect": "allow"},
    {"action": "shell", "resource": "git diff *", "effect": "allow"},
    {"action": "external_directory", "resource": "*", "effect": "deny"}
  ]
}
```

env는 OpenCode가 어떤 환경 변수를 자격 증명으로 읽을지 정합니다. `OMNIAKEY_API_KEY`는 server 프로세스의 환경에서 들어옵니다. `modelID`는 OmniaKey로 보내는 ID이고 models의 키는 OpenCode가 provider/model 참조에 쓰는 ID입니다. 둘 다 `minimax-m3.1-flash`로 두면 이름을 찾을 때 헷갈리지 않습니다.

limit와 capabilities는 [모르는 모델에 대한 OpenCode 기본값](https://opencode.ai/docs/models.md)을 덮어씁니다. 기본값은 컨텍스트 20만 토큰과 이미지 입력을 가정합니다. [OmniaKey 모델 페이지](https://omniakey.com/ko/minimax-m3-1-flash)에는 컨텍스트 1M 토큰이 적혀 있고 비전 항목은 없습니다. 그래서 컨텍스트 상한을 `1000000`으로 두고 입력은 텍스트만 선언했습니다. 1M은 공개된 창 크기이며 이번 작은 작업에서 끝까지 쓰지는 않았습니다.

body에는 이번 실행에서 시험한 두 값, medium 사고와 `max_tokens` 4096이 들어 있습니다. capabilities의 effort 목록은 MiniMax 문서가 제시하는 다섯 단계이고, 테스트에는 medium을 썼습니다.

permissions는 데모 저장소에 맞춰 좁게 잡았습니다. 먼저 모두 거부한 뒤 읽기, glob, grep, `src/normalize.js` 편집, `node --test`와 git diff만 허용합니다. 외부 디렉터리는 거부합니다. 내 프로젝트로 옮길 때는 파일 경로와 명령을 바꾸십시오. 저장소 전체 편집과 임의 shell 실행을 허용하면 이 규모의 작업에는 권한이 너무 큽니다.

## Key는 server를 띄운 shell에 둡니다

OpenCode는 보통 공유 백그라운드 server를 띄우거나 이미 도는 server를 찾아 씁니다. 세션, 설정, 도구 실행을 이 server가 맡고 Provider의 env도 server 자신의 환경에서 읽습니다. 다른 터미널에서 export한 Key는 닿지 않습니다. 공유 server와 `--standalone`의 동작은 [OpenCode CLI 문서](https://opencode.ai/docs/cli.md)에 나옵니다.

처음 실행할 때는 Key가 있는 shell에서 전용 server를 띄우면 결과가 분명합니다.

```bash
export OMNIAKEY_API_KEY="your-omniakey-api-key"
opencode --standalone models
```

실측한 models 명령에는 provider 인자를 넣지 않습니다. 목록에 `omniakey/minimax-m3.1-flash`가 보이면 설정이 읽힌 것입니다. 이어서 작업 하나를 실행합니다. 실측에 쓴 모델 인자와 아래 프롬프트 블록을 조합한 형태이며, 표시해 둔 자리표시자를 프롬프트 전문으로 바꿉니다.

```bash
# Replace <task prompt> with the text from the prompt block below.
opencode --standalone run --model omniakey/minimax-m3.1-flash '<task prompt>'
```

`--standalone`은 그 shell에서 전용 server를 띄우므로 server가 Key를 물려받고 프로젝트 설정도 읽습니다. 먼저 띄운 공유 server는 자기 환경만 봅니다. 위 Key 줄은 자리표시자이고 설정 파일에는 여전히 비밀이 없습니다.

이미 OMNIAKEY\_API\_KEY가 있는 환경에서 공유 server를 돌리고 있다면 그대로 써도 됩니다. 환경이 불분명할 때는 전용 server가 재현하기 쉬운 길입니다.

## 읽기, 쓰기, 테스트 한 바퀴 확인

도구 호출이 되는지는 작은 Node 예제로 충분합니다. 준비한 예제에는 정렬만 하는 스텁이 있는 `src/normalize.js`, 12개 케이스의 테스트 파일, node --test 스크립트가 있었습니다. 수정 전에는 3개가 통과하고 9개가 실패했습니다.

실행에 쓴 프롬프트는 다음과 같습니다.

```prompt
Fix src/normalize.js in this small JavaScript repository. Read the source and existing tests, then implement normalizeIntervals: accept valid half-open numeric intervals [start,end], drop empty intervals, sort them, and merge overlapping or touching ranges. Return fresh arrays without mutating the input. Do not change tests or configuration. Run `node --test` and summarize the result. Work only in this repository; do not read any credentials, network resources or files outside it. Use at most 8 tool calls.
```

실행 중 HTTP 요청은 6회였고 모두 200으로 돌아왔습니다. 도구 작업은 7회였습니다.

|도구|횟수|한 일|
|-|-|-|
|`read`|5|저장소 목록, 소스, 테스트 디렉터리, `package.json`, 테스트 파일|
|`write`|1|`src/normalize.js`|
|`shell`|1|`node --test`|

첫 턴에서 저장소 목록과 소스를 나란히 읽었고, 다음 두 턴에서 테스트 디렉터리, package.json, 테스트 파일을 읽었습니다. 쓰기가 소스를 바꿨고 마지막 shell 호출이 테스트를 돌렸습니다. 걸린 시간은 70.172초입니다.

루프 안의 테스트 출력은 다음과 같습니다.

```text
ℹ tests 12
ℹ suites 0
ℹ pass 12
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 52.316459
```

마지막 답변은 바뀐 파일과 12/12 결과를 알려 주었습니다. 6회의 usage를 더하면 캐시로 읽은 앞부분을 포함해 입력 20,739토큰, 출력 803토큰입니다. 한 번의 출력은 최대 363토큰이라 4096 상한에는 닿지 않았습니다.

로컬 전달 프로세스가 요청 본문과 스트림 응답을 바꾸지 않고 OmniaKey로 보냈습니다. 작은 작업 하나의 기록이며, 이 저장소에서 읽기, 쓰기, 테스트 한 바퀴가 돌았다는 확인입니다. 속도나 코드 품질을 넓게 비교한 측정은 아닙니다.

## effort, 컨텍스트, 출력 상한 정하기

M3.1 Flash는 사고를 끌 수 없습니다. [MiniMax 텍스트 생성 가이드](https://platform.minimax.io/docs/guides/text-generation.md)는 항상 사고한다고 밝히고, `thinking: {"type": "disabled"}`나 `reasoning_effort: "none"`을 보내면 [OpenAI 호환 API 참조](https://platform.minimax.io/docs/api-reference/text-openai-api.md)가 HTTP 400을 돌려줍니다. 턴을 줄이고 싶으면 사고를 끄지 말고 effort를 낮추십시오.

|설정|실측값|역할|
|-|-|-|
|`reasoning_effort`|`medium`|답하기 전 사고량|
|`max_tokens`|`4096`|호출 한 번의 클라이언트 출력 상한|
|`limit.context`|`1000000`|공개된 컨텍스트 창|

`reasoning_effort`는 low, medium, high, xhigh, max를 받고, 생략하면 [MiniMax 가이드](https://platform.minimax.io/docs/guides/text-generation.md) 기준으로 max입니다. 이번 작업은 범위가 좁아 medium으로 충분했습니다. effort를 낮추면 사고가 짧아질 뿐 사고 자체는 꺼지지 않습니다.

temperature와 top\_p는 이 모델에서 작동하지 않습니다. [MiniMax API 참조](https://platform.minimax.io/docs/api-reference/text-openai-api.md)에 따르면 M3.1 Flash는 항상 1과 0.95를 쓰므로, 무시되는 값을 조정하기보다 두 필드를 지우는 편이 깔끔합니다.

1M 토큰 컨텍스트는 [OmniaKey 모델 페이지](https://omniakey.com/ko/minimax-m3-1-flash)와 [MiniMax 가이드](https://platform.minimax.io/docs/guides/text-generation.md)에 적힌 값입니다. 4096은 이번 실행을 위해 정한 클라이언트 상한이고 제공사가 공개한 최대 출력은 아닙니다. 사고 토큰도 이 상한에 포함되므로 긴 사고 끝에 `finish_reason: "length"`로 끝나고 본문이 거의 남지 않을 수 있습니다. 먼저 effort를 낮추고, 그래도 공간이 부족할 때 상한을 올리십시오.

## Key, 모델 ID, 이어짐 오류 해결

성공한 실행에서는 오류가 나오지 않았습니다. 아래 표는 링크한 OpenCode와 MiniMax 문서를 기준으로 정리한 점검 항목입니다. Base URL은 `https://api.omniakey.com/v1`이 전체 형태입니다.

|증상|확인할 것|해결|
|-|-|-|
|`401` 또는 `403`|server 환경에 `OMNIAKEY_API_KEY`가 있는가|OpenCode를 띄우는 shell에서 export하거나 `--standalone`을 쓴다. Key는 JSON에 넣지 않는다|
|`Model unavailable`, 모델을 찾을 수 없음|models 키와 `modelID`가 모두 `minimax-m3.1-flash`인가|철자와 대소문자를 고친다. 상류의 `MiniMax-M3.1-Flash`는 쓰지 않는다. provider 활성화도 확인한다|
|게이트웨이에서 `404`|`settings.baseURL`이 OmniaKey 주소 그대로인가|위에 적은 Base URL을 그대로 넣고 군더더기 경로를 지운다|
|adaptive thinking 관련 `400`|사고 비활성화나 `reasoning_effort: "none"`을 보냈는가|그 지정을 지우고 effort를 낮춘다|
|첫 도구 호출 뒤 멈춤|reasoning 필드를 설정했는가, 기록에 넣었는가|`reasoningField`를 `"reasoning_content"`로 두고 같은 프롬프트로 다시 실행한다|
|본문이 비고 `finish_reason`이 `length`|사고가 출력 상한을 다 썼는가|effort를 먼저 낮추고 그다음 `max_tokens`를 올린다|
|30만 토큰 프롬프트에서 컨텍스트 오류|OpenCode가 아직 20만 기본값을 쓰는가|`limit.context`를 `1000000`으로 두고 프롬프트를 줄인다|
|이미지나 PDF 입력 실패|OmniaKey 모델 페이지에 비전 입력이 있는가|텍스트만 보내고 파일을 먼저 글자로 바꾼다|

이어짐 실패는 모델 문제처럼 보여도 설정에서 생깁니다. [MiniMax API 참조](https://platform.minimax.io/docs/api-reference/text-openai-api.md)는 assistant 응답을 `tool_calls`와 `reasoning_content`의 사고까지 포함해 다음 턴 기록에 넣으라고 요구합니다. [OpenCode의 reasoningField 설정](https://opencode.ai/docs/models.md)은 그 필드를 스트림에서 읽어 기록을 보낼 때 되살립니다.

이번 실행에서는 두 번째 요청부터 모든 assistant 도구 호출 메시지에 `reasoning_content`가 붙었고, 6회 요청이 모두 끝까지 갔으며, 각 도구 결과가 다음 턴으로 넘어갔습니다.

## 비용, 권한, 다음 단계

OmniaKey는 토큰 단위로 과금하고 단가는 모델 페이지의 현재 요율을 따릅니다. 이번 6회 호출은 캐시로 읽은 앞부분을 포함해 입력 20,739토큰, 출력 803토큰을 썼습니다. 비슷한 작업을 가늠할 때는 사용량을 캐시 없는 입력, 캐시 읽기 입력, 출력으로 나누고 각각 현재 단가를 곱하십시오. 입력 합계에 단가 하나를 곱하는 계산은 맞지 않습니다.

내 저장소에서는 모두 거부에서 시작해 작업에 필요한 폴더와 명령만 더하십시오. 편집 권한은 작업이 바꾸는 파일에, shell 권한은 테스트 명령에 남깁니다. 프로젝트마다 다시 쓸 부분은 이 부분이고 Provider와 모델 블록은 그대로 두어도 됩니다.

같은 Key와 Base URL 조합은 다른 클라이언트에도 적용됩니다. OmniaKey의 [Claude Code 설정 가이드](https://omniakey.com/ko/blog/claude-code-setup)는 Claude Code 절차를, [코딩 에이전트 문서](https://docs.omniakey.com/en/coding)는 도구별 단계를 다룹니다.

## 자주 묻는 질문

### OpenCode V1에서도 이 설정을 쓸 수 있나요?

실측 버전은 OpenCode v2.2.3이고 설정은 V2의 복수형 providers 객체를 씁니다. V1은 구조가 다르므로 오래된 설치에 복사하기 전에 버전을 확인하십시오.

### `opencode --standalone models`에 provider 이름이 필요한가요?

필요 없습니다. 실측 명령은 `opencode --standalone models`이고 위치 인자가 없습니다. 목록에 `omniakey/minimax-m3.1-flash`가 나옵니다.

### OmniaKey를 통해 이미지나 PDF를 보낼 수 있나요?

OmniaKey 모델 페이지에는 비전 입력이 없고 실측 설정도 텍스트 입력만 선언합니다. 텍스트를 보내고 이미지나 PDF는 먼저 글자로 바꾸십시오. MiniMax 상류 모델은 이미지를 받지만, 그 사실이 OmniaKey 모델 페이지에 이미지 입력을 더하지는 않습니다.

### `max_tokens`를 4096보다 높일 수 있나요?

클라이언트 상한은 올릴 수 있습니다. 4096은 실측값이고 현재 페이지에 이 모델의 고정 최댓값은 적혀 있지 않습니다. 사고도 상한에 포함되므로 길이로 잘리거나 본문이 비는지 살피고, effort를 먼저 낮춘 뒤 상한을 올리십시오.

## 확인한 출처

- [OpenCode Providers](https://opencode.ai/docs/providers/) — 2026년 11월 12일 확인
- [OpenCode Models](https://opencode.ai/docs/models.md) — 2026년 11월 12일 확인
- [OpenCode CLI](https://opencode.ai/docs/cli.md) — 2026년 11월 12일 확인
- [MiniMax 텍스트 생성 가이드](https://platform.minimax.io/docs/guides/text-generation.md) — 2026년 11월 12일 확인
- [MiniMax OpenAI 호환 API 참조](https://platform.minimax.io/docs/api-reference/text-openai-api.md) — 2026년 11월 12일 확인
- [OmniaKey: MiniMax M3.1 Flash](https://omniakey.com/ko/minimax-m3-1-flash) — 2026년 11월 12일 확인
