Gateway

로컬 모델

로컬 모델은 가능합니다. 또한 하드웨어, 컨텍스트 크기, 프롬프트 인젝션 방어의 기준도 높아집니다. 작거나 과도하게 양자화된 카드는 컨텍스트를 잘라내고 안전성을 약화시킵니다. 이 페이지는 고급 로컬 스택과 사용자 지정 OpenAI 호환 로컬 서버를 위한 주관적 가이드입니다. 가장 낮은 마찰의 온보딩을 원하면 LM Studio 또는 Ollamaopenclaw onboard로 시작하세요.

선택한 모델이 필요할 때만 시작되어야 하는 로컬 서버는 로컬 모델 서비스를 참조하세요.

하드웨어 최소 기준

높게 잡으세요. 쾌적한 에이전트 루프를 위해 **최대 사양 Mac Studio 2대 이상 또는 동급 GPU 장비(~$30k+)**를 목표로 하세요. 단일 24 GB GPU는 더 높은 지연 시간에서 가벼운 프롬프트에만 적합합니다. 항상 호스팅할 수 있는 가장 큰 / 풀사이즈 변형을 실행하세요. 작거나 과도하게 양자화된 체크포인트는 프롬프트 인젝션 위험을 높입니다(보안 참조).

백엔드 선택

백엔드 사용 시점
ds4 OpenAI 호환 도구 호출을 사용하는 macOS Metal의 로컬 DeepSeek V4 Flash
LM Studio 첫 로컬 설정, GUI 로더, 네이티브 Responses API
LiteLLM / OAI-proxy / 사용자 지정 OpenAI 호환 프록시 다른 모델 API를 앞단에 두고 OpenClaw가 이를 OpenAI처럼 취급해야 할 때
MLX / vLLM / SGLang OpenAI 호환 HTTP 엔드포인트를 사용하는 고처리량 셀프 호스팅 서빙
Ollama CLI 워크플로, 모델 라이브러리, 손댈 필요 없는 systemd 서비스

백엔드가 지원하면 Responses API(api: "openai-responses")를 사용하세요(LM Studio는 지원합니다). 그렇지 않으면 Chat Completions(api: "openai-completions")를 유지하세요.

권장: LM Studio + 대형 로컬 모델(Responses API)

현재 최상의 로컬 스택입니다. LM Studio에서 대형 모델(예: 풀사이즈 Qwen, DeepSeek 또는 Llama 빌드)을 로드하고, 로컬 서버(기본값 http://127.0.0.1:1234)를 활성화한 뒤, Responses API를 사용해 추론을 최종 텍스트와 분리하세요.

json5
{  agents: {    defaults: {      model: { primary: "lmstudio/my-local-model" },      models: {        "anthropic/claude-opus-4-6": { alias: "Opus" },        "lmstudio/my-local-model": { alias: "Local" },      },    },  },  models: {    mode: "merge",    providers: {      lmstudio: {        baseUrl: "http://127.0.0.1:1234/v1",        apiKey: "lmstudio",        api: "openai-responses",        models: [          {            id: "my-local-model",            name: "Local Model",            reasoning: false,            input: ["text"],            cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },            contextWindow: 196608,            maxTokens: 8192,          },        ],      },    },  },}

설정 체크리스트

  • LM Studio 설치: https://lmstudio.ai
  • LM Studio에서 사용 가능한 가장 큰 모델 빌드를 다운로드하고("small"/과도하게 양자화된 변형은 피하세요), 서버를 시작한 뒤 http://127.0.0.1:1234/v1/models에 목록이 표시되는지 확인하세요.
  • my-local-model을 LM Studio에 표시된 실제 모델 ID로 바꾸세요.
  • 모델을 로드된 상태로 유지하세요. 콜드 로드는 시작 지연 시간을 추가합니다.
  • LM Studio 빌드가 다르면 contextWindow/maxTokens를 조정하세요.
  • WhatsApp의 경우 최종 텍스트만 전송되도록 Responses API를 유지하세요.

로컬을 실행할 때도 호스팅 모델을 계속 구성해 두세요. models.mode: "merge"를 사용해 폴백이 계속 사용 가능하게 하세요.

하이브리드 구성: 호스팅 기본, 로컬 폴백

json5
{  agents: {    defaults: {      model: {        primary: "anthropic/claude-sonnet-4-6",        fallbacks: ["lmstudio/my-local-model", "anthropic/claude-opus-4-6"],      },      models: {        "anthropic/claude-sonnet-4-6": { alias: "Sonnet" },        "lmstudio/my-local-model": { alias: "Local" },        "anthropic/claude-opus-4-6": { alias: "Opus" },      },    },  },  models: {    mode: "merge",    providers: {      lmstudio: {        baseUrl: "http://127.0.0.1:1234/v1",        apiKey: "lmstudio",        api: "openai-responses",        models: [          {            id: "my-local-model",            name: "Local Model",            reasoning: false,            input: ["text"],            cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },            contextWindow: 196608,            maxTokens: 8192,          },        ],      },    },  },}

호스팅 안전망이 있는 로컬 우선

기본과 폴백 순서를 바꾸세요. 로컬 장비가 다운되었을 때 Sonnet 또는 Opus로 폴백할 수 있도록 동일한 providers 블록과 models.mode: "merge"를 유지하세요.

지역 호스팅 / 데이터 라우팅

  • 호스팅 MiniMax/Kimi/GLM 변형은 OpenRouter에도 지역 고정 엔드포인트(예: 미국 호스팅)로 존재합니다. Anthropic/OpenAI 폴백을 위해 models.mode: "merge"를 계속 사용하면서, 선택한 관할권 내에 트래픽을 유지하려면 그곳에서 지역 변형을 선택하세요.
  • 로컬 전용은 여전히 가장 강력한 개인정보 보호 경로입니다. 호스팅 지역 라우팅은 공급자 기능이 필요하지만 데이터 흐름을 제어하고 싶을 때의 중간 지점입니다.

기타 OpenAI 호환 로컬 프록시

MLX(mlx_lm.server), vLLM, SGLang, LiteLLM, OAI-proxy 또는 사용자 지정 게이트웨이는 OpenAI 스타일 /v1/chat/completions 엔드포인트를 노출하면 동작합니다. 백엔드가 /v1/responses 지원을 명시적으로 문서화하지 않았다면 Chat Completions 어댑터를 사용하세요. 위의 provider 블록을 사용자의 엔드포인트와 모델 ID로 바꾸세요.

json5
{  agents: {    defaults: {      model: { primary: "local/my-local-model" },    },  },  models: {    mode: "merge",    providers: {      local: {        baseUrl: "http://127.0.0.1:8000/v1",        apiKey: "sk-local",        api: "openai-completions",        timeoutSeconds: 300,        models: [          {            id: "my-local-model",            name: "Local Model",            reasoning: false,            input: ["text"],            cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },            contextWindow: 120000,            maxTokens: 8192,          },        ],      },    },  },}

baseUrl이 있는 사용자 지정 provider에서 api가 생략되면 OpenClaw는 기본적으로 openai-completions를 사용합니다. 사용자 지정/로컬 provider 항목은 보호된 모델 요청에 대해 loopback, LAN, tailnet, 비공개 DNS 호스트를 포함하여 정확히 구성된 baseUrl 원본을 신뢰합니다. 다른 비공개 원본으로의 요청에는 여전히 request.allowPrivateNetwork: true가 필요합니다. metadata/link-local 원본은 명시적 옵트인 없이는 계속 차단됩니다. 정확한 원본 신뢰를 옵트아웃하려면 이를 false로 설정하세요.

models.providers.<id>.models[].id 값은 provider 로컬입니다. 여기에 provider 접두사를 포함하지 마세요. 예를 들어 mlx_lm.server --model mlx-community/Qwen3-30B-A3B-6bit로 시작한 MLX 서버는 다음 카탈로그 id와 모델 ref를 사용해야 합니다.

  • models.providers.mlx.models[].id: "mlx-community/Qwen3-30B-A3B-6bit"
  • agents.defaults.model.primary: "mlx/mlx-community/Qwen3-30B-A3B-6bit"

이미지 첨부가 에이전트 턴에 주입되도록 로컬 또는 프록시된 비전 모델에는 input: ["text", "image"]를 설정하세요. 대화형 사용자 지정 provider 온보딩은 일반적인 비전 모델 ID를 추론하고 알 수 없는 이름에 대해서만 질문합니다. 비대화형 온보딩도 같은 추론을 사용합니다. 알 수 없는 비전 ID에는 --custom-image-input을, 엔드포인트 뒤에서 텍스트 전용인 것으로 보이는 알려진 모델에는 --custom-text-input을 사용하세요.

호스팅 모델이 폴백으로 계속 사용 가능하도록 models.mode: "merge"를 유지하세요. 느린 로컬 또는 원격 모델 서버에는 agents.defaults.timeoutSeconds를 높이기 전에 models.providers.<id>.timeoutSeconds를 사용하세요. provider 타임아웃은 연결, 헤더, 본문 스트리밍, 전체 보호된 fetch 중단을 포함한 모델 HTTP 요청에만 적용됩니다. 에이전트 또는 실행 타임아웃이 더 낮다면, provider 타임아웃이 전체 에이전트 실행을 연장할 수 없으므로 그 상한도 함께 높이세요.

로컬/프록시된 /v1 백엔드의 동작 참고:

  • OpenClaw는 이를 네이티브 OpenAI 엔드포인트가 아니라 프록시 스타일 OpenAI 호환 경로로 취급합니다
  • 네이티브 OpenAI 전용 요청 shaping은 여기 적용되지 않습니다. service_tier 없음, Responses store 없음, OpenAI 추론 호환 페이로드 shaping 없음, 프롬프트 캐시 힌트 없음
  • 숨겨진 OpenClaw attribution 헤더(originator, version, User-Agent)는 이 사용자 지정 프록시 URL에 주입되지 않습니다

더 엄격한 OpenAI 호환 백엔드에 대한 호환성 참고:

  • 일부 서버는 Chat Completions에서 구조화된 content-part 배열이 아니라 문자열 messages[].content만 허용합니다. 이러한 엔드포인트에는 models.providers.<provider>.models[].compat.requiresStringContent: true를 설정하세요.

  • 일부 로컬 모델은 [tool_name] 뒤에 JSON과 [END_TOOL_REQUEST]가 이어지는 형태처럼 독립적인 대괄호 도구 요청을 텍스트로 내보냅니다. OpenClaw는 그 이름이 해당 턴에 등록된 도구와 정확히 일치할 때만 이를 실제 도구 호출로 승격합니다. 그렇지 않으면 블록은 지원되지 않는 텍스트로 취급되고 사용자에게 보이는 응답에서는 숨겨집니다.

  • 모델이 도구 호출처럼 보이는 JSON, XML 또는 ReAct 스타일 텍스트를 내보내지만 provider가 구조화된 호출을 내보내지 않았다면, OpenClaw는 이를 텍스트로 남기고 가능한 경우 run id, provider/model, 감지된 패턴, 도구 이름과 함께 경고를 기록합니다. 이를 완료된 도구 실행이 아니라 provider/model 도구 호출 비호환성으로 취급하세요.

  • 도구가 실행되지 않고 어시스턴트 텍스트로 나타나는 경우(예: 원시 JSON, XML, ReAct 구문 또는 provider 응답의 빈 tool_calls 배열), 먼저 서버가 도구 호출을 지원하는 채팅 템플릿/파서를 사용하고 있는지 확인하세요. 도구 사용이 강제될 때만 파서가 동작하는 OpenAI 호환 Chat Completions 백엔드의 경우, 텍스트 파싱에 의존하지 말고 모델별 요청 오버라이드를 설정하세요.

    json5
    {  agents: {    defaults: {      models: {        "local/my-local-model": {          params: {            extra_body: {              tool_choice: "required",            },          },        },      },    },  },}

    모든 일반 턴이 도구를 호출해야 하는 모델/세션에만 이를 사용하세요. 이는 OpenClaw의 기본 프록시 값인 tool_choice: "auto"를 오버라이드합니다. local/my-local-modelopenclaw models list에 표시된 정확한 provider/model ref로 바꾸세요.

    bash
    openclaw config set agents.defaults.models '{"local/my-local-model":{"params":{"extra_body":{"tool_choice":"required"}}}}' --strict-json --merge
  • 사용자 지정 OpenAI 호환 모델이 내장 프로필을 넘어서는 OpenAI reasoning efforts를 허용한다면, 이를 모델 compat 블록에 선언하세요. 여기에 "xhigh"를 추가하면 /think xhigh, 세션 선택기, Gateway 검증, llm-task 검증이 해당 구성된 provider/model ref에 대해 그 수준을 노출합니다:

    json5
    {  models: {    providers: {      local: {        baseUrl: "http://127.0.0.1:8000/v1",        apiKey: "sk-local",        api: "openai-responses",        models: [          {            id: "gpt-5.4",            name: "GPT 5.4 via local proxy",            reasoning: true,            input: ["text"],            cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },            contextWindow: 196608,            maxTokens: 8192,            compat: {              supportedReasoningEfforts: ["low", "medium", "high", "xhigh"],              reasoningEffortMap: { xhigh: "xhigh" },            },          },        ],      },    },  },}

더 작거나 더 엄격한 백엔드

모델은 정상적으로 로드되지만 전체 에이전트 턴이 오작동한다면, 위에서 아래로 확인하세요. 먼저 전송을 확인한 다음 범위를 좁힙니다.

  1. 로컬 모델 자체가 응답하는지 확인합니다. 도구도, 에이전트 컨텍스트도 없습니다.

    bash
    openclaw infer model run --local --model <provider/model> --prompt "Reply with exactly: pong" --json
  2. Gateway 라우팅을 확인합니다. 제공된 프롬프트만 보냅니다. 트랜스크립트, AGENTS 부트스트랩, 컨텍스트 엔진 조립, 도구, 번들 MCP 서버는 건너뛰지만 Gateway 라우팅, 인증, 제공자 선택은 계속 실행합니다.

    bash
    openclaw infer model run --gateway --model <provider/model> --prompt "Reply with exactly: pong" --json
  3. 린 모드를 시도합니다. 두 프로브가 모두 통과하지만 실제 에이전트 턴이 잘못된 형식의 도구 호출이나 과도하게 큰 프롬프트로 실패한다면 agents.defaults.experimental.localModelLean: true를 활성화하세요. 직접적인 message 전달 의미 체계를 유지해야 하는 실행을 제외하고, 가장 무거운 기본 도구 세 가지(browser, cron, message)를 제거하고 더 큰 도구 카탈로그를 구조화된 도구 검색 컨트롤 뒤에 기본 배치합니다. 전체 설명, 사용 시점, 활성화 여부 확인 방법은 실험적 기능 → 로컬 모델 린 모드를 참조하세요.

  4. 마지막 수단으로 도구를 완전히 비활성화합니다. 린 모드로 충분하지 않다면 해당 모델 항목에 models.providers.<provider>.models[].compat.supportsTools: false를 설정하세요. 그러면 에이전트는 해당 모델에서 도구 호출 없이 작동합니다.

  5. 그 이후의 병목은 업스트림입니다. 린 모드와 supportsTools: false 이후에도 백엔드가 더 큰 OpenClaw 실행에서만 계속 실패한다면, 남은 문제는 보통 업스트림 모델 또는 서버 용량입니다. 컨텍스트 윈도우, GPU 메모리, kv-cache 축출, 백엔드 버그 등이 원인일 수 있습니다. 그 시점에서는 OpenClaw의 전송 계층 문제가 아닙니다.

문제 해결

  • Gateway가 프록시에 도달할 수 있나요? curl http://127.0.0.1:1234/v1/models.
  • LM Studio 모델이 언로드되었나요? 다시 로드하세요. 콜드 스타트는 "중단된 것처럼 보이는" 흔한 원인입니다.
  • 로컬 서버가 terminated, ECONNRESET을 표시하거나 턴 중간에 스트림을 닫나요? OpenClaw는 진단 정보에 낮은 카디널리티의 model.call.error.failureKind와 OpenClaw 프로세스 RSS/힙 스냅샷을 기록합니다. LM Studio/Ollama 메모리 압박의 경우, 해당 타임스탬프를 서버 로그 또는 macOS 크래시 / jetsam 로그와 대조해 모델 서버가 종료되었는지 확인하세요.
  • OpenClaw는 감지된 모델 윈도우에서 컨텍스트 윈도우 사전 점검 임계값을 도출하거나, agents.defaults.contextTokens가 유효 윈도우를 낮출 때는 제한 없는 모델 윈도우에서 도출합니다. 20% 미만에서는 8k 하한으로 경고합니다. 하드 차단은 4k 하한의 10% 임계값을 사용하며, 과도하게 큰 모델 메타데이터가 유효한 사용자 상한을 거부하지 않도록 유효 컨텍스트 윈도우로 제한됩니다. 해당 사전 점검에 걸리면 서버/모델 컨텍스트 제한을 높이거나 더 큰 모델을 선택하세요.
  • 컨텍스트 오류인가요? contextWindow를 낮추거나 서버 제한을 높이세요.
  • OpenAI 호환 서버가 messages[].content ... expected a string을 반환하나요? 해당 모델 항목에 compat.requiresStringContent: true를 추가하세요.
  • OpenAI 호환 서버가 validation.keys를 반환하거나 메시지 항목에는 rolecontent만 허용된다고 하나요? 해당 모델 항목에 compat.strictMessageKeys: true를 추가하세요.
  • 직접 수행한 작은 /v1/chat/completions 호출은 작동하지만 openclaw infer model run --local이 Gemma 또는 다른 로컬 모델에서 실패하나요? 먼저 제공자 URL, 모델 참조, 인증 마커, 서버 로그를 확인하세요. 로컬 model run에는 에이전트 도구가 포함되지 않습니다. 로컬 model run은 성공하지만 더 큰 에이전트 턴이 실패한다면 localModelLean 또는 compat.supportsTools: false로 에이전트 도구 범위를 줄이세요.
  • 도구 호출이 원시 JSON/XML/ReAct 텍스트로 표시되거나 제공자가 빈 tool_calls 배열을 반환하나요? 어시스턴트 텍스트를 무작정 도구 실행으로 변환하는 프록시를 추가하지 마세요. 먼저 서버 채팅 템플릿/파서를 수정하세요. 모델이 도구 사용을 강제할 때만 작동한다면, 위의 모델별 params.extra_body.tool_choice: "required" 재정의를 추가하고 모든 턴에서 도구 호출이 예상되는 세션에만 해당 모델 항목을 사용하세요.
  • 안전: 로컬 모델은 제공자 측 필터를 건너뜁니다. 프롬프트 인젝션 영향 범위를 제한하려면 에이전트를 좁게 유지하고 Compaction을 켜두세요.

관련 항목

Was this useful?
On this page

On this page