chore(i18n): refresh ko translations
This commit is contained in:
parent
915b075f06
commit
daf239367e
@ -1,21 +1,21 @@
|
||||
---
|
||||
read_when:
|
||||
- BlueBubbles 채널 설정
|
||||
- BlueBubbles 채널 설정하기
|
||||
- Webhook 페어링 문제 해결
|
||||
- macOS에서 iMessage 구성하기
|
||||
- macOS에서 iMessage 설정하기
|
||||
sidebarTitle: BlueBubbles
|
||||
summary: BlueBubbles macOS 서버를 통한 iMessage(REST 송수신, 입력 중 표시, 반응, 페어링, 고급 작업).
|
||||
summary: BlueBubbles macOS 서버를 통한 iMessage(REST 송신/수신, 입력 중 표시, 반응, 페어링, 고급 작업).
|
||||
title: BlueBubbles
|
||||
x-i18n:
|
||||
generated_at: "2026-05-01T06:23:23Z"
|
||||
generated_at: "2026-05-04T02:21:34Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 499cc2a46db6e0eddfb897e96ec4b3e4a39ba9f2f6da8e7485c1c46562de4145
|
||||
source_hash: 78a054da0c7c32b161997acd05914896259dd1a050e736a4c9e438a452ab6a51
|
||||
source_path: channels/bluebubbles.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
상태: HTTP를 통해 BlueBubbles macOS 서버와 통신하는 번들 Plugin입니다. 기존 imsg 채널보다 API가 더 풍부하고 설정이 더 쉬워서 **iMessage 통합에 권장됩니다**.
|
||||
상태: HTTP를 통해 BlueBubbles macOS 서버와 통신하는 번들 Plugin입니다. 레거시 imsg 채널보다 API가 더 풍부하고 설정이 쉬워 **iMessage 통합에 권장됩니다**.
|
||||
|
||||
<Note>
|
||||
현재 OpenClaw 릴리스에는 BlueBubbles가 번들로 포함되어 있으므로, 일반 패키지 빌드에서는 별도의 `openclaw plugins install` 단계가 필요하지 않습니다.
|
||||
@ -24,26 +24,26 @@ x-i18n:
|
||||
## 개요
|
||||
|
||||
- BlueBubbles 헬퍼 앱([bluebubbles.app](https://bluebubbles.app))을 통해 macOS에서 실행됩니다.
|
||||
- 권장/테스트됨: macOS Sequoia (15). macOS Tahoe (26)도 동작하지만, 현재 Tahoe에서는 편집 기능이 깨져 있으며 그룹 아이콘 업데이트가 성공으로 보고되더라도 동기화되지 않을 수 있습니다.
|
||||
- 권장/테스트됨: macOS Sequoia (15). macOS Tahoe (26)도 작동하지만, Tahoe에서는 현재 편집이 깨져 있으며 그룹 아이콘 업데이트가 성공으로 보고되더라도 동기화되지 않을 수 있습니다.
|
||||
- OpenClaw는 REST API(`GET /api/v1/ping`, `POST /message/text`, `POST /chat/:id/*`)를 통해 BlueBubbles와 통신합니다.
|
||||
- 수신 메시지는 Webhook으로 도착하며, 발신 답장, 입력 표시, 읽음 확인, 탭백은 REST 호출입니다.
|
||||
- 첨부 파일과 스티커는 인바운드 미디어로 수집됩니다(가능한 경우 에이전트에 표시됨).
|
||||
- 수신 메시지는 Webhook을 통해 도착하며, 발신 답장, 입력 표시기, 읽음 확인, tapback은 REST 호출입니다.
|
||||
- 첨부 파일과 스티커는 인바운드 미디어로 수집됩니다(가능한 경우 에이전트에 노출됨).
|
||||
- MP3 또는 CAF 오디오를 합성하는 자동 TTS 답장은 일반 파일 첨부 대신 iMessage 음성 메모 말풍선으로 전달됩니다.
|
||||
- 페어링/허용 목록은 다른 채널(`/channels/pairing` 등)과 동일하게 `channels.bluebubbles.allowFrom` + 페어링 코드로 동작합니다.
|
||||
- 반응은 Slack/Telegram과 동일하게 시스템 이벤트로 표시되므로 에이전트가 답장하기 전에 이를 "언급"할 수 있습니다.
|
||||
- 고급 기능: 편집, 보내기 취소, 답장 스레딩, 메시지 효과, 그룹 관리.
|
||||
- 페어링/허용 목록은 다른 채널(`/channels/pairing` 등)과 동일한 방식으로 작동하며 `channels.bluebubbles.allowFrom` + 페어링 코드를 사용합니다.
|
||||
- 반응은 Slack/Telegram과 마찬가지로 시스템 이벤트로 노출되므로 에이전트가 답장하기 전에 이를 "언급"할 수 있습니다.
|
||||
- 고급 기능: 편집, 전송 취소, 답장 스레딩, 메시지 효과, 그룹 관리.
|
||||
|
||||
## 빠른 시작
|
||||
|
||||
<Steps>
|
||||
<Step title="BlueBubbles 설치">
|
||||
Mac에 BlueBubbles 서버를 설치합니다([bluebubbles.app/install](https://bluebubbles.app/install)의 안내를 따르세요).
|
||||
Mac에 BlueBubbles 서버를 설치합니다([bluebubbles.app/install](https://bluebubbles.app/install)의 지침을 따르세요).
|
||||
</Step>
|
||||
<Step title="웹 API 활성화">
|
||||
BlueBubbles 설정에서 웹 API를 활성화하고 비밀번호를 설정합니다.
|
||||
BlueBubbles 구성에서 웹 API를 활성화하고 비밀번호를 설정합니다.
|
||||
</Step>
|
||||
<Step title="OpenClaw 설정">
|
||||
`openclaw onboard`를 실행하고 BlueBubbles를 선택하거나, 수동으로 설정합니다.
|
||||
<Step title="OpenClaw 구성">
|
||||
`openclaw onboard`를 실행하고 BlueBubbles를 선택하거나, 수동으로 구성합니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -71,18 +71,18 @@ x-i18n:
|
||||
**보안**
|
||||
|
||||
- 항상 Webhook 비밀번호를 설정하세요.
|
||||
- Webhook 인증은 항상 필요합니다. OpenClaw는 local loopback/프록시 토폴로지와 관계없이 `channels.bluebubbles.password`와 일치하는 비밀번호/guid(예: `?password=<password>` 또는 `x-password`)가 포함되지 않은 BlueBubbles Webhook 요청을 거부합니다.
|
||||
- Webhook 인증은 항상 필요합니다. OpenClaw는 local loopback/프록시 토폴로지와 관계없이 `channels.bluebubbles.password`와 일치하는 비밀번호/guid를 포함하지 않는 BlueBubbles Webhook 요청을 거부합니다(예: `?password=<password>` 또는 `x-password`).
|
||||
- 비밀번호 인증은 전체 Webhook 본문을 읽거나 파싱하기 전에 확인됩니다.
|
||||
|
||||
</Warning>
|
||||
|
||||
## Messages.app을 계속 활성 상태로 유지하기(VM / 헤드리스 설정)
|
||||
## Messages.app 유지 실행(VM / 헤드리스 설정)
|
||||
|
||||
일부 macOS VM / 상시 실행 설정에서는 Messages.app이 "유휴" 상태가 되어 앱을 열거나 포그라운드로 가져올 때까지 수신 이벤트가 멈출 수 있습니다. 간단한 해결 방법은 AppleScript + LaunchAgent를 사용해 **5분마다 Messages를 깨우는 것**입니다.
|
||||
일부 macOS VM / 상시 실행 설정에서는 Messages.app이 "유휴" 상태가 될 수 있습니다(앱을 열거나 포그라운드로 가져올 때까지 수신 이벤트가 중지됨). 간단한 해결 방법은 AppleScript + LaunchAgent를 사용해 **5분마다 Messages를 깨우는 것**입니다.
|
||||
|
||||
<Steps>
|
||||
<Step title="AppleScript 저장">
|
||||
다음 내용을 `~/Scripts/poke-messages.scpt`로 저장합니다.
|
||||
다음을 `~/Scripts/poke-messages.scpt`로 저장합니다.
|
||||
|
||||
```applescript
|
||||
try
|
||||
@ -101,7 +101,7 @@ x-i18n:
|
||||
|
||||
</Step>
|
||||
<Step title="LaunchAgent 설치">
|
||||
다음 내용을 `~/Library/LaunchAgents/com.user.poke-messages.plist`로 저장합니다.
|
||||
다음을 `~/Library/LaunchAgents/com.user.poke-messages.plist`로 저장합니다.
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
@ -151,25 +151,25 @@ BlueBubbles는 대화형 온보딩에서 사용할 수 있습니다.
|
||||
openclaw onboard
|
||||
```
|
||||
|
||||
마법사는 다음 항목을 입력하라고 안내합니다.
|
||||
마법사는 다음을 요청합니다.
|
||||
|
||||
<ParamField path="Server URL" type="string" required>
|
||||
<ParamField path="서버 URL" type="string" required>
|
||||
BlueBubbles 서버 주소(예: `http://192.168.1.100:1234`).
|
||||
</ParamField>
|
||||
<ParamField path="Password" type="string" required>
|
||||
BlueBubbles Server 설정의 API 비밀번호.
|
||||
<ParamField path="비밀번호" type="string" required>
|
||||
BlueBubbles 서버 설정의 API 비밀번호.
|
||||
</ParamField>
|
||||
<ParamField path="Webhook path" type="string" default="/bluebubbles-webhook">
|
||||
<ParamField path="Webhook 경로" type="string" default="/bluebubbles-webhook">
|
||||
Webhook 엔드포인트 경로.
|
||||
</ParamField>
|
||||
<ParamField path="DM policy" type="string">
|
||||
<ParamField path="DM 정책" type="string">
|
||||
`pairing`, `allowlist`, `open` 또는 `disabled`.
|
||||
</ParamField>
|
||||
<ParamField path="Allow list" type="string[]">
|
||||
<ParamField path="허용 목록" type="string[]">
|
||||
전화번호, 이메일 또는 채팅 대상.
|
||||
</ParamField>
|
||||
|
||||
CLI로 BlueBubbles를 추가할 수도 있습니다.
|
||||
CLI를 통해 BlueBubbles를 추가할 수도 있습니다.
|
||||
|
||||
```
|
||||
openclaw channels add bluebubbles --http-url http://192.168.1.100:1234 --password <password>
|
||||
@ -180,7 +180,7 @@ openclaw channels add bluebubbles --http-url http://192.168.1.100:1234 --passwor
|
||||
<Tabs>
|
||||
<Tab title="DM">
|
||||
- 기본값: `channels.bluebubbles.dmPolicy = "pairing"`.
|
||||
- 알 수 없는 발신자는 페어링 코드를 받으며, 승인될 때까지 메시지가 무시됩니다(코드는 1시간 후 만료).
|
||||
- 알 수 없는 발신자는 페어링 코드를 받으며, 승인될 때까지 메시지는 무시됩니다(코드는 1시간 후 만료).
|
||||
- 승인 방법:
|
||||
- `openclaw pairing list bluebubbles`
|
||||
- `openclaw pairing approve bluebubbles <CODE>`
|
||||
@ -188,20 +188,20 @@ openclaw channels add bluebubbles --http-url http://192.168.1.100:1234 --passwor
|
||||
|
||||
</Tab>
|
||||
<Tab title="그룹">
|
||||
- `channels.bluebubbles.groupPolicy = open | allowlist | disabled`(기본값: `allowlist`).
|
||||
- `allowlist`가 설정된 경우 `channels.bluebubbles.groupAllowFrom`은 그룹에서 누가 트리거할 수 있는지 제어합니다.
|
||||
- `channels.bluebubbles.groupPolicy = open | allowlist | disabled` (기본값: `allowlist`).
|
||||
- `channels.bluebubbles.groupAllowFrom`은 `allowlist`가 설정된 경우 그룹에서 누가 트리거할 수 있는지 제어합니다.
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### 연락처 이름 보강(macOS, 선택 사항)
|
||||
|
||||
BlueBubbles 그룹 Webhook에는 원시 참가자 주소만 포함되는 경우가 많습니다. `GroupMembers` 컨텍스트에 로컬 연락처 이름을 대신 표시하려면 macOS에서 로컬 연락처 보강을 선택할 수 있습니다.
|
||||
BlueBubbles 그룹 Webhook에는 원시 참가자 주소만 포함되는 경우가 많습니다. `GroupMembers` 컨텍스트에 로컬 연락처 이름을 대신 표시하려면 macOS에서 로컬 연락처 보강을 옵트인할 수 있습니다.
|
||||
|
||||
- `channels.bluebubbles.enrichGroupParticipantsFromContacts = true`는 조회를 활성화합니다. 기본값: `false`.
|
||||
- 조회는 그룹 접근, 명령 승인, 멘션 게이팅이 메시지를 통과시킨 후에만 실행됩니다.
|
||||
- 조회는 그룹 접근, 명령 권한 부여, 멘션 게이팅이 메시지를 통과시킨 후에만 실행됩니다.
|
||||
- 이름이 없는 전화 참가자만 보강됩니다.
|
||||
- 로컬 일치 항목이 없으면 원시 전화번호가 대체값으로 유지됩니다.
|
||||
- 로컬 일치 항목이 없으면 원시 전화번호가 폴백으로 유지됩니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -215,13 +215,13 @@ BlueBubbles 그룹 Webhook에는 원시 참가자 주소만 포함되는 경우
|
||||
|
||||
### 멘션 게이팅(그룹)
|
||||
|
||||
BlueBubbles는 iMessage/WhatsApp 동작과 일치하는 그룹 채팅 멘션 게이팅을 지원합니다.
|
||||
BlueBubbles는 iMessage/WhatsApp 동작과 일치하는 그룹 채팅용 멘션 게이팅을 지원합니다.
|
||||
|
||||
- 멘션을 감지하기 위해 `agents.list[].groupChat.mentionPatterns`(또는 `messages.groupChat.mentionPatterns`)를 사용합니다.
|
||||
- 그룹에 `requireMention`이 활성화된 경우, 에이전트는 멘션되었을 때만 응답합니다.
|
||||
- 승인된 발신자의 제어 명령은 멘션 게이팅을 우회합니다.
|
||||
- 멘션 감지에 `agents.list[].groupChat.mentionPatterns`(또는 `messages.groupChat.mentionPatterns`)를 사용합니다.
|
||||
- 그룹에 `requireMention`이 활성화된 경우 에이전트는 멘션되었을 때만 응답합니다.
|
||||
- 권한이 있는 발신자의 제어 명령은 멘션 게이팅을 우회합니다.
|
||||
|
||||
그룹별 설정:
|
||||
그룹별 구성:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -240,13 +240,13 @@ BlueBubbles는 iMessage/WhatsApp 동작과 일치하는 그룹 채팅 멘션 게
|
||||
|
||||
### 명령 게이팅
|
||||
|
||||
- 제어 명령(예: `/config`, `/model`)에는 승인이 필요합니다.
|
||||
- 명령 승인을 결정하기 위해 `allowFrom` 및 `groupAllowFrom`을 사용합니다.
|
||||
- 승인된 발신자는 그룹에서 멘션하지 않아도 제어 명령을 실행할 수 있습니다.
|
||||
- 제어 명령(예: `/config`, `/model`)에는 권한 부여가 필요합니다.
|
||||
- 명령 권한 부여 여부를 결정하기 위해 `allowFrom` 및 `groupAllowFrom`을 사용합니다.
|
||||
- 권한이 있는 발신자는 그룹에서 멘션하지 않아도 제어 명령을 실행할 수 있습니다.
|
||||
|
||||
### 그룹별 시스템 프롬프트
|
||||
|
||||
`channels.bluebubbles.groups.*` 아래의 각 항목은 선택적 `systemPrompt` 문자열을 허용합니다. 이 값은 해당 그룹의 메시지를 처리하는 모든 턴에서 에이전트의 시스템 프롬프트에 삽입되므로, 에이전트 프롬프트를 편집하지 않고도 그룹별 페르소나 또는 동작 규칙을 설정할 수 있습니다.
|
||||
`channels.bluebubbles.groups.*` 아래의 각 항목은 선택적 `systemPrompt` 문자열을 허용합니다. 이 값은 해당 그룹의 메시지를 처리하는 모든 턴에서 에이전트의 시스템 프롬프트에 주입되므로, 에이전트 프롬프트를 편집하지 않고도 그룹별 페르소나 또는 동작 규칙을 설정할 수 있습니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -262,11 +262,11 @@ BlueBubbles는 iMessage/WhatsApp 동작과 일치하는 그룹 채팅 멘션 게
|
||||
}
|
||||
```
|
||||
|
||||
키는 BlueBubbles가 그룹에 대해 보고하는 `chatGuid` / `chatIdentifier` / 숫자 `chatId`와 일치하며, `"*"` 와일드카드 항목은 정확히 일치하는 항목이 없는 모든 그룹의 기본값을 제공합니다(`requireMention` 및 그룹별 도구 정책과 동일한 패턴 사용). 정확히 일치하는 항목은 항상 와일드카드보다 우선합니다. DM은 이 필드를 무시합니다. 대신 에이전트 수준 또는 계정 수준 프롬프트 사용자 지정을 사용하세요.
|
||||
키는 BlueBubbles가 그룹에 대해 보고하는 `chatGuid` / `chatIdentifier` / 숫자 `chatId`와 일치하며, `"*"` 와일드카드 항목은 정확히 일치하는 항목이 없는 모든 그룹의 기본값을 제공합니다(`requireMention` 및 그룹별 도구 정책에서 사용하는 것과 동일한 패턴). 정확히 일치하는 항목은 항상 와일드카드보다 우선합니다. DM은 이 필드를 무시합니다. 대신 에이전트 수준 또는 계정 수준 프롬프트 사용자 지정을 사용하세요.
|
||||
|
||||
#### 작업 예시: 스레드 답장과 탭백 반응(Private API)
|
||||
#### 예제: 스레드 답장과 tapback 반응(Private API)
|
||||
|
||||
BlueBubbles Private API가 활성화되어 있으면 인바운드 메시지는 짧은 메시지 ID(예: `[[reply_to:5]]`)와 함께 도착하며, 에이전트는 `action=reply`를 호출해 특정 메시지에 스레드로 답하거나 `action=react`를 호출해 탭백을 남길 수 있습니다. 그룹별 `systemPrompt`는 에이전트가 올바른 도구를 선택하도록 유지하는 신뢰할 수 있는 방법입니다.
|
||||
BlueBubbles Private API가 활성화되면 인바운드 메시지는 짧은 메시지 ID(예: `[[reply_to:5]]`)와 함께 도착하며, 에이전트는 `action=reply`를 호출해 특정 메시지에 스레드로 답하거나 `action=react`를 호출해 tapback을 남길 수 있습니다. 그룹별 `systemPrompt`는 에이전트가 올바른 도구를 선택하도록 유지하는 신뢰할 수 있는 방법입니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -274,15 +274,7 @@ BlueBubbles Private API가 활성화되어 있으면 인바운드 메시지는
|
||||
bluebubbles: {
|
||||
groups: {
|
||||
"iMessage;+;chat-family": {
|
||||
systemPrompt: [
|
||||
"When replying in this group, always call action=reply with the",
|
||||
"[[reply_to:N]] messageId from context so your response threads",
|
||||
"under the triggering message. Never send a new unlinked message.",
|
||||
"",
|
||||
"For short acknowledgements ('ok', 'got it', 'on it'), use",
|
||||
"action=react with an appropriate tapback emoji (❤️, 👍, 😂, ‼️, ❓)",
|
||||
"instead of sending a text reply.",
|
||||
].join(" "),
|
||||
systemPrompt: "When replying in this group, always call action=reply with the [[reply_to:N]] messageId from context so your response threads under the triggering message. Never send a new unlinked message. For short acknowledgements ('ok', 'got it', 'on it'), use action=react with an appropriate tapback emoji (❤️, 👍, 😂, ‼️, ❓) instead of sending a text reply.",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -290,7 +282,7 @@ BlueBubbles Private API가 활성화되어 있으면 인바운드 메시지는
|
||||
}
|
||||
```
|
||||
|
||||
탭백 반응과 스레드 답장 모두 BlueBubbles Private API가 필요합니다. 기본 메커니즘은 [고급 작업](#advanced-actions) 및 [메시지 ID](#message-ids-short-vs-full)를 참조하세요.
|
||||
tapback 반응과 스레드 답장은 모두 BlueBubbles Private API가 필요합니다. 기본 메커니즘은 [고급 작업](#advanced-actions) 및 [메시지 ID](#message-ids-short-vs-full)를 참조하세요.
|
||||
|
||||
## ACP 대화 바인딩
|
||||
|
||||
@ -299,11 +291,11 @@ BlueBubbles 채팅은 전송 계층을 변경하지 않고도 지속적인 ACP
|
||||
빠른 운영자 흐름:
|
||||
|
||||
- DM 또는 허용된 그룹 채팅 안에서 `/acp spawn codex --bind here`를 실행합니다.
|
||||
- 이후 동일한 BlueBubbles 대화의 메시지는 생성된 ACP 세션으로 라우팅됩니다.
|
||||
- 이후 같은 BlueBubbles 대화의 메시지는 생성된 ACP 세션으로 라우팅됩니다.
|
||||
- `/new` 및 `/reset`은 동일한 바인딩된 ACP 세션을 제자리에서 재설정합니다.
|
||||
- `/acp close`는 ACP 세션을 닫고 바인딩을 제거합니다.
|
||||
|
||||
구성된 영구 바인딩은 `type: "acp"` 및 `match.channel: "bluebubbles"`가 있는 최상위 `bindings[]` 항목을 통해서도 지원됩니다.
|
||||
구성된 영구 바인딩은 최상위 `bindings[]` 항목을 통해서도 지원되며 `type: "acp"` 및 `match.channel: "bluebubbles"`를 사용합니다.
|
||||
|
||||
`match.peer.id`는 지원되는 모든 BlueBubbles 대상 형식을 사용할 수 있습니다.
|
||||
|
||||
@ -312,7 +304,7 @@ BlueBubbles 채팅은 전송 계층을 변경하지 않고도 지속적인 ACP
|
||||
- `chat_guid:<guid>`
|
||||
- `chat_identifier:<identifier>`
|
||||
|
||||
안정적인 그룹 바인딩에는 `chat_id:*` 또는 `chat_identifier:*`를 선호하세요.
|
||||
안정적인 그룹 바인딩에는 `chat_id:*` 또는 `chat_identifier:*`를 권장합니다.
|
||||
|
||||
예:
|
||||
|
||||
@ -350,7 +342,7 @@ BlueBubbles 채팅은 전송 계층을 변경하지 않고도 지속적인 ACP
|
||||
|
||||
- **입력 표시기**: 응답 생성 전과 생성 중에 자동으로 전송됩니다.
|
||||
- **읽음 확인**: `channels.bluebubbles.sendReadReceipts`로 제어됩니다(기본값: `true`).
|
||||
- **입력 표시기**: OpenClaw는 입력 시작 이벤트를 전송합니다. BlueBubbles는 전송 또는 시간 초과 시 입력 상태를 자동으로 지웁니다(DELETE를 통한 수동 중지는 신뢰할 수 없습니다).
|
||||
- **입력 표시기**: OpenClaw는 입력 시작 이벤트를 전송합니다. BlueBubbles는 전송 또는 시간 초과 시 입력 상태를 자동으로 지웁니다(DELETE를 통한 수동 중지는 신뢰할 수 없음).
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -362,9 +354,9 @@ BlueBubbles 채팅은 전송 계층을 변경하지 않고도 지속적인 ACP
|
||||
}
|
||||
```
|
||||
|
||||
## 고급 동작
|
||||
## 고급 작업
|
||||
|
||||
BlueBubbles는 설정에서 활성화된 경우 고급 메시지 동작을 지원합니다.
|
||||
BlueBubbles는 구성에서 활성화하면 고급 메시지 작업을 지원합니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -389,68 +381,68 @@ BlueBubbles는 설정에서 활성화된 경우 고급 메시지 동작을 지
|
||||
```
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Available actions">
|
||||
- **react**: Tapback 반응을 추가/제거합니다(`messageId`, `emoji`, `remove`). iMessage의 기본 tapback 세트는 `love`, `like`, `dislike`, `laugh`, `emphasize`, `question`입니다. 에이전트가 해당 세트 밖의 이모지(예: `👀`)를 선택하면, 반응 도구는 전체 요청을 실패시키지 않고 tapback이 계속 렌더링되도록 `love`로 폴백합니다. 구성된 확인 반응은 여전히 엄격하게 검증되며 알 수 없는 값에서는 오류가 발생합니다.
|
||||
- **edit**: 보낸 메시지를 편집합니다(`messageId`, `text`).
|
||||
- **unsend**: 메시지 전송을 취소합니다(`messageId`).
|
||||
<Accordion title="사용 가능한 작업">
|
||||
- **react**: tapback 반응을 추가/제거합니다(`messageId`, `emoji`, `remove`). iMessage의 기본 tapback 세트는 `love`, `like`, `dislike`, `laugh`, `emphasize`, `question`입니다. 에이전트가 해당 세트 밖의 이모지(예: `👀`)를 선택하면, 전체 요청을 실패시키는 대신 tapback이 계속 렌더링되도록 반응 도구가 `love`로 대체합니다. 구성된 확인 반응은 여전히 엄격하게 검증되며 알 수 없는 값에서는 오류가 발생합니다.
|
||||
- **edit**: 보낸 메시지를 수정합니다(`messageId`, `text`).
|
||||
- **unsend**: 메시지 보내기를 취소합니다(`messageId`).
|
||||
- **reply**: 특정 메시지에 답장합니다(`messageId`, `text`, `to`).
|
||||
- **sendWithEffect**: iMessage 효과와 함께 보냅니다(`text`, `to`, `effectId`).
|
||||
- **renameGroup**: 그룹 채팅 이름을 변경합니다(`chatGuid`, `displayName`).
|
||||
- **setGroupIcon**: 그룹 채팅의 아이콘/사진을 설정합니다(`chatGuid`, `media`). macOS 26 Tahoe에서는 불안정합니다(API가 성공을 반환해도 아이콘이 동기화되지 않을 수 있음).
|
||||
- **addParticipant**: 그룹에 사람을 추가합니다(`chatGuid`, `address`).
|
||||
- **removeParticipant**: 그룹에서 사람을 제거합니다(`chatGuid`, `address`).
|
||||
- **leaveGroup**: 그룹 채팅에서 나갑니다(`chatGuid`).
|
||||
- **leaveGroup**: 그룹 채팅을 나갑니다(`chatGuid`).
|
||||
- **upload-file**: 미디어/파일을 보냅니다(`to`, `buffer`, `filename`, `asVoice`).
|
||||
- 음성 메모: **MP3** 또는 **CAF** 오디오와 함께 `asVoice: true`를 설정하면 iMessage 음성 메시지로 보낼 수 있습니다. BlueBubbles는 음성 메모를 보낼 때 MP3 → CAF로 변환합니다.
|
||||
- 레거시 별칭: `sendAttachment`도 여전히 동작하지만, 정식 동작 이름은 `upload-file`입니다.
|
||||
- 음성 메모: **MP3** 또는 **CAF** 오디오와 함께 `asVoice: true`를 설정하여 iMessage 음성 메시지로 보냅니다. BlueBubbles는 음성 메모를 보낼 때 MP3 → CAF로 변환합니다.
|
||||
- 레거시 별칭: `sendAttachment`는 여전히 작동하지만, 표준 작업 이름은 `upload-file`입니다.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
### 메시지 ID(짧은 형식 vs 전체 형식)
|
||||
### 메시지 ID(짧은 형식과 전체 형식)
|
||||
|
||||
OpenClaw는 토큰을 절약하기 위해 _짧은_ 메시지 ID(예: `1`, `2`)를 노출할 수 있습니다.
|
||||
OpenClaw는 토큰을 절약하기 위해 _짧은_ 메시지 ID(예: `1`, `2`)를 표시할 수 있습니다.
|
||||
|
||||
- `MessageSid` / `ReplyToId`는 짧은 ID일 수 있습니다.
|
||||
- `MessageSidFull` / `ReplyToIdFull`에는 제공자의 전체 ID가 들어 있습니다.
|
||||
- `MessageSidFull` / `ReplyToIdFull`에는 provider 전체 ID가 들어 있습니다.
|
||||
- 짧은 ID는 메모리 내에만 있으며, 재시작 또는 캐시 제거 시 만료될 수 있습니다.
|
||||
- 동작은 짧은 `messageId` 또는 전체 `messageId`를 허용하지만, 짧은 ID를 더 이상 사용할 수 없으면 오류가 발생합니다.
|
||||
- 작업은 짧은 `messageId` 또는 전체 `messageId`를 모두 허용하지만, 짧은 ID를 더 이상 사용할 수 없으면 오류가 발생합니다.
|
||||
|
||||
내구성 있는 자동화와 저장에는 전체 ID를 사용하세요.
|
||||
내구성 있는 자동화 및 저장에는 전체 ID를 사용하세요.
|
||||
|
||||
- 템플릿: `{{MessageSidFull}}`, `{{ReplyToIdFull}}`
|
||||
- 컨텍스트: 인바운드 페이로드의 `MessageSidFull` / `ReplyToIdFull`
|
||||
|
||||
템플릿 변수는 [설정](/ko/gateway/configuration)을 참고하세요.
|
||||
템플릿 변수는 [구성](/ko/gateway/configuration)을 참조하세요.
|
||||
|
||||
<a id="coalescing-split-send-dms-command--url-in-one-composition"></a>
|
||||
|
||||
## 분할 전송 DM 병합(한 번의 작성에 명령 + URL)
|
||||
## 분할 전송 DM 병합(하나의 작성 내용에 명령 + URL)
|
||||
|
||||
사용자가 iMessage에서 명령과 URL을 함께 입력하면(예: `Dump https://example.com/article`) Apple은 전송을 **두 개의 별도 Webhook 전달**로 분할합니다.
|
||||
|
||||
1. 텍스트 메시지(`"Dump"`).
|
||||
2. OG 미리보기 이미지가 첨부된 URL 미리보기 말풍선(`"https://..."`).
|
||||
2. 첨부 파일로 OG 미리보기 이미지가 포함된 URL 미리보기 말풍선(`"https://..."`).
|
||||
|
||||
대부분의 설정에서 두 Webhook은 약 0.8~2.0초 간격으로 OpenClaw에 도착합니다. 병합이 없으면 에이전트는 1턴에서 명령만 받고 응답하며(흔히 "URL을 보내 달라"는 식), 2턴에서야 URL을 보게 됩니다. 이때는 이미 명령 컨텍스트가 사라진 상태입니다.
|
||||
대부분의 설정에서 두 Webhook은 약 0.8~2.0초 간격으로 OpenClaw에 도착합니다. 병합하지 않으면 에이전트는 1턴에서 명령만 받고 응답하며(대개 "URL을 보내 주세요"), 2턴에서야 URL을 보게 됩니다. 이때는 이미 명령 컨텍스트가 사라진 뒤입니다.
|
||||
|
||||
`channels.bluebubbles.coalesceSameSenderDms`는 DM에서 같은 발신자의 연속 Webhook을 단일 에이전트 턴으로 병합하도록 선택합니다. 그룹 채팅은 다중 사용자 턴 구조를 보존하기 위해 계속 메시지별로 키를 지정합니다.
|
||||
`channels.bluebubbles.coalesceSameSenderDms`는 DM에서 연속된 동일 발신자 Webhook을 하나의 에이전트 턴으로 병합하도록 선택합니다. 그룹 채팅은 다중 사용자 턴 구조를 보존하기 위해 계속 메시지별로 키를 지정합니다.
|
||||
|
||||
<Tabs>
|
||||
<Tab title="When to enable">
|
||||
<Tab title="활성화해야 하는 경우">
|
||||
다음 경우 활성화하세요.
|
||||
|
||||
- 한 메시지에서 `command + payload`를 기대하는 skills를 배포합니다(dump, paste, save, queue 등).
|
||||
- 사용자가 명령과 함께 URL, 이미지 또는 긴 콘텐츠를 붙여 넣습니다.
|
||||
- 추가되는 DM 턴 지연 시간을 허용할 수 있습니다(아래 참고).
|
||||
- 하나의 메시지에 `command + payload`가 있어야 하는 skills를 배포하는 경우(dump, paste, save, queue 등).
|
||||
- 사용자가 명령과 함께 URL, 이미지 또는 긴 콘텐츠를 붙여 넣는 경우.
|
||||
- 추가되는 DM 턴 지연 시간을 허용할 수 있는 경우(아래 참조).
|
||||
|
||||
다음 경우 비활성화된 상태로 두세요.
|
||||
다음 경우 비활성화 상태로 두세요.
|
||||
|
||||
- 한 단어 DM 트리거에 최소 명령 지연 시간이 필요합니다.
|
||||
- 모든 흐름이 후속 페이로드 없는 일회성 명령입니다.
|
||||
- 단일 단어 DM 트리거에 대해 최소 명령 지연 시간이 필요한 경우.
|
||||
- 모든 플로가 payload 후속 입력 없는 일회성 명령인 경우.
|
||||
|
||||
</Tab>
|
||||
<Tab title="Enabling">
|
||||
<Tab title="활성화">
|
||||
```json5
|
||||
{
|
||||
channels: {
|
||||
@ -461,9 +453,9 @@ OpenClaw는 토큰을 절약하기 위해 _짧은_ 메시지 ID(예: `1`, `2`)
|
||||
}
|
||||
```
|
||||
|
||||
플래그가 켜져 있고 명시적인 `messages.inbound.byChannel.bluebubbles`가 없으면 디바운스 창이 **2500 ms**로 넓어집니다(병합하지 않을 때의 기본값은 500 ms). 더 넓은 창이 필요합니다. Apple의 분할 전송 간격인 0.8~2.0초는 더 좁은 기본값에 맞지 않습니다.
|
||||
플래그가 켜져 있고 명시적인 `messages.inbound.byChannel.bluebubbles`가 없으면 debounce 윈도우가 **2500 ms**로 넓어집니다(비병합 기본값은 500 ms). 더 넓은 윈도우가 필요합니다. Apple의 0.8~2.0초 분할 전송 간격은 더 좁은 기본값에 맞지 않습니다.
|
||||
|
||||
창을 직접 조정하려면:
|
||||
윈도우를 직접 조정하려면 다음을 사용하세요.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -480,62 +472,62 @@ OpenClaw는 토큰을 절약하기 위해 _짧은_ 메시지 ID(예: `1`, `2`)
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab title="Trade-offs">
|
||||
- **DM 제어 명령에 추가 지연이 발생합니다.** 플래그가 켜져 있으면 DM 제어 명령 메시지(예: `Dump`, `Save` 등)는 페이로드 Webhook이 올 수 있으므로 디스패치 전에 최대 디바운스 창만큼 기다립니다. 그룹 채팅 명령은 즉시 디스패치됩니다.
|
||||
- **병합된 출력은 제한됩니다.** 병합된 텍스트는 명시적인 `…[truncated]` 표시와 함께 4000자로 제한됩니다. 첨부 파일은 20개로 제한됩니다. 소스 항목은 10개로 제한됩니다(그 이상은 첫 항목과 최신 항목을 유지). 모든 소스 `messageId`는 여전히 인바운드 중복 제거에 도달하므로, 나중에 MessagePoller가 개별 이벤트를 재생해도 중복으로 인식됩니다.
|
||||
<Tab title="트레이드오프">
|
||||
- **DM 제어 명령의 지연 시간 증가.** 플래그가 켜져 있으면 DM 제어 명령 메시지(예: `Dump`, `Save` 등)는 payload Webhook이 들어올 수 있으므로 dispatch 전에 최대 debounce 윈도우까지 기다립니다. 그룹 채팅 명령은 즉시 dispatch를 유지합니다.
|
||||
- **병합된 출력에는 한계가 있습니다.** 병합 텍스트는 명시적인 `…[truncated]` 표시와 함께 4000자로 제한됩니다. 첨부 파일은 20개로 제한됩니다. source 항목은 10개로 제한됩니다(이를 초과하면 처음 항목과 최신 항목을 유지). 모든 source `messageId`는 여전히 인바운드 중복 제거에 도달하므로, 나중에 MessagePoller가 개별 이벤트를 다시 재생해도 중복으로 인식됩니다.
|
||||
- **채널별 옵트인입니다.** 다른 채널(Telegram, WhatsApp, Slack, …)에는 영향을 주지 않습니다.
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### 시나리오와 에이전트가 보는 내용
|
||||
### 시나리오 및 에이전트가 보는 내용
|
||||
|
||||
| 사용자가 작성한 내용 | Apple 전달 방식 | 플래그 꺼짐(기본값) | 플래그 켜짐 + 2500 ms 창 |
|
||||
| 사용자가 작성한 내용 | Apple 전달 | 플래그 꺼짐(기본값) | 플래그 켜짐 + 2500 ms 윈도우 |
|
||||
| ------------------------------------------------------------------ | ------------------------- | --------------------------------------- | ----------------------------------------------------------------------- |
|
||||
| `Dump https://example.com`(한 번 전송) | 약 1초 간격의 Webhook 2개 | 두 에이전트 턴: "Dump"만, 그다음 URL | 한 턴: 병합된 텍스트 `Dump https://example.com` |
|
||||
| `Save this 📎image.jpg caption`(첨부 파일 + 텍스트) | Webhook 2개 | 두 턴 | 한 턴: 텍스트 + 이미지 |
|
||||
| `/status`(독립 명령) | Webhook 1개 | 즉시 디스패치 | **최대 창만큼 기다린 뒤 디스패치** |
|
||||
| URL만 붙여 넣음 | Webhook 1개 | 즉시 디스패치 | 즉시 디스패치(버킷에 항목이 하나뿐임) |
|
||||
| 텍스트 + URL을 몇 분 간격으로 의도적으로 별도 메시지 2개로 전송 | 창 밖의 Webhook 2개 | 두 턴 | 두 턴(그 사이에 창 만료) |
|
||||
| 빠른 폭주(창 안에 작은 DM 10개 초과) | Webhook N개 | N턴 | 한 턴, 제한된 출력(첫 항목 + 최신 항목, 텍스트/첨부 파일 제한 적용) |
|
||||
| `Dump https://example.com`(한 번 전송) | 약 1초 간격의 Webhook 2개 | 두 에이전트 턴: "Dump"만, 이후 URL | 한 턴: 병합된 텍스트 `Dump https://example.com` |
|
||||
| `Save this 📎image.jpg caption`(첨부 파일 + 텍스트) | Webhook 2개 | 두 턴 | 한 턴: 텍스트 + 이미지 |
|
||||
| `/status`(독립 명령) | Webhook 1개 | 즉시 dispatch | **최대 윈도우까지 기다린 뒤 dispatch** |
|
||||
| URL만 붙여넣음 | Webhook 1개 | 즉시 dispatch | 즉시 dispatch(버킷에 항목이 하나뿐임) |
|
||||
| 텍스트 + URL을 몇 분 간격으로 의도적으로 별도 메시지 두 개로 전송 | 윈도우 밖의 Webhook 2개 | 두 턴 | 두 턴(그 사이 윈도우 만료) |
|
||||
| 빠른 폭주(윈도우 안에서 작은 DM 10개 초과) | Webhook N개 | N턴 | 한 턴, 제한된 출력(처음 + 최신, 텍스트/첨부 파일 한도 적용) |
|
||||
|
||||
### 분할 전송 병합 문제 해결
|
||||
|
||||
플래그가 켜져 있는데도 분할 전송이 여전히 두 턴으로 도착하면 각 계층을 확인하세요.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Config actually loaded">
|
||||
<Accordion title="구성이 실제로 로드됨">
|
||||
```
|
||||
grep coalesceSameSenderDms ~/.openclaw/openclaw.json
|
||||
```
|
||||
|
||||
그런 다음 `openclaw gateway restart`를 실행합니다. 플래그는 디바운서 레지스트리 생성 시 읽힙니다.
|
||||
그런 다음 `openclaw gateway restart`를 실행하세요. 플래그는 debouncer-registry 생성 시 읽힙니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Debounce window wide enough for your setup">
|
||||
<Accordion title="설정에 충분히 넓은 debounce 윈도우">
|
||||
`~/Library/Logs/bluebubbles-server/main.log` 아래의 BlueBubbles 서버 로그를 확인하세요.
|
||||
|
||||
```
|
||||
grep -E "Dispatching event to webhook" main.log | tail -20
|
||||
```
|
||||
|
||||
`"Dump"` 스타일 텍스트 디스패치와 그 뒤에 오는 `"https://..."; Attachments:` 디스패치 사이의 간격을 측정합니다. `messages.inbound.byChannel.bluebubbles`를 해당 간격을 충분히 덮도록 올리세요.
|
||||
`"Dump"` 스타일 텍스트 dispatch와 뒤따르는 `"https://..."; Attachments:` dispatch 사이의 간격을 측정하세요. 해당 간격을 여유 있게 포함하도록 `messages.inbound.byChannel.bluebubbles`를 늘리세요.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Session JSONL timestamps ≠ webhook arrival">
|
||||
세션 이벤트 타임스탬프(`~/.openclaw/agents/<id>/sessions/*.jsonl`)는 Webhook이 도착한 시점이 아니라 Gateway가 메시지를 에이전트에 넘긴 시점을 반영합니다. `[Queued messages while agent was busy]`로 태그된 대기 중인 두 번째 메시지는 두 번째 Webhook이 도착했을 때 첫 번째 턴이 아직 실행 중이었다는 뜻입니다. 병합 버킷은 이미 플러시된 상태였습니다. 세션 로그가 아니라 BB 서버 로그를 기준으로 창을 조정하세요.
|
||||
<Accordion title="세션 JSONL 타임스탬프 ≠ Webhook 도착">
|
||||
세션 이벤트 타임스탬프(`~/.openclaw/agents/<id>/sessions/*.jsonl`)는 Webhook이 도착한 시점이 **아니라** Gateway가 메시지를 에이전트에 넘긴 시점을 반영합니다. `[Queued messages while agent was busy]` 태그가 붙은 대기 중 두 번째 메시지는 두 번째 Webhook이 도착했을 때 첫 번째 턴이 아직 실행 중이었다는 뜻입니다. 병합 버킷은 이미 flush된 상태였습니다. 세션 로그가 아니라 BB 서버 로그를 기준으로 윈도우를 조정하세요.
|
||||
</Accordion>
|
||||
<Accordion title="Memory pressure slowing reply dispatch">
|
||||
더 작은 머신(8 GB)에서는 에이전트 턴이 충분히 오래 걸려 응답이 완료되기 전에 병합 버킷이 플러시되고, URL이 대기 중인 두 번째 턴으로 들어갈 수 있습니다. `memory_pressure`와 `ps -o rss -p $(pgrep openclaw-gateway)`를 확인하세요. Gateway가 약 500 MB RSS를 넘고 압축기가 활성 상태라면 다른 무거운 프로세스를 닫거나 더 큰 호스트로 올리세요.
|
||||
<Accordion title="메모리 압박으로 인한 답장 dispatch 지연">
|
||||
더 작은 머신(8 GB)에서는 에이전트 턴이 충분히 오래 걸려 답장이 완료되기 전에 병합 버킷이 flush되고 URL이 대기 중 두 번째 턴으로 들어갈 수 있습니다. `memory_pressure` 및 `ps -o rss -p $(pgrep openclaw-gateway)`를 확인하세요. Gateway가 약 500 MB RSS를 넘고 compressor가 활성 상태라면 다른 무거운 프로세스를 닫거나 더 큰 호스트로 올리세요.
|
||||
</Accordion>
|
||||
<Accordion title="Reply-quote sends are a different path">
|
||||
사용자가 기존 URL 말풍선에 대한 **답장**으로 `Dump`를 탭했다면(iMessage가 Dump 말풍선에 "1 Reply" 배지를 표시), URL은 두 번째 Webhook이 아니라 `replyToBody`에 있습니다. 병합은 적용되지 않습니다. 이는 디바운서 문제가 아니라 skill/프롬프트 문제입니다.
|
||||
<Accordion title="답장 인용 전송은 다른 경로">
|
||||
사용자가 기존 URL 말풍선에 **답장**으로 `Dump`를 탭한 경우(iMessage가 Dump 말풍선에 "1 Reply" 배지를 표시), URL은 두 번째 Webhook이 아니라 `replyToBody`에 있습니다. 병합은 적용되지 않습니다. 이는 debouncer 문제가 아니라 skill/prompt 관련 문제입니다.
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 블록 스트리밍
|
||||
|
||||
응답을 단일 메시지로 보낼지 블록 단위로 스트리밍할지 제어합니다.
|
||||
응답을 단일 메시지로 보낼지 블록으로 스트리밍할지 제어합니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -550,50 +542,50 @@ OpenClaw는 토큰을 절약하기 위해 _짧은_ 메시지 ID(예: `1`, `2`)
|
||||
## 미디어 + 제한
|
||||
|
||||
- 인바운드 첨부 파일은 다운로드되어 미디어 캐시에 저장됩니다.
|
||||
- 인바운드 및 아웃바운드 미디어의 미디어 한도는 `channels.bluebubbles.mediaMaxMb`를 통해 설정합니다(기본값: 8 MB).
|
||||
- 인바운드 및 아웃바운드 미디어에 대해 `channels.bluebubbles.mediaMaxMb`로 미디어 한도를 설정합니다(기본값: 8 MB).
|
||||
- 아웃바운드 텍스트는 `channels.bluebubbles.textChunkLimit`에 따라 청크로 나뉩니다(기본값: 4000자).
|
||||
|
||||
## 설정 참조
|
||||
## 구성 참조
|
||||
|
||||
전체 설정: [설정](/ko/gateway/configuration)
|
||||
전체 구성: [구성](/ko/gateway/configuration)
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Connection and webhook">
|
||||
<Accordion title="연결 및 Webhook">
|
||||
- `channels.bluebubbles.enabled`: 채널을 활성화/비활성화합니다.
|
||||
- `channels.bluebubbles.serverUrl`: BlueBubbles REST API 기본 URL입니다.
|
||||
- `channels.bluebubbles.password`: API 비밀번호입니다.
|
||||
- `channels.bluebubbles.webhookPath`: Webhook 엔드포인트 경로입니다(기본값: `/bluebubbles-webhook`).
|
||||
- `channels.bluebubbles.serverUrl`: BlueBubbles REST API 기본 URL.
|
||||
- `channels.bluebubbles.password`: API 비밀번호.
|
||||
- `channels.bluebubbles.webhookPath`: Webhook 엔드포인트 경로(기본값: `/bluebubbles-webhook`).
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Access policy">
|
||||
<Accordion title="접근 정책">
|
||||
- `channels.bluebubbles.dmPolicy`: `pairing | allowlist | open | disabled`(기본값: `pairing`).
|
||||
- `channels.bluebubbles.allowFrom`: DM 허용 목록입니다(핸들, 이메일, E.164 번호, `chat_id:*`, `chat_guid:*`).
|
||||
- `channels.bluebubbles.allowFrom`: DM 허용 목록(handles, emails, E.164 numbers, `chat_id:*`, `chat_guid:*`).
|
||||
- `channels.bluebubbles.groupPolicy`: `open | allowlist | disabled`(기본값: `allowlist`).
|
||||
- `channels.bluebubbles.groupAllowFrom`: 그룹 발신자 허용 목록입니다.
|
||||
- `channels.bluebubbles.enrichGroupParticipantsFromContacts`: macOS에서 게이트 통과 후 이름 없는 그룹 참여자를 로컬 연락처에서 선택적으로 보강합니다. 기본값: `false`.
|
||||
- `channels.bluebubbles.groups`: 그룹별 설정입니다(`requireMention` 등).
|
||||
- `channels.bluebubbles.groupAllowFrom`: 그룹 발신자 허용 목록.
|
||||
- `channels.bluebubbles.enrichGroupParticipantsFromContacts`: macOS에서, 게이트 통과 후 이름 없는 그룹 참여자를 로컬 연락처에서 선택적으로 보강합니다. 기본값: `false`.
|
||||
- `channels.bluebubbles.groups`: 그룹별 구성(`requireMention` 등).
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="전송 및 청크 처리">
|
||||
- `channels.bluebubbles.sendReadReceipts`: 읽음 확인을 보냅니다(기본값: `true`).
|
||||
- `channels.bluebubbles.blockStreaming`: 블록 스트리밍을 활성화합니다(기본값: `false`; 스트리밍 답장에 필요).
|
||||
- `channels.bluebubbles.textChunkLimit`: 발신 청크 크기(문자 수, 기본값: 4000).
|
||||
- `channels.bluebubbles.sendTimeoutMs`: `/api/v1/message/text`를 통한 발신 텍스트 전송의 요청당 제한 시간(ms, 기본값: 30000). Private API iMessage 전송이 iMessage 프레임워크 안에서 60초 이상 멈출 수 있는 macOS 26 설정에서는 값을 높이세요. 예: `45000` 또는 `60000`. 프로브, 채팅 조회, 반응, 편집, 상태 확인은 현재 더 짧은 10초 기본값을 유지합니다. 반응과 편집까지 적용 범위를 넓히는 작업은 후속으로 계획되어 있습니다. 계정별 재정의: `channels.bluebubbles.accounts.<accountId>.sendTimeoutMs`.
|
||||
- `channels.bluebubbles.sendTimeoutMs`: `/api/v1/message/text`를 통한 발신 텍스트 전송의 요청별 제한 시간(ms)(기본값: 30000). Private API iMessage 전송이 iMessage 프레임워크 내부에서 60초 이상 멈출 수 있는 macOS 26 설정에서는 값을 높이세요. 예: `45000` 또는 `60000`. 프로브, 채팅 조회, 반응, 편집, 상태 확인은 현재 더 짧은 10초 기본값을 유지합니다. 반응과 편집까지 적용 범위를 넓히는 작업은 후속으로 계획되어 있습니다. 계정별 재정의: `channels.bluebubbles.accounts.<accountId>.sendTimeoutMs`.
|
||||
- `channels.bluebubbles.chunkMode`: `length`(기본값)는 `textChunkLimit`를 초과할 때만 분할합니다. `newline`은 길이 기반 청크 처리 전에 빈 줄(문단 경계)에서 분할합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="미디어 및 기록">
|
||||
- `channels.bluebubbles.mediaMaxMb`: 수신/발신 미디어 상한(MB, 기본값: 8).
|
||||
- `channels.bluebubbles.mediaLocalRoots`: 발신 로컬 미디어 경로에 허용되는 절대 로컬 디렉터리의 명시적 허용 목록입니다. 이를 구성하지 않으면 로컬 경로 전송은 기본적으로 거부됩니다. 계정별 재정의: `channels.bluebubbles.accounts.<accountId>.mediaLocalRoots`.
|
||||
- `channels.bluebubbles.coalesceSameSenderDms`: 같은 발신자가 연속으로 보낸 DM Webhook을 하나의 에이전트 턴으로 병합하여 Apple의 텍스트+URL 분할 전송이 단일 메시지로 도착하게 합니다(기본값: `false`). 시나리오, 창 조정, 트레이드오프는 [분할 전송 DM 병합](#coalescing-split-send-dms-command--url-in-one-composition)을 참고하세요. 명시적인 `messages.inbound.byChannel.bluebubbles` 없이 활성화하면 기본 수신 디바운스 창이 500 ms에서 2500 ms로 넓어집니다.
|
||||
- `channels.bluebubbles.mediaMaxMb`: 수신/발신 미디어 한도(MB)(기본값: 8).
|
||||
- `channels.bluebubbles.mediaLocalRoots`: 발신 로컬 미디어 경로에 허용되는 절대 로컬 디렉터리의 명시적 허용 목록입니다. 이 항목이 구성되지 않으면 로컬 경로 전송은 기본적으로 거부됩니다. 계정별 재정의: `channels.bluebubbles.accounts.<accountId>.mediaLocalRoots`.
|
||||
- `channels.bluebubbles.coalesceSameSenderDms`: 연속된 동일 발신자 DM Webhook을 하나의 에이전트 턴으로 병합하여 Apple의 텍스트+URL 분리 전송이 단일 메시지로 도착하게 합니다(기본값: `false`). 시나리오, 창 조정, 트레이드오프는 [분리 전송 DM 병합](#coalescing-split-send-dms-command--url-in-one-composition)을 참고하세요. 명시적 `messages.inbound.byChannel.bluebubbles` 없이 활성화하면 기본 수신 디바운스 창을 500ms에서 2500ms로 넓힙니다.
|
||||
- `channels.bluebubbles.historyLimit`: 컨텍스트용 최대 그룹 메시지 수(0은 비활성화).
|
||||
- `channels.bluebubbles.dmHistoryLimit`: DM 기록 제한.
|
||||
- `channels.bluebubbles.replyContextApiFallback`: 수신 답장에 `replyToBody`/`replyToSender`가 없고 메모리 내 답장 컨텍스트 캐시도 빗나간 경우, 최선형 폴백으로 BlueBubbles HTTP API에서 원본 메시지를 가져옵니다(기본값: `false`). 하나의 BlueBubbles 계정을 공유하는 다중 인스턴스 배포, 프로세스 재시작 후, 또는 장기 TTL/LRU 캐시 축출 후에 유용합니다. 가져오기는 다른 모든 BlueBubbles 클라이언트 요청과 동일한 정책으로 SSRF 보호되며, 절대 예외를 던지지 않고, 이후 답장이 분산 처리되도록 캐시를 채웁니다. 계정별 재정의: `channels.bluebubbles.accounts.<accountId>.replyContextApiFallback`. 채널 수준 설정은 해당 플래그를 생략한 계정으로 전파됩니다.
|
||||
- `channels.bluebubbles.dmHistoryLimit`: DM 기록 한도.
|
||||
- `channels.bluebubbles.replyContextApiFallback`: 수신 답장이 `replyToBody`/`replyToSender` 없이 도착하고 메모리 내 답장 컨텍스트 캐시가 누락되면, 최선의 폴백으로 BlueBubbles HTTP API에서 원본 메시지를 가져옵니다(기본값: `false`). 하나의 BlueBubbles 계정을 공유하는 다중 인스턴스 배포, 프로세스 재시작 후, 또는 장기 TTL/LRU 캐시 축출 후에 유용합니다. 가져오기는 다른 모든 BlueBubbles 클라이언트 요청과 동일한 정책으로 SSRF 보호를 받으며, 예외를 던지지 않고, 이후 답장이 비용을 분산할 수 있도록 캐시를 채웁니다. 계정별 재정의: `channels.bluebubbles.accounts.<accountId>.replyContextApiFallback`. 채널 수준 설정은 해당 플래그를 생략한 계정에 전파됩니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="작업 및 계정">
|
||||
- `channels.bluebubbles.actions`: 특정 작업을 활성화/비활성화합니다.
|
||||
- `channels.bluebubbles.accounts`: 다중 계정 구성.
|
||||
- `channels.bluebubbles.accounts`: 다중 계정 구성입니다.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
@ -615,32 +607,32 @@ OpenClaw는 토큰을 절약하기 위해 _짧은_ 메시지 ID(예: `1`, `2`)
|
||||
|
||||
### iMessage와 SMS 라우팅
|
||||
|
||||
동일한 핸들이 Mac에서 iMessage 채팅과 SMS 채팅을 모두 가지고 있는 경우(예: iMessage에 등록되어 있지만 초록 말풍선 폴백도 수신한 전화번호), OpenClaw는 iMessage 채팅을 선호하며 자동으로 SMS로 다운그레이드하지 않습니다. SMS 채팅을 강제로 사용하려면 명시적인 `sms:` 대상 접두사를 사용하세요(예: `sms:+15555550123`). 일치하는 iMessage 채팅이 없는 핸들은 BlueBubbles가 보고하는 채팅을 통해 그대로 전송됩니다.
|
||||
Mac에서 동일한 핸들에 iMessage 채팅과 SMS 채팅이 모두 있는 경우(예: iMessage에 등록되어 있지만 초록 말풍선 폴백도 받은 전화번호), OpenClaw는 iMessage 채팅을 선호하며 묵시적으로 SMS로 낮추지 않습니다. SMS 채팅을 강제하려면 명시적 `sms:` 대상 접두사를 사용하세요(예: `sms:+15555550123`). 일치하는 iMessage 채팅이 없는 핸들은 BlueBubbles가 보고하는 채팅을 통해 그대로 전송됩니다.
|
||||
|
||||
## 보안
|
||||
|
||||
- Webhook 요청은 `guid`/`password` 쿼리 매개변수 또는 헤더를 `channels.bluebubbles.password`와 비교하여 인증됩니다.
|
||||
- API 비밀번호와 Webhook 엔드포인트를 비밀로 유지하세요(자격 증명처럼 취급하세요).
|
||||
- BlueBubbles Webhook 인증에는 localhost 우회가 없습니다. Webhook 트래픽을 프록시하는 경우 요청의 처음부터 끝까지 BlueBubbles 비밀번호를 유지하세요. 여기서 `gateway.trustedProxies`는 `channels.bluebubbles.password`를 대체하지 않습니다. [Gateway 보안](/ko/gateway/security#reverse-proxy-configuration)을 참고하세요.
|
||||
- API 비밀번호와 Webhook 엔드포인트는 비밀로 유지하세요(자격 증명처럼 취급).
|
||||
- BlueBubbles Webhook 인증에는 localhost 우회가 없습니다. Webhook 트래픽을 프록시하는 경우, 요청의 처음부터 끝까지 BlueBubbles 비밀번호를 유지하세요. 여기서 `gateway.trustedProxies`는 `channels.bluebubbles.password`를 대체하지 않습니다. [Gateway 보안](/ko/gateway/security#reverse-proxy-configuration)을 참고하세요.
|
||||
- LAN 외부에 노출하는 경우 BlueBubbles 서버에서 HTTPS와 방화벽 규칙을 활성화하세요.
|
||||
|
||||
## 문제 해결
|
||||
|
||||
- 입력/읽음 이벤트가 작동을 멈추면 BlueBubbles Webhook 로그를 확인하고 Gateway 경로가 `channels.bluebubbles.webhookPath`와 일치하는지 검증하세요.
|
||||
- 입력/읽음 이벤트가 작동을 멈추면 BlueBubbles Webhook 로그를 확인하고 Gateway 경로가 `channels.bluebubbles.webhookPath`와 일치하는지 확인하세요.
|
||||
- 페어링 코드는 한 시간 후 만료됩니다. `openclaw pairing list bluebubbles` 및 `openclaw pairing approve bluebubbles <code>`를 사용하세요.
|
||||
- 반응에는 BlueBubbles private API(`POST /api/v1/message/react`)가 필요합니다. 서버 버전이 이를 노출하는지 확인하세요.
|
||||
- 편집/전송 취소에는 macOS 13+와 호환되는 BlueBubbles 서버 버전이 필요합니다. macOS 26(Tahoe)에서는 private API 변경으로 인해 현재 편집이 깨져 있습니다.
|
||||
- 그룹 아이콘 업데이트는 macOS 26(Tahoe)에서 불안정할 수 있습니다. API가 성공을 반환하더라도 새 아이콘이 동기화되지 않을 수 있습니다.
|
||||
- OpenClaw는 BlueBubbles 서버의 macOS 버전에 따라 깨진 것으로 알려진 작업을 자동으로 숨깁니다. macOS 26(Tahoe)에서도 편집이 계속 표시되면 `channels.bluebubbles.actions.edit=false`로 수동 비활성화하세요.
|
||||
- `coalesceSameSenderDms`가 활성화되었지만 분할 전송(예: `Dump` + URL)이 여전히 두 턴으로 도착하는 경우: [분할 전송 병합 문제 해결](#split-send-coalescing-troubleshooting) 체크리스트를 참고하세요. 일반적인 원인은 너무 짧은 디바운스 창, Webhook 도착 시간으로 잘못 해석한 세션 로그 타임스탬프, 또는 답장 인용 전송(`replyToBody`를 사용하며 두 번째 Webhook이 아님)입니다.
|
||||
- 반응에는 BlueBubbles private API(`POST /api/v1/message/react`)가 필요합니다. 서버 버전에서 이를 노출하는지 확인하세요.
|
||||
- 편집/전송 취소에는 macOS 13 이상과 호환되는 BlueBubbles 서버 버전이 필요합니다. macOS 26(Tahoe)에서는 private API 변경으로 인해 현재 편집이 동작하지 않습니다.
|
||||
- 그룹 아이콘 업데이트는 macOS 26(Tahoe)에서 불안정할 수 있습니다. API가 성공을 반환해도 새 아이콘이 동기화되지 않을 수 있습니다.
|
||||
- OpenClaw는 BlueBubbles 서버의 macOS 버전을 기준으로 작동하지 않는 것으로 알려진 작업을 자동으로 숨깁니다. macOS 26(Tahoe)에서 편집이 계속 표시되면 `channels.bluebubbles.actions.edit=false`로 수동 비활성화하세요.
|
||||
- `coalesceSameSenderDms`가 활성화되어 있지만 분리 전송(예: `Dump` + URL)이 여전히 두 턴으로 도착하는 경우: [분리 전송 병합 문제 해결](#split-send-coalescing-troubleshooting) 체크리스트를 참고하세요. 일반적인 원인은 지나치게 짧은 디바운스 창, Webhook 도착 시각으로 잘못 읽은 세션 로그 타임스탬프, 또는 답장 인용 전송(`replyToBody`를 사용하며 두 번째 Webhook이 아님)입니다.
|
||||
- 상태/헬스 정보: `openclaw status --all` 또는 `openclaw status --deep`.
|
||||
|
||||
일반 채널 워크플로 참고 자료는 [채널](/ko/channels) 및 [Plugins](/ko/tools/plugin) 가이드를 참고하세요.
|
||||
일반 채널 워크플로 참조는 [채널](/ko/channels) 및 [Plugins](/ko/tools/plugin) 가이드를 참고하세요.
|
||||
|
||||
## 관련 항목
|
||||
## 관련 문서
|
||||
|
||||
- [채널 라우팅](/ko/channels/channel-routing) — 메시지용 세션 라우팅
|
||||
- [채널 라우팅](/ko/channels/channel-routing) — 메시지의 세션 라우팅
|
||||
- [채널 개요](/ko/channels) — 지원되는 모든 채널
|
||||
- [그룹](/ko/channels/groups) — 그룹 채팅 동작 및 멘션 게이트
|
||||
- [그룹](/ko/channels/groups) — 그룹 채팅 동작 및 멘션 게이팅
|
||||
- [페어링](/ko/channels/pairing) — DM 인증 및 페어링 흐름
|
||||
- [보안](/ko/gateway/security) — 액세스 모델 및 강화
|
||||
- [보안](/ko/gateway/security) — 접근 모델 및 강화
|
||||
|
||||
@ -1,31 +1,31 @@
|
||||
---
|
||||
read_when:
|
||||
- 브로드캐스트 그룹 구성
|
||||
- WhatsApp에서 다중 에이전트 답장 디버깅하기
|
||||
- WhatsApp에서 다중 에이전트 응답 디버깅
|
||||
sidebarTitle: Broadcast groups
|
||||
status: experimental
|
||||
summary: 여러 에이전트에게 WhatsApp 메시지 브로드캐스트하기
|
||||
title: 브로드캐스트 그룹
|
||||
x-i18n:
|
||||
generated_at: "2026-04-30T06:16:47Z"
|
||||
generated_at: "2026-05-04T02:21:25Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: b0de4ccc85bf79e2ceb1dddd60db067309b15b7f876c92e7d591ff0b4b4315ec
|
||||
source_hash: eab43d3c3ffddb360340469433d74a380fbab98e662b2463a54f62eafc375b55
|
||||
source_path: channels/broadcast-groups.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
<Note>
|
||||
**상태:** 실험적 기능입니다. 2026.1.9에 추가되었습니다.
|
||||
**상태:** 실험적 기능. 2026.1.9에 추가됨.
|
||||
</Note>
|
||||
|
||||
## 개요
|
||||
|
||||
브로드캐스트 그룹을 사용하면 여러 에이전트가 동일한 메시지를 동시에 처리하고 응답할 수 있습니다. 이를 통해 하나의 WhatsApp 그룹이나 DM에서 함께 작업하는 전문 에이전트 팀을 만들 수 있으며, 모두 하나의 전화번호를 사용합니다.
|
||||
브로드캐스트 그룹을 사용하면 여러 에이전트가 동일한 메시지를 동시에 처리하고 응답할 수 있습니다. 이를 통해 하나의 WhatsApp 그룹 또는 DM에서 함께 작업하는 전문 에이전트 팀을 만들 수 있으며, 모두 하나의 전화번호를 사용합니다.
|
||||
|
||||
현재 범위: **WhatsApp만 지원**(웹 채널).
|
||||
현재 범위: **WhatsApp만 해당**(웹 채널).
|
||||
|
||||
브로드캐스트 그룹은 채널 허용 목록과 그룹 활성화 규칙 이후에 평가됩니다. WhatsApp 그룹에서는 OpenClaw가 일반적으로 응답할 때 브로드캐스트가 발생한다는 뜻입니다(예: 그룹 설정에 따라 멘션 시).
|
||||
브로드캐스트 그룹은 채널 허용 목록과 그룹 활성화 규칙 이후에 평가됩니다. WhatsApp 그룹에서는 OpenClaw가 일반적으로 응답할 때 브로드캐스트가 발생한다는 의미입니다(예: 그룹 설정에 따라 멘션 시).
|
||||
|
||||
## 사용 사례
|
||||
|
||||
@ -73,7 +73,7 @@ x-i18n:
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 설정
|
||||
## 구성
|
||||
|
||||
### 기본 설정
|
||||
|
||||
@ -97,7 +97,7 @@ x-i18n:
|
||||
에이전트가 메시지를 처리하는 방식을 제어합니다.
|
||||
|
||||
<Tabs>
|
||||
<Tab title="parallel (기본값)">
|
||||
<Tab title="parallel(기본값)">
|
||||
모든 에이전트가 동시에 처리합니다.
|
||||
|
||||
```json
|
||||
@ -111,7 +111,7 @@ x-i18n:
|
||||
|
||||
</Tab>
|
||||
<Tab title="sequential">
|
||||
에이전트가 순서대로 처리합니다(하나가 이전 에이전트의 완료를 기다림).
|
||||
에이전트가 순서대로 처리합니다(하나가 이전 에이전트가 완료될 때까지 기다림).
|
||||
|
||||
```json
|
||||
{
|
||||
@ -178,12 +178,12 @@ x-i18n:
|
||||
|
||||
</Step>
|
||||
<Step title="브로드캐스트 목록에 없는 경우">
|
||||
일반 라우팅이 적용됩니다(처음 일치하는 바인딩).
|
||||
일반 라우팅이 적용됩니다(첫 번째로 일치하는 바인딩).
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
브로드캐스트 그룹은 채널 허용 목록이나 그룹 활성화 규칙(멘션/명령 등)을 우회하지 않습니다. 메시지가 처리 대상일 때 _어떤 에이전트가 실행되는지_만 변경합니다.
|
||||
브로드캐스트 그룹은 채널 허용 목록이나 그룹 활성화 규칙(멘션/명령 등)을 우회하지 않습니다. 메시지가 처리 대상일 때 _어떤 에이전트가 실행되는지_ 만 변경합니다.
|
||||
</Note>
|
||||
|
||||
### 세션 격리
|
||||
@ -192,21 +192,21 @@ x-i18n:
|
||||
|
||||
- **세션 키**(`agent:alfred:whatsapp:group:120363...` vs `agent:baerbel:whatsapp:group:120363...`)
|
||||
- **대화 기록**(에이전트는 다른 에이전트의 메시지를 보지 않음)
|
||||
- **작업 공간**(설정된 경우 별도 샌드박스)
|
||||
- **도구 접근 권한**(서로 다른 허용/거부 목록)
|
||||
- **작업공간**(구성된 경우 별도 샌드박스)
|
||||
- **도구 접근**(서로 다른 허용/거부 목록)
|
||||
- **메모리/컨텍스트**(별도 IDENTITY.md, SOUL.md 등)
|
||||
- **그룹 컨텍스트 버퍼**(컨텍스트에 사용되는 최근 그룹 메시지)는 피어별로 공유되므로, 트리거될 때 모든 브로드캐스트 에이전트가 동일한 컨텍스트를 봅니다
|
||||
- **그룹 컨텍스트 버퍼**(컨텍스트에 사용되는 최근 그룹 메시지)는 피어별로 공유되므로, 모든 브로드캐스트 에이전트는 트리거될 때 동일한 컨텍스트를 봅니다.
|
||||
|
||||
이를 통해 각 에이전트는 다음을 가질 수 있습니다.
|
||||
|
||||
- 서로 다른 성격
|
||||
- 서로 다른 도구 접근 권한(예: 읽기 전용 vs. 읽기-쓰기)
|
||||
- 서로 다른 도구 접근(예: 읽기 전용 vs. 읽기/쓰기)
|
||||
- 서로 다른 모델(예: opus vs. sonnet)
|
||||
- 서로 다른 Skills 설치
|
||||
|
||||
### 예시: 격리된 세션
|
||||
|
||||
그룹 `120363403215116621@g.us`에 에이전트 `["alfred", "baerbel"]`가 있는 경우:
|
||||
`120363403215116621@g.us` 그룹에서 에이전트가 `["alfred", "baerbel"]`인 경우:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Alfred의 컨텍스트">
|
||||
@ -230,7 +230,7 @@ x-i18n:
|
||||
## 모범 사례
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="1. 에이전트의 초점을 유지">
|
||||
<Accordion title="1. 에이전트를 집중적으로 유지">
|
||||
각 에이전트를 하나의 명확한 책임으로 설계합니다.
|
||||
|
||||
```json
|
||||
@ -241,7 +241,7 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
✅ **좋음:** 각 에이전트에 하나의 작업이 있습니다. ❌ **나쁨:** 하나의 범용 "dev-helper" 에이전트.
|
||||
✅ **좋음:** 각 에이전트는 하나의 작업을 담당합니다. ❌ **나쁨:** 하나의 범용 "dev-helper" 에이전트.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="2. 설명적인 이름 사용">
|
||||
@ -258,29 +258,31 @@ x-i18n:
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="3. 서로 다른 도구 접근 권한 설정">
|
||||
에이전트에게 필요한 도구만 제공합니다.
|
||||
<Accordion title="3. 서로 다른 도구 접근 구성">
|
||||
에이전트에 필요한 도구만 부여합니다.
|
||||
|
||||
```json
|
||||
{
|
||||
"agents": {
|
||||
"reviewer": {
|
||||
"tools": { "allow": ["read", "exec"] } // Read-only
|
||||
"tools": { "allow": ["read", "exec"] }
|
||||
},
|
||||
"fixer": {
|
||||
"tools": { "allow": ["read", "write", "edit", "exec"] } // Read-write
|
||||
"tools": { "allow": ["read", "write", "edit", "exec"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`reviewer`는 읽기 전용입니다. `fixer`는 읽고 쓸 수 있습니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="4. 성능 모니터링">
|
||||
에이전트가 많은 경우 다음을 고려하세요.
|
||||
|
||||
- 속도를 위해 `"strategy": "parallel"`(기본값) 사용
|
||||
- 브로드캐스트 그룹을 5~10개 에이전트로 제한
|
||||
- 단순한 에이전트에는 더 빠른 모델 사용
|
||||
- 더 단순한 에이전트에는 더 빠른 모델 사용
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="5. 실패를 우아하게 처리">
|
||||
@ -350,7 +352,7 @@ x-i18n:
|
||||
<Accordion title="하나의 에이전트만 응답함">
|
||||
**원인:** 피어 ID가 `bindings`에는 있지만 `broadcast`에는 없을 수 있습니다.
|
||||
|
||||
**수정:** 브로드캐스트 설정에 추가하거나 바인딩에서 제거합니다.
|
||||
**해결:** 브로드캐스트 구성에 추가하거나 바인딩에서 제거합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="성능 문제">
|
||||
@ -401,14 +403,14 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
**사용자 전송:** 코드 조각.
|
||||
**사용자 전송:** 코드 스니펫.
|
||||
|
||||
**응답:**
|
||||
|
||||
- code-formatter: "들여쓰기를 수정하고 타입 힌트를 추가했습니다"
|
||||
- security-scanner: "⚠️ 12번째 줄에 SQL 인젝션 취약점이 있습니다"
|
||||
- test-coverage: "커버리지는 45%이며, 오류 사례에 대한 테스트가 누락되었습니다"
|
||||
- docs-checker: "`process_data` 함수에 문서 문자열이 없습니다"
|
||||
- security-scanner: "⚠️ 12번째 줄에 SQL 삽입 취약점이 있습니다"
|
||||
- test-coverage: "커버리지가 45%이며 오류 사례에 대한 테스트가 없습니다"
|
||||
- docs-checker: "`process_data` 함수의 docstring이 없습니다"
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="예시 2: 다국어 지원">
|
||||
@ -432,7 +434,7 @@ x-i18n:
|
||||
|
||||
## API 참조
|
||||
|
||||
### 설정 스키마
|
||||
### 구성 스키마
|
||||
|
||||
```typescript
|
||||
interface OpenClawConfig {
|
||||
@ -446,18 +448,18 @@ interface OpenClawConfig {
|
||||
### 필드
|
||||
|
||||
<ParamField path="strategy" type='"parallel" | "sequential"' default='"parallel"'>
|
||||
에이전트를 처리하는 방법입니다. `parallel`은 모든 에이전트를 동시에 실행하고, `sequential`은 배열 순서대로 실행합니다.
|
||||
에이전트를 처리하는 방식입니다. `parallel`은 모든 에이전트를 동시에 실행하고, `sequential`은 배열 순서대로 실행합니다.
|
||||
</ParamField>
|
||||
<ParamField path="[peerId]" type="string[]">
|
||||
WhatsApp 그룹 JID, E.164 번호 또는 기타 피어 ID입니다. 값은 메시지를 처리해야 하는 에이전트 ID 배열입니다.
|
||||
WhatsApp 그룹 JID, E.164 번호 또는 기타 피어 ID입니다. 값은 메시지를 처리해야 하는 에이전트 ID의 배열입니다.
|
||||
</ParamField>
|
||||
|
||||
## 제한 사항
|
||||
|
||||
1. **최대 에이전트 수:** 엄격한 제한은 없지만, 10개 이상의 에이전트는 느릴 수 있습니다.
|
||||
1. **최대 에이전트 수:** 엄격한 제한은 없지만, 에이전트가 10개 이상이면 느릴 수 있습니다.
|
||||
2. **공유 컨텍스트:** 에이전트는 서로의 응답을 보지 않습니다(의도된 설계).
|
||||
3. **메시지 순서:** 병렬 응답은 어떤 순서로든 도착할 수 있습니다.
|
||||
4. **속도 제한:** 모든 에이전트가 WhatsApp 속도 제한에 합산됩니다.
|
||||
3. **메시지 순서:** 병렬 응답은 임의의 순서로 도착할 수 있습니다.
|
||||
4. **속도 제한:** 모든 에이전트가 WhatsApp 속도 제한에 포함됩니다.
|
||||
|
||||
## 향후 개선 사항
|
||||
|
||||
@ -472,6 +474,6 @@ interface OpenClawConfig {
|
||||
|
||||
- [채널 라우팅](/ko/channels/channel-routing)
|
||||
- [그룹](/ko/channels/groups)
|
||||
- [다중 에이전트 샌드박스 도구](/ko/tools/multi-agent-sandbox-tools)
|
||||
- [멀티 에이전트 샌드박스 도구](/ko/tools/multi-agent-sandbox-tools)
|
||||
- [페어링](/ko/channels/pairing)
|
||||
- [세션 관리](/ko/concepts/session)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,83 +1,83 @@
|
||||
---
|
||||
read_when:
|
||||
- Google Chat 채널 기능 작업하기
|
||||
- Google Chat 채널 기능 작업 중
|
||||
summary: Google Chat 앱 지원 상태, 기능 및 구성
|
||||
title: Google Chat
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T20:41:24Z"
|
||||
generated_at: "2026-05-04T02:21:22Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: fdb8dcf651602e92801d7107646d853871ea6cef188a8733a831695a1243740e
|
||||
source_hash: afa2ca4d9673396aa24a55ca5855a34ad26a4640c3a1f6928dbf7246e403cb04
|
||||
source_path: channels/googlechat.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
Status: Google Chat API Webhook를 통해 DM 및 스페이스에서 사용할 수 있는 다운로드 가능한 Plugin(HTTP 전용).
|
||||
상태: Google Chat API Webhook(HTTP 전용)을 통해 DM + 스페이스에서 사용할 수 있는 다운로드 가능한 Plugin입니다.
|
||||
|
||||
## 설치
|
||||
|
||||
채널을 구성하기 전에 Google Chat을 설치합니다.
|
||||
채널을 구성하기 전에 Google Chat을 설치하세요.
|
||||
|
||||
```bash
|
||||
openclaw plugins install @openclaw/googlechat
|
||||
```
|
||||
|
||||
로컬 체크아웃(git 저장소에서 실행하는 경우):
|
||||
로컬 체크아웃(git repo에서 실행하는 경우):
|
||||
|
||||
```bash
|
||||
openclaw plugins install ./path/to/local/googlechat-plugin
|
||||
```
|
||||
|
||||
## 빠른 설정(초보자용)
|
||||
## 빠른 설정(초보자)
|
||||
|
||||
1. Google Cloud 프로젝트를 만들고 **Google Chat API**를 활성화합니다.
|
||||
- 이동: [Google Chat API Credentials](https://console.cloud.google.com/apis/api/chat.googleapis.com/credentials)
|
||||
- API가 아직 활성화되어 있지 않다면 활성화합니다.
|
||||
2. **Service Account**를 만듭니다.
|
||||
- **Create Credentials** > **Service Account**를 누릅니다.
|
||||
- 이동: [Google Chat API 사용자 인증 정보](https://console.cloud.google.com/apis/api/chat.googleapis.com/credentials)
|
||||
- API가 아직 활성화되지 않았다면 활성화합니다.
|
||||
2. **서비스 계정**을 만듭니다.
|
||||
- **사용자 인증 정보 만들기** > **서비스 계정**을 누릅니다.
|
||||
- 원하는 이름을 지정합니다(예: `openclaw-chat`).
|
||||
- 권한은 비워 둡니다(**Continue**를 누름).
|
||||
- 액세스 권한이 있는 주체도 비워 둡니다(**Done**을 누름).
|
||||
3. **JSON Key**를 만들고 다운로드합니다.
|
||||
- 권한은 비워 둡니다(**계속** 누르기).
|
||||
- 액세스 권한이 있는 주 구성원도 비워 둡니다(**완료** 누르기).
|
||||
3. **JSON 키**를 만들고 다운로드합니다.
|
||||
- 서비스 계정 목록에서 방금 만든 계정을 클릭합니다.
|
||||
- **Keys** 탭으로 이동합니다.
|
||||
- **Add Key** > **Create new key**를 클릭합니다.
|
||||
- **JSON**을 선택하고 **Create**를 누릅니다.
|
||||
- **키** 탭으로 이동합니다.
|
||||
- **키 추가** > **새 키 만들기**를 클릭합니다.
|
||||
- **JSON**을 선택하고 **만들기**를 누릅니다.
|
||||
4. 다운로드한 JSON 파일을 Gateway 호스트에 저장합니다(예: `~/.openclaw/googlechat-service-account.json`).
|
||||
5. [Google Cloud Console Chat Configuration](https://console.cloud.google.com/apis/api/chat.googleapis.com/hangouts-chat)에서 Google Chat 앱을 만듭니다.
|
||||
- **Application info**를 입력합니다.
|
||||
- **App name**: (예: `OpenClaw`)
|
||||
- **Avatar URL**: (예: `https://openclaw.ai/logo.png`)
|
||||
- **Description**: (예: `Personal AI Assistant`)
|
||||
- **Interactive features**를 활성화합니다.
|
||||
- **Functionality**에서 **Join spaces and group conversations**를 선택합니다.
|
||||
- **Connection settings**에서 **HTTP endpoint URL**을 선택합니다.
|
||||
- **Triggers**에서 **Use a common HTTP endpoint URL for all triggers**를 선택하고 Gateway의 공개 URL 뒤에 `/googlechat`을 붙인 값으로 설정합니다.
|
||||
5. [Google Cloud Console Chat 구성](https://console.cloud.google.com/apis/api/chat.googleapis.com/hangouts-chat)에서 Google Chat 앱을 만듭니다.
|
||||
- **애플리케이션 정보**를 입력합니다.
|
||||
- **앱 이름**: (예: `OpenClaw`)
|
||||
- **아바타 URL**: (예: `https://openclaw.ai/logo.png`)
|
||||
- **설명**: (예: `Personal AI Assistant`)
|
||||
- **대화형 기능**을 활성화합니다.
|
||||
- **기능**에서 **스페이스 및 그룹 대화 참여**를 선택합니다.
|
||||
- **연결 설정**에서 **HTTP 엔드포인트 URL**을 선택합니다.
|
||||
- **트리거**에서 **모든 트리거에 공통 HTTP 엔드포인트 URL 사용**을 선택하고, Gateway의 공개 URL 뒤에 `/googlechat`을 붙여 설정합니다.
|
||||
- _팁: Gateway의 공개 URL을 찾으려면 `openclaw status`를 실행하세요._
|
||||
- **Visibility**에서 **Make this Chat app available to specific people and groups in `<Your Domain>`**을 선택합니다.
|
||||
- 텍스트 상자에 이메일 주소(예: `user@example.com`)를 입력합니다.
|
||||
- 아래쪽의 **Save**를 클릭합니다.
|
||||
6. **앱 상태를 활성화합니다**.
|
||||
- **공개 범위**에서 **`<Your Domain>`의 특정 사용자 및 그룹이 이 Chat 앱을 사용할 수 있도록 설정**을 선택합니다.
|
||||
- 텍스트 상자에 이메일 주소를 입력합니다(예: `user@example.com`).
|
||||
- 아래쪽의 **저장**을 클릭합니다.
|
||||
6. **앱 상태를 활성화**합니다.
|
||||
- 저장한 뒤 **페이지를 새로고침**합니다.
|
||||
- **App status** 섹션을 찾습니다(보통 저장 후 위쪽이나 아래쪽에 표시됨).
|
||||
- 상태를 **Live - available to users**로 변경합니다.
|
||||
- 다시 **Save**를 클릭합니다.
|
||||
7. 서비스 계정 경로와 Webhook 대상 값으로 OpenClaw를 구성합니다.
|
||||
- **앱 상태** 섹션을 찾습니다(보통 저장 후 위쪽이나 아래쪽 근처에 표시됨).
|
||||
- 상태를 **실시간 - 사용자가 이용 가능**으로 변경합니다.
|
||||
- **저장**을 다시 클릭합니다.
|
||||
7. 서비스 계정 경로 + Webhook 대상 값으로 OpenClaw를 구성합니다.
|
||||
- Env: `GOOGLE_CHAT_SERVICE_ACCOUNT_FILE=/path/to/service-account.json`
|
||||
- 또는 config: `channels.googlechat.serviceAccountFile: "/path/to/service-account.json"`.
|
||||
8. Webhook 대상 유형과 값을 설정합니다(Chat 앱 구성과 일치해야 함).
|
||||
9. Gateway를 시작합니다. Google Chat이 Webhook 경로로 POST 요청을 보냅니다.
|
||||
8. Webhook 대상 유형 + 값을 설정합니다(Chat 앱 구성과 일치해야 함).
|
||||
9. Gateway를 시작합니다. Google Chat이 Webhook 경로로 POST를 보냅니다.
|
||||
|
||||
## Google Chat에 추가
|
||||
|
||||
Gateway가 실행 중이고 이메일이 공개 대상 목록에 추가되었으면 다음을 수행합니다.
|
||||
Gateway가 실행 중이고 이메일이 공개 범위 목록에 추가되면:
|
||||
|
||||
1. [Google Chat](https://chat.google.com/)으로 이동합니다.
|
||||
2. **Direct Messages** 옆의 **+**(더하기) 아이콘을 클릭합니다.
|
||||
3. 검색창(보통 사람을 추가하는 곳)에 Google Cloud Console에서 구성한 **App name**을 입력합니다.
|
||||
- **참고**: 비공개 앱이므로 봇은 "Marketplace" 찾아보기 목록에 _표시되지 않습니다_. 이름으로 검색해야 합니다.
|
||||
2. **직접 메시지** 옆의 **+**(더하기) 아이콘을 클릭합니다.
|
||||
3. 검색창(보통 사용자를 추가하는 곳)에 Google Cloud Console에서 구성한 **앱 이름**을 입력합니다.
|
||||
- **참고**: 비공개 앱이므로 봇은 "Marketplace" 탐색 목록에 _나타나지 않습니다_. 이름으로 검색해야 합니다.
|
||||
4. 결과에서 봇을 선택합니다.
|
||||
5. 1:1 대화를 시작하려면 **Add** 또는 **Chat**을 클릭합니다.
|
||||
5. **추가** 또는 **채팅**을 클릭해 1:1 대화를 시작합니다.
|
||||
6. 어시스턴트를 트리거하려면 "Hello"를 보냅니다!
|
||||
|
||||
## 공개 URL(Webhook 전용)
|
||||
@ -86,9 +86,9 @@ Google Chat Webhook에는 공개 HTTPS 엔드포인트가 필요합니다. 보
|
||||
|
||||
### 옵션 A: Tailscale Funnel(권장)
|
||||
|
||||
비공개 대시보드에는 Tailscale Serve를, 공개 Webhook 경로에는 Funnel을 사용합니다. 이렇게 하면 `/`는 비공개로 유지하면서 `/googlechat`만 노출할 수 있습니다.
|
||||
비공개 대시보드에는 Tailscale Serve를 사용하고, 공개 Webhook 경로에는 Funnel을 사용합니다. 이렇게 하면 `/`는 비공개로 유지하면서 `/googlechat`만 노출할 수 있습니다.
|
||||
|
||||
1. **Gateway가 바인딩된 주소를 확인합니다.**
|
||||
1. **Gateway가 어떤 주소에 바인딩되어 있는지 확인합니다.**
|
||||
|
||||
```bash
|
||||
ss -tlnp | grep 18789
|
||||
@ -96,28 +96,28 @@ Google Chat Webhook에는 공개 HTTPS 엔드포인트가 필요합니다. 보
|
||||
|
||||
IP 주소를 확인합니다(예: `127.0.0.1`, `0.0.0.0` 또는 `100.x.x.x` 같은 Tailscale IP).
|
||||
|
||||
2. **대시보드를 tailnet에만 노출합니다(포트 8443).**
|
||||
2. **대시보드를 tailnet 전용으로 노출합니다(포트 8443).**
|
||||
|
||||
```bash
|
||||
# localhost(127.0.0.1 또는 0.0.0.0)에 바인딩된 경우:
|
||||
# If bound to localhost (127.0.0.1 or 0.0.0.0):
|
||||
tailscale serve --bg --https 8443 http://127.0.0.1:18789
|
||||
|
||||
# Tailscale IP에만 바인딩된 경우(예: 100.106.161.80):
|
||||
# If bound to Tailscale IP only (e.g., 100.106.161.80):
|
||||
tailscale serve --bg --https 8443 http://100.106.161.80:18789
|
||||
```
|
||||
|
||||
3. **Webhook 경로만 공개적으로 노출합니다.**
|
||||
3. **Webhook 경로만 공개로 노출합니다.**
|
||||
|
||||
```bash
|
||||
# localhost(127.0.0.1 또는 0.0.0.0)에 바인딩된 경우:
|
||||
# If bound to localhost (127.0.0.1 or 0.0.0.0):
|
||||
tailscale funnel --bg --set-path /googlechat http://127.0.0.1:18789/googlechat
|
||||
|
||||
# Tailscale IP에만 바인딩된 경우(예: 100.106.161.80):
|
||||
# If bound to Tailscale IP only (e.g., 100.106.161.80):
|
||||
tailscale funnel --bg --set-path /googlechat http://100.106.161.80:18789/googlechat
|
||||
```
|
||||
|
||||
4. **Funnel 액세스용으로 Node를 승인합니다.**
|
||||
메시지가 표시되면 출력에 표시된 승인 URL을 방문하여 tailnet 정책에서 이 Node에 대해 Funnel을 활성화합니다.
|
||||
4. **Funnel 액세스용 노드를 승인합니다.**
|
||||
메시지가 표시되면 출력에 표시된 승인 URL을 방문하여 tailnet 정책에서 이 노드의 Funnel을 활성화합니다.
|
||||
|
||||
5. **구성을 확인합니다.**
|
||||
|
||||
@ -132,13 +132,13 @@ Google Chat Webhook에는 공개 HTTPS 엔드포인트가 필요합니다. 보
|
||||
비공개 대시보드는 tailnet 전용으로 유지됩니다.
|
||||
`https://<node-name>.<tailnet>.ts.net:8443/`
|
||||
|
||||
Google Chat 앱 구성에는 공개 URL(`:8443` 제외)을 사용합니다.
|
||||
Google Chat 앱 구성에는 공개 URL(`:8443` 제외)을 사용하세요.
|
||||
|
||||
> 참고: 이 구성은 재부팅 후에도 유지됩니다. 나중에 제거하려면 `tailscale funnel reset`과 `tailscale serve reset`을 실행하세요.
|
||||
> 참고: 이 구성은 재부팅 후에도 유지됩니다. 나중에 제거하려면 `tailscale funnel reset` 및 `tailscale serve reset`을 실행하세요.
|
||||
|
||||
### 옵션 B: 리버스 프록시(Caddy)
|
||||
|
||||
Caddy 같은 리버스 프록시를 사용하는 경우 특정 경로만 프록시합니다.
|
||||
Caddy 같은 리버스 프록시를 사용하는 경우 특정 경로만 프록시하세요.
|
||||
|
||||
```caddy
|
||||
your-domain.com {
|
||||
@ -146,36 +146,36 @@ your-domain.com {
|
||||
}
|
||||
```
|
||||
|
||||
이 구성에서는 `your-domain.com/`에 대한 모든 요청이 무시되거나 404로 반환되고, `your-domain.com/googlechat`은 안전하게 OpenClaw로 라우팅됩니다.
|
||||
이 구성에서는 `your-domain.com/`으로 들어오는 모든 요청이 무시되거나 404로 반환되고, `your-domain.com/googlechat`은 OpenClaw로 안전하게 라우팅됩니다.
|
||||
|
||||
### 옵션 C: Cloudflare Tunnel
|
||||
|
||||
Webhook 경로만 라우팅하도록 터널의 수신 규칙을 구성합니다.
|
||||
Webhook 경로만 라우팅하도록 터널의 인그레스 규칙을 구성합니다.
|
||||
|
||||
- **Path**: `/googlechat` -> `http://localhost:18789/googlechat`
|
||||
- **Default Rule**: HTTP 404 (Not Found)
|
||||
- **경로**: `/googlechat` -> `http://localhost:18789/googlechat`
|
||||
- **기본 규칙**: HTTP 404(찾을 수 없음)
|
||||
|
||||
## 작동 방식
|
||||
|
||||
1. Google Chat은 Gateway로 Webhook POST를 보냅니다. 각 요청에는 `Authorization: Bearer <token>` 헤더가 포함됩니다.
|
||||
- 헤더가 있는 경우 OpenClaw는 전체 Webhook 본문을 읽거나 파싱하기 전에 Bearer 인증을 확인합니다.
|
||||
- 본문에 `authorizationEventObject.systemIdToken`을 포함하는 Google Workspace Add-on 요청은 더 엄격한 사전 인증 본문 예산을 통해 지원됩니다.
|
||||
2. OpenClaw는 구성된 `audienceType` + `audience`를 기준으로 토큰을 확인합니다.
|
||||
- `audienceType: "app-url"` → audience는 HTTPS Webhook URL입니다.
|
||||
- `audienceType: "project-number"` → audience는 Cloud 프로젝트 번호입니다.
|
||||
1. Google Chat이 Webhook POST를 Gateway로 보냅니다. 각 요청에는 `Authorization: Bearer <token>` 헤더가 포함됩니다.
|
||||
- OpenClaw는 헤더가 있을 때 전체 Webhook 본문을 읽거나 파싱하기 전에 bearer 인증을 확인합니다.
|
||||
- 본문에 `authorizationEventObject.systemIdToken`이 포함된 Google Workspace 애드온 요청은 더 엄격한 사전 인증 본문 예산을 통해 지원됩니다.
|
||||
2. OpenClaw는 구성된 `audienceType` + `audience`에 대해 토큰을 확인합니다.
|
||||
- `audienceType: "app-url"` → 대상은 HTTPS Webhook URL입니다.
|
||||
- `audienceType: "project-number"` → 대상은 Cloud 프로젝트 번호입니다.
|
||||
3. 메시지는 스페이스별로 라우팅됩니다.
|
||||
- DM은 세션 키 `agent:<agentId>:googlechat:direct:<spaceId>`를 사용합니다.
|
||||
- 스페이스는 세션 키 `agent:<agentId>:googlechat:group:<spaceId>`를 사용합니다.
|
||||
4. DM 액세스는 기본적으로 페어링 방식입니다. 알 수 없는 발신자는 페어링 코드를 받으며, 다음 명령으로 승인합니다.
|
||||
- `openclaw pairing approve googlechat <code>`
|
||||
5. 그룹 스페이스는 기본적으로 @멘션이 필요합니다. 멘션 감지에 앱의 사용자 이름이 필요하면 `botUser`를 사용합니다.
|
||||
5. 그룹 스페이스는 기본적으로 @멘션이 필요합니다. 멘션 감지에 앱의 사용자 이름이 필요한 경우 `botUser`를 사용하세요.
|
||||
|
||||
## 대상
|
||||
|
||||
전송 및 허용 목록에는 다음 식별자를 사용합니다.
|
||||
전송 및 허용 목록에 다음 식별자를 사용하세요.
|
||||
|
||||
- 다이렉트 메시지: `users/<userId>`(권장).
|
||||
- 원시 이메일 `name@example.com`은 변경 가능하며 `channels.googlechat.dangerouslyAllowNameMatching: true`일 때만 다이렉트 허용 목록 매칭에 사용됩니다.
|
||||
- 직접 메시지: `users/<userId>`(권장).
|
||||
- 원시 이메일 `name@example.com`은 변경 가능하며, `channels.googlechat.dangerouslyAllowNameMatching: true`일 때 직접 허용 목록 매칭에만 사용됩니다.
|
||||
- 사용 중단됨: `users/<email>`은 이메일 허용 목록이 아니라 사용자 ID로 처리됩니다.
|
||||
- 스페이스: `spaces/<spaceId>`.
|
||||
|
||||
@ -199,7 +199,7 @@ Webhook 경로만 라우팅하도록 터널의 수신 규칙을 구성합니다.
|
||||
groupPolicy: "allowlist",
|
||||
groups: {
|
||||
"spaces/AAAA": {
|
||||
allow: true,
|
||||
enabled: true,
|
||||
requireMention: true,
|
||||
users: ["users/1234567890"],
|
||||
systemPrompt: "Short answers only.",
|
||||
@ -215,20 +215,20 @@ Webhook 경로만 라우팅하도록 터널의 수신 규칙을 구성합니다.
|
||||
|
||||
참고:
|
||||
|
||||
- 서비스 계정 자격 증명은 `serviceAccount`(JSON 문자열)로 인라인 전달할 수도 있습니다.
|
||||
- `serviceAccountRef`도 지원됩니다(env/file SecretRef). `channels.googlechat.accounts.<id>.serviceAccountRef` 아래의 계정별 ref도 포함됩니다.
|
||||
- 서비스 계정 사용자 인증 정보는 `serviceAccount`(JSON 문자열)로 인라인 전달할 수도 있습니다.
|
||||
- `serviceAccountRef`도 지원됩니다(env/file SecretRef). 여기에는 `channels.googlechat.accounts.<id>.serviceAccountRef` 아래의 계정별 ref도 포함됩니다.
|
||||
- `webhookPath`가 설정되지 않은 경우 기본 Webhook 경로는 `/googlechat`입니다.
|
||||
- `dangerouslyAllowNameMatching`은 허용 목록에 대해 변경 가능한 이메일 주체 매칭을 다시 활성화합니다(비상 호환성 모드).
|
||||
- `actions.reactions`가 활성화되면 `reactions` 도구와 `channels action`을 통해 반응을 사용할 수 있습니다.
|
||||
- 메시지 액션은 텍스트용 `send`와 명시적 첨부 파일 전송용 `upload-file`을 노출합니다. `upload-file`은 `media` / `filePath` / `path`와 선택적 `message`, `filename`, 스레드 대상을 받습니다.
|
||||
- `dangerouslyAllowNameMatching`은 허용 목록에 대해 변경 가능한 이메일 주체 매칭을 다시 활성화합니다(긴급 호환 모드).
|
||||
- `actions.reactions`가 활성화된 경우 `reactions` 도구와 `channels action`을 통해 반응을 사용할 수 있습니다.
|
||||
- 메시지 액션은 텍스트용 `send`와 명시적 첨부파일 전송용 `upload-file`을 노출합니다. `upload-file`은 `media` / `filePath` / `path`와 선택 사항인 `message`, `filename`, 스레드 대상을 받습니다.
|
||||
- `typingIndicator`는 `none`, `message`(기본값), `reaction`을 지원합니다(`reaction`에는 사용자 OAuth가 필요함).
|
||||
- 첨부 파일은 Chat API를 통해 다운로드되어 미디어 파이프라인에 저장됩니다(크기는 `mediaMaxMb`로 제한됨).
|
||||
- 첨부파일은 Chat API를 통해 다운로드되며 미디어 파이프라인에 저장됩니다(크기는 `mediaMaxMb`로 제한됨).
|
||||
|
||||
시크릿 참조 세부 정보: [시크릿 관리](/ko/gateway/secrets).
|
||||
비밀 정보 참조 세부 정보: [비밀 정보 관리](/ko/gateway/secrets).
|
||||
|
||||
## 문제 해결
|
||||
|
||||
### 405 Method Not Allowed
|
||||
### 405 메서드가 허용되지 않음
|
||||
|
||||
Google Cloud Logs Explorer에 다음과 같은 오류가 표시되는 경우:
|
||||
|
||||
@ -236,31 +236,31 @@ Google Cloud Logs Explorer에 다음과 같은 오류가 표시되는 경우:
|
||||
status code: 405, reason phrase: HTTP error response: HTTP/1.1 405 Method Not Allowed
|
||||
```
|
||||
|
||||
이는 Webhook 핸들러가 등록되지 않았다는 뜻입니다. 일반적인 원인은 다음과 같습니다.
|
||||
이는 Webhook 핸들러가 등록되지 않았다는 뜻입니다. 일반적인 원인:
|
||||
|
||||
1. **채널이 구성되지 않음**: 구성에 `channels.googlechat` 섹션이 없습니다. 다음으로 확인합니다.
|
||||
1. **채널이 구성되지 않음**: 구성에 `channels.googlechat` 섹션이 없습니다. 다음으로 확인하세요.
|
||||
|
||||
```bash
|
||||
openclaw config get channels.googlechat
|
||||
```
|
||||
|
||||
"Config path not found"가 반환되면 구성을 추가합니다([구성 주요 사항](#config-highlights) 참고).
|
||||
"Config path not found"가 반환되면 구성을 추가하세요([구성 주요 사항](#config-highlights) 참조).
|
||||
|
||||
2. **Plugin이 활성화되지 않음**: Plugin 상태를 확인합니다.
|
||||
2. **Plugin이 활성화되지 않음**: Plugin 상태를 확인하세요.
|
||||
|
||||
```bash
|
||||
openclaw plugins list | grep googlechat
|
||||
```
|
||||
|
||||
"disabled"가 표시되면 구성에 `plugins.entries.googlechat.enabled: true`를 추가합니다.
|
||||
"disabled"로 표시되면 구성에 `plugins.entries.googlechat.enabled: true`를 추가하세요.
|
||||
|
||||
3. **Gateway가 재시작되지 않음**: 구성을 추가한 후 Gateway를 재시작합니다.
|
||||
3. **Gateway가 다시 시작되지 않음**: 구성을 추가한 뒤 Gateway를 다시 시작하세요.
|
||||
|
||||
```bash
|
||||
openclaw gateway restart
|
||||
```
|
||||
|
||||
채널이 실행 중인지 확인합니다.
|
||||
채널이 실행 중인지 확인하세요.
|
||||
|
||||
```bash
|
||||
openclaw channels status
|
||||
@ -269,10 +269,10 @@ openclaw channels status
|
||||
|
||||
### 기타 문제
|
||||
|
||||
- 인증 오류나 누락된 audience 구성을 확인하려면 `openclaw channels status --probe`를 확인합니다.
|
||||
- 메시지가 도착하지 않으면 Chat 앱의 Webhook URL과 이벤트 구독을 확인합니다.
|
||||
- 멘션 게이트가 응답을 차단하면 `botUser`를 앱의 사용자 리소스 이름으로 설정하고 `requireMention`을 확인합니다.
|
||||
- 테스트 메시지를 보내는 동안 요청이 Gateway에 도달하는지 확인하려면 `openclaw logs --follow`를 사용합니다.
|
||||
- 인증 오류 또는 누락된 대상 구성을 확인하려면 `openclaw channels status --probe`를 확인하세요.
|
||||
- 메시지가 도착하지 않으면 Chat 앱의 Webhook URL + 이벤트 구독을 확인하세요.
|
||||
- 멘션 게이팅이 응답을 차단하는 경우 `botUser`를 앱의 사용자 리소스 이름으로 설정하고 `requireMention`을 확인하세요.
|
||||
- 요청이 Gateway에 도달하는지 확인하려면 테스트 메시지를 보내는 동안 `openclaw logs --follow`를 사용하세요.
|
||||
|
||||
관련 문서:
|
||||
|
||||
@ -284,6 +284,6 @@ openclaw channels status
|
||||
|
||||
- [채널 개요](/ko/channels) — 지원되는 모든 채널
|
||||
- [페어링](/ko/channels/pairing) — DM 인증 및 페어링 흐름
|
||||
- [그룹](/ko/channels/groups) — 그룹 채팅 동작 및 멘션 게이트
|
||||
- [채널 라우팅](/ko/channels/channel-routing) — 메시지용 세션 라우팅
|
||||
- [그룹](/ko/channels/groups) — 그룹 채팅 동작 및 멘션 게이팅
|
||||
- [채널 라우팅](/ko/channels/channel-routing) — 메시지의 세션 라우팅
|
||||
- [보안](/ko/gateway/security) — 액세스 모델 및 강화
|
||||
|
||||
@ -2,13 +2,13 @@
|
||||
read_when:
|
||||
- 그룹 채팅 동작 또는 멘션 게이팅 변경
|
||||
sidebarTitle: Groups
|
||||
summary: 여러 플랫폼에서의 그룹 채팅 동작 (Discord/iMessage/Matrix/Microsoft Teams/Signal/Slack/Telegram/WhatsApp/Zalo)
|
||||
summary: 표면 전반의 그룹 채팅 동작(Discord/iMessage/Matrix/Microsoft Teams/Signal/Slack/Telegram/WhatsApp/Zalo)
|
||||
title: 그룹
|
||||
x-i18n:
|
||||
generated_at: "2026-05-03T21:27:20Z"
|
||||
generated_at: "2026-05-04T02:21:22Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 6fd4fcaa8335f1dc4b4b1a719d6654ab0c10530f74284269ed6205dd5f87c116
|
||||
source_hash: dea506c011a5d8f6155b2f56aacb236482cb8c5b7457001cb2171fd45932443d
|
||||
source_path: channels/groups.md
|
||||
workflow: 16
|
||||
---
|
||||
@ -17,15 +17,15 @@ OpenClaw는 여러 표면에서 그룹 채팅을 일관되게 처리합니다: D
|
||||
|
||||
## 초보자 소개(2분)
|
||||
|
||||
OpenClaw는 사용자의 자체 메시징 계정에서 "동작"합니다. 별도의 WhatsApp 봇 사용자는 없습니다. **사용자**가 그룹에 있으면 OpenClaw는 해당 그룹을 볼 수 있고 그곳에서 응답할 수 있습니다.
|
||||
OpenClaw는 사용자의 메시징 계정 안에서 "동작"합니다. 별도의 WhatsApp 봇 사용자가 없습니다. **사용자**가 그룹에 있으면 OpenClaw는 해당 그룹을 볼 수 있고 그곳에서 응답할 수 있습니다.
|
||||
|
||||
기본 동작:
|
||||
|
||||
- 그룹은 제한됩니다(`groupPolicy: "allowlist"`).
|
||||
- 명시적으로 멘션 게이팅을 비활성화하지 않는 한, 응답에는 멘션이 필요합니다.
|
||||
- 그룹/채널의 일반 최종 응답은 기본적으로 비공개입니다. 보이는 방 출력은 `message` 도구를 사용합니다.
|
||||
- 그룹/채널의 일반 최종 응답은 기본적으로 비공개입니다. 방에 보이는 출력은 `message` 도구를 사용합니다.
|
||||
|
||||
즉, 허용 목록에 있는 발신자는 OpenClaw를 멘션하여 트리거할 수 있습니다.
|
||||
해석: 허용 목록에 있는 발신자는 OpenClaw를 멘션하여 트리거할 수 있습니다.
|
||||
|
||||
<Note>
|
||||
**요약**
|
||||
@ -47,20 +47,29 @@ otherwise -> reply
|
||||
|
||||
## 보이는 응답
|
||||
|
||||
그룹/채널 방의 경우 OpenClaw는 기본값으로 `messages.groupChat.visibleReplies: "message_tool"`을 사용합니다.
|
||||
`openclaw doctor --fix`는 이를 생략한 구성된 채널 설정에 이 기본값을 기록합니다.
|
||||
즉, 에이전트는 여전히 턴을 처리하고 메모리/세션 상태를 업데이트할 수 있지만, 일반 최종 답변이 방에 자동으로 게시되지는 않습니다. 보이게 말하려면 에이전트가 `message(action=send)`를 사용합니다.
|
||||
그룹/채널 방에서 OpenClaw의 기본값은 `messages.groupChat.visibleReplies: "message_tool"`입니다.
|
||||
`openclaw doctor --fix`는 이 값을 생략한 구성된 채널 설정에 이 기본값을 기록합니다.
|
||||
즉, 에이전트는 여전히 턴을 처리하고 메모리/세션 상태를 업데이트할 수 있지만, 일반 최종 답변은 방에 자동으로 게시되지 않습니다. 보이게 말하려면 에이전트가 `message(action=send)`를 사용합니다.
|
||||
|
||||
활성 도구 정책에서 메시지 도구를 사용할 수 없으면 OpenClaw는 응답을 조용히 억제하는 대신 자동 보이는 응답으로 폴백합니다.
|
||||
이 기본값은 도구를 안정적으로 호출하는 모델/런타임에 의존합니다. 로그에
|
||||
어시스턴트 텍스트가 표시되지만 `didSendViaMessagingTool: false`라면, 모델이
|
||||
메시지 도구를 호출하는 대신 비공개로 답변한 것입니다. 이는
|
||||
Discord/Slack/Telegram 전송 실패가 아닙니다. 그룹/채널 세션에는
|
||||
도구 호출이 안정적인 모델을 사용하거나,
|
||||
`messages.groupChat.visibleReplies: "automatic"`을 설정하여 기존의 보이는
|
||||
최종 응답을 복원하세요.
|
||||
|
||||
활성 도구 정책에서 메시지 도구를 사용할 수 없으면 OpenClaw는 응답을 조용히 억제하는 대신
|
||||
자동 보이는 응답으로 폴백합니다.
|
||||
`openclaw doctor`는 이 불일치에 대해 경고합니다.
|
||||
|
||||
직접 채팅 및 그 밖의 모든 소스 턴에는 `messages.visibleReplies: "message_tool"`을 사용해 동일한 도구 전용 보이는 응답 동작을 전역으로 적용합니다. 하네스도 이를 설정되지 않은 기본값으로 선택할 수 있으며, Codex 하네스는 Codex 모드 직접 채팅에서 이렇게 합니다. `messages.groupChat.visibleReplies`는 그룹/채널 방에 대한 더 구체적인 오버라이드로 유지됩니다.
|
||||
직접 채팅과 기타 모든 소스 턴에는 `messages.visibleReplies: "message_tool"`을 사용하여 동일한 도구 전용 보이는 응답 동작을 전역으로 적용하세요. 하네스도 이를 미설정 기본값으로 선택할 수 있으며, Codex 하네스는 Codex 모드 직접 채팅에서 이렇게 합니다. `messages.groupChat.visibleReplies`는 그룹/채널 방에 대한 더 구체적인 오버라이드로 남습니다.
|
||||
|
||||
이는 대부분의 관망 모드 턴에서 모델이 `NO_REPLY`로 답하도록 강제하던 예전 패턴을 대체합니다. 도구 전용 모드에서 보이는 동작을 하지 않는다는 것은 단순히 메시지 도구를 호출하지 않는다는 뜻입니다.
|
||||
이는 대부분의 대기 모드 턴에서 모델이 `NO_REPLY`로 답하도록 강제하던 이전 패턴을 대체합니다. 도구 전용 모드에서 보이는 동작을 하지 않는다는 것은 단순히 메시지 도구를 호출하지 않는다는 뜻입니다.
|
||||
|
||||
에이전트가 도구 전용 모드에서 작업하는 동안에도 입력 표시기는 계속 전송됩니다. 이러한 턴에서는 에이전트가 메시지 도구를 호출할지 결정하기 전에 일반 어시스턴트 메시지 텍스트가 전혀 없을 수 있으므로, 기본 그룹 입력 모드는 "message"에서 "instant"로 업그레이드됩니다. 명시적인 입력 모드 설정이 있으면 여전히 그것이 우선합니다.
|
||||
도구 전용 모드에서 에이전트가 작업하는 동안에도 입력 표시기는 계속 전송됩니다. 이러한 턴에서는 에이전트가 메시지 도구를 호출할지 결정하기 전에 일반 어시스턴트 메시지 텍스트가 없을 수 있으므로, 기본 그룹 입력 모드는 "message"에서 "instant"로 업그레이드됩니다. 명시적인 입력 모드 설정은 여전히 우선합니다.
|
||||
|
||||
그룹/채널 방에 대해 레거시 자동 최종 응답을 복원하려면:
|
||||
그룹/채널 방에서 기존 자동 최종 응답을 복원하려면:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -72,9 +81,10 @@ otherwise -> reply
|
||||
}
|
||||
```
|
||||
|
||||
Gateway는 파일이 저장된 후 `messages` 설정을 핫 리로드합니다. 배포에서 파일 감시 또는 설정 리로드가 비활성화된 경우에만 다시 시작하세요.
|
||||
파일이 저장되면 Gateway는 `messages` 설정을 핫 리로드합니다. 배포에서 파일 감시 또는 설정 리로드가 비활성화된 경우에만
|
||||
다시 시작하세요.
|
||||
|
||||
모든 소스 채팅에서 보이는 출력이 메시지 도구를 통해서만 나가도록 하려면:
|
||||
모든 소스 채팅의 보이는 출력이 메시지 도구를 통해 전달되도록 요구하려면:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -84,27 +94,27 @@ Gateway는 파일이 저장된 후 `messages` 설정을 핫 리로드합니다.
|
||||
}
|
||||
```
|
||||
|
||||
네이티브 슬래시 명령(Discord, Telegram 및 네이티브 명령 지원이 있는 다른 표면)은 `visibleReplies: "message_tool"`을 우회하고 항상 보이게 응답하므로 채널 네이티브 명령 UI가 기대하는 응답을 받을 수 있습니다. 이는 검증된 네이티브 명령 턴에만 적용됩니다. 텍스트로 입력한 `/...` 명령과 일반 채팅 턴은 여전히 구성된 그룹 기본값을 따릅니다.
|
||||
네이티브 슬래시 명령(Discord, Telegram 및 네이티브 명령 지원이 있는 기타 표면)은 `visibleReplies: "message_tool"`을 우회하고 항상 보이게 응답하므로 채널 네이티브 명령 UI가 예상하는 응답을 받습니다. 이는 검증된 네이티브 명령 턴에만 적용됩니다. 텍스트로 입력한 `/...` 명령과 일반 채팅 턴은 여전히 구성된 그룹 기본값을 따릅니다.
|
||||
|
||||
## 컨텍스트 가시성과 허용 목록
|
||||
## 컨텍스트 표시와 허용 목록
|
||||
|
||||
그룹 안전에는 두 가지 서로 다른 제어가 관여합니다.
|
||||
|
||||
- **트리거 권한 부여**: 에이전트를 트리거할 수 있는 사람(`groupPolicy`, `groups`, `groupAllowFrom`, 채널별 허용 목록).
|
||||
- **컨텍스트 가시성**: 모델에 주입되는 보조 컨텍스트(응답 텍스트, 인용, 스레드 기록, 전달된 메타데이터).
|
||||
- **트리거 권한 부여**: 누가 에이전트를 트리거할 수 있는지(`groupPolicy`, `groups`, `groupAllowFrom`, 채널별 허용 목록).
|
||||
- **컨텍스트 표시**: 모델에 주입되는 보조 컨텍스트(답글 텍스트, 인용, 스레드 기록, 전달된 메타데이터).
|
||||
|
||||
기본적으로 OpenClaw는 일반 채팅 동작을 우선하며 컨텍스트를 대부분 수신된 그대로 유지합니다. 즉, 허용 목록은 주로 누가 작업을 트리거할 수 있는지를 결정하며, 모든 인용 또는 기록 스니펫에 대한 보편적인 수정 경계가 아닙니다.
|
||||
기본적으로 OpenClaw는 일반 채팅 동작을 우선시하며 컨텍스트를 대부분 수신된 그대로 유지합니다. 즉, 허용 목록은 주로 누가 작업을 트리거할 수 있는지를 결정하며, 인용되거나 과거에 기록된 모든 스니펫에 대한 보편적인 수정 경계는 아닙니다.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Current behavior is channel-specific">
|
||||
- 일부 채널은 이미 특정 경로에서 보조 컨텍스트에 발신자 기반 필터링을 적용합니다(예: Slack 스레드 시딩, Matrix 응답/스레드 조회).
|
||||
- 다른 채널은 아직 인용/응답/전달 컨텍스트를 수신된 그대로 전달합니다.
|
||||
<Accordion title="현재 동작은 채널별로 다릅니다">
|
||||
- 일부 채널은 이미 특정 경로에서 보조 컨텍스트에 대해 발신자 기반 필터링을 적용합니다(예: Slack 스레드 시딩, Matrix 답글/스레드 조회).
|
||||
- 다른 채널은 여전히 인용/답글/전달 컨텍스트를 수신된 그대로 전달합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Hardening direction (planned)">
|
||||
<Accordion title="강화 방향(예정)">
|
||||
- `contextVisibility: "all"`(기본값)은 현재의 수신된 그대로 동작을 유지합니다.
|
||||
- `contextVisibility: "allowlist"`는 보조 컨텍스트를 허용 목록에 있는 발신자로 필터링합니다.
|
||||
- `contextVisibility: "allowlist_quote"`는 `allowlist`에 하나의 명시적 인용/응답 예외를 더한 것입니다.
|
||||
- `contextVisibility: "allowlist"`는 보조 컨텍스트를 허용 목록의 발신자로 필터링합니다.
|
||||
- `contextVisibility: "allowlist_quote"`는 `allowlist`에 명시적인 인용/답글 예외 하나를 더한 것입니다.
|
||||
|
||||
이 강화 모델이 채널 전반에 일관되게 구현될 때까지는 표면별 차이를 예상하세요.
|
||||
|
||||
@ -121,36 +131,36 @@ Gateway는 파일이 저장된 후 `messages` 설정을 핫 리로드합니다.
|
||||
| 모든 그룹 응답 비활성화 | `groupPolicy: "disabled"` |
|
||||
| 특정 그룹만 | `groups: { "<group-id>": { ... } }` (`"*"` 키 없음) |
|
||||
| 그룹에서 사용자만 트리거 가능 | `groupPolicy: "allowlist"`, `groupAllowFrom: ["+1555..."]` |
|
||||
| 채널 전반에서 신뢰할 수 있는 발신자 집합 하나 재사용 | `groupAllowFrom: ["accessGroup:operators"]` |
|
||||
| 채널 간에 신뢰할 수 있는 발신자 집합 하나 재사용 | `groupAllowFrom: ["accessGroup:operators"]` |
|
||||
|
||||
재사용 가능한 발신자 허용 목록은 [접근 그룹](/ko/channels/access-groups)을 참조하세요.
|
||||
재사용 가능한 발신자 허용 목록은 [액세스 그룹](/ko/channels/access-groups)을 참조하세요.
|
||||
|
||||
## 세션 키
|
||||
|
||||
- 그룹 세션은 `agent:<agentId>:<channel>:group:<id>` 세션 키를 사용합니다(방/채널은 `agent:<agentId>:<channel>:channel:<id>` 사용).
|
||||
- Telegram 포럼 주제는 그룹 ID에 `:topic:<threadId>`를 추가하여 각 주제가 자체 세션을 갖도록 합니다.
|
||||
- 직접 채팅은 기본 세션(또는 구성된 경우 발신자별 세션)을 사용합니다.
|
||||
- Heartbeat는 그룹 세션에서 건너뜁니다.
|
||||
- 직접 채팅은 기본 세션(또는 설정된 경우 발신자별 세션)을 사용합니다.
|
||||
- 그룹 세션에서는 Heartbeat가 건너뛰어집니다.
|
||||
|
||||
<a id="pattern-personal-dms-public-groups-single-agent"></a>
|
||||
|
||||
## 패턴: 개인 DM + 공개 그룹(단일 에이전트)
|
||||
|
||||
예, "개인" 트래픽이 **DM**이고 "공개" 트래픽이 **그룹**이라면 잘 동작합니다.
|
||||
예. "개인" 트래픽이 **DM**이고 "공개" 트래픽이 **그룹**이라면 잘 작동합니다.
|
||||
|
||||
이유: 단일 에이전트 모드에서 DM은 일반적으로 **기본** 세션 키(`agent:main:main`)에 들어오지만, 그룹은 항상 **비기본** 세션 키(`agent:main:<channel>:group:<id>`)를 사용합니다. `mode: "non-main"`으로 샌드박싱을 활성화하면 해당 그룹 세션은 구성된 샌드박스 백엔드에서 실행되고, 기본 DM 세션은 호스트에 남습니다. 백엔드를 선택하지 않으면 Docker가 기본 백엔드입니다.
|
||||
이유: 단일 에이전트 모드에서 DM은 일반적으로 **메인** 세션 키(`agent:main:main`)에 도착하지만, 그룹은 항상 **비메인** 세션 키(`agent:main:<channel>:group:<id>`)를 사용합니다. `mode: "non-main"`으로 샌드박싱을 활성화하면, 해당 그룹 세션은 구성된 샌드박스 백엔드에서 실행되고 메인 DM 세션은 호스트에 남습니다. 백엔드를 선택하지 않으면 Docker가 기본 백엔드입니다.
|
||||
|
||||
이렇게 하면 하나의 에이전트 "두뇌"(공유 작업공간 + 메모리)를 사용하면서도 두 가지 실행 태세를 가질 수 있습니다.
|
||||
이를 통해 하나의 에이전트 "두뇌"(공유 워크스페이스 + 메모리)를 사용하면서도 두 가지 실행 태세를 갖게 됩니다.
|
||||
|
||||
- **DM**: 전체 도구(호스트)
|
||||
- **그룹**: 샌드박스 + 제한된 도구
|
||||
|
||||
<Note>
|
||||
진정으로 분리된 작업공간/페르소나("개인"과 "공개"가 절대 섞이면 안 됨)가 필요하면 두 번째 에이전트 + 바인딩을 사용하세요. [다중 에이전트 라우팅](/ko/concepts/multi-agent)을 참조하세요.
|
||||
진정으로 분리된 워크스페이스/페르소나("개인"과 "공개"가 절대 섞이면 안 됨)가 필요하다면 두 번째 에이전트 + 바인딩을 사용하세요. [다중 에이전트 라우팅](/ko/concepts/multi-agent)을 참조하세요.
|
||||
</Note>
|
||||
|
||||
<Tabs>
|
||||
<Tab title="DMs on host, groups sandboxed">
|
||||
<Tab title="호스트의 DM, 샌드박스된 그룹">
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
@ -174,8 +184,8 @@ Gateway는 파일이 저장된 후 `messages` 설정을 핫 리로드합니다.
|
||||
}
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Groups see only an allowlisted folder">
|
||||
"호스트 접근 없음" 대신 "그룹은 폴더 X만 볼 수 있음"을 원하나요? `workspaceAccess: "none"`을 유지하고 허용 목록에 있는 경로만 샌드박스에 마운트하세요.
|
||||
<Tab title="그룹은 허용 목록에 있는 폴더만 봅니다">
|
||||
"그룹은 호스트 접근 없음" 대신 "그룹은 X 폴더만 볼 수 있음"을 원한다면 `workspaceAccess: "none"`을 유지하고 허용 목록에 있는 경로만 샌드박스에 마운트하세요.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -202,18 +212,18 @@ Gateway는 파일이 저장된 후 `messages` 설정을 핫 리로드합니다.
|
||||
|
||||
관련 항목:
|
||||
|
||||
- 설정 키 및 기본값: [Gateway 구성](/ko/gateway/config-agents#agentsdefaultssandbox)
|
||||
- 도구가 차단된 이유 디버깅: [샌드박스와 도구 정책 및 권한 상승](/ko/gateway/sandbox-vs-tool-policy-vs-elevated)
|
||||
- 설정 키와 기본값: [Gateway 설정](/ko/gateway/config-agents#agentsdefaultssandbox)
|
||||
- 도구가 차단된 이유 디버깅: [샌드박스 vs 도구 정책 vs 상승 권한](/ko/gateway/sandbox-vs-tool-policy-vs-elevated)
|
||||
- 바인드 마운트 세부 정보: [샌드박싱](/ko/gateway/sandboxing#custom-bind-mounts)
|
||||
|
||||
## 표시 레이블
|
||||
|
||||
- UI 레이블은 사용 가능한 경우 `displayName`을 사용하며, `<channel>:<token>` 형식입니다.
|
||||
- `#room`은 방/채널용으로 예약되어 있습니다. 그룹 채팅은 `g-<slug>`를 사용합니다(소문자, 공백 -> `-`, `#@+._-` 유지).
|
||||
- UI 레이블은 사용 가능한 경우 `displayName`을 사용하며, `<channel>:<token>` 형식으로 지정됩니다.
|
||||
- `#room`은 방/채널용으로 예약되어 있으며, 그룹 채팅은 `g-<slug>`를 사용합니다(소문자, 공백 -> `-`, `#@+._-` 유지).
|
||||
|
||||
## 그룹 정책
|
||||
|
||||
채널별로 그룹/방 메시지를 처리하는 방식을 제어합니다.
|
||||
채널별로 그룹/방 메시지 처리 방식을 제어합니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -267,23 +277,23 @@ Gateway는 파일이 저장된 후 `messages` 설정을 핫 리로드합니다.
|
||||
| `"allowlist"` | 구성된 허용 목록과 일치하는 그룹/방만 허용합니다. |
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Per-channel notes">
|
||||
<Accordion title="채널별 참고 사항">
|
||||
- `groupPolicy`는 멘션 게이팅(@멘션 필요)과 별개입니다.
|
||||
- WhatsApp/Telegram/Signal/iMessage/Microsoft Teams/Zalo: `groupAllowFrom`을 사용합니다(폴백: 명시적 `allowFrom`).
|
||||
- Signal: `groupAllowFrom`은 인바운드 Signal 그룹 ID 또는 발신자 전화번호/UUID와 일치할 수 있습니다.
|
||||
- DM 페어링 승인(`*-allowFrom` 저장소 항목)은 DM 접근에만 적용됩니다. 그룹 발신자 권한 부여는 그룹 허용 목록에 명시적으로 유지됩니다.
|
||||
- WhatsApp/Telegram/Signal/iMessage/Microsoft Teams/Zalo: `groupAllowFrom`을 사용하세요(대체: 명시적 `allowFrom`).
|
||||
- Signal: `groupAllowFrom`은 인바운드 Signal 그룹 ID 또는 보낸 사람의 전화번호/UUID와 일치할 수 있습니다.
|
||||
- DM 페어링 승인(`*-allowFrom` 저장소 항목)은 DM 접근에만 적용됩니다. 그룹 보낸 사람 권한 부여는 그룹 허용 목록에 명시적으로 유지됩니다.
|
||||
- Discord: 허용 목록은 `channels.discord.guilds.<id>.channels`를 사용합니다.
|
||||
- Slack: 허용 목록은 `channels.slack.channels`를 사용합니다.
|
||||
- Matrix: 허용 목록은 `channels.matrix.groups`를 사용합니다. 방 ID 또는 별칭을 선호하세요. 참여한 방 이름 조회는 최선의 노력 방식이며, 해석되지 않은 이름은 런타임에 무시됩니다. 발신자를 제한하려면 `channels.matrix.groupAllowFrom`을 사용하세요. 방별 `users` 허용 목록도 지원됩니다.
|
||||
- Matrix: 허용 목록은 `channels.matrix.groups`를 사용합니다. 방 ID 또는 별칭을 선호하세요. 참여한 방 이름 조회는 최선 노력 방식이며, 확인되지 않은 이름은 런타임에 무시됩니다. 보낸 사람을 제한하려면 `channels.matrix.groupAllowFrom`을 사용하세요. 방별 `users` 허용 목록도 지원됩니다.
|
||||
- 그룹 DM은 별도로 제어됩니다(`channels.discord.dm.*`, `channels.slack.dm.*`).
|
||||
- Telegram 허용 목록은 사용자 ID(`"123456789"`, `"telegram:123456789"`, `"tg:123456789"`) 또는 사용자 이름(`"@alice"` 또는 `"alice"`)과 일치할 수 있습니다. 접두사는 대소문자를 구분하지 않습니다.
|
||||
- 기본값은 `groupPolicy: "allowlist"`입니다. 그룹 허용 목록이 비어 있으면 그룹 메시지는 차단됩니다.
|
||||
- 런타임 안전: 공급자 블록이 완전히 누락된 경우(`channels.<provider>` 없음), 그룹 정책은 `channels.defaults.groupPolicy`를 상속하는 대신 실패 시 닫힘 모드(일반적으로 `allowlist`)로 폴백합니다.
|
||||
- 기본값은 `groupPolicy: "allowlist"`입니다. 그룹 허용 목록이 비어 있으면 그룹 메시지가 차단됩니다.
|
||||
- 런타임 안전성: 제공자 블록이 완전히 누락된 경우(`channels.<provider>` 없음), 그룹 정책은 `channels.defaults.groupPolicy`를 상속하는 대신 실패 시 차단 모드(일반적으로 `allowlist`)로 대체됩니다.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
빠른 개념 모델(그룹 메시지 평가 순서):
|
||||
빠르게 이해하는 모델(그룹 메시지 평가 순서):
|
||||
|
||||
<Steps>
|
||||
<Step title="groupPolicy">
|
||||
@ -299,9 +309,9 @@ Gateway는 파일이 저장된 후 `messages` 설정을 핫 리로드합니다.
|
||||
|
||||
## 멘션 게이팅(기본값)
|
||||
|
||||
그룹 메시지는 그룹별로 재정의하지 않는 한 멘션이 필요합니다. 기본값은 `*.groups."*"` 아래에서 하위 시스템별로 설정됩니다.
|
||||
그룹 메시지는 그룹별로 재정의하지 않는 한 멘션이 필요합니다. 기본값은 하위 시스템별로 `*.groups."*"` 아래에 있습니다.
|
||||
|
||||
채널이 답장 메타데이터를 지원하는 경우 봇 메시지에 답장하면 암시적 멘션으로 간주됩니다. 인용 메타데이터를 노출하는 채널에서는 봇 메시지를 인용하는 것도 암시적 멘션으로 간주될 수 있습니다. 현재 내장 사례에는 Telegram, WhatsApp, Slack, Discord, Microsoft Teams, ZaloUser가 포함됩니다.
|
||||
채널이 답장 메타데이터를 지원하는 경우, 봇 메시지에 답장하면 암시적 멘션으로 간주됩니다. 인용 메타데이터를 노출하는 채널에서는 봇 메시지를 인용하는 것도 암시적 멘션으로 간주될 수 있습니다. 현재 기본 제공 사례에는 Telegram, WhatsApp, Slack, Discord, Microsoft Teams, ZaloUser가 포함됩니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -342,24 +352,24 @@ Gateway는 파일이 저장된 후 `messages` 설정을 핫 리로드합니다.
|
||||
<AccordionGroup>
|
||||
<Accordion title="멘션 게이팅 참고 사항">
|
||||
- `mentionPatterns`는 대소문자를 구분하지 않는 안전한 정규식 패턴입니다. 잘못된 패턴과 안전하지 않은 중첩 반복 형식은 무시됩니다.
|
||||
- 명시적 멘션을 제공하는 표면은 계속 통과합니다. 패턴은 대체 수단입니다.
|
||||
- 명시적 멘션을 제공하는 표면은 그대로 통과합니다. 패턴은 대체 수단입니다.
|
||||
- 에이전트별 재정의: `agents.list[].groupChat.mentionPatterns`(여러 에이전트가 그룹을 공유할 때 유용).
|
||||
- 멘션 게이팅은 멘션 감지가 가능한 경우(네이티브 멘션 또는 `mentionPatterns`가 구성된 경우)에만 적용됩니다.
|
||||
- 그룹이나 발신자를 허용 목록에 추가해도 멘션 게이팅은 비활성화되지 않습니다. 모든 메시지가 트리거되어야 하는 경우 해당 그룹의 `requireMention`을 `false`로 설정하세요.
|
||||
- 그룹 채팅 프롬프트 컨텍스트는 매 턴 해결된 무응답 지시를 전달합니다. 워크스페이스 파일은 `NO_REPLY` 메커니즘을 중복해서는 안 됩니다.
|
||||
- 무응답이 허용되는 그룹은 깨끗한 빈 모델 턴이나 추론만 있는 모델 턴을 `NO_REPLY`와 동일한 무응답으로 처리합니다. 직접 채팅은 직접 무응답이 명시적으로 허용된 경우에만 동일하게 동작합니다. 그렇지 않으면 빈 답장은 실패한 에이전트 턴으로 남습니다.
|
||||
- 그룹 또는 보낸 사람을 허용 목록에 추가해도 멘션 게이팅은 비활성화되지 않습니다. 모든 메시지가 트리거되어야 한다면 해당 그룹의 `requireMention`을 `false`로 설정하세요.
|
||||
- 그룹 채팅 프롬프트 컨텍스트는 매 턴 확인된 무응답 지시를 포함합니다. 워크스페이스 파일은 `NO_REPLY` 메커니즘을 중복해서는 안 됩니다.
|
||||
- 무응답이 허용된 그룹은 깨끗한 빈 모델 턴이나 추론만 있는 모델 턴을 `NO_REPLY`와 동일하게 무응답으로 처리합니다. 직접 채팅도 직접 무응답이 명시적으로 허용된 경우에만 동일하게 동작합니다. 그렇지 않으면 빈 답장은 실패한 에이전트 턴으로 남습니다.
|
||||
- Discord 기본값은 `channels.discord.guilds."*"`에 있습니다(길드/채널별로 재정의 가능).
|
||||
- 그룹 기록 컨텍스트는 채널 전반에서 일관되게 래핑되며 **보류 중인 항목만** 포함합니다(멘션 게이팅으로 건너뛴 메시지). 전역 기본값은 `messages.groupChat.historyLimit`을 사용하고, 재정의에는 `channels.<channel>.historyLimit`(또는 `channels.<channel>.accounts.*.historyLimit`)을 사용하세요. 비활성화하려면 `0`으로 설정하세요.
|
||||
- 그룹 기록 컨텍스트는 채널 전반에서 균일하게 래핑되며 **대기 중 항목만** 포함합니다(멘션 게이팅으로 건너뛴 메시지). 전역 기본값에는 `messages.groupChat.historyLimit`을 사용하고, 재정의에는 `channels.<channel>.historyLimit`(또는 `channels.<channel>.accounts.*.historyLimit`)을 사용하세요. 비활성화하려면 `0`을 설정하세요.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 그룹/채널 도구 제한 사항(선택 사항)
|
||||
## 그룹/채널 도구 제한(선택 사항)
|
||||
|
||||
일부 채널 구성은 **특정 그룹/방/채널 내부**에서 사용할 수 있는 도구를 제한하는 기능을 지원합니다.
|
||||
일부 채널 구성은 **특정 그룹/방/채널 내부에서** 사용할 수 있는 도구를 제한하도록 지원합니다.
|
||||
|
||||
- `tools`: 전체 그룹에 대해 도구를 허용/거부합니다.
|
||||
- `toolsBySender`: 그룹 내 발신자별 재정의입니다. 명시적 키 접두사를 사용하세요: `id:<senderId>`, `e164:<phone>`, `username:<handle>`, `name:<displayName>`, 그리고 `"*"` 와일드카드. 레거시 접두사 없는 키도 여전히 허용되며 `id:`로만 매칭됩니다.
|
||||
- `toolsBySender`: 그룹 내 보낸 사람별 재정의입니다. 명시적 키 접두사를 사용하세요: `id:<senderId>`, `e164:<phone>`, `username:<handle>`, `name:<displayName>`, `"*"` 와일드카드. 레거시 무접두사 키도 여전히 허용되며 `id:`로만 일치합니다.
|
||||
|
||||
해결 순서(가장 구체적인 항목이 우선):
|
||||
|
||||
@ -399,15 +409,15 @@ Gateway는 파일이 저장된 후 `messages` 설정을 핫 리로드합니다.
|
||||
```
|
||||
|
||||
<Note>
|
||||
그룹/채널 도구 제한은 전역/에이전트 도구 정책에 추가로 적용됩니다(거부가 여전히 우선합니다). 일부 채널은 방/채널에 대해 다른 중첩 구조를 사용합니다(예: Discord `guilds.*.channels.*`, Slack `channels.*`, Microsoft Teams `teams.*.channels.*`).
|
||||
그룹/채널 도구 제한은 전역/에이전트 도구 정책에 추가로 적용됩니다(거부가 여전히 우선). 일부 채널은 방/채널에 다른 중첩 구조를 사용합니다(예: Discord `guilds.*.channels.*`, Slack `channels.*`, Microsoft Teams `teams.*.channels.*`).
|
||||
</Note>
|
||||
|
||||
## 그룹 허용 목록
|
||||
|
||||
`channels.whatsapp.groups`, `channels.telegram.groups`, 또는 `channels.imessage.groups`가 구성되면 키가 그룹 허용 목록으로 동작합니다. 기본 멘션 동작을 설정하면서 모든 그룹을 허용하려면 `"*"`를 사용하세요.
|
||||
`channels.whatsapp.groups`, `channels.telegram.groups` 또는 `channels.imessage.groups`가 구성된 경우, 키는 그룹 허용 목록으로 동작합니다. 기본 멘션 동작을 계속 설정하면서 모든 그룹을 허용하려면 `"*"`를 사용하세요.
|
||||
|
||||
<Warning>
|
||||
흔한 혼동: DM 페어링 승인은 그룹 권한 부여와 다릅니다. DM 페어링을 지원하는 채널의 경우 페어링 저장소는 DM만 잠금 해제합니다. 그룹 명령에는 여전히 `groupAllowFrom` 같은 구성 허용 목록이나 해당 채널에 대해 문서화된 구성 대체 경로에서 명시적인 그룹 발신자 권한 부여가 필요합니다.
|
||||
흔한 혼동: DM 페어링 승인은 그룹 권한 부여와 같지 않습니다. DM 페어링을 지원하는 채널의 경우, 페어링 저장소는 DM만 잠금 해제합니다. 그룹 명령은 여전히 `groupAllowFrom` 같은 구성 허용 목록이나 해당 채널에 문서화된 구성 대체값을 통한 명시적 그룹 보낸 사람 권한 부여가 필요합니다.
|
||||
</Warning>
|
||||
|
||||
일반적인 의도(복사/붙여넣기):
|
||||
@ -467,7 +477,7 @@ Gateway는 파일이 저장된 후 `messages` 설정을 핫 리로드합니다.
|
||||
- `/activation mention`
|
||||
- `/activation always`
|
||||
|
||||
소유자는 `channels.whatsapp.allowFrom`(설정되지 않은 경우 봇 자신의 E.164)으로 결정됩니다. 명령은 단독 메시지로 보내세요. 다른 표면은 현재 `/activation`을 무시합니다.
|
||||
소유자는 `channels.whatsapp.allowFrom`(설정되지 않은 경우 봇 자신의 E.164)으로 결정됩니다. 명령은 독립된 메시지로 보내세요. 다른 표면은 현재 `/activation`을 무시합니다.
|
||||
|
||||
## 컨텍스트 필드
|
||||
|
||||
@ -481,15 +491,15 @@ Gateway는 파일이 저장된 후 `messages` 설정을 핫 리로드합니다.
|
||||
|
||||
채널별 참고 사항:
|
||||
|
||||
- BlueBubbles는 `GroupMembers`를 채우기 전에 이름이 없는 macOS 그룹 참가자를 로컬 연락처 데이터베이스에서 선택적으로 보강할 수 있습니다. 기본적으로 꺼져 있으며 일반 그룹 게이팅을 통과한 후에만 실행됩니다.
|
||||
- BlueBubbles는 `GroupMembers`를 채우기 전에 로컬 연락처 데이터베이스에서 이름이 없는 macOS 그룹 참가자를 선택적으로 보강할 수 있습니다. 이는 기본적으로 꺼져 있으며, 일반 그룹 게이팅을 통과한 뒤에만 실행됩니다.
|
||||
|
||||
에이전트 시스템 프롬프트는 새 그룹 세션의 첫 턴에 그룹 소개를 포함합니다. 이 소개는 모델에게 사람처럼 응답하고, Markdown 표를 피하며, 빈 줄을 최소화하고 일반적인 채팅 간격을 따르며, 리터럴 `\n` 시퀀스를 입력하지 않도록 상기시킵니다. 채널에서 가져온 그룹 이름과 참가자 레이블은 인라인 시스템 지시가 아니라 펜스로 감싼 신뢰할 수 없는 메타데이터로 렌더링됩니다.
|
||||
에이전트 시스템 프롬프트는 새 그룹 세션의 첫 턴에 그룹 소개를 포함합니다. 이는 모델에게 사람처럼 응답하고, Markdown 표를 피하며, 빈 줄을 최소화하고 일반적인 채팅 간격을 따르며, 리터럴 `\n` 시퀀스를 입력하지 않도록 상기시킵니다. 채널에서 가져온 그룹 이름과 참가자 레이블은 인라인 시스템 지시가 아니라 펜스 처리된 신뢰할 수 없는 메타데이터로 렌더링됩니다.
|
||||
|
||||
## iMessage 세부 사항
|
||||
|
||||
- 라우팅하거나 허용 목록을 설정할 때는 `chat_id:<id>`를 선호하세요.
|
||||
- 채팅 목록 표시: `imsg chats --limit 20`.
|
||||
- 그룹 답장은 항상 동일한 `chat_id`로 돌아갑니다.
|
||||
- 라우팅하거나 허용 목록에 추가할 때는 `chat_id:<id>`를 선호하세요.
|
||||
- 채팅 목록: `imsg chats --limit 20`.
|
||||
- 그룹 답장은 항상 같은 `chat_id`로 돌아갑니다.
|
||||
|
||||
## WhatsApp 시스템 프롬프트
|
||||
|
||||
@ -497,7 +507,7 @@ Gateway는 파일이 저장된 후 `messages` 설정을 핫 리로드합니다.
|
||||
|
||||
## WhatsApp 세부 사항
|
||||
|
||||
WhatsApp 전용 동작(기록 주입, 멘션 처리 세부 사항)은 [그룹 메시지](/ko/channels/group-messages)를 참조하세요.
|
||||
WhatsApp 전용 동작(기록 주입, 멘션 처리 세부 정보)은 [그룹 메시지](/ko/channels/group-messages)를 참조하세요.
|
||||
|
||||
## 관련 항목
|
||||
|
||||
|
||||
@ -1,20 +1,20 @@
|
||||
---
|
||||
read_when:
|
||||
- OpenClaw를 IRC 채널 또는 DM에 연결하려는 경우
|
||||
- IRC 허용 목록, 그룹 정책 또는 멘션 게이팅을 구성하는 경우
|
||||
summary: IRC Plugin 설정, 액세스 제어 및 문제 해결
|
||||
- IRC 허용 목록, 그룹 정책 또는 멘션 게이팅을 구성하고 있습니다
|
||||
summary: IRC Plugin 설정, 접근 제어 및 문제 해결
|
||||
title: IRC
|
||||
x-i18n:
|
||||
generated_at: "2026-04-24T06:03:51Z"
|
||||
model: gpt-5.4
|
||||
generated_at: "2026-05-04T02:21:26Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 76f316c0f026d0387a97dc5dcb6d8967f6e4841d94b95b36e42f6f6284882a69
|
||||
source_hash: 43c3098fe49a5e7405443df73e1bf752a579460dc0b2070c3d07f43b512bb555
|
||||
source_path: channels/irc.md
|
||||
workflow: 15
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
OpenClaw를 IRC 채널이나 DM에 연결하려는 경우 사용하세요.
|
||||
IRC는 번들 Plugin으로 제공되지만, 설정은 메인 구성의 `channels.irc` 아래에서 합니다.
|
||||
클래식 채널(`#room`)과 다이렉트 메시지에서 OpenClaw를 사용하려면 IRC를 사용하세요.
|
||||
IRC는 번들 Plugin으로 제공되지만, 기본 구성의 `channels.irc` 아래에서 설정됩니다.
|
||||
|
||||
## 빠른 시작
|
||||
|
||||
@ -36,50 +36,51 @@ IRC는 번들 Plugin으로 제공되지만, 설정은 메인 구성의 `channels
|
||||
}
|
||||
```
|
||||
|
||||
봇 조정을 위해서는 비공개 IRC 서버를 권장합니다. 의도적으로 공개 IRC 네트워크를 사용하는 경우 일반적인 선택지로는 Libera.Chat, OFTC, Snoonet가 있습니다. 봇 또는 스웜 백채널 트래픽에는 예측 가능한 공개 채널을 피하세요.
|
||||
봇 조정을 위해서는 비공개 IRC 서버를 선호하세요. 의도적으로 공개 IRC 네트워크를 사용하는 경우 일반적인 선택지는 Libera.Chat, OFTC, Snoonet입니다. 봇 또는 스웜 백채널 트래픽에는 예측 가능한 공개 채널을 피하세요.
|
||||
|
||||
3. Gateway를 시작하거나 재시작합니다.
|
||||
3. gateway를 시작/재시작합니다.
|
||||
|
||||
```bash
|
||||
openclaw gateway run
|
||||
```
|
||||
|
||||
## 기본 보안 설정
|
||||
## 보안 기본값
|
||||
|
||||
- IRC는 OpenClaw 운영자 관리형 전달 프록시 라우팅 외부에서 원시 TCP/TLS 소켓을 사용합니다. 모든 송신 트래픽이 해당 전달 프록시를 거쳐야 하는 배포에서는 직접 IRC 송신이 명시적으로 승인되지 않는 한 `channels.irc.enabled=false`를 설정하세요.
|
||||
- `channels.irc.dmPolicy`의 기본값은 `"pairing"`입니다.
|
||||
- `channels.irc.groupPolicy`의 기본값은 `"allowlist"`입니다.
|
||||
- `groupPolicy="allowlist"`일 때는 허용된 채널을 정의하기 위해 `channels.irc.groups`를 설정하세요.
|
||||
- 의도적으로 평문 전송을 허용하는 것이 아니라면 TLS(`channels.irc.tls=true`)를 사용하세요.
|
||||
- `groupPolicy="allowlist"`를 사용할 때는 `channels.irc.groups`를 설정해 허용된 채널을 정의하세요.
|
||||
- 의도적으로 평문 전송을 허용하는 경우가 아니라면 TLS(`channels.irc.tls=true`)를 사용하세요.
|
||||
|
||||
## 액세스 제어
|
||||
## 접근 제어
|
||||
|
||||
IRC 채널에는 두 가지 별도의 “게이트”가 있습니다.
|
||||
IRC 채널에는 두 개의 별도 “게이트”가 있습니다.
|
||||
|
||||
1. **채널 액세스**(`groupPolicy` + `groups`): 봇이 해당 채널의 메시지를 아예 수락할지 여부
|
||||
2. **발신자 액세스**(`groupAllowFrom` / 채널별 `groups["#channel"].allowFrom`): 해당 채널 안에서 누가 봇을 트리거할 수 있는지 여부
|
||||
1. **채널 접근**(`groupPolicy` + `groups`): 봇이 해당 채널의 메시지를 아예 허용할지 여부입니다.
|
||||
2. **발신자 접근**(`groupAllowFrom` / 채널별 `groups["#channel"].allowFrom`): 해당 채널 안에서 봇을 트리거할 수 있는 사람입니다.
|
||||
|
||||
구성 키:
|
||||
|
||||
- DM 허용 목록(DM 발신자 액세스): `channels.irc.allowFrom`
|
||||
- 그룹 발신자 허용 목록(채널 발신자 액세스): `channels.irc.groupAllowFrom`
|
||||
- DM 허용 목록(DM 발신자 접근): `channels.irc.allowFrom`
|
||||
- 그룹 발신자 허용 목록(채널 발신자 접근): `channels.irc.groupAllowFrom`
|
||||
- 채널별 제어(채널 + 발신자 + 멘션 규칙): `channels.irc.groups["#channel"]`
|
||||
- `channels.irc.groupPolicy="open"`은 구성되지 않은 채널도 허용합니다(**그래도 기본적으로는 멘션 게이팅이 적용됩니다**)
|
||||
- `channels.irc.groupPolicy="open"`은 구성되지 않은 채널을 허용합니다(**그래도 기본적으로 멘션 게이트가 적용됨**)
|
||||
|
||||
허용 목록 항목에는 안정적인 발신자 식별자(`nick!user@host`)를 사용해야 합니다.
|
||||
닉네임만 사용하는 매칭은 변경 가능하며 `channels.irc.dangerouslyAllowNameMatching: true`일 때만 활성화됩니다.
|
||||
허용 목록 항목은 안정적인 발신자 ID(`nick!user@host`)를 사용해야 합니다.
|
||||
단순 닉네임 매칭은 변경 가능하며 `channels.irc.dangerouslyAllowNameMatching: true`일 때만 활성화됩니다.
|
||||
|
||||
### 흔한 함정: `allowFrom`은 채널용이 아니라 DM용입니다
|
||||
### 흔한 함정: `allowFrom`은 DM용이며 채널용이 아닙니다
|
||||
|
||||
다음과 같은 로그가 보인다면:
|
||||
다음과 같은 로그가 보이면:
|
||||
|
||||
- `irc: drop group sender alice!ident@host (policy=allowlist)`
|
||||
|
||||
이는 **그룹/채널** 메시지의 발신자가 허용되지 않았다는 뜻입니다. 다음 중 하나로 수정하세요.
|
||||
…이는 발신자가 **그룹/채널** 메시지에 대해 허용되지 않았다는 뜻입니다. 다음 중 하나로 수정하세요.
|
||||
|
||||
- `channels.irc.groupAllowFrom` 설정(모든 채널에 대한 전역 설정), 또는
|
||||
- `channels.irc.groupAllowFrom` 설정(모든 채널에 전역 적용), 또는
|
||||
- 채널별 발신자 허용 목록 설정: `channels.irc.groups["#channel"].allowFrom`
|
||||
|
||||
예시(`#tuirc-dev`에서 누구나 봇에게 말을 걸 수 있도록 허용):
|
||||
예시(`#tuirc-dev`의 누구나 봇에게 말할 수 있게 허용):
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -96,11 +97,11 @@ IRC 채널에는 두 가지 별도의 “게이트”가 있습니다.
|
||||
|
||||
## 응답 트리거(멘션)
|
||||
|
||||
채널이 허용되어 있고(`groupPolicy` + `groups`) 발신자도 허용되어 있더라도, OpenClaw는 그룹 컨텍스트에서 기본적으로 **멘션 게이팅**을 사용합니다.
|
||||
채널이 허용되어 있고(`groupPolicy` + `groups` 사용) 발신자도 허용되어 있더라도 OpenClaw는 그룹 컨텍스트에서 기본적으로 **멘션 게이트**를 적용합니다.
|
||||
|
||||
즉, 메시지에 봇과 일치하는 멘션 패턴이 포함되어 있지 않으면 `drop channel … (missing-mention)` 같은 로그가 보일 수 있습니다.
|
||||
|
||||
멘션 없이도 IRC 채널에서 봇이 응답하게 하려면 해당 채널의 멘션 게이팅을 비활성화하세요.
|
||||
IRC 채널에서 **멘션 없이도** 봇이 응답하게 하려면 해당 채널의 멘션 게이트를 비활성화하세요.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -118,7 +119,7 @@ IRC 채널에는 두 가지 별도의 “게이트”가 있습니다.
|
||||
}
|
||||
```
|
||||
|
||||
또는 **모든** IRC 채널을 허용하고(채널별 허용 목록 없이) 멘션 없이도 응답하게 하려면:
|
||||
또는 **모든** IRC 채널을 허용하고(채널별 허용 목록 없음) 멘션 없이도 응답하게 하려면:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -138,7 +139,7 @@ IRC 채널에는 두 가지 별도의 “게이트”가 있습니다.
|
||||
공개 채널에서 `allowFrom: ["*"]`를 허용하면 누구나 봇에 프롬프트를 보낼 수 있습니다.
|
||||
위험을 줄이려면 해당 채널의 도구를 제한하세요.
|
||||
|
||||
### 채널의 모든 사용자에게 동일한 도구 적용
|
||||
### 채널의 모든 사람에게 동일한 도구 적용
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -157,9 +158,9 @@ IRC 채널에는 두 가지 별도의 “게이트”가 있습니다.
|
||||
}
|
||||
```
|
||||
|
||||
### 발신자별로 다른 도구 적용(소유자에게 더 많은 권한 부여)
|
||||
### 발신자별 다른 도구 적용(소유자는 더 많은 권한 획득)
|
||||
|
||||
`toolsBySender`를 사용해 `"*"`에는 더 엄격한 정책을, 자신의 닉네임에는 더 느슨한 정책을 적용합니다.
|
||||
`toolsBySender`를 사용해 `"*"`에는 더 엄격한 정책을, 내 닉네임에는 더 느슨한 정책을 적용하세요.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -185,12 +186,12 @@ IRC 채널에는 두 가지 별도의 “게이트”가 있습니다.
|
||||
|
||||
참고:
|
||||
|
||||
- `toolsBySender` 키는 IRC 발신자 식별자 값에 대해 `id:`를 사용해야 합니다:
|
||||
더 강한 매칭을 위해 `id:eigen` 또는 `id:eigen!~eigen@174.127.248.171`
|
||||
- `toolsBySender` 키는 IRC 발신자 ID 값에 `id:`를 사용해야 합니다.
|
||||
더 강한 매칭을 위해 `id:eigen` 또는 `id:eigen!~eigen@174.127.248.171`을 사용합니다.
|
||||
- 레거시 접두사 없는 키도 여전히 허용되며 `id:`로만 매칭됩니다.
|
||||
- 가장 먼저 일치하는 발신자 정책이 적용되며, `"*"`는 와일드카드 대체 항목입니다.
|
||||
- 처음 일치하는 발신자 정책이 적용되며, `"*"`는 와일드카드 폴백입니다.
|
||||
|
||||
그룹 액세스와 멘션 게이팅(그리고 이 둘의 상호작용)에 대한 자세한 내용은 [/channels/groups](/ko/channels/groups)를 참조하세요.
|
||||
그룹 접근과 멘션 게이트의 차이(및 상호 작용)에 대한 자세한 내용은 다음을 참고하세요: [/channels/groups](/ko/channels/groups).
|
||||
|
||||
## NickServ
|
||||
|
||||
@ -210,7 +211,7 @@ IRC 채널에는 두 가지 별도의 “게이트”가 있습니다.
|
||||
}
|
||||
```
|
||||
|
||||
연결 시 선택적 1회 등록:
|
||||
연결 시 선택적 일회성 등록:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -225,7 +226,7 @@ IRC 채널에는 두 가지 별도의 “게이트”가 있습니다.
|
||||
}
|
||||
```
|
||||
|
||||
반복적인 REGISTER 시도를 피하려면 닉네임 등록 후 `register`를 비활성화하세요.
|
||||
닉네임이 등록된 후에는 반복적인 REGISTER 시도를 피하기 위해 `register`를 비활성화하세요.
|
||||
|
||||
## 환경 변수
|
||||
|
||||
@ -242,18 +243,18 @@ IRC 채널에는 두 가지 별도의 “게이트”가 있습니다.
|
||||
- `IRC_NICKSERV_PASSWORD`
|
||||
- `IRC_NICKSERV_REGISTER_EMAIL`
|
||||
|
||||
`IRC_HOST`는 워크스페이스 `.env`에서 설정할 수 없습니다. [워크스페이스 `.env` 파일](/ko/gateway/security)을 참조하세요.
|
||||
`IRC_HOST`는 워크스페이스 `.env`에서 설정할 수 없습니다. [워크스페이스 `.env` 파일](/ko/gateway/security)을 참고하세요.
|
||||
|
||||
## 문제 해결
|
||||
|
||||
- 봇이 연결되지만 채널에서 전혀 응답하지 않는다면 `channels.irc.groups`와 멘션 게이팅이 메시지를 차단하고 있는지(`missing-mention`)를 모두 확인하세요. 핑 없이 응답하게 하려면 해당 채널에 `requireMention:false`를 설정하세요.
|
||||
- 로그인에 실패하면 닉네임 사용 가능 여부와 서버 비밀번호를 확인하세요.
|
||||
- 사용자 지정 네트워크에서 TLS에 실패하면 호스트/포트와 인증서 설정을 확인하세요.
|
||||
- 봇이 연결되지만 채널에서 전혀 응답하지 않는다면 `channels.irc.groups` **및** 멘션 게이트가 메시지를 삭제하고 있는지(`missing-mention`) 확인하세요. 핑 없이 응답하게 하려면 해당 채널에 `requireMention:false`를 설정하세요.
|
||||
- 로그인이 실패하면 닉네임 사용 가능 여부와 서버 비밀번호를 확인하세요.
|
||||
- 사용자 지정 네트워크에서 TLS가 실패하면 호스트/포트와 인증서 설정을 확인하세요.
|
||||
|
||||
## 관련
|
||||
## 관련 항목
|
||||
|
||||
- [채널 개요](/ko/channels) — 지원되는 모든 채널
|
||||
- [페어링](/ko/channels/pairing) — DM 인증 및 페어링 흐름
|
||||
- [그룹](/ko/channels/groups) — 그룹 채팅 동작 및 멘션 게이팅
|
||||
- [채널 라우팅](/ko/channels/channel-routing) — 메시지용 세션 라우팅
|
||||
- [보안](/ko/gateway/security) — 액세스 모델 및 강화
|
||||
- [그룹](/ko/channels/groups) — 그룹 채팅 동작 및 멘션 게이트
|
||||
- [채널 라우팅](/ko/channels/channel-routing) — 메시지에 대한 세션 라우팅
|
||||
- [보안](/ko/gateway/security) — 접근 모델 및 강화
|
||||
|
||||
@ -3,40 +3,40 @@ read_when:
|
||||
- DM 접근 제어 설정
|
||||
- 새 iOS/Android Node 페어링
|
||||
- OpenClaw 보안 태세 검토
|
||||
summary: '페어링 개요: 나에게 개인 메시지를 보낼 수 있는 사람 + 참여할 수 있는 노드 승인'
|
||||
summary: '페어링 개요: 나에게 직접 메시지를 보낼 수 있는 사람 + 참여할 수 있는 노드 승인'
|
||||
title: 페어링
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T20:42:38Z"
|
||||
generated_at: "2026-05-04T02:21:33Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: bb68d87c0e1dfe7c9a6a6d9415f4c63625755fb43a2e22a1d1374ff0a63e49c4
|
||||
source_hash: 4fb27840f7c9ef55e7270cc29f813e6db90b240aa2180f30952eb9485f0f8874
|
||||
source_path: channels/pairing.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
“페어링”은 OpenClaw의 명시적인 액세스 승인 단계입니다.
|
||||
두 곳에서 사용됩니다:
|
||||
두 곳에서 사용됩니다.
|
||||
|
||||
1. **DM 페어링**(봇과 대화할 수 있는 사람)
|
||||
2. **Node 페어링**(Gateway 네트워크에 참여할 수 있는 기기/Node)
|
||||
|
||||
보안 맥락: [보안](/ko/gateway/security)
|
||||
보안 컨텍스트: [보안](/ko/gateway/security)
|
||||
|
||||
## 1) DM 페어링(인바운드 채팅 액세스)
|
||||
|
||||
채널이 DM 정책 `pairing`으로 구성되어 있으면, 알 수 없는 발신자는 짧은 코드를 받으며 승인할 때까지 해당 메시지는 **처리되지 않습니다**.
|
||||
채널이 DM 정책 `pairing`으로 구성되어 있으면 알 수 없는 발신자는 짧은 코드를 받으며, 승인할 때까지 해당 메시지는 **처리되지 않습니다**.
|
||||
|
||||
기본 DM 정책은 다음 문서에 설명되어 있습니다: [보안](/ko/gateway/security)
|
||||
|
||||
`dmPolicy: "open"`은 유효한 DM 허용 목록에 `"*"`가 포함된 경우에만 공개 상태입니다.
|
||||
설정 및 검증은 공개 오픈 구성에 이 와일드카드를 요구합니다. 기존
|
||||
`dmPolicy: "open"`은 유효한 DM 허용 목록에 `"*"`가 포함된 경우에만 공개입니다.
|
||||
공개 오픈 구성의 설정과 검증에는 이 와일드카드가 필요합니다. 기존
|
||||
상태에 구체적인 `allowFrom` 항목과 함께 `open`이 포함되어 있으면, 런타임은 여전히
|
||||
해당 발신자만 허용하며, 페어링 저장소 승인은 `open` 액세스를 확장하지 않습니다.
|
||||
해당 발신자만 허용하며 페어링 저장소 승인은 `open` 액세스를 확장하지 않습니다.
|
||||
|
||||
페어링 코드:
|
||||
|
||||
- 8자, 대문자, 혼동하기 쉬운 문자 없음(`0O1I`).
|
||||
- **1시간 후 만료됩니다**. 봇은 새 요청이 생성될 때만 페어링 메시지를 보냅니다(발신자당 대략 시간당 한 번).
|
||||
- **1시간 후 만료**됩니다. 봇은 새 요청이 생성될 때만 페어링 메시지를 보냅니다(발신자당 대략 1시간에 한 번).
|
||||
- 대기 중인 DM 페어링 요청은 기본적으로 **채널당 3개**로 제한됩니다. 추가 요청은 하나가 만료되거나 승인될 때까지 무시됩니다.
|
||||
|
||||
### 발신자 승인
|
||||
@ -46,21 +46,21 @@ openclaw pairing list telegram
|
||||
openclaw pairing approve telegram <CODE>
|
||||
```
|
||||
|
||||
아직 명령 소유자가 구성되어 있지 않으면, DM 페어링 코드를 승인하면 승인된 발신자(예: `telegram:123456789`)로
|
||||
`commands.ownerAllowFrom`도 부트스트랩됩니다.
|
||||
이를 통해 최초 설정 시 권한 있는 명령과 exec 승인 프롬프트에 대한 명시적인 소유자가 제공됩니다.
|
||||
소유자가 존재한 후에는 이후 페어링 승인은 DM 액세스만 부여하며,
|
||||
소유자를 더 추가하지 않습니다.
|
||||
아직 명령 소유자가 구성되어 있지 않으면, DM 페어링 코드를 승인할 때
|
||||
`commands.ownerAllowFrom`도 승인된 발신자(예: `telegram:123456789`)로 부트스트랩됩니다.
|
||||
이는 최초 설정에 권한 있는 명령과 exec 승인 프롬프트를 위한 명시적 소유자를 제공합니다.
|
||||
소유자가 생긴 뒤에는 이후 페어링 승인은 DM 액세스만 부여하며,
|
||||
소유자를 추가하지 않습니다.
|
||||
|
||||
지원 채널: `bluebubbles`, `discord`, `feishu`, `googlechat`, `imessage`, `irc`, `line`, `matrix`, `mattermost`, `msteams`, `nextcloud-talk`, `nostr`, `openclaw-weixin`, `signal`, `slack`, `synology-chat`, `telegram`, `twitch`, `whatsapp`, `zalo`, `zalouser`.
|
||||
|
||||
### 재사용 가능한 발신자 그룹
|
||||
|
||||
동일한 신뢰할 수 있는 발신자 집합을 여러 메시지 채널 또는 DM과 그룹 허용 목록 모두에
|
||||
적용해야 할 때는 최상위 `accessGroups`를 사용하세요.
|
||||
동일한 신뢰할 수 있는 발신자 집합을 여러 메시지 채널에 적용하거나
|
||||
DM과 그룹 허용 목록 모두에 적용해야 할 때는 최상위 `accessGroups`를 사용하세요.
|
||||
|
||||
정적 그룹은 `type: "message.senders"`를 사용하며, 채널 허용 목록에서
|
||||
`accessGroup:<name>`으로 참조됩니다:
|
||||
정적 그룹은 `type: "message.senders"`를 사용하며 채널 허용 목록에서
|
||||
`accessGroup:<name>`으로 참조됩니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -85,59 +85,58 @@ openclaw pairing approve telegram <CODE>
|
||||
|
||||
### 상태가 저장되는 위치
|
||||
|
||||
`~/.openclaw/credentials/` 아래에 저장됩니다:
|
||||
`~/.openclaw/credentials/` 아래에 저장됩니다.
|
||||
|
||||
- 대기 중인 요청: `<channel>-pairing.json`
|
||||
- 승인된 허용 목록 저장소:
|
||||
- 기본 계정: `<channel>-allowFrom.json`
|
||||
- 기본이 아닌 계정: `<channel>-<accountId>-allowFrom.json`
|
||||
|
||||
계정 범위 동작:
|
||||
계정 범위 지정 동작:
|
||||
|
||||
- 기본이 아닌 계정은 해당 범위의 허용 목록 파일만 읽고 씁니다.
|
||||
- 기본이 아닌 계정은 범위가 지정된 자신의 허용 목록 파일만 읽고 씁니다.
|
||||
- 기본 계정은 채널 범위의 범위 미지정 허용 목록 파일을 사용합니다.
|
||||
|
||||
이 파일들은 민감하게 취급하세요(어시스턴트 액세스를 통제합니다).
|
||||
이 파일들은 민감한 것으로 취급하세요(어시스턴트에 대한 액세스를 제어합니다).
|
||||
|
||||
<Note>
|
||||
페어링 허용 목록 저장소는 DM 액세스용입니다. 그룹 권한 부여는 별도입니다.
|
||||
DM 페어링 코드를 승인해도 해당 발신자가 자동으로 그룹
|
||||
명령을 실행하거나 그룹에서 봇을 제어할 수 있게 되지는 않습니다. 최초 소유자 부트스트랩은
|
||||
DM 페어링 코드를 승인해도 해당 발신자가 그룹 명령을 실행하거나
|
||||
그룹에서 봇을 제어할 수 있게 자동으로 허용되지는 않습니다. 최초 소유자 부트스트랩은
|
||||
`commands.ownerAllowFrom`의 별도 구성 상태이며, 그룹 채팅 전달은 여전히
|
||||
채널의 그룹 허용 목록(예: `groupAllowFrom`, `groups`, 또는 채널에 따라 그룹별
|
||||
또는 주제별 재정의)을 따릅니다.
|
||||
채널의 그룹 허용 목록(예: `groupAllowFrom`, `groups`, 또는 채널에 따라
|
||||
그룹별 또는 토픽별 오버라이드)을 따릅니다.
|
||||
</Note>
|
||||
|
||||
## 2) Node 기기 페어링(iOS/Android/macOS/헤드리스 Node)
|
||||
|
||||
Node는 `role: node`가 있는 **기기**로 Gateway에 연결됩니다. Gateway는
|
||||
승인되어야 하는 기기 페어링 요청을 생성합니다.
|
||||
Node는 `role: node`가 있는 **기기**로 Gateway에 연결합니다. Gateway는
|
||||
승인해야 하는 기기 페어링 요청을 생성합니다.
|
||||
|
||||
### Telegram을 통한 페어링(iOS에 권장)
|
||||
### Telegram을 통해 페어링(iOS에 권장)
|
||||
|
||||
`device-pair` Plugin을 사용하면 Telegram에서 최초 기기 페어링을 완전히 진행할 수 있습니다:
|
||||
`device-pair` Plugin을 사용하는 경우 최초 기기 페어링을 Telegram에서 모두 수행할 수 있습니다.
|
||||
|
||||
1. Telegram에서 봇에게 `/pair` 메시지를 보냅니다.
|
||||
2. 봇은 두 개의 메시지로 응답합니다: 안내 메시지와 별도의 **설정 코드** 메시지(Telegram에서 복사/붙여넣기 쉬움).
|
||||
3. 휴대폰에서 OpenClaw iOS 앱 → Settings → Gateway를 엽니다.
|
||||
1. Telegram에서 봇에게 메시지를 보냅니다: `/pair`
|
||||
2. 봇은 두 개의 메시지로 응답합니다. 안내 메시지와 별도의 **설정 코드** 메시지입니다(Telegram에서 복사/붙여넣기 쉽습니다).
|
||||
3. 휴대폰에서 OpenClaw iOS 앱 → 설정 → Gateway를 엽니다.
|
||||
4. 설정 코드를 붙여넣고 연결합니다.
|
||||
5. Telegram으로 돌아가 `/pair pending`(요청 ID, 역할, 범위 검토)을 실행한 다음 승인합니다.
|
||||
5. Telegram으로 돌아가서: `/pair pending`(요청 ID, 역할, 범위를 검토)한 다음 승인합니다.
|
||||
|
||||
설정 코드는 다음을 포함하는 base64 인코딩 JSON 페이로드입니다:
|
||||
설정 코드는 다음을 포함하는 base64 인코딩 JSON 페이로드입니다.
|
||||
|
||||
- `url`: Gateway WebSocket URL(`ws://...` 또는 `wss://...`)
|
||||
- `bootstrapToken`: 초기 페어링 핸드셰이크에 사용되는 수명이 짧은 단일 기기 부트스트랩 토큰
|
||||
|
||||
해당 부트스트랩 토큰은 내장 페어링 부트스트랩 프로필을 전달합니다:
|
||||
해당 부트스트랩 토큰에는 내장 페어링 부트스트랩 프로필이 포함됩니다.
|
||||
|
||||
- 기본으로 넘겨지는 `node` 토큰은 `scopes: []`를 유지합니다
|
||||
- 넘겨지는 모든 `operator` 토큰은 부트스트랩 허용 목록으로 제한됩니다:
|
||||
- 전달된 기본 `node` 토큰은 `scopes: []`로 유지됩니다
|
||||
- 전달된 모든 `operator` 토큰은 부트스트랩 허용 목록으로 제한됩니다:
|
||||
`operator.approvals`, `operator.read`, `operator.talk.secrets`, `operator.write`
|
||||
- 부트스트랩 범위 검사는 하나의 평면 범위 풀이 아니라 역할 접두사가 붙습니다:
|
||||
operator 범위 항목은 operator 요청만 충족하며, operator가 아닌 역할은
|
||||
여전히 자체 역할 접두사 아래에서 범위를 요청해야 합니다
|
||||
- 이후 토큰 회전/폐기는 기기의 승인된 역할 계약과 호출자 세션의 operator 범위 모두에 의해
|
||||
계속 제한됩니다
|
||||
operator 범위 항목은 operator 요청만 충족하며, 비 operator 역할은
|
||||
여전히 자체 역할 접두사 아래의 범위를 요청해야 합니다
|
||||
- 이후 토큰 회전/폐기는 기기의 승인된 역할 계약과 호출자 세션의 operator 범위 모두로 계속 제한됩니다
|
||||
|
||||
설정 코드는 유효한 동안 비밀번호처럼 취급하세요.
|
||||
|
||||
@ -149,17 +148,23 @@ openclaw devices approve <requestId>
|
||||
openclaw devices reject <requestId>
|
||||
```
|
||||
|
||||
승인하는 페어링된 기기 세션이 페어링 전용 범위로 열려 있어 명시적 승인이 거부되면,
|
||||
CLI는 동일한 요청을 `operator.admin`으로 다시 시도합니다. 이를 통해 기존의 관리자 가능
|
||||
페어링 기기가 `devices/paired.json`을 직접 편집하지 않고도 새 Control UI/브라우저 페어링을
|
||||
복구할 수 있습니다. Gateway는 여전히 재시도된 연결을 검증합니다. `operator.admin`으로
|
||||
인증할 수 없는 토큰은 계속 차단됩니다.
|
||||
|
||||
동일한 기기가 다른 인증 세부 정보(예: 다른 역할/범위/공개 키)로 다시 시도하면,
|
||||
이전 대기 요청은 대체되고 새 `requestId`가 생성됩니다.
|
||||
|
||||
<Note>
|
||||
이미 페어링된 기기가 조용히 더 넓은 액세스를 얻지는 않습니다. 더 많은 범위나 더 넓은 역할을 요청하며 다시 연결하면, OpenClaw는 기존 승인을 그대로 유지하고 새 대기 업그레이드 요청을 생성합니다. 승인하기 전에 `openclaw devices list`를 사용해 현재 승인된 액세스와 새로 요청된 액세스를 비교하세요.
|
||||
이미 페어링된 기기는 조용히 더 넓은 액세스를 얻지 않습니다. 더 많은 범위나 더 넓은 역할을 요청하며 다시 연결하면 OpenClaw는 기존 승인을 그대로 유지하고 새로운 대기 중 업그레이드 요청을 생성합니다. 승인하기 전에 `openclaw devices list`를 사용해 현재 승인된 액세스와 새로 요청된 액세스를 비교하세요.
|
||||
</Note>
|
||||
|
||||
### 선택 사항: 신뢰할 수 있는 CIDR Node 자동 승인
|
||||
|
||||
기기 페어링은 기본적으로 수동입니다. 엄격히 통제되는 Node 네트워크의 경우,
|
||||
명시적인 CIDR 또는 정확한 IP를 사용해 최초 Node 자동 승인을 옵트인할 수 있습니다:
|
||||
기기 페어링은 기본적으로 수동입니다. 엄격하게 제어되는 Node 네트워크에서는
|
||||
명시적인 CIDR 또는 정확한 IP를 사용해 최초 Node 자동 승인을 선택할 수 있습니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -173,25 +178,24 @@ openclaw devices reject <requestId>
|
||||
}
|
||||
```
|
||||
|
||||
이는 요청된 범위가 없는 새 `role: node` 페어링 요청에만 적용됩니다.
|
||||
Operator, 브라우저, Control UI, WebChat 클라이언트는 여전히 수동
|
||||
승인이 필요합니다. 역할, 범위, 메타데이터, 공개 키 변경도 여전히 수동
|
||||
승인이 필요합니다.
|
||||
이는 요청된 범위가 없는 신규 `role: node` 페어링 요청에만 적용됩니다.
|
||||
Operator, 브라우저, Control UI, WebChat 클라이언트는 여전히 수동 승인이 필요합니다.
|
||||
역할, 범위, 메타데이터, 공개 키 변경도 여전히 수동 승인이 필요합니다.
|
||||
|
||||
### Node 페어링 상태 저장소
|
||||
|
||||
`~/.openclaw/devices/` 아래에 저장됩니다:
|
||||
`~/.openclaw/devices/` 아래에 저장됩니다.
|
||||
|
||||
- `pending.json`(수명이 짧음; 대기 요청은 만료됨)
|
||||
- `pending.json`(수명이 짧음, 대기 중인 요청은 만료됨)
|
||||
- `paired.json`(페어링된 기기 + 토큰)
|
||||
|
||||
### 참고
|
||||
|
||||
- 레거시 `node.pair.*` API(CLI: `openclaw nodes pending|approve|reject|remove|rename`)는
|
||||
별도의 Gateway 소유 페어링 저장소입니다. WS Node는 여전히 기기 페어링이 필요합니다.
|
||||
- 페어링 기록은 승인된 역할에 대한 지속적인 단일 진실 공급원입니다. 활성
|
||||
기기 토큰은 승인된 역할 집합으로 계속 제한되며, 승인된 역할 밖의 이탈 토큰 항목은
|
||||
새 액세스를 만들지 않습니다.
|
||||
- 페어링 레코드는 승인된 역할에 대한 지속적인 단일 정보 출처입니다. 활성
|
||||
기기 토큰은 승인된 해당 역할 집합으로 계속 제한됩니다. 승인된 역할 밖의
|
||||
우발적인 토큰 항목은 새 액세스를 생성하지 않습니다.
|
||||
|
||||
## 관련 문서
|
||||
|
||||
|
||||
@ -6,17 +6,20 @@ read_when:
|
||||
summary: QQ 봇 설정, 구성 및 사용법
|
||||
title: QQ 봇
|
||||
x-i18n:
|
||||
generated_at: "2026-05-03T21:27:30Z"
|
||||
generated_at: "2026-05-04T02:21:31Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 471c24110bf0ab8896d22f5bb5932ac4e03ff5169560c99ba6b9d1ca4025d9a8
|
||||
source_hash: e17fa0da2f6939ed28cac5f13b3e37e6c63b87a10250ff213f7a86685a6141d6
|
||||
source_path: channels/qqbot.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
QQ Bot은 공식 QQ Bot API(WebSocket Gateway)를 통해 OpenClaw에 연결됩니다. 이 Plugin은 리치 미디어(이미지, 음성, 동영상, 파일)를 포함한 C2C 개인 채팅, 그룹 @메시지, 길드 채널 메시지를 지원합니다.
|
||||
QQ Bot은 공식 QQ Bot API(WebSocket Gateway)를 통해 OpenClaw에 연결됩니다. 이
|
||||
Plugin은 C2C 비공개 채팅, 그룹 @메시지, 길드 채널 메시지와
|
||||
리치 미디어(이미지, 음성, 비디오, 파일)를 지원합니다.
|
||||
|
||||
상태: 다운로드 가능한 Plugin. 다이렉트 메시지, 그룹 채팅, 길드 채널, 미디어가 지원됩니다. 반응과 스레드는 지원되지 않습니다.
|
||||
상태: 다운로드 가능한 Plugin. 다이렉트 메시지, 그룹 채팅, 길드 채널 및
|
||||
미디어가 지원됩니다. 반응과 스레드는 지원되지 않습니다.
|
||||
|
||||
## 설치
|
||||
|
||||
@ -28,11 +31,12 @@ openclaw plugins install @openclaw/qqbot
|
||||
|
||||
## 설정
|
||||
|
||||
1. [QQ Open Platform](https://q.qq.com/)으로 이동한 뒤 휴대폰 QQ로 QR 코드를 스캔하여 등록하거나 로그인합니다.
|
||||
2. **Create Bot**을 클릭하여 새 QQ bot을 만듭니다.
|
||||
3. 봇 설정 페이지에서 **AppID**와 **AppSecret**을 찾아 복사합니다.
|
||||
1. [QQ Open Platform](https://q.qq.com/)으로 이동한 뒤 휴대폰 QQ로 QR 코드를
|
||||
스캔하여 등록 / 로그인합니다.
|
||||
2. **Create Bot**을 클릭하여 새 QQ Bot을 만듭니다.
|
||||
3. Bot 설정 페이지에서 **AppID**와 **AppSecret**을 찾아 복사합니다.
|
||||
|
||||
> AppSecret은 평문으로 저장되지 않습니다. 저장하지 않고 페이지를 떠나면
|
||||
> AppSecret은 일반 텍스트로 저장되지 않습니다. 저장하지 않고 페이지를 떠나면
|
||||
> 새로 다시 생성해야 합니다.
|
||||
|
||||
4. 채널을 추가합니다.
|
||||
@ -41,7 +45,7 @@ openclaw plugins install @openclaw/qqbot
|
||||
openclaw channels add --channel qqbot --token "AppID:AppSecret"
|
||||
```
|
||||
|
||||
5. Gateway를 재시작합니다.
|
||||
5. Gateway를 다시 시작합니다.
|
||||
|
||||
대화형 설정 경로:
|
||||
|
||||
@ -85,7 +89,7 @@ openclaw configure --section channels
|
||||
}
|
||||
```
|
||||
|
||||
환경 변수 SecretRef AppSecret:
|
||||
Env SecretRef AppSecret:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -101,14 +105,16 @@ openclaw configure --section channels
|
||||
|
||||
참고:
|
||||
|
||||
- 환경 변수 폴백은 기본 QQ Bot 계정에만 적용됩니다.
|
||||
- `openclaw channels add --channel qqbot --token-file ...`은 AppSecret만 제공합니다. AppID는 이미 구성이나 `QQBOT_APP_ID`에 설정되어 있어야 합니다.
|
||||
- `clientSecret`은 평문 문자열뿐 아니라 SecretRef 입력도 허용합니다.
|
||||
- 기존 `secretref:/...` 마커 문자열은 유효한 `clientSecret` 값이 아닙니다. 위 예시처럼 구조화된 SecretRef 객체를 사용하세요.
|
||||
- Env 대체는 기본 QQ Bot 계정에만 적용됩니다.
|
||||
- `openclaw channels add --channel qqbot --token-file ...`은 AppSecret만
|
||||
제공합니다. AppID는 이미 구성이나 `QQBOT_APP_ID`에 설정되어 있어야 합니다.
|
||||
- `clientSecret`은 일반 텍스트 문자열뿐 아니라 SecretRef 입력도 허용합니다.
|
||||
- 기존 `secretref:/...` 마커 문자열은 유효한 `clientSecret` 값이 아닙니다.
|
||||
위 예시처럼 구조화된 SecretRef 객체를 사용하세요.
|
||||
|
||||
### 다중 계정 설정
|
||||
|
||||
단일 OpenClaw 인스턴스에서 여러 QQ bot을 실행합니다.
|
||||
단일 OpenClaw 인스턴스에서 여러 QQ Bot을 실행합니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -129,9 +135,10 @@ openclaw configure --section channels
|
||||
}
|
||||
```
|
||||
|
||||
각 계정은 자체 WebSocket 연결을 시작하고 독립적인 토큰 캐시(`appId` 기준으로 격리됨)를 유지합니다.
|
||||
각 계정은 자체 WebSocket 연결을 시작하고 독립적인 토큰 캐시를
|
||||
유지합니다(`appId`로 격리됨).
|
||||
|
||||
CLI로 두 번째 봇 추가:
|
||||
CLI로 두 번째 Bot을 추가합니다.
|
||||
|
||||
```bash
|
||||
openclaw channels add --channel qqbot --account bot2 --token "222222222:secret-of-bot-2"
|
||||
@ -139,7 +146,8 @@ openclaw channels add --channel qqbot --account bot2 --token "222222222:secret-o
|
||||
|
||||
### 그룹 채팅
|
||||
|
||||
QQ Bot 그룹 채팅 지원은 표시 이름이 아니라 QQ 그룹 OpenID를 사용합니다. 봇을 그룹에 추가한 다음 멘션하거나, 멘션 없이 실행되도록 그룹을 구성하세요.
|
||||
QQ Bot 그룹 채팅 지원은 표시 이름이 아니라 QQ 그룹 OpenID를 사용합니다. Bot을
|
||||
그룹에 추가한 다음 멘션하거나, 멘션 없이 실행되도록 그룹을 구성하세요.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -166,27 +174,33 @@ QQ Bot 그룹 채팅 지원은 표시 이름이 아니라 QQ 그룹 OpenID를
|
||||
}
|
||||
```
|
||||
|
||||
`groups["*"]`는 모든 그룹의 기본값을 설정하고, 구체적인 `groups.GROUP_OPENID` 항목은 한 그룹에 대해 해당 기본값을 재정의합니다. 그룹 설정에는 다음이 포함됩니다.
|
||||
`groups["*"]`는 모든 그룹의 기본값을 설정하고, 구체적인
|
||||
`groups.GROUP_OPENID` 항목은 한 그룹에 대해 해당 기본값을 재정의합니다. 그룹
|
||||
설정에는 다음이 포함됩니다.
|
||||
|
||||
- `requireMention`: 봇이 응답하기 전에 @멘션을 요구합니다. 기본값: `true`.
|
||||
- `ignoreOtherMentions`: 다른 사람을 멘션하지만 봇을 멘션하지 않은 메시지를 버립니다.
|
||||
- `historyLimit`: 다음 멘션된 턴의 컨텍스트로 최근 비멘션 그룹 메시지를 유지합니다. 비활성화하려면 `0`으로 설정합니다.
|
||||
- `toolPolicy`: 그룹 범위 도구에 대해 `full`, `restricted`, 또는 `none`.
|
||||
- `name`: 로그와 그룹 컨텍스트에 사용되는 친숙한 레이블.
|
||||
- `prompt`: 에이전트 컨텍스트에 추가되는 그룹별 동작 프롬프트.
|
||||
- `requireMention`: Bot이 답장하기 전에 @멘션을 요구합니다. 기본값: `true`.
|
||||
- `ignoreOtherMentions`: 다른 사람을 멘션하지만 Bot은 멘션하지 않은 메시지를 삭제합니다.
|
||||
- `historyLimit`: 다음 멘션된 차례의 컨텍스트로 최근 비멘션 그룹 메시지를 유지합니다. 비활성화하려면 `0`으로 설정합니다.
|
||||
- `toolPolicy`: 그룹 범위 도구에 대해 `full`, `restricted` 또는 `none`.
|
||||
- `name`: 로그와 그룹 컨텍스트에 사용되는 친숙한 레이블입니다.
|
||||
- `prompt`: 에이전트 컨텍스트에 추가되는 그룹별 동작 프롬프트입니다.
|
||||
|
||||
활성화 모드는 `mention`과 `always`입니다. `requireMention: true`는 `mention`에 매핑되고, `requireMention: false`는 `always`에 매핑됩니다. 세션 수준 활성화 재정의가 있으면 구성을 우선합니다.
|
||||
활성화 모드는 `mention`과 `always`입니다. `requireMention: true`는
|
||||
`mention`에 매핑되고, `requireMention: false`는 `always`에 매핑됩니다. 세션 수준
|
||||
활성화 재정의가 있으면 구성보다 우선합니다.
|
||||
|
||||
인바운드 큐는 피어별입니다. 그룹 피어는 더 큰 큐 한도를 가지며, 큐가 가득 찼을 때 봇이 작성한 잡담보다 사람 메시지를 우선 유지하고, 일반 그룹 메시지의 버스트를 하나의 발신자 표시 턴으로 병합합니다. 슬래시 명령은 여전히 하나씩 실행됩니다.
|
||||
인바운드 큐는 피어별입니다. 그룹 피어는 더 큰 큐 한도를 가지며, 가득 찼을 때
|
||||
Bot이 작성한 잡담보다 사람 메시지를 앞에 유지하고, 일반 그룹 메시지의 버스트를
|
||||
하나의 귀속된 차례로 병합합니다. 슬래시 명령은 여전히 하나씩 실행됩니다.
|
||||
|
||||
### 음성(STT / TTS)
|
||||
|
||||
STT와 TTS는 우선순위 폴백이 있는 2단계 구성을 지원합니다.
|
||||
STT와 TTS는 우선순위 대체가 있는 2단계 구성을 지원합니다.
|
||||
|
||||
| 설정 | Plugin별 | 프레임워크 폴백 |
|
||||
| ---- | -------------------------------------------------------- | ----------------------------- |
|
||||
| STT | `channels.qqbot.stt` | `tools.media.audio.models[0]` |
|
||||
| TTS | `channels.qqbot.tts`, `channels.qqbot.accounts.<id>.tts` | `messages.tts` |
|
||||
| 설정 | Plugin별 | 프레임워크 대체값 |
|
||||
| ------- | -------------------------------------------------------- | ----------------------------- |
|
||||
| STT | `channels.qqbot.stt` | `tools.media.audio.models[0]` |
|
||||
| TTS | `channels.qqbot.tts`, `channels.qqbot.accounts.<id>.tts` | `messages.tts` |
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -202,7 +216,7 @@ STT와 TTS는 우선순위 폴백이 있는 2단계 구성을 지원합니다.
|
||||
voice: "your-voice",
|
||||
},
|
||||
accounts: {
|
||||
qq-main: {
|
||||
"qq-main": {
|
||||
tts: {
|
||||
providers: {
|
||||
openai: { voice: "shimmer" },
|
||||
@ -216,11 +230,16 @@ STT와 TTS는 우선순위 폴백이 있는 2단계 구성을 지원합니다.
|
||||
```
|
||||
|
||||
비활성화하려면 둘 중 하나에 `enabled: false`를 설정합니다.
|
||||
계정 수준 TTS 재정의는 `messages.tts`와 같은 형태를 사용하며 채널/전역 TTS 구성 위에 딥 머지됩니다.
|
||||
계정 수준 TTS 재정의는 `messages.tts`와 동일한 형태를 사용하며 채널/전역 TTS
|
||||
구성 위에 딥 병합됩니다.
|
||||
|
||||
인바운드 QQ 음성 첨부 파일은 원시 음성 파일을 일반 `MediaPaths` 밖에 유지하면서 에이전트에 오디오 미디어 메타데이터로 노출됩니다. TTS가 구성된 경우 `[[audio_as_voice]]` 일반 텍스트 응답은 TTS를 합성하여 네이티브 QQ 음성 메시지를 보냅니다.
|
||||
인바운드 QQ 음성 첨부 파일은 원시 음성 파일을 일반 `MediaPaths` 밖에 유지하면서
|
||||
오디오 미디어 메타데이터로 에이전트에 노출됩니다. `[[audio_as_voice]]` 일반
|
||||
텍스트 답장은 TTS를 합성하고, TTS가 구성되어 있으면 네이티브 QQ 음성 메시지를
|
||||
전송합니다.
|
||||
|
||||
아웃바운드 오디오 업로드/트랜스코딩 동작은 `channels.qqbot.audioFormatPolicy`로도 조정할 수 있습니다.
|
||||
아웃바운드 오디오 업로드/트랜스코딩 동작은
|
||||
`channels.qqbot.audioFormatPolicy`로도 조정할 수 있습니다.
|
||||
|
||||
- `sttDirectFormats`
|
||||
- `uploadDirectFormats`
|
||||
@ -228,60 +247,66 @@ STT와 TTS는 우선순위 폴백이 있는 2단계 구성을 지원합니다.
|
||||
|
||||
## 대상 형식
|
||||
|
||||
| 형식 | 설명 |
|
||||
| -------------------------- | ---------------- |
|
||||
| `qqbot:c2c:OPENID` | 개인 채팅(C2C) |
|
||||
| `qqbot:group:GROUP_OPENID` | 그룹 채팅 |
|
||||
| `qqbot:channel:CHANNEL_ID` | 길드 채널 |
|
||||
| 형식 | 설명 |
|
||||
| -------------------------- | ------------------ |
|
||||
| `qqbot:c2c:OPENID` | 비공개 채팅(C2C) |
|
||||
| `qqbot:group:GROUP_OPENID` | 그룹 채팅 |
|
||||
| `qqbot:channel:CHANNEL_ID` | 길드 채널 |
|
||||
|
||||
> 각 봇에는 고유한 사용자 OpenID 집합이 있습니다. Bot A가 받은 OpenID는 Bot B를 통해 메시지를 보내는 데 **사용할 수 없습니다**.
|
||||
> 각 Bot은 자체 사용자 OpenID 집합을 가집니다. Bot A가 받은 OpenID는 **Bot B를
|
||||
> 통해 메시지를 보내는 데 사용할 수 없습니다**.
|
||||
|
||||
## 슬래시 명령
|
||||
|
||||
AI 큐 전에 가로채는 내장 명령:
|
||||
AI 큐 전에 가로채는 기본 제공 명령:
|
||||
|
||||
| 명령 | 설명 |
|
||||
| -------------- | ------------------------------------------------------------------------------------------------- |
|
||||
| `/bot-ping` | 지연 시간 테스트 |
|
||||
| `/bot-version` | OpenClaw 프레임워크 버전 표시 |
|
||||
| `/bot-help` | 모든 명령 나열 |
|
||||
| `/bot-me` | `allowFrom`/`groupAllowFrom` 설정을 위한 보낸 사람의 QQ 사용자 ID(openid) 표시 |
|
||||
| `/bot-upgrade` | QQBot 업그레이드 가이드 링크 표시 |
|
||||
| `/bot-logs` | 최근 Gateway 로그를 파일로 내보내기 |
|
||||
| `/bot-approve` | 네이티브 흐름을 통해 대기 중인 QQ Bot 작업(예: C2C 또는 그룹 업로드 확인)을 승인합니다. |
|
||||
| 명령 | 설명 |
|
||||
| -------------- | -------------------------------------------------------------------------------------------------------- |
|
||||
| `/bot-ping` | 지연 시간 테스트 |
|
||||
| `/bot-version` | OpenClaw 프레임워크 버전 표시 |
|
||||
| `/bot-help` | 모든 명령 나열 |
|
||||
| `/bot-me` | `allowFrom`/`groupAllowFrom` 설정을 위한 보낸 사람의 QQ 사용자 ID(openid) 표시 |
|
||||
| `/bot-upgrade` | QQBot 업그레이드 가이드 링크 표시 |
|
||||
| `/bot-logs` | 최근 Gateway 로그를 파일로 내보내기 |
|
||||
| `/bot-approve` | 네이티브 흐름을 통해 보류 중인 QQ Bot 작업 승인(예: C2C 또는 그룹 업로드 확인). |
|
||||
|
||||
사용법 도움말을 보려면 아무 명령에나 `?`를 추가하세요(예: `/bot-upgrade ?`).
|
||||
|
||||
관리자 명령(`/bot-me`, `/bot-upgrade`, `/bot-logs`, `/bot-clear-storage`, `/bot-streaming`, `/bot-approve`)은 다이렉트 메시지에서만 사용할 수 있으며, 보낸 사람의 openid가 명시적인 비와일드카드 `allowFrom` 목록에 있어야 합니다. 와일드카드 `allowFrom: ["*"]`는 채팅을 허용하지만 관리자 명령 액세스 권한은 부여하지 않습니다. 그룹 메시지는 먼저 `groupAllowFrom`과 대조하고, 없으면 `allowFrom`으로 폴백합니다. 그룹에서 관리자 명령을 실행하면 조용히 무시하는 대신 힌트를 반환합니다.
|
||||
관리자 명령(`/bot-me`, `/bot-upgrade`, `/bot-logs`, `/bot-clear-storage`, `/bot-streaming`, `/bot-approve`)은 다이렉트 메시지 전용이며, 보낸 사람의 openid가 명시적인 비와일드카드 `allowFrom` 목록에 있어야 합니다. 와일드카드 `allowFrom: ["*"]`는 채팅을 허용하지만 관리자 명령 접근 권한은 부여하지 않습니다. 그룹 메시지는 먼저 `groupAllowFrom`과 일치시키고, 없으면 `allowFrom`으로 대체합니다. 그룹에서 관리자 명령을 실행하면 조용히 삭제하는 대신 힌트를 반환합니다.
|
||||
|
||||
## 엔진 아키텍처
|
||||
|
||||
QQ Bot은 Plugin 내부에 자체 완결형 엔진으로 제공됩니다.
|
||||
QQ Bot은 Plugin 내부의 독립형 엔진으로 제공됩니다.
|
||||
|
||||
- 각 계정은 `appId`를 키로 하는 격리된 리소스 스택(WebSocket 연결, API 클라이언트, 토큰 캐시, 미디어 저장소 루트)을 소유합니다. 계정은 인바운드/아웃바운드 상태를 절대 공유하지 않습니다.
|
||||
- 다중 계정 로거는 소유 계정으로 로그 줄에 태그를 지정하므로, 하나의 Gateway에서 여러 봇을 실행할 때도 진단 정보를 분리할 수 있습니다.
|
||||
- 인바운드, 아웃바운드, Gateway 브리지 경로는 `~/.openclaw/media` 아래의 단일 미디어 페이로드 루트를 공유하므로, 업로드, 다운로드, 트랜스코드 캐시가 서브시스템별 트리 대신 하나의 보호된 디렉터리 아래에 저장됩니다.
|
||||
- 리치 미디어 전달은 C2C 및 그룹 대상에 대해 하나의 `sendMedia` 경로를 통합니다. 대용량 파일 임계값을 넘는 로컬 파일과 버퍼는 QQ의 청크 업로드 엔드포인트를 사용하고, 더 작은 페이로드는 원샷 미디어 API를 사용합니다.
|
||||
- 자격 증명은 표준 OpenClaw 자격 증명 스냅샷의 일부로 백업 및 복원할 수 있습니다. 엔진은 새 QR 코드 페어링을 요구하지 않고 복원 시 각 계정의 리소스 스택을 다시 연결합니다.
|
||||
- 다중 계정 로거는 소유 계정으로 로그 줄에 태그를 지정하므로 하나의 Gateway에서 여러 Bot을 실행할 때도 진단을 분리해 유지할 수 있습니다.
|
||||
- 인바운드, 아웃바운드 및 Gateway 브리지 경로는 `~/.openclaw/media` 아래의 단일 미디어 페이로드 루트를 공유하므로 업로드, 다운로드 및 트랜스코딩 캐시가 서브시스템별 트리가 아니라 하나의 보호된 디렉터리 아래에 위치합니다.
|
||||
- 리치 미디어 전달은 C2C 및 그룹 대상에 대해 하나의 `sendMedia` 경로를 거칩니다. 대용량 파일 임계값을 초과하는 로컬 파일과 버퍼는 QQ의 청크 업로드 엔드포인트를 사용하고, 더 작은 페이로드는 원샷 미디어 API를 사용합니다.
|
||||
- 자격 증명은 표준 OpenClaw 자격 증명 스냅샷의 일부로 백업 및 복원할 수 있습니다. 엔진은 복원 시 새 QR 코드 페어가 필요하지 않도록 각 계정의 리소스 스택을 다시 연결합니다.
|
||||
|
||||
## QR 코드 온보딩
|
||||
|
||||
`AppID:AppSecret`을 수동으로 붙여넣는 대신, 엔진은 QQ Bot을 OpenClaw에 연결하기 위한 QR 코드 온보딩 흐름을 지원합니다.
|
||||
`AppID:AppSecret`을 수동으로 붙여넣는 대신, 엔진은 QQ Bot을 OpenClaw에 연결하는 QR 코드 온보딩 흐름을 지원합니다.
|
||||
|
||||
1. QQ Bot 설정 경로(예: `openclaw channels add --channel qqbot`)를 실행하고 프롬프트가 표시되면 QR 코드 흐름을 선택합니다.
|
||||
2. 대상 QQ Bot에 연결된 휴대폰 앱으로 생성된 QR 코드를 스캔합니다.
|
||||
3. 휴대폰에서 페어링을 승인합니다. OpenClaw는 반환된 자격 증명을 올바른 계정 범위 아래의 `credentials/`에 저장합니다.
|
||||
3. 휴대폰에서 페어링을 승인합니다. OpenClaw는 반환된 자격 증명을 올바른 계정 범위 아래의 `credentials/`에 유지합니다.
|
||||
|
||||
봇 자체에서 생성된 승인 프롬프트(예: QQ Bot API가 노출하는 "이 작업을 허용하시겠습니까?" 흐름)는 원시 QQ 클라이언트를 통해 답장하는 대신 `/bot-approve`로 수락할 수 있는 네이티브 OpenClaw 프롬프트로 표시됩니다.
|
||||
Bot 자체에서 생성된 승인 프롬프트(예: QQ Bot API가 노출하는 "이 작업을 허용하시겠습니까?" 흐름)는 원시 QQ 클라이언트를 통해 답장하는 대신 `/bot-approve`로 수락할 수 있는 네이티브 OpenClaw 프롬프트로 표시됩니다.
|
||||
|
||||
## 문제 해결
|
||||
|
||||
- **봇이 "gone to Mars"라고 응답함:** 자격 증명이 구성되지 않았거나 Gateway가 시작되지 않았습니다.
|
||||
- **인바운드 메시지 없음:** `appId`와 `clientSecret`이 올바른지, QQ Open Platform에서 봇이 활성화되어 있는지 확인하세요.
|
||||
- **반복적인 자기 응답:** OpenClaw는 QQ 아웃바운드 참조 인덱스를 봇 작성으로 기록하고 현재 `msgIdx`가 동일한 봇 계정과 일치하는 인바운드 이벤트를 무시합니다. 이렇게 하면 플랫폼 에코 루프를 방지하면서도 사용자가 이전 봇 메시지를 인용하거나 답장할 수 있습니다.
|
||||
- **`--token-file`로 설정해도 여전히 구성되지 않음으로 표시됨:** `--token-file`은 AppSecret만 설정합니다. 구성 또는 `QQBOT_APP_ID`에 `appId`가 여전히 필요합니다.
|
||||
- **사전 메시지가 도착하지 않음:** 사용자가 최근에 상호작용하지 않았다면 QQ가 봇이 시작한 메시지를 가로챌 수 있습니다.
|
||||
- **음성이 전사되지 않음:** STT가 구성되어 있고 제공자에 연결할 수 있는지 확인하세요.
|
||||
- **Bot이 "gone to Mars"라고 답장함:** 자격 증명이 구성되지 않았거나 Gateway가 시작되지 않았습니다.
|
||||
- **인바운드 메시지가 없음:** `appId`와 `clientSecret`이 올바른지, 그리고
|
||||
Bot이 QQ Open Platform에서 활성화되어 있는지 확인하세요.
|
||||
- **반복되는 자기 답장:** OpenClaw는 QQ 아웃바운드 참조 인덱스를 Bot 작성으로
|
||||
기록하고, 현재 `msgIdx`가 동일한 Bot 계정과 일치하는 인바운드 이벤트를 무시합니다.
|
||||
이렇게 하면 플랫폼 에코 루프를 방지하면서도 사용자가 이전 Bot 메시지를
|
||||
인용하거나 답장할 수 있습니다.
|
||||
- **`--token-file`로 설정해도 여전히 구성되지 않음으로 표시됨:** `--token-file`은
|
||||
AppSecret만 설정합니다. 구성 또는 `QQBOT_APP_ID`에 `appId`가 여전히 필요합니다.
|
||||
- **사전 메시지가 도착하지 않음:** 사용자가 최근에 상호작용하지 않았다면 QQ가 Bot 시작 메시지를 가로챌 수 있습니다.
|
||||
- **음성이 전사되지 않음:** STT가 구성되어 있고 공급자에 연결할 수 있는지 확인하세요.
|
||||
|
||||
## 관련 항목
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,13 +1,13 @@
|
||||
---
|
||||
read_when:
|
||||
- Tlon/Urbit 채널 기능 작업 중
|
||||
summary: Tlon/Urbit 지원 상태, 기능 및 설정
|
||||
summary: Tlon/Urbit 지원 상태, 기능 및 구성
|
||||
title: Tlon
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T22:16:27Z"
|
||||
generated_at: "2026-05-04T02:22:06Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 30915170786fc1ee8b84fb8be2ea42280262923064cfa9ca7107036096a13add
|
||||
source_hash: 1718044541b431ff2437508e7e6659c14206f4aa84ab8b207e0d791dea2a48c5
|
||||
source_path: channels/tlon.md
|
||||
workflow: 16
|
||||
---
|
||||
@ -16,39 +16,39 @@ Tlon은 Urbit 기반의 탈중앙화 메신저입니다. OpenClaw는 사용자
|
||||
DM과 그룹 채팅 메시지에 응답할 수 있습니다. 그룹 답장은 기본적으로 @ 멘션이 필요하며,
|
||||
허용 목록을 통해 더 제한할 수 있습니다.
|
||||
|
||||
상태: 번들 Plugin. DM, 그룹 멘션, 스레드 답장, 리치 텍스트 서식, 그리고
|
||||
이미지 업로드가 지원됩니다. 반응과 투표는 아직 지원되지 않습니다.
|
||||
상태: 번들 Plugin. DM, 그룹 멘션, 스레드 답장, 리치 텍스트 서식, 이미지 업로드가
|
||||
지원됩니다. 반응과 투표는 아직 지원되지 않습니다.
|
||||
|
||||
## 번들 Plugin
|
||||
|
||||
Tlon은 현재 OpenClaw 릴리스에서 번들 Plugin으로 제공되므로, 일반 패키지
|
||||
빌드에는 별도 설치가 필요하지 않습니다.
|
||||
|
||||
Tlon이 제외된 오래된 빌드나 사용자 지정 설치를 사용 중이라면,
|
||||
현재 npm 패키지를 설치하세요.
|
||||
Tlon을 제외한 이전 빌드나 사용자 지정 설치를 사용 중이라면, 현재 npm 패키지를
|
||||
설치하세요.
|
||||
|
||||
CLI로 설치(npm registry):
|
||||
CLI(npm registry)를 통해 설치:
|
||||
|
||||
```bash
|
||||
openclaw plugins install @openclaw/tlon
|
||||
```
|
||||
|
||||
현재 공식 릴리스 태그를 따르려면 기본 패키지를 사용하세요. 재현 가능한
|
||||
설치가 필요할 때만 정확한 버전을 고정하세요.
|
||||
현재 공식 릴리스 태그를 따르려면 기본 패키지를 사용하세요. 재현 가능한 설치가
|
||||
필요할 때만 정확한 버전을 고정하세요.
|
||||
|
||||
로컬 체크아웃(git repo에서 실행하는 경우):
|
||||
로컬 체크아웃(git 저장소에서 실행할 때):
|
||||
|
||||
```bash
|
||||
openclaw plugins install ./path/to/local/tlon-plugin
|
||||
```
|
||||
|
||||
자세히: [Plugins](/ko/tools/plugin)
|
||||
자세한 내용: [Plugins](/ko/tools/plugin)
|
||||
|
||||
## 설정
|
||||
|
||||
1. Tlon Plugin을 사용할 수 있는지 확인합니다.
|
||||
- 현재 패키지된 OpenClaw 릴리스에는 이미 번들로 포함되어 있습니다.
|
||||
- 오래된/사용자 지정 설치에서는 위 명령으로 수동 추가할 수 있습니다.
|
||||
- 현재 패키지된 OpenClaw 릴리스에는 이미 번들되어 있습니다.
|
||||
- 이전/사용자 지정 설치에서는 위 명령으로 수동 추가할 수 있습니다.
|
||||
2. ship URL과 로그인 코드를 준비합니다.
|
||||
3. `channels.tlon`을 구성합니다.
|
||||
4. Gateway를 다시 시작합니다.
|
||||
@ -73,7 +73,7 @@ openclaw plugins install ./path/to/local/tlon-plugin
|
||||
## 비공개/LAN ship
|
||||
|
||||
기본적으로 OpenClaw는 SSRF 보호를 위해 비공개/내부 호스트 이름과 IP 범위를 차단합니다.
|
||||
ship이 비공개 네트워크(localhost, LAN IP 또는 내부 호스트 이름)에서 실행 중이라면,
|
||||
ship이 비공개 네트워크(localhost, LAN IP 또는 내부 호스트 이름)에서 실행 중이라면
|
||||
명시적으로 옵트인해야 합니다.
|
||||
|
||||
```json5
|
||||
@ -93,8 +93,8 @@ ship이 비공개 네트워크(localhost, LAN IP 또는 내부 호스트 이름)
|
||||
- `http://192.168.x.x:8080`
|
||||
- `http://my-ship.local:8080`
|
||||
|
||||
⚠️ 로컬 네트워크를 신뢰하는 경우에만 이를 활성화하세요. 이 설정은 ship URL에 대한
|
||||
요청에서 SSRF 보호를 비활성화합니다.
|
||||
⚠️ 로컬 네트워크를 신뢰하는 경우에만 활성화하세요. 이 설정은 ship URL로 보내는 요청에 대한
|
||||
SSRF 보호를 비활성화합니다.
|
||||
|
||||
## 그룹 채널
|
||||
|
||||
@ -161,7 +161,7 @@ DM 허용 목록(비어 있음 = DM 허용 안 함, 승인 흐름에는 `ownerSh
|
||||
|
||||
## 소유자 및 승인 시스템
|
||||
|
||||
권한이 없는 사용자가 상호작용을 시도할 때 승인 요청을 받을 소유자 ship을 설정합니다.
|
||||
권한이 없는 사용자가 상호작용하려고 할 때 승인 요청을 받을 소유자 ship을 설정합니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -173,19 +173,19 @@ DM 허용 목록(비어 있음 = DM 허용 안 함, 승인 흐름에는 `ownerSh
|
||||
}
|
||||
```
|
||||
|
||||
소유자 ship은 **모든 곳에서 자동으로 권한이 부여됩니다**. DM 초대는 자동 수락되고
|
||||
소유자 ship은 **모든 곳에서 자동으로 권한이 부여됩니다**. DM 초대는 자동 수락되며
|
||||
채널 메시지는 항상 허용됩니다. 소유자를 `dmAllowlist` 또는
|
||||
`defaultAuthorizedShips`에 추가할 필요가 없습니다.
|
||||
|
||||
설정되면 소유자는 다음에 대한 DM 알림을 받습니다.
|
||||
설정하면 소유자는 다음에 대한 DM 알림을 받습니다.
|
||||
|
||||
- 허용 목록에 없는 ship의 DM 요청
|
||||
- 권한이 없는 채널의 멘션
|
||||
- 권한 부여가 없는 채널의 멘션
|
||||
- 그룹 초대 요청
|
||||
|
||||
## 자동 수락 설정
|
||||
|
||||
DM 초대 자동 수락(dmAllowlist에 있는 ship):
|
||||
DM 초대 자동 수락(`dmAllowlist`에 있는 ship의 경우):
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -197,18 +197,22 @@ DM 초대 자동 수락(dmAllowlist에 있는 ship):
|
||||
}
|
||||
```
|
||||
|
||||
그룹 초대 자동 수락:
|
||||
신뢰할 수 있는 ship의 그룹 초대 자동 수락:
|
||||
|
||||
```json5
|
||||
{
|
||||
channels: {
|
||||
tlon: {
|
||||
autoAcceptGroupInvites: true,
|
||||
groupInviteAllowlist: ["~zod"],
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
`autoAcceptGroupInvites`는 `groupInviteAllowlist`가 비어 있으면 닫힌 상태로 실패합니다.
|
||||
그룹 초대를 자동으로 수락할 ship으로 허용 목록을 설정하세요.
|
||||
|
||||
## 전달 대상(CLI/cron)
|
||||
|
||||
`openclaw message send` 또는 cron 전달과 함께 사용하세요.
|
||||
@ -218,33 +222,34 @@ DM 초대 자동 수락(dmAllowlist에 있는 ship):
|
||||
|
||||
## 번들 스킬
|
||||
|
||||
Tlon Plugin에는 Tlon 작업에 대한 CLI 접근을 제공하는 번들 스킬([`@tloncorp/tlon-skill`](https://github.com/tloncorp/tlon-skill))이 포함되어 있습니다.
|
||||
Tlon Plugin에는 Tlon 작업에 CLI 접근을 제공하는 번들 스킬([`@tloncorp/tlon-skill`](https://github.com/tloncorp/tlon-skill))이
|
||||
포함되어 있습니다.
|
||||
|
||||
- **연락처**: 프로필 가져오기/업데이트, 연락처 목록 보기
|
||||
- **채널**: 목록 보기, 생성, 메시지 게시, 기록 가져오기
|
||||
- **그룹**: 목록 보기, 생성, 멤버 관리
|
||||
- **연락처**: 프로필 가져오기/업데이트, 연락처 목록 표시
|
||||
- **채널**: 목록 표시, 생성, 메시지 게시, 기록 가져오기
|
||||
- **그룹**: 목록 표시, 생성, 멤버 관리
|
||||
- **DM**: 메시지 보내기, 메시지에 반응하기
|
||||
- **반응**: 게시물과 DM에 emoji 반응 추가/제거
|
||||
- **설정**: slash command를 통해 Plugin 권한 관리
|
||||
- **반응**: 게시물과 DM에 이모지 반응 추가/제거
|
||||
- **설정**: 슬래시 명령을 통해 Plugin 권한 관리
|
||||
|
||||
Plugin이 설치되면 스킬은 자동으로 사용할 수 있습니다.
|
||||
Plugin이 설치되면 스킬을 자동으로 사용할 수 있습니다.
|
||||
|
||||
## 기능
|
||||
|
||||
| 기능 | 상태 |
|
||||
| 기능 | 상태 |
|
||||
| --------------- | --------------------------------------- |
|
||||
| 직접 메시지 | ✅ 지원됨 |
|
||||
| 그룹/채널 | ✅ 지원됨(기본적으로 멘션으로 제한) |
|
||||
| 스레드 | ✅ 지원됨(스레드에서 자동 답장) |
|
||||
| 리치 텍스트 | ✅ Markdown이 Tlon 형식으로 변환됨 |
|
||||
| 이미지 | ✅ Tlon 저장소에 업로드됨 |
|
||||
| 반응 | ✅ [번들 스킬](#bundled-skill)을 통해 가능 |
|
||||
| 투표 | ❌ 아직 지원되지 않음 |
|
||||
| 네이티브 명령 | ✅ 지원됨(기본적으로 소유자 전용) |
|
||||
| 다이렉트 메시지 | ✅ 지원됨 |
|
||||
| 그룹/채널 | ✅ 지원됨(기본적으로 멘션 게이트 적용) |
|
||||
| 스레드 | ✅ 지원됨(스레드에서 자동 답장) |
|
||||
| 리치 텍스트 | ✅ Markdown이 Tlon 형식으로 변환됨 |
|
||||
| 이미지 | ✅ Tlon 저장소에 업로드됨 |
|
||||
| 반응 | ✅ [번들 스킬](#번들-스킬)을 통해 지원 |
|
||||
| 투표 | ❌ 아직 지원되지 않음 |
|
||||
| 네이티브 명령 | ✅ 지원됨(기본적으로 소유자 전용) |
|
||||
|
||||
## 문제 해결
|
||||
|
||||
먼저 이 순서대로 실행하세요.
|
||||
먼저 이 순서로 실행하세요.
|
||||
|
||||
```bash
|
||||
openclaw status
|
||||
@ -255,28 +260,29 @@ openclaw doctor
|
||||
|
||||
일반적인 실패:
|
||||
|
||||
- **DM이 무시됨**: 보낸 사람이 `dmAllowlist`에 없고 승인 흐름을 위한 `ownerShip`이 구성되지 않았습니다.
|
||||
- **그룹 메시지가 무시됨**: 채널이 검색되지 않았거나 보낸 사람에게 권한이 없습니다.
|
||||
- **연결 오류**: ship URL에 연결할 수 있는지 확인하세요. 로컬 ship에는 `allowPrivateNetwork`를 활성화하세요.
|
||||
- **DM 무시됨**: 보낸 사람이 `dmAllowlist`에 없고 승인 흐름을 위한 `ownerShip`이 구성되지 않았습니다.
|
||||
- **그룹 메시지 무시됨**: 채널이 검색되지 않았거나 보낸 사람에게 권한이 없습니다.
|
||||
- **연결 오류**: ship URL에 접근 가능한지 확인하세요. 로컬 ship의 경우 `allowPrivateNetwork`를 활성화하세요.
|
||||
- **인증 오류**: 로그인 코드가 최신인지 확인하세요(코드는 순환됩니다).
|
||||
|
||||
## 구성 참조
|
||||
|
||||
전체 구성: [Configuration](/ko/gateway/configuration)
|
||||
전체 구성: [구성](/ko/gateway/configuration)
|
||||
|
||||
Provider 옵션:
|
||||
제공자 옵션:
|
||||
|
||||
- `channels.tlon.enabled`: 채널 시작을 활성화/비활성화합니다.
|
||||
- `channels.tlon.ship`: 봇의 Urbit ship 이름(예: `~sampel-palnet`).
|
||||
- `channels.tlon.url`: ship URL(예: `https://sampel-palnet.tlon.network`).
|
||||
- `channels.tlon.code`: ship 로그인 코드.
|
||||
- `channels.tlon.allowPrivateNetwork`: localhost/LAN URL 허용(SSRF 우회).
|
||||
- `channels.tlon.ownerShip`: 승인 시스템용 소유자 ship(항상 권한 있음).
|
||||
- `channels.tlon.ownerShip`: 승인 시스템의 소유자 ship(항상 권한 부여됨).
|
||||
- `channels.tlon.dmAllowlist`: DM이 허용된 ship(비어 있음 = 없음).
|
||||
- `channels.tlon.autoAcceptDmInvites`: 허용 목록에 있는 ship의 DM을 자동 수락합니다.
|
||||
- `channels.tlon.autoAcceptGroupInvites`: 모든 그룹 초대를 자동 수락합니다.
|
||||
- `channels.tlon.autoAcceptDmInvites`: 허용 목록의 ship에서 온 DM을 자동 수락합니다.
|
||||
- `channels.tlon.autoAcceptGroupInvites`: 허용 목록의 ship에서 온 그룹 초대를 자동 수락합니다.
|
||||
- `channels.tlon.groupInviteAllowlist`: 그룹 초대를 자동 수락할 수 있는 ship.
|
||||
- `channels.tlon.autoDiscoverChannels`: 그룹 채널 자동 검색(기본값: true).
|
||||
- `channels.tlon.groupChannels`: 수동으로 고정된 채널 nest.
|
||||
- `channels.tlon.groupChannels`: 수동으로 고정한 채널 nest.
|
||||
- `channels.tlon.defaultAuthorizedShips`: 모든 채널에 대해 권한이 부여된 ship.
|
||||
- `channels.tlon.authorization.channelRules`: 채널별 인증 규칙.
|
||||
- `channels.tlon.showModelSignature`: 메시지에 모델 이름을 추가합니다.
|
||||
@ -284,14 +290,14 @@ Provider 옵션:
|
||||
## 참고
|
||||
|
||||
- 그룹 답장은 응답하려면 멘션(예: `~your-bot-ship`)이 필요합니다.
|
||||
- 스레드 답장: 인바운드 메시지가 스레드에 있으면 OpenClaw는 스레드 안에서 답장합니다.
|
||||
- 스레드 답장: 수신 메시지가 스레드에 있으면 OpenClaw는 스레드 안에서 답장합니다.
|
||||
- 리치 텍스트: Markdown 서식(굵게, 기울임, 코드, 헤더, 목록)이 Tlon의 네이티브 형식으로 변환됩니다.
|
||||
- 이미지: URL은 Tlon 저장소에 업로드되고 이미지 블록으로 임베드됩니다.
|
||||
|
||||
## 관련 항목
|
||||
|
||||
- [채널 개요](/ko/channels) — 지원되는 모든 채널
|
||||
- [Pairing](/ko/channels/pairing) — DM 인증 및 페어링 흐름
|
||||
- [그룹](/ko/channels/groups) — 그룹 채팅 동작 및 멘션 제한
|
||||
- [페어링](/ko/channels/pairing) — DM 인증 및 페어링 흐름
|
||||
- [그룹](/ko/channels/groups) — 그룹 채팅 동작 및 멘션 게이팅
|
||||
- [채널 라우팅](/ko/channels/channel-routing) — 메시지의 세션 라우팅
|
||||
- [보안](/ko/gateway/security) — 접근 모델 및 강화
|
||||
|
||||
@ -1,21 +1,21 @@
|
||||
---
|
||||
read_when:
|
||||
- 채널 전송 계층은 연결됨으로 표시되지만 답장이 실패함
|
||||
- 자세한 제공자 문서를 보기 전에 채널별 확인이 필요합니다
|
||||
- 채널 전송 계층은 연결되었다고 표시되지만 답장이 실패함
|
||||
- 심층 프로바이더 문서에 들어가기 전에 채널별 확인이 필요합니다
|
||||
summary: 채널별 실패 시그니처와 해결 방법을 포함한 빠른 채널 수준 문제 해결
|
||||
title: 채널 문제 해결
|
||||
x-i18n:
|
||||
generated_at: "2026-04-30T06:20:17Z"
|
||||
generated_at: "2026-05-04T02:22:21Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 6024f2ae0a058b2296758c237c912a5cd8ea6bbafea33cc201690cc081efcbee
|
||||
source_hash: a3a0737156ae83897c44d18505e0355a5d8e5700106b984496d94874c270deb2
|
||||
source_path: channels/troubleshooting.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
동작은 잘못되지만 채널은 연결되는 경우 이 페이지를 사용하세요.
|
||||
채널이 연결되었지만 동작이 잘못된 경우 이 페이지를 사용하세요.
|
||||
|
||||
## 명령 사다리
|
||||
## 명령 단계
|
||||
|
||||
먼저 다음을 순서대로 실행하세요.
|
||||
|
||||
@ -27,23 +27,23 @@ openclaw doctor
|
||||
openclaw channels status --probe
|
||||
```
|
||||
|
||||
정상 기준선:
|
||||
정상 기준:
|
||||
|
||||
- `Runtime: running`
|
||||
- `Connectivity probe: ok`
|
||||
- `Capability: read-only`, `write-capable` 또는 `admin-capable`
|
||||
- `Capability: read-only`, `write-capable`, 또는 `admin-capable`
|
||||
- 채널 프로브에 전송 계층이 연결된 것으로 표시되고, 지원되는 경우 `works` 또는 `audit ok`가 표시됨
|
||||
|
||||
## WhatsApp
|
||||
|
||||
### WhatsApp 실패 징후
|
||||
|
||||
| 증상 | 가장 빠른 확인 방법 | 수정 |
|
||||
| 증상 | 가장 빠른 확인 방법 | 해결 방법 |
|
||||
| ------------------------------- | --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 연결되었지만 DM 응답 없음 | `openclaw pairing list whatsapp` | 발신자를 승인하거나 DM 정책/허용 목록을 변경하세요. |
|
||||
| 그룹 메시지가 무시됨 | 구성에서 `requireMention` 및 멘션 패턴 확인 | 봇을 멘션하거나 해당 그룹의 멘션 정책을 완화하세요. |
|
||||
| QR 로그인 시간이 408로 초과됨 | Gateway `HTTPS_PROXY` / `HTTP_PROXY` 환경 변수 확인 | 연결 가능한 프록시를 설정하고, `NO_PROXY`는 우회에만 사용하세요. |
|
||||
| 무작위 연결 해제/재로그인 반복 | `openclaw channels status --probe` + 로그 | 현재 연결되어 있어도 최근 재연결은 플래그로 표시됩니다. 로그를 확인하고 Gateway를 재시작한 다음, 플래핑이 계속되면 다시 연결하세요. |
|
||||
| 연결되었지만 DM 응답 없음 | `openclaw pairing list whatsapp` | 발신자를 승인하거나 DM 정책/허용 목록을 전환하세요. |
|
||||
| 그룹 메시지가 무시됨 | 설정에서 `requireMention` + 멘션 패턴 확인 | 봇을 멘션하거나 해당 그룹의 멘션 정책을 완화하세요. |
|
||||
| QR 로그인 시간이 408로 초과됨 | Gateway `HTTPS_PROXY` / `HTTP_PROXY` env 확인 | 도달 가능한 프록시를 설정하세요. 우회할 때만 `NO_PROXY`를 사용하세요. |
|
||||
| 임의의 연결 해제/재로그인 루프 | `openclaw channels status --probe` + 로그 | 현재 연결되어 있어도 최근 재연결이 표시됩니다. 로그를 확인하고 Gateway를 다시 시작한 뒤, 계속 불안정하면 다시 연결하세요. |
|
||||
|
||||
전체 문제 해결: [WhatsApp 문제 해결](/ko/channels/whatsapp#troubleshooting)
|
||||
|
||||
@ -51,15 +51,15 @@ openclaw channels status --probe
|
||||
|
||||
### Telegram 실패 징후
|
||||
|
||||
| 증상 | 가장 빠른 확인 방법 | 수정 |
|
||||
| ------------------------------------ | ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `/start`했지만 사용할 수 있는 응답 흐름 없음 | `openclaw pairing list telegram` | 페어링을 승인하거나 DM 정책을 변경하세요. |
|
||||
| 봇은 온라인이지만 그룹이 계속 조용함 | 멘션 요구 사항과 봇 개인정보 보호 모드 확인 | 그룹 가시성을 위해 개인정보 보호 모드를 비활성화하거나 봇을 멘션하세요. |
|
||||
| 네트워크 오류로 전송 실패 | Telegram API 호출 실패에 대한 로그 검사 | `api.telegram.org`로 가는 DNS/IPv6/프록시 라우팅을 수정하세요. |
|
||||
| 시작 시 `getMe returned 401` 보고 | 구성된 토큰 소스 확인 | BotFather 토큰을 다시 복사하거나 재생성하고 `botToken`, `tokenFile` 또는 기본 계정 `TELEGRAM_BOT_TOKEN`을 업데이트하세요. |
|
||||
| 폴링이 멈추거나 느리게 재연결됨 | 폴링 진단을 위해 `openclaw logs --follow` 실행 | 업그레이드하세요. 재시작이 오탐이면 `pollingStallThresholdMs`를 조정하세요. 지속적인 중단은 여전히 프록시/DNS/IPv6 문제를 가리킵니다. |
|
||||
| 시작 시 `setMyCommands` 거부됨 | `BOT_COMMANDS_TOO_MUCH`에 대한 로그 검사 | Plugin/skill/사용자 지정 Telegram 명령을 줄이거나 네이티브 메뉴를 비활성화하세요. |
|
||||
| 업그레이드 후 허용 목록이 사용자를 차단함 | `openclaw security audit` 및 구성 허용 목록 | `openclaw doctor --fix`를 실행하거나 `@username`을 숫자 발신자 ID로 바꾸세요. |
|
||||
| 증상 | 가장 빠른 확인 방법 | 해결 방법 |
|
||||
| ----------------------------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `/start` 후에도 사용할 수 있는 응답 흐름 없음 | `openclaw pairing list telegram` | 페어링을 승인하거나 DM 정책을 변경하세요. |
|
||||
| 봇이 온라인이지만 그룹이 계속 조용함 | 멘션 요구 사항과 봇 개인정보 보호 모드 확인 | 그룹 가시성을 위해 개인정보 보호 모드를 비활성화하거나 봇을 멘션하세요. |
|
||||
| 네트워크 오류로 전송 실패 | Telegram API 호출 실패 로그 검사 | `api.telegram.org`로 가는 DNS/IPv6/프록시 라우팅을 수정하세요. |
|
||||
| 시작 시 `getMe returned 401` 보고 | 구성된 토큰 소스 확인 | BotFather 토큰을 다시 복사하거나 재생성한 뒤 `botToken`, `tokenFile`, 또는 기본 계정 `TELEGRAM_BOT_TOKEN`을 업데이트하세요. |
|
||||
| 폴링이 멈추거나 재연결이 느림 | 폴링 진단을 위해 `openclaw logs --follow` 실행 | 업그레이드하세요. 재시작이 오탐이면 `pollingStallThresholdMs`를 조정하세요. 지속적인 멈춤은 여전히 프록시/DNS/IPv6를 가리킵니다. |
|
||||
| 시작 시 `setMyCommands`가 거부됨 | `BOT_COMMANDS_TOO_MUCH` 로그 검사 | Plugin/skill/사용자 지정 Telegram 명령을 줄이거나 네이티브 메뉴를 비활성화하세요. |
|
||||
| 업그레이드 후 허용 목록이 사용자를 차단함 | `openclaw security audit` 및 설정 허용 목록 확인 | `openclaw doctor --fix`를 실행하거나 `@username`을 숫자 발신자 ID로 바꾸세요. |
|
||||
|
||||
전체 문제 해결: [Telegram 문제 해결](/ko/channels/telegram#troubleshooting)
|
||||
|
||||
@ -67,11 +67,12 @@ openclaw channels status --probe
|
||||
|
||||
### Discord 실패 징후
|
||||
|
||||
| 증상 | 가장 빠른 확인 방법 | 수정 |
|
||||
| ------------------------------- | ----------------------------------- | --------------------------------------------------------- |
|
||||
| 봇은 온라인이지만 길드 응답 없음 | `openclaw channels status --probe` | 길드/채널을 허용하고 메시지 콘텐츠 인텐트를 확인하세요. |
|
||||
| 그룹 메시지가 무시됨 | 멘션 게이팅 드롭에 대한 로그 확인 | 봇을 멘션하거나 길드/채널 `requireMention: false`를 설정하세요. |
|
||||
| DM 응답 누락 | `openclaw pairing list discord` | DM 페어링을 승인하거나 DM 정책을 조정하세요. |
|
||||
| 증상 | 가장 빠른 확인 방법 | 해결 방법 |
|
||||
| ----------------------------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| 봇이 온라인이지만 길드 응답 없음 | `openclaw channels status --probe` | 길드/채널을 허용하고 메시지 콘텐츠 intent를 확인하세요. |
|
||||
| 그룹 메시지가 무시됨 | 멘션 게이팅 드롭 로그 확인 | 봇을 멘션하거나 길드/채널 `requireMention: false`를 설정하세요. |
|
||||
| 입력/토큰 사용은 있지만 Discord 메시지 없음 | 세션 로그에 `didSendViaMessagingTool: false`가 포함된 어시스턴트 텍스트 표시 | 모델이 메시지 도구를 호출하는 대신 비공개로 답했습니다. 도구 호출이 안정적인 모델을 사용하거나, 자동 게시를 위해 `messages.groupChat.visibleReplies: "automatic"`을 설정하세요. |
|
||||
| DM 응답 누락 | `openclaw pairing list discord` | DM 페어링을 승인하거나 DM 정책을 조정하세요. |
|
||||
|
||||
전체 문제 해결: [Discord 문제 해결](/ko/channels/discord#troubleshooting)
|
||||
|
||||
@ -79,11 +80,11 @@ openclaw channels status --probe
|
||||
|
||||
### Slack 실패 징후
|
||||
|
||||
| 증상 | 가장 빠른 확인 방법 | 수정 |
|
||||
| -------------------------------------- | ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 소켓 모드는 연결되었지만 응답 없음 | `openclaw channels status --probe` | 앱 토큰 + 봇 토큰과 필요한 범위를 확인하세요. SecretRef 기반 설정에서는 `botTokenStatus` / `appTokenStatus = configured_unavailable`을 주시하세요. |
|
||||
| DM 차단됨 | `openclaw pairing list slack` | 페어링을 승인하거나 DM 정책을 완화하세요. |
|
||||
| 채널 메시지가 무시됨 | `groupPolicy` 및 채널 허용 목록 확인 | 채널을 허용하거나 정책을 `open`으로 변경하세요. |
|
||||
| 증상 | 가장 빠른 확인 방법 | 해결 방법 |
|
||||
| ----------------------------------------- | ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Socket mode가 연결되었지만 응답 없음 | `openclaw channels status --probe` | app token + bot token 및 필요한 범위를 확인하세요. SecretRef 기반 설정에서는 `botTokenStatus` / `appTokenStatus = configured_unavailable`을 주시하세요. |
|
||||
| DM 차단됨 | `openclaw pairing list slack` | 페어링을 승인하거나 DM 정책을 완화하세요. |
|
||||
| 채널 메시지가 무시됨 | `groupPolicy`와 채널 허용 목록 확인 | 채널을 허용하거나 정책을 `open`으로 전환하세요. |
|
||||
|
||||
전체 문제 해결: [Slack 문제 해결](/ko/channels/slack#troubleshooting)
|
||||
|
||||
@ -91,11 +92,11 @@ openclaw channels status --probe
|
||||
|
||||
### iMessage 및 BlueBubbles 실패 징후
|
||||
|
||||
| 증상 | 가장 빠른 확인 방법 | 수정 |
|
||||
| -------------------------------- | ----------------------------------------------------------------------- | ----------------------------------------------------- |
|
||||
| 인바운드 이벤트 없음 | Webhook/서버 접근성과 앱 권한 확인 | Webhook URL 또는 BlueBubbles 서버 상태를 수정하세요. |
|
||||
| macOS에서 전송은 되지만 수신 없음 | Messages 자동화에 대한 macOS 개인정보 보호 권한 확인 | TCC 권한을 다시 부여하고 채널 프로세스를 재시작하세요. |
|
||||
| DM 발신자 차단됨 | `openclaw pairing list imessage` 또는 `openclaw pairing list bluebubbles` | 페어링을 승인하거나 허용 목록을 업데이트하세요. |
|
||||
| 증상 | 가장 빠른 확인 방법 | 해결 방법 |
|
||||
| ---------------------------- | ------------------------------------------------------------------------ | -------------------------------------------------------- |
|
||||
| 인바운드 이벤트 없음 | Webhook/서버 도달 가능성과 앱 권한 확인 | Webhook URL 또는 BlueBubbles 서버 상태를 수정하세요. |
|
||||
| macOS에서 전송은 되지만 수신 없음 | Messages 자동화에 대한 macOS 개인정보 보호 권한 확인 | TCC 권한을 다시 부여하고 채널 프로세스를 다시 시작하세요. |
|
||||
| DM 발신자가 차단됨 | `openclaw pairing list imessage` 또는 `openclaw pairing list bluebubbles` | 페어링을 승인하거나 허용 목록을 업데이트하세요. |
|
||||
|
||||
전체 문제 해결:
|
||||
|
||||
@ -106,11 +107,11 @@ openclaw channels status --probe
|
||||
|
||||
### Signal 실패 징후
|
||||
|
||||
| 증상 | 가장 빠른 확인 방법 | 수정 |
|
||||
| ------------------------------- | ------------------------------------------ | -------------------------------------------------------- |
|
||||
| 데몬에 접근 가능하지만 봇이 조용함 | `openclaw channels status --probe` | `signal-cli` 데몬 URL/계정 및 수신 모드를 확인하세요. |
|
||||
| DM 차단됨 | `openclaw pairing list signal` | 발신자를 승인하거나 DM 정책을 조정하세요. |
|
||||
| 그룹 응답이 트리거되지 않음 | 그룹 허용 목록과 멘션 패턴 확인 | 발신자/그룹을 추가하거나 게이팅을 완화하세요. |
|
||||
| 증상 | 가장 빠른 확인 방법 | 해결 방법 |
|
||||
| ----------------------------- | ------------------------------------------ | ----------------------------------------------------------- |
|
||||
| 데몬에 도달 가능하지만 봇이 조용함 | `openclaw channels status --probe` | `signal-cli` 데몬 URL/계정과 수신 모드를 확인하세요. |
|
||||
| DM 차단됨 | `openclaw pairing list signal` | 발신자를 승인하거나 DM 정책을 조정하세요. |
|
||||
| 그룹 응답이 트리거되지 않음 | 그룹 허용 목록과 멘션 패턴 확인 | 발신자/그룹을 추가하거나 게이팅을 완화하세요. |
|
||||
|
||||
전체 문제 해결: [Signal 문제 해결](/ko/channels/signal#troubleshooting)
|
||||
|
||||
@ -118,12 +119,12 @@ openclaw channels status --probe
|
||||
|
||||
### QQ Bot 실패 징후
|
||||
|
||||
| 증상 | 가장 빠른 확인 방법 | 수정 |
|
||||
| ------------------------------- | ------------------------------------------- | --------------------------------------------------------------- |
|
||||
| 봇이 "gone to Mars"라고 응답함 | 구성에서 `appId` 및 `clientSecret` 확인 | 자격 증명을 설정하거나 Gateway를 재시작하세요. |
|
||||
| 인바운드 메시지 없음 | `openclaw channels status --probe` | QQ Open Platform에서 자격 증명을 확인하세요. |
|
||||
| 음성이 전사되지 않음 | STT 제공자 구성 확인 | `channels.qqbot.stt` 또는 `tools.media.audio`를 구성하세요. |
|
||||
| 사전 메시지가 도착하지 않음 | QQ 플랫폼 상호작용 요구 사항 확인 | 최근 상호작용이 없으면 QQ가 봇 시작 메시지를 차단할 수 있습니다. |
|
||||
| 증상 | 가장 빠른 확인 방법 | 해결 방법 |
|
||||
| ----------------------------------- | --------------------------------------------- | ---------------------------------------------------------------- |
|
||||
| 봇이 "gone to Mars"라고 응답함 | 설정에서 `appId` 및 `clientSecret` 확인 | 자격 증명을 설정하거나 Gateway를 다시 시작하세요. |
|
||||
| 인바운드 메시지 없음 | `openclaw channels status --probe` | QQ Open Platform에서 자격 증명을 확인하세요. |
|
||||
| 음성이 전사되지 않음 | STT 제공자 설정 확인 | `channels.qqbot.stt` 또는 `tools.media.audio`를 구성하세요. |
|
||||
| 사전 메시지가 도착하지 않음 | QQ 플랫폼 상호작용 요구 사항 확인 | 최근 상호작용이 없으면 QQ가 봇이 시작한 메시지를 차단할 수 있습니다. |
|
||||
|
||||
전체 문제 해결: [QQ Bot 문제 해결](/ko/channels/qqbot#troubleshooting)
|
||||
|
||||
@ -131,13 +132,13 @@ openclaw channels status --probe
|
||||
|
||||
### Matrix 실패 징후
|
||||
|
||||
| 증상 | 가장 빠른 확인 방법 | 수정 |
|
||||
| ----------------------------------- | -------------------------------------- | ------------------------------------------------------------------------- |
|
||||
| 로그인되었지만 룸 메시지를 무시함 | `openclaw channels status --probe` | `groupPolicy`, 룸 허용 목록 및 멘션 게이팅을 확인하세요. |
|
||||
| DM이 처리되지 않음 | `openclaw pairing list matrix` | 발신자를 승인하거나 DM 정책을 조정하세요. |
|
||||
| 암호화된 룸 실패 | `openclaw matrix verify status` | 디바이스를 다시 확인한 다음 `openclaw matrix verify backup status`를 확인하세요. |
|
||||
| 백업 복원이 보류 중이거나 손상됨 | `openclaw matrix verify backup status` | `openclaw matrix verify backup restore`를 실행하거나 복구 키로 다시 실행하세요. |
|
||||
| 교차 서명/부트스트랩이 잘못된 것으로 보임 | `openclaw matrix verify bootstrap` | 비밀 저장소, 교차 서명 및 백업 상태를 한 번에 복구하세요. |
|
||||
| 증상 | 가장 빠른 확인 방법 | 해결 방법 |
|
||||
| ------------------------------------- | --------------------------------------------- | -------------------------------------------------------------------------- |
|
||||
| 로그인되었지만 방 메시지를 무시함 | `openclaw channels status --probe` | `groupPolicy`, 방 허용 목록, 멘션 게이팅을 확인하세요. |
|
||||
| DM이 처리되지 않음 | `openclaw pairing list matrix` | 발신자를 승인하거나 DM 정책을 조정하세요. |
|
||||
| 암호화된 방 실패 | `openclaw matrix verify status` | 디바이스를 다시 확인한 뒤 `openclaw matrix verify backup status`를 확인하세요. |
|
||||
| 백업 복원이 대기 중이거나 손상됨 | `openclaw matrix verify backup status` | `openclaw matrix verify backup restore`를 실행하거나 복구 키로 다시 실행하세요. |
|
||||
| 교차 서명/부트스트랩이 잘못된 것처럼 보임 | `openclaw matrix verify bootstrap` | 비밀 저장소, 교차 서명, 백업 상태를 한 번에 복구하세요. |
|
||||
|
||||
전체 설정 및 구성: [Matrix](/ko/channels/matrix)
|
||||
|
||||
|
||||
@ -1,28 +1,28 @@
|
||||
---
|
||||
read_when:
|
||||
- 연결/인증 문제가 있어 안내에 따라 해결하고 싶은 경우
|
||||
- 업데이트 후 정상 여부를 확인하려는 경우
|
||||
- 연결/인증 문제가 있어 안내형 해결 방법이 필요한 경우
|
||||
- 업데이트했고 기본 검증이 필요한 경우
|
||||
summary: '`openclaw doctor`에 대한 CLI 참조(상태 점검 + 안내식 복구)'
|
||||
title: 진단
|
||||
x-i18n:
|
||||
generated_at: "2026-05-03T21:28:34Z"
|
||||
generated_at: "2026-05-04T02:22:27Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: d4baab5b0cd4d046d12ae5bd14ccf05224115856d45e630a57e77a2be15e5db0
|
||||
source_hash: cd7fb09d373c313e4be45ad9e3b19ceb187a5787ef3e70fcd2b1f1f01b50c905
|
||||
source_path: cli/doctor.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
# `openclaw doctor`
|
||||
|
||||
Gateway 및 채널을 위한 상태 점검 + 빠른 수정.
|
||||
Gateway 및 채널을 위한 상태 점검 + 빠른 수정입니다.
|
||||
|
||||
관련 항목:
|
||||
|
||||
- 문제 해결: [문제 해결](/ko/gateway/troubleshooting)
|
||||
- 보안 감사: [보안](/ko/gateway/security)
|
||||
|
||||
## 예시
|
||||
## 예제
|
||||
|
||||
```bash
|
||||
openclaw doctor
|
||||
@ -35,44 +35,44 @@ openclaw doctor --generate-gateway-token
|
||||
## 옵션
|
||||
|
||||
- `--no-workspace-suggestions`: 워크스페이스 메모리/검색 제안 비활성화
|
||||
- `--yes`: 묻지 않고 기본값 수락
|
||||
- `--repair`: 묻지 않고 권장 비서비스 복구 적용. Gateway 서비스 설치 및 재작성에는 여전히 대화형 확인 또는 명시적 Gateway 명령이 필요함
|
||||
- `--yes`: 프롬프트 없이 기본값 수락
|
||||
- `--repair`: 프롬프트 없이 권장 비서비스 수리 적용; Gateway 서비스 설치 및 재작성에는 여전히 대화형 확인 또는 명시적 Gateway 명령이 필요함
|
||||
- `--fix`: `--repair`의 별칭
|
||||
- `--force`: 필요할 때 사용자 지정 서비스 구성을 덮어쓰는 것을 포함해 적극적인 복구 적용
|
||||
- `--non-interactive`: 프롬프트 없이 실행. 안전한 마이그레이션과 비서비스 복구만 수행
|
||||
- `--force`: 필요할 때 사용자 지정 서비스 구성을 덮어쓰는 것을 포함해 강력한 수리 적용
|
||||
- `--non-interactive`: 프롬프트 없이 실행; 안전한 마이그레이션 및 비서비스 수리만 수행
|
||||
- `--generate-gateway-token`: Gateway 토큰 생성 및 구성
|
||||
- `--deep`: 추가 Gateway 설치를 찾기 위해 시스템 서비스 스캔
|
||||
|
||||
참고:
|
||||
|
||||
- 대화형 프롬프트(예: 키체인/OAuth 수정)는 stdin이 TTY이고 `--non-interactive`가 설정되어 **있지 않을 때만** 실행됩니다. 헤드리스 실행(cron, Telegram, 터미널 없음)은 프롬프트를 건너뜁니다.
|
||||
- 성능: 비대화형 `doctor` 실행은 적극적인 Plugin 로드를 건너뛰어 헤드리스 상태 점검을 빠르게 유지합니다. 대화형 세션은 점검에 Plugin의 기여가 필요할 때 여전히 Plugin을 완전히 로드합니다.
|
||||
- `--fix`(`--repair`의 별칭)는 `~/.openclaw/openclaw.json.bak`에 백업을 쓰고 알 수 없는 구성 키를 제거하며, 각 제거 항목을 나열합니다.
|
||||
- `doctor --fix --non-interactive`는 누락되었거나 오래된 Gateway 서비스 정의를 보고하지만, 업데이트 복구 모드 외부에서는 이를 설치하거나 재작성하지 않습니다. 누락된 서비스에는 `openclaw gateway install`을 실행하고, 런처를 의도적으로 교체하려면 `openclaw gateway install --force`를 실행하세요.
|
||||
- 상태 무결성 점검은 이제 세션 디렉터리의 고아 transcript 파일을 감지합니다. 이를 `.deleted.<timestamp>`로 아카이브하려면 대화형 확인이 필요합니다. `--fix`, `--yes`, 헤드리스 실행은 이를 그대로 둡니다.
|
||||
- Doctor는 또한 `~/.openclaw/cron/jobs.json`(또는 `cron.store`)에서 레거시 cron 작업 형태를 스캔하고, 스케줄러가 런타임에 자동 정규화하기 전에 이를 제자리에서 재작성할 수 있습니다.
|
||||
- Linux에서 doctor는 사용자의 crontab이 여전히 레거시 `~/.openclaw/bin/ensure-whatsapp.sh`를 실행할 때 경고합니다. 해당 스크립트는 더 이상 유지 관리되지 않으며 cron에 systemd 사용자 버스 환경이 없을 때 잘못된 WhatsApp Gateway 중단을 로그로 남길 수 있습니다.
|
||||
- Doctor는 이전 OpenClaw 버전이 만든 레거시 Plugin 의존성 스테이징 상태를 정리합니다. 또한 레지스트리가 이를 해석할 수 있을 때 누락된 구성된 다운로드 가능 Plugin을 복구하며, 2026.5.2 doctor 패스는 해당 릴리스에 대해 구성이 변경된 것으로 표시하기 전에 이전 구성이 이미 사용하는 다운로드 가능 Plugin을 자동 설치합니다.
|
||||
- Doctor는 Plugin 발견이 정상일 때 `plugins.allow`/`plugins.entries`에서 누락된 Plugin id를 제거하고, 일치하는 매달린 채널 구성, Heartbeat 대상, 채널 모델 재정의도 함께 제거해 오래된 Plugin 구성을 복구합니다.
|
||||
- 대화형 프롬프트(예: 키체인/OAuth 수정)는 stdin이 TTY이고 `--non-interactive`가 설정되지 않은 경우에만 실행됩니다. 헤드리스 실행(cron, Telegram, 터미널 없음)은 프롬프트를 건너뜁니다.
|
||||
- 성능: 비대화형 `doctor` 실행은 즉시 Plugin 로드를 건너뛰므로 헤드리스 상태 점검이 빠르게 유지됩니다. 대화형 세션은 점검에 Plugin 기여가 필요할 때 여전히 Plugin을 완전히 로드합니다.
|
||||
- `--fix`(`--repair`의 별칭)는 백업을 `~/.openclaw/openclaw.json.bak`에 쓰고 알 수 없는 구성 키를 제거하며, 각 제거 항목을 나열합니다.
|
||||
- `doctor --fix --non-interactive`는 누락되었거나 오래된 Gateway 서비스 정의를 보고하지만, 업데이트 수리 모드 밖에서는 이를 설치하거나 재작성하지 않습니다. 누락된 서비스에는 `openclaw gateway install`을 실행하고, 실행기를 의도적으로 교체하려는 경우에는 `openclaw gateway install --force`를 실행하세요.
|
||||
- 상태 무결성 점검은 이제 세션 디렉터리의 고아 transcript 파일을 감지합니다. 이를 `.deleted.<timestamp>`로 보관하려면 대화형 확인이 필요합니다. `--fix`, `--yes`, 헤드리스 실행은 이를 그대로 둡니다.
|
||||
- Doctor는 레거시 Cron 작업 형태를 찾기 위해 `~/.openclaw/cron/jobs.json`(또는 `cron.store`)도 스캔하며, 스케줄러가 런타임에 이를 자동 정규화해야 하기 전에 제자리에서 재작성할 수 있습니다.
|
||||
- Linux에서 Doctor는 사용자의 crontab이 여전히 레거시 `~/.openclaw/bin/ensure-whatsapp.sh`를 실행할 때 경고합니다. 이 스크립트는 더 이상 유지 관리되지 않으며, cron에 systemd 사용자 버스 환경이 없을 때 WhatsApp Gateway 중단을 잘못 기록할 수 있습니다.
|
||||
- Doctor는 이전 OpenClaw 버전에서 생성된 레거시 Plugin 의존성 스테이징 상태를 정리합니다. 또한 레지스트리가 이를 확인할 수 있을 때 누락된 구성된 다운로드 가능 Plugin을 수리하며, 2026.5.2 Doctor 패스는 해당 릴리스에 대해 구성이 변경된 것으로 표시하기 전에 이전 구성이 이미 사용 중인 다운로드 가능 Plugin을 자동으로 설치합니다. 다운로드가 실패하면 Doctor는 설치 오류를 보고하고 다음 수리 시도를 위해 구성된 Plugin 항목을 보존합니다.
|
||||
- Doctor는 Plugin 검색이 정상일 때 `plugins.allow`/`plugins.entries`에서 누락된 Plugin ID를 제거하고, 일치하는 연결되지 않은 채널 구성, Heartbeat 대상, 채널 모델 재정의도 함께 제거하여 오래된 Plugin 구성을 수리합니다.
|
||||
- Doctor는 영향을 받은 `plugins.entries.<id>` 항목을 비활성화하고 잘못된 `config` 페이로드를 제거하여 유효하지 않은 Plugin 구성을 격리합니다. Gateway 시작은 이미 해당 잘못된 Plugin만 건너뛰므로 다른 Plugin과 채널은 계속 실행될 수 있습니다.
|
||||
- 다른 supervisor가 Gateway 수명 주기를 소유할 때는 `OPENCLAW_SERVICE_REPAIR_POLICY=external`을 설정하세요. Doctor는 여전히 Gateway/서비스 상태를 보고하고 비서비스 복구를 적용하지만, 서비스 설치/시작/재시작/bootstrap 및 레거시 서비스 정리는 건너뜁니다.
|
||||
- Linux에서 doctor는 비활성 추가 Gateway 유사 systemd 유닛을 무시하고, 복구 중 실행 중인 systemd Gateway 서비스의 명령/엔트리포인트 메타데이터를 재작성하지 않습니다. 활성 런처를 의도적으로 교체하려면 먼저 서비스를 중지하거나 `openclaw gateway install --force`를 사용하세요.
|
||||
- 다른 감독자가 Gateway 수명 주기를 소유하는 경우 `OPENCLAW_SERVICE_REPAIR_POLICY=external`을 설정하세요. Doctor는 여전히 Gateway/서비스 상태를 보고하고 비서비스 수리를 적용하지만, 서비스 설치/시작/재시작/부트스트랩 및 레거시 서비스 정리는 건너뜁니다.
|
||||
- Linux에서 Doctor는 비활성 추가 Gateway 유사 systemd 유닛을 무시하며, 수리 중 실행 중인 systemd Gateway 서비스의 명령/진입점 메타데이터를 재작성하지 않습니다. 활성 실행기를 의도적으로 교체하려면 먼저 서비스를 중지하거나 `openclaw gateway install --force`를 사용하세요.
|
||||
- Doctor는 레거시 플랫 Talk 구성(`talk.voiceId`, `talk.modelId` 및 관련 항목)을 `talk.provider` + `talk.providers.<provider>`로 자동 마이그레이션합니다.
|
||||
- 반복되는 `doctor --fix` 실행은 유일한 차이가 객체 키 순서뿐일 때 더 이상 Talk 정규화를 보고/적용하지 않습니다.
|
||||
- Doctor에는 메모리 검색 준비 상태 점검이 포함되어 있으며, 임베딩 자격 증명이 없을 때 `openclaw configure --section model`을 권장할 수 있습니다.
|
||||
- Doctor는 명령 소유자가 구성되지 않았을 때 경고합니다. 명령 소유자는 소유자 전용 명령을 실행하고 위험한 작업을 승인할 수 있는 인간 운영자 계정입니다. DM 페어링은 누군가가 봇과 대화할 수 있게만 합니다. 첫 소유자 bootstrap이 존재하기 전에 발신자를 승인했다면 `commands.ownerAllowFrom`을 명시적으로 설정하세요.
|
||||
- Doctor는 Codex 모드 에이전트가 구성되어 있고 운영자의 Codex 홈에 개인 Codex CLI 자산이 있을 때 경고합니다. 로컬 Codex 앱 서버 실행은 에이전트별로 격리된 홈을 사용하므로, 의도적으로 승격해야 하는 자산을 인벤토리화하려면 `openclaw migrate codex --dry-run`을 사용하세요.
|
||||
- Doctor는 기본 에이전트에 허용된 Skills가 bin, env var, 구성 또는 OS 요구 사항 누락 때문에 현재 런타임 환경에서 사용할 수 없을 때 경고합니다. `doctor --fix`는 `skills.entries.<skill>.enabled=false`로 사용할 수 없는 Skills를 비활성화할 수 있습니다. Skills를 활성 상태로 유지하려면 대신 누락된 요구 사항을 설치/구성하세요.
|
||||
- sandbox 모드가 활성화되어 있지만 Docker를 사용할 수 없으면, doctor는 해결 방법(`install Docker` 또는 `openclaw config set agents.defaults.sandbox.mode off`)과 함께 신호가 높은 경고를 보고합니다.
|
||||
- 레거시 sandbox 레지스트리 파일(`~/.openclaw/sandbox/containers.json` 또는 `~/.openclaw/sandbox/browsers.json`)이 있으면 doctor가 이를 보고합니다. `openclaw doctor --fix`는 유효한 항목을 샤딩된 레지스트리 디렉터리로 마이그레이션하고 유효하지 않은 레거시 파일은 격리합니다.
|
||||
- `gateway.auth.token`/`gateway.auth.password`가 SecretRef 관리 대상이고 현재 명령 경로에서 사용할 수 없으면, doctor는 읽기 전용 경고를 보고하고 평문 대체 자격 증명을 쓰지 않습니다.
|
||||
- 수정 경로에서 채널 SecretRef 검사가 실패하면, doctor는 조기 종료하는 대신 계속 진행하고 경고를 보고합니다.
|
||||
- 상태 디렉터리 마이그레이션 후, 활성화된 기본 Telegram 또는 Discord 계정이 env fallback에 의존하고 `TELEGRAM_BOT_TOKEN` 또는 `DISCORD_BOT_TOKEN`을 doctor 프로세스에서 사용할 수 없으면 doctor가 경고합니다.
|
||||
- Telegram `allowFrom` 사용자 이름 자동 해석(`doctor --fix`)에는 현재 명령 경로에서 해석 가능한 Telegram 토큰이 필요합니다. 토큰 검사를 사용할 수 없으면 doctor는 경고를 보고하고 해당 패스의 자동 해석을 건너뜁니다.
|
||||
- 반복되는 `doctor --fix` 실행은 유일한 차이가 객체 키 순서일 때 더 이상 Talk 정규화를 보고/적용하지 않습니다.
|
||||
- Doctor에는 메모리 검색 준비 상태 점검이 포함되며, 임베딩 자격 증명이 누락된 경우 `openclaw configure --section model`을 권장할 수 있습니다.
|
||||
- Doctor는 명령 소유자가 구성되지 않은 경우 경고합니다. 명령 소유자는 소유자 전용 명령을 실행하고 위험한 작업을 승인할 수 있는 인간 운영자 계정입니다. DM 페어링은 누군가가 봇과 대화할 수 있게만 합니다. 첫 소유자 부트스트랩이 존재하기 전에 보낸 사람을 승인했다면 `commands.ownerAllowFrom`을 명시적으로 설정하세요.
|
||||
- Doctor는 Codex 모드 에이전트가 구성되어 있고 개인 Codex CLI 자산이 운영자의 Codex 홈에 있을 때 경고합니다. 로컬 Codex 앱 서버 실행은 격리된 에이전트별 홈을 사용하므로, 의도적으로 승격해야 하는 자산을 인벤토리화하려면 `openclaw migrate codex --dry-run`을 사용하세요.
|
||||
- Doctor는 기본 에이전트에 허용된 Skills가 bin, 환경 변수, 구성 또는 OS 요구 사항 누락으로 인해 현재 런타임 환경에서 사용할 수 없을 때 경고합니다. `doctor --fix`는 `skills.entries.<skill>.enabled=false`로 사용할 수 없는 Skills를 비활성화할 수 있습니다. Skill을 활성 상태로 유지하려면 대신 누락된 요구 사항을 설치/구성하세요.
|
||||
- 샌드박스 모드가 활성화되어 있지만 Docker를 사용할 수 없는 경우, Doctor는 해결 방법(`install Docker` 또는 `openclaw config set agents.defaults.sandbox.mode off`)과 함께 신호가 높은 경고를 보고합니다.
|
||||
- 레거시 샌드박스 레지스트리 파일(`~/.openclaw/sandbox/containers.json` 또는 `~/.openclaw/sandbox/browsers.json`)이 있으면 Doctor가 이를 보고합니다. `openclaw doctor --fix`는 유효한 항목을 샤드된 레지스트리 디렉터리로 마이그레이션하고 유효하지 않은 레거시 파일을 격리합니다.
|
||||
- `gateway.auth.token`/`gateway.auth.password`가 SecretRef로 관리되고 현재 명령 경로에서 사용할 수 없는 경우, Doctor는 읽기 전용 경고를 보고하며 일반 텍스트 대체 자격 증명을 쓰지 않습니다.
|
||||
- 수정 경로에서 채널 SecretRef 검사가 실패하면, Doctor는 조기 종료 대신 계속 진행하고 경고를 보고합니다.
|
||||
- 상태 디렉터리 마이그레이션 후, 활성화된 기본 Telegram 또는 Discord 계정이 환경 대체에 의존하고 `TELEGRAM_BOT_TOKEN` 또는 `DISCORD_BOT_TOKEN`을 Doctor 프로세스에서 사용할 수 없을 때 Doctor가 경고합니다.
|
||||
- Telegram `allowFrom` 사용자 이름 자동 확인(`doctor --fix`)에는 현재 명령 경로에서 확인 가능한 Telegram 토큰이 필요합니다. 토큰 검사를 사용할 수 없으면 Doctor는 경고를 보고하고 해당 패스의 자동 확인을 건너뜁니다.
|
||||
|
||||
## macOS: `launchctl` env 재정의
|
||||
## macOS: `launchctl` 환경 변수 재정의
|
||||
|
||||
이전에 `launchctl setenv OPENCLAW_GATEWAY_TOKEN ...`(또는 `...PASSWORD`)을 실행했다면, 해당 값이 구성 파일을 재정의하고 지속적인 “unauthorized” 오류를 일으킬 수 있습니다.
|
||||
이전에 `launchctl setenv OPENCLAW_GATEWAY_TOKEN ...`(또는 `...PASSWORD`)을 실행했다면, 해당 값이 구성 파일을 재정의하여 지속적인 “unauthorized” 오류를 유발할 수 있습니다.
|
||||
|
||||
```bash
|
||||
launchctl getenv OPENCLAW_GATEWAY_TOKEN
|
||||
@ -85,4 +85,4 @@ launchctl unsetenv OPENCLAW_GATEWAY_PASSWORD
|
||||
## 관련 항목
|
||||
|
||||
- [CLI 참조](/ko/cli)
|
||||
- [Gateway doctor](/ko/gateway/doctor)
|
||||
- [Gateway Doctor](/ko/gateway/doctor)
|
||||
|
||||
@ -1,128 +1,104 @@
|
||||
---
|
||||
read_when:
|
||||
- 에이전트 런타임, 워크스페이스 부트스트랩 또는 세션 동작 변경
|
||||
- 에이전트 런타임, 작업 공간 부트스트랩 또는 세션 동작 변경
|
||||
summary: 에이전트 런타임, 워크스페이스 계약 및 세션 부트스트랩
|
||||
title: 에이전트 런타임
|
||||
x-i18n:
|
||||
generated_at: "2026-04-30T06:25:13Z"
|
||||
generated_at: "2026-05-04T02:22:16Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: f4d65ee96cece296251d7d3a0512f12d2dfa900db0e5ffc0f37dcddae7ea55ad
|
||||
source_hash: 89bbbd05a9bf2054d3a1f24aeed005a05b61152a047b593addfb46817baae05a
|
||||
source_path: concepts/agent.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
OpenClaw는 **단일 내장 에이전트 런타임**을 실행합니다. Gateway마다 하나의 에이전트 프로세스가 있으며,
|
||||
자체 작업 영역, 부트스트랩 파일, 세션 저장소를 가집니다. 이 페이지에서는
|
||||
해당 런타임 계약을 다룹니다. 작업 영역에 무엇이 포함되어야 하는지, 어떤 파일이
|
||||
주입되는지, 세션이 이를 기준으로 어떻게 부트스트랩되는지를 설명합니다.
|
||||
OpenClaw는 **단일 내장형 에이전트 런타임**을 실행합니다. Gateway당 하나의 에이전트 프로세스가 있으며, 각 프로세스에는 자체 워크스페이스, 부트스트랩 파일, 세션 저장소가 있습니다. 이 페이지에서는 해당 런타임 규약을 다룹니다. 워크스페이스에 무엇이 포함되어야 하는지, 어떤 파일이 주입되는지, 세션이 이를 기준으로 어떻게 부트스트랩되는지를 설명합니다.
|
||||
|
||||
## 작업 영역(필수)
|
||||
## 워크스페이스(필수)
|
||||
|
||||
OpenClaw는 단일 에이전트 작업 영역 디렉터리(`agents.defaults.workspace`)를 도구와 컨텍스트를 위한 에이전트의 **유일한** 작업 디렉터리(`cwd`)로 사용합니다.
|
||||
OpenClaw는 단일 에이전트 워크스페이스 디렉터리(`agents.defaults.workspace`)를 도구와 컨텍스트를 위한 에이전트의 **유일한** 작업 디렉터리(`cwd`)로 사용합니다.
|
||||
|
||||
권장: `~/.openclaw/openclaw.json`이 없으면 `openclaw setup`을 사용해 생성하고 작업 영역 파일을 초기화하세요.
|
||||
권장: `openclaw setup`을 사용해 `~/.openclaw/openclaw.json`이 없으면 생성하고 워크스페이스 파일을 초기화하세요.
|
||||
|
||||
전체 작업 영역 레이아웃 + 백업 가이드: [에이전트 작업 영역](/ko/concepts/agent-workspace)
|
||||
전체 워크스페이스 레이아웃 + 백업 가이드: [에이전트 워크스페이스](/ko/concepts/agent-workspace)
|
||||
|
||||
`agents.defaults.sandbox`가 활성화되어 있으면, 메인이 아닌 세션은
|
||||
`agents.defaults.sandbox.workspaceRoot` 아래의 세션별 작업 영역으로 이를 재정의할 수 있습니다.
|
||||
([Gateway 구성](/ko/gateway/configuration) 참조).
|
||||
`agents.defaults.sandbox`가 활성화되어 있으면, main이 아닌 세션은 `agents.defaults.sandbox.workspaceRoot` 아래의 세션별 워크스페이스로 이를 재정의할 수 있습니다([Gateway 구성](/ko/gateway/configuration) 참조).
|
||||
|
||||
## 부트스트랩 파일(주입됨)
|
||||
|
||||
`agents.defaults.workspace` 내부에서 OpenClaw는 다음 사용자가 편집 가능한 파일을 예상합니다.
|
||||
`agents.defaults.workspace` 내부에서 OpenClaw는 다음 사용자 편집 가능 파일을 기대합니다.
|
||||
|
||||
- `AGENTS.md` — 운영 지침 + “메모리”
|
||||
- `SOUL.md` — 페르소나, 경계, 어조
|
||||
- `TOOLS.md` — 사용자가 관리하는 도구 메모(예: `imsg`, `sag`, 규칙)
|
||||
- `TOOLS.md` — 사용자가 관리하는 도구 참고 사항(예: `imsg`, `sag`, 규칙)
|
||||
- `BOOTSTRAP.md` — 최초 실행 시 한 번만 수행하는 의식(완료 후 삭제됨)
|
||||
- `IDENTITY.md` — 에이전트 이름/분위기/이모지
|
||||
- `USER.md` — 사용자 프로필 + 선호 호칭
|
||||
|
||||
새 세션의 첫 번째 턴에서 OpenClaw는 이 파일들의 내용을 에이전트 컨텍스트에 직접 주입합니다.
|
||||
새 세션의 첫 번째 턴에서 OpenClaw는 이 파일들의 내용을 시스템 프롬프트의 프로젝트 컨텍스트에 주입합니다.
|
||||
|
||||
빈 파일은 건너뜁니다. 큰 파일은 프롬프트를 간결하게 유지하기 위해 마커와 함께 다듬고 잘라냅니다(전체 내용은 파일을 읽으세요).
|
||||
빈 파일은 건너뜁니다. 큰 파일은 프롬프트를 간결하게 유지하기 위해 마커와 함께 줄이고 잘라냅니다(전체 내용은 파일을 읽으세요).
|
||||
|
||||
파일이 없으면 OpenClaw는 단일 “파일 없음” 마커 줄을 주입합니다(그리고 `openclaw setup`은 안전한 기본 템플릿을 생성합니다).
|
||||
파일이 없으면 OpenClaw는 단일 “누락된 파일” 마커 줄을 주입합니다(그리고 `openclaw setup`은 안전한 기본 템플릿을 생성합니다).
|
||||
|
||||
`BOOTSTRAP.md`는 **완전히 새로운 작업 영역**(다른 부트스트랩 파일이 없는 경우)에만 생성됩니다. 의식을 완료한 뒤 삭제했다면, 이후 재시작 시 다시 생성되지 않아야 합니다.
|
||||
`BOOTSTRAP.md`는 **완전히 새로운 워크스페이스**(다른 부트스트랩 파일이 없는 경우)에만 생성됩니다. 대기 중인 동안 OpenClaw는 이를 프로젝트 컨텍스트에 유지하고, 사용자 메시지에 복사하는 대신 초기 의식을 위한 시스템 프롬프트 부트스트랩 안내를 추가합니다. 의식을 완료한 뒤 삭제하면 이후 재시작 시 다시 생성되지 않아야 합니다.
|
||||
|
||||
부트스트랩 파일 생성을 완전히 비활성화하려면(미리 준비된 작업 영역의 경우) 다음을 설정하세요.
|
||||
부트스트랩 파일 생성을 완전히 비활성화하려면(미리 채워진 워크스페이스의 경우) 다음을 설정하세요.
|
||||
|
||||
```json5
|
||||
{ agents: { defaults: { skipBootstrap: true } } }
|
||||
```
|
||||
|
||||
## 내장 도구
|
||||
## 기본 제공 도구
|
||||
|
||||
핵심 도구(read/exec/edit/write 및 관련 시스템 도구)는 도구 정책에 따라 항상 사용할 수 있습니다. `apply_patch`는 선택 사항이며
|
||||
`tools.exec.applyPatch`로 제어됩니다. `TOOLS.md`는 어떤 도구가 존재하는지를 제어하지 않습니다. 이는
|
||||
_사용자_가 도구를 어떻게 사용하길 원하는지에 대한 지침입니다.
|
||||
핵심 도구(read/exec/edit/write 및 관련 시스템 도구)는 도구 정책의 적용을 받으며 항상 사용할 수 있습니다. `apply_patch`는 선택 사항이며 `tools.exec.applyPatch`로 제한됩니다. `TOOLS.md`는 어떤 도구가 존재하는지 제어하지 않습니다. 이는 _사용자가_ 도구를 어떻게 사용하길 원하는지에 대한 안내입니다.
|
||||
|
||||
## Skills
|
||||
|
||||
OpenClaw는 다음 위치에서 Skills를 로드합니다(우선순위가 높은 순).
|
||||
OpenClaw는 다음 위치에서 Skills를 로드합니다(우선순위가 높은 순서).
|
||||
|
||||
- 작업 영역: `<workspace>/skills`
|
||||
- 워크스페이스: `<workspace>/skills`
|
||||
- 프로젝트 에이전트 Skills: `<workspace>/.agents/skills`
|
||||
- 개인 에이전트 Skills: `~/.agents/skills`
|
||||
- 관리/로컬: `~/.openclaw/skills`
|
||||
- 관리형/로컬: `~/.openclaw/skills`
|
||||
- 번들(설치와 함께 제공됨)
|
||||
- 추가 Skill 폴더: `skills.load.extraDirs`
|
||||
|
||||
Skills는 구성/env로 제어할 수 있습니다([Gateway 구성](/ko/gateway/configuration)의 `skills` 참조).
|
||||
Skills는 구성/env로 제한할 수 있습니다([Gateway 구성](/ko/gateway/configuration)의 `skills` 참조).
|
||||
|
||||
## 런타임 경계
|
||||
|
||||
내장 에이전트 런타임은 Pi 에이전트 코어(모델, 도구,
|
||||
프롬프트 파이프라인)를 기반으로 합니다. 세션 관리, 검색, 도구 연결, 채널
|
||||
전달은 해당 코어 위에 있는 OpenClaw 소유 계층입니다.
|
||||
내장형 에이전트 런타임은 Pi 에이전트 코어(모델, 도구, 프롬프트 파이프라인)를 기반으로 구축됩니다. 세션 관리, 탐색, 도구 연결, 채널 전달은 해당 코어 위에 있는 OpenClaw 소유 계층입니다.
|
||||
|
||||
## 세션
|
||||
|
||||
세션 transcript는 JSONL로 다음 위치에 저장됩니다.
|
||||
세션 전사는 다음 위치에 JSONL로 저장됩니다.
|
||||
|
||||
- `~/.openclaw/agents/<agentId>/sessions/<SessionId>.jsonl`
|
||||
|
||||
세션 ID는 안정적이며 OpenClaw가 선택합니다.
|
||||
다른 도구의 레거시 세션 폴더는 읽지 않습니다.
|
||||
|
||||
## 스트리밍 중 조향
|
||||
## 스트리밍 중 스티어링
|
||||
|
||||
큐 모드가 `steer`이면 인바운드 메시지가 현재 실행에 주입됩니다.
|
||||
큐에 쌓인 조향은 **현재 assistant 턴이 도구 호출 실행을 마친 후**,
|
||||
다음 LLM 호출 전에 전달됩니다. Pi는 `steer`에 대해 대기 중인
|
||||
모든 조향 메시지를 함께 비웁니다. 레거시 `queue`는 모델 경계마다 메시지 하나를 비웁니다.
|
||||
조향은 더 이상 현재 assistant 메시지의 남은 도구 호출을 건너뛰지 않습니다.
|
||||
큐 모드가 `steer`이면 인바운드 메시지가 현재 실행에 주입됩니다. 큐에 쌓인 스티어링은 **현재 어시스턴트 턴이 도구 호출 실행을 마친 후**, 다음 LLM 호출 전에 전달됩니다. Pi는 `steer`의 경우 대기 중인 모든 스티어링 메시지를 함께 비웁니다. 레거시 `queue`는 모델 경계마다 메시지 하나를 비웁니다. 스티어링은 더 이상 현재 어시스턴트 메시지의 남은 도구 호출을 건너뛰지 않습니다.
|
||||
|
||||
큐 모드가 `followup` 또는 `collect`이면 인바운드 메시지는 현재
|
||||
턴이 끝날 때까지 보류된 뒤, 큐에 쌓인 페이로드로 새 에이전트 턴이 시작됩니다.
|
||||
모드 및 경계 동작은 [큐](/ko/concepts/queue) 및 [조향 큐](/ko/concepts/queue-steering)를 참조하세요.
|
||||
큐 모드가 `followup` 또는 `collect`이면 인바운드 메시지는 현재 턴이 끝날 때까지 보류된 뒤, 큐에 쌓인 페이로드로 새 에이전트 턴이 시작됩니다. 모드와 경계 동작은 [큐](/ko/concepts/queue) 및 [스티어링 큐](/ko/concepts/queue-steering)를 참조하세요.
|
||||
|
||||
블록 스트리밍은 완료된 assistant 블록을 완료되는 즉시 전송합니다. 이는
|
||||
**기본적으로 꺼져 있습니다**(`agents.defaults.blockStreamingDefault: "off"`).
|
||||
`agents.defaults.blockStreamingBreak`로 경계를 조정하세요(`text_end`와 `message_end`; 기본값은 text_end).
|
||||
`agents.defaults.blockStreamingChunk`로 소프트 블록 청킹을 제어하세요(기본값은
|
||||
800~1200자, 문단 나눔을 우선하고 그다음 줄바꿈, 문장은 마지막).
|
||||
`agents.defaults.blockStreamingCoalesce`로 스트리밍된 청크를 병합해
|
||||
한 줄 스팸을 줄이세요(전송 전 유휴 기반 병합). Telegram이 아닌 채널은 블록 응답을 활성화하려면
|
||||
명시적으로 `*.blockStreaming: true`가 필요합니다.
|
||||
자세한 도구 요약은 도구 시작 시 내보냅니다(디바운스 없음). Control UI는
|
||||
가능한 경우 에이전트 이벤트를 통해 도구 출력을 스트리밍합니다.
|
||||
블록 스트리밍은 완료된 어시스턴트 블록을 완료되는 즉시 전송합니다. 이는 **기본적으로 꺼져 있습니다**(`agents.defaults.blockStreamingDefault: "off"`).
|
||||
`agents.defaults.blockStreamingBreak`로 경계를 조정하세요(`text_end` 대 `message_end`; 기본값은 text_end).
|
||||
`agents.defaults.blockStreamingChunk`로 소프트 블록 청킹을 제어하세요(기본값은 800~1200자, 단락 구분을 우선하고 그다음 줄바꿈, 마지막으로 문장).
|
||||
`agents.defaults.blockStreamingCoalesce`로 스트리밍된 청크를 병합하여 한 줄 스팸을 줄이세요(전송 전 유휴 기반 병합). Telegram이 아닌 채널은 블록 답장을 활성화하려면 명시적으로 `*.blockStreaming: true`가 필요합니다.
|
||||
자세한 도구 요약은 도구 시작 시 내보냅니다(디바운스 없음). Control UI는 가능한 경우 에이전트 이벤트를 통해 도구 출력을 스트리밍합니다.
|
||||
자세한 내용: [스트리밍 + 청킹](/ko/concepts/streaming).
|
||||
|
||||
## 모델 참조
|
||||
|
||||
구성의 모델 참조(예: `agents.defaults.model` 및 `agents.defaults.models`)는 **첫 번째** `/`를 기준으로 나누어 파싱됩니다.
|
||||
구성의 모델 참조(예: `agents.defaults.model` 및 `agents.defaults.models`)는 **첫 번째** `/`를 기준으로 분리해 파싱됩니다.
|
||||
|
||||
- 모델을 구성할 때는 `provider/model`을 사용하세요.
|
||||
- 모델 ID 자체에 `/`가 포함된 경우(OpenRouter 스타일), 제공자 접두사를 포함하세요(예: `openrouter/moonshotai/kimi-k2`).
|
||||
- 제공자를 생략하면 OpenClaw는 먼저 별칭을 시도한 다음, 해당 정확한 모델 ID에 대해
|
||||
구성된 제공자 중 유일하게 일치하는 항목을 시도하고, 그 후에야
|
||||
구성된 기본 제공자로 폴백합니다. 해당 제공자가 더 이상
|
||||
구성된 기본 모델을 노출하지 않으면, OpenClaw는 오래된 제거된 제공자 기본값을 표시하는 대신
|
||||
구성된 첫 번째 제공자/모델로 폴백합니다.
|
||||
- 모델 ID 자체에 `/`가 포함된 경우(OpenRouter 스타일) 제공자 접두사를 포함하세요(예: `openrouter/moonshotai/kimi-k2`).
|
||||
- 제공자를 생략하면 OpenClaw는 먼저 별칭을 시도한 다음, 해당 정확한 모델 ID에 대해 구성된 제공자 중 유일하게 일치하는 항목을 찾고, 그 후에야 구성된 기본 제공자로 폴백합니다. 해당 제공자가 더 이상 구성된 기본 모델을 제공하지 않으면, OpenClaw는 오래된 제거된 제공자 기본값을 표시하는 대신 첫 번째로 구성된 제공자/모델로 폴백합니다.
|
||||
|
||||
## 구성(최소)
|
||||
|
||||
@ -135,8 +111,8 @@ Skills는 구성/env로 제어할 수 있습니다([Gateway 구성](/ko/gateway/
|
||||
|
||||
_다음: [그룹 채팅](/ko/channels/group-messages)_ 🦞
|
||||
|
||||
## 관련
|
||||
## 관련 항목
|
||||
|
||||
- [에이전트 작업 영역](/ko/concepts/agent-workspace)
|
||||
- [에이전트 워크스페이스](/ko/concepts/agent-workspace)
|
||||
- [멀티 에이전트 라우팅](/ko/concepts/multi-agent)
|
||||
- [세션 관리](/ko/concepts/session)
|
||||
|
||||
@ -1,65 +1,73 @@
|
||||
---
|
||||
read_when:
|
||||
- OpenClaw 버그에 대한 실시간 시각적 QA 빌드 또는 실행
|
||||
- 풀 리퀘스트에 전후 검증 추가
|
||||
- Discord, Slack, WhatsApp 또는 기타 실시간 전송 시나리오 추가
|
||||
- 풀 리퀘스트에 대한 전후 검증 추가하기
|
||||
- Discord, Slack, WhatsApp 또는 기타 라이브 전송 시나리오 추가
|
||||
- 스크린샷, 브라우저 자동화 또는 VNC 액세스가 필요한 QA 실행 디버깅
|
||||
summary: Mantis는 라이브 트랜스포트에서 OpenClaw 버그를 재현하고, 전후 증거를 캡처하며, PR에 아티팩트를 첨부하기 위한 시각적 엔드투엔드 검증 시스템입니다.
|
||||
summary: Mantis는 실시간 전송 수단에서 OpenClaw 버그를 재현하고, 전후 증거를 캡처하며, 아티팩트를 풀 리퀘스트에 첨부하기 위한 시각적 엔드투엔드 검증 시스템입니다.
|
||||
title: 사마귀
|
||||
x-i18n:
|
||||
generated_at: "2026-05-03T21:30:03Z"
|
||||
generated_at: "2026-05-04T02:22:55Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 3463882b01a7941f6d758c509d6cd70e099aa8352053347fa9c37a80e5b256ce
|
||||
source_hash: 5a86ab4bc876d1c53ada1c30580034165f028194a072f559eb54a898a369211d
|
||||
source_path: concepts/mantis.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
Mantis는 실제 런타임, 실제 전송 계층, 눈으로 확인할 수 있는 증거가 필요한 버그를 위한 OpenClaw 엔드투엔드 검증 시스템입니다. 알려진 불량 ref에 대해 시나리오를 실행하고, 증거를 캡처한 다음, 후보 ref에 대해 같은 시나리오를 실행하고, 관리자가 PR 또는 로컬 명령에서 검사할 수 있는 아티팩트로 비교 결과를 게시합니다.
|
||||
Mantis는 실제 runtime, 실제 transport, 그리고 눈에 보이는 증거가 필요한 버그를 위한 OpenClaw 종단 간 검증 시스템입니다. 알려진
|
||||
나쁜 ref에 대해 시나리오를 실행하고, 증거를 캡처한 뒤, candidate ref에 대해
|
||||
같은 시나리오를 실행하고, maintainer가 PR 또는 로컬 명령에서 검사할 수 있는
|
||||
artifact로 비교 결과를 게시합니다.
|
||||
|
||||
Mantis는 Discord에서 시작합니다. Discord는 실제 봇 인증, 실제 길드 채널, 반응, 스레드, 네이티브 명령, 그리고 사람이 전송 계층에 표시된 내용을 시각적으로 확인할 수 있는 브라우저 UI라는 가치 높은 첫 번째 레인을 제공하기 때문입니다.
|
||||
Mantis는 Discord부터 시작합니다. Discord는 가치가 높은 첫 lane을 제공하기 때문입니다:
|
||||
실제 bot auth, 실제 guild channel, reaction, thread, native command, 그리고
|
||||
사람이 transport가 보여 준 내용을 시각적으로 확인할 수 있는 browser UI입니다.
|
||||
|
||||
## 목표
|
||||
|
||||
- GitHub 이슈 또는 PR의 버그를 사용자가 보는 것과 같은 전송 계층 형태로 재현합니다.
|
||||
- 수정 사항을 적용하기 전에 기준 ref에서 **이전** 아티팩트를 캡처합니다.
|
||||
- 수정 사항을 적용한 후 후보 ref에서 **이후** 아티팩트를 캡처합니다.
|
||||
- 가능할 때마다 Discord REST 반응 조회 또는 채널 트랜스크립트 검사 같은 결정적 오라클을 사용합니다.
|
||||
- 버그에 표시되는 UI 표면이 있으면 스크린샷을 캡처합니다.
|
||||
- 에이전트가 제어하는 CLI에서 로컬로 실행하고 GitHub에서 원격으로 실행합니다.
|
||||
- 로그인, 브라우저 자동화 또는 공급자 인증이 막혔을 때 VNC 복구를 위해 충분한 머신 상태를 보존합니다.
|
||||
- 실행이 차단되거나, 수동 VNC 도움이 필요하거나, 완료되면 운영자 Discord 채널에 간결한 상태를 게시합니다.
|
||||
- GitHub issue 또는 PR의 버그를 사용자가 보는 것과 같은 transport 형태로 재현합니다.
|
||||
- fix를 적용하기 전에 baseline ref에서 **before** artifact를 캡처합니다.
|
||||
- fix를 적용한 뒤 candidate ref에서 **after** artifact를 캡처합니다.
|
||||
- 가능하면 Discord REST reaction 읽기 또는 channel transcript 확인 같은 결정적 oracle을 사용합니다.
|
||||
- 버그에 보이는 UI 표면이 있을 때 screenshot을 캡처합니다.
|
||||
- agent가 제어하는 CLI에서 로컬로, 그리고 GitHub에서 원격으로 실행합니다.
|
||||
- login, browser automation, provider auth가 막혔을 때 VNC rescue에 필요한 충분한 machine state를 보존합니다.
|
||||
- 실행이 차단되었거나, 수동 VNC 도움이 필요하거나, 완료되었을 때 operator Discord channel에 간결한 status를 게시합니다.
|
||||
|
||||
## 비목표
|
||||
|
||||
- Mantis는 단위 테스트를 대체하지 않습니다. Mantis 실행은 보통 수정 사항을 이해한 뒤 더 작은 회귀 테스트가 되어야 합니다.
|
||||
- Mantis는 일반적인 빠른 CI 게이트가 아닙니다. 더 느리고, 라이브 자격 증명을 사용하며, 라이브 환경이 중요한 버그에 한정됩니다.
|
||||
- Mantis는 정상 동작에서 사람을 필요로 해서는 안 됩니다. 수동 VNC는 복구 경로이지 정상 경로가 아닙니다.
|
||||
- Mantis는 원시 시크릿을 아티팩트, 로그, 스크린샷, Markdown 보고서 또는 PR 댓글에 저장하지 않습니다.
|
||||
- Mantis는 unit test를 대체하지 않습니다. Mantis 실행은 보통 fix가 이해된 뒤 더 작은 regression test가 되어야 합니다.
|
||||
- Mantis는 일반적인 빠른 CI gate가 아닙니다. 더 느리고, live credential을 사용하며,
|
||||
live environment가 중요한 버그를 위해 예약됩니다.
|
||||
- Mantis는 정상 동작에 사람을 요구해서는 안 됩니다. 수동 VNC는 rescue path이지 happy path가 아닙니다.
|
||||
- Mantis는 raw secret을 artifact, log, screenshot, Markdown report, PR comment에 저장하지 않습니다.
|
||||
|
||||
## 소유권
|
||||
|
||||
Mantis는 OpenClaw QA 스택에 속합니다.
|
||||
Mantis는 OpenClaw QA stack에 속합니다.
|
||||
|
||||
- OpenClaw는 `pnpm openclaw qa mantis` 아래의 시나리오 런타임, 전송 계층 어댑터, 증거 스키마, 로컬 CLI를 소유합니다.
|
||||
- QA Lab은 라이브 전송 계층 하네스 구성 요소, 브라우저 캡처 헬퍼, 아티팩트 작성기를 소유합니다.
|
||||
- Crabbox는 원격 VM이 필요할 때 예열된 Linux 머신을 소유합니다.
|
||||
- GitHub Actions는 원격 워크플로 진입점과 아티팩트 보존을 소유합니다.
|
||||
- ClawSweeper는 관리자 명령 파싱, 워크플로 디스패치, 최종 PR 댓글 게시 같은 GitHub 댓글 라우팅을 소유합니다.
|
||||
- OpenClaw 에이전트는 시나리오에 에이전트식 설정, 디버깅 또는 정지 상태 보고가 필요할 때 Codex를 통해 Mantis를 구동합니다.
|
||||
- OpenClaw는 `pnpm openclaw qa mantis` 아래의 scenario runtime, transport adapter, evidence schema, local CLI를 소유합니다.
|
||||
- QA Lab은 live transport harness 구성 요소, browser capture helper, artifact writer를 소유합니다.
|
||||
- Crabbox는 remote VM이 필요할 때 warmed Linux machine을 소유합니다.
|
||||
- GitHub Actions는 remote workflow entrypoint와 artifact retention을 소유합니다.
|
||||
- ClawSweeper는 maintainer command parsing, workflow dispatch, 최종 PR comment 게시 같은 GitHub comment routing을 소유합니다.
|
||||
- OpenClaw agent는 시나리오에 agentic setup, debugging, stuck-state reporting이 필요할 때 Codex를 통해 Mantis를 구동합니다.
|
||||
|
||||
이 경계는 전송 계층 지식은 OpenClaw에, 머신 스케줄링은 Crabbox에, 관리자 워크플로 연결 코드는 ClawSweeper에 유지합니다.
|
||||
이 경계는 transport knowledge를 OpenClaw에, machine scheduling을
|
||||
Crabbox에, maintainer workflow glue를 ClawSweeper에 유지합니다.
|
||||
|
||||
## 명령 형태
|
||||
## 명령 형식
|
||||
|
||||
첫 번째 로컬 명령은 Discord 봇, 길드, 채널, 메시지 전송, 반응 전송, 아티팩트 경로를 검증합니다.
|
||||
첫 로컬 명령은 Discord bot, guild, channel, message send,
|
||||
reaction send, artifact path를 검증합니다:
|
||||
|
||||
```bash
|
||||
pnpm openclaw qa mantis discord-smoke \
|
||||
--output-dir .artifacts/qa-e2e/mantis/discord-smoke
|
||||
```
|
||||
|
||||
로컬 이전 및 이후 러너는 다음 형태를 받습니다.
|
||||
로컬 before/after runner는 이 형식을 받습니다:
|
||||
|
||||
```bash
|
||||
pnpm openclaw qa mantis run \
|
||||
@ -70,72 +78,112 @@ pnpm openclaw qa mantis run \
|
||||
--output-dir .artifacts/qa-e2e/mantis/local-discord-status-reactions
|
||||
```
|
||||
|
||||
러너는 출력 디렉터리 아래에 분리된 기준 및 후보 워크트리를 만들고, 종속성을 설치하고, 각 ref를 빌드하고, `--allow-failures`로 시나리오를 실행한 다음, `baseline/`, `candidate/`, `comparison.json`, `mantis-report.md`를 작성합니다. 첫 Discord 시나리오에서 성공적인 검증은 기준 상태가 `fail`이고 후보 상태가 `pass`임을 의미합니다.
|
||||
runner는 output directory 아래에 detached baseline 및 candidate worktree를 만들고,
|
||||
dependency를 설치하고, 각 ref를 build하고, `--allow-failures`로 시나리오를 실행한 뒤
|
||||
`baseline/`, `candidate/`, `comparison.json`, `mantis-report.md`를 씁니다. 첫 Discord 시나리오에서 성공적인 검증은
|
||||
baseline status가 `fail`이고 candidate status가 `pass`임을 의미합니다.
|
||||
|
||||
GitHub 스모크 워크플로는 `Mantis Discord Smoke`입니다. 첫 번째 실제 시나리오의 이전 및 이후 GitHub 워크플로는 `Mantis Discord Status Reactions`입니다. 다음을 받습니다.
|
||||
첫 VM/browser primitive는 desktop smoke입니다:
|
||||
|
||||
- `baseline_ref`: queued-only 동작을 재현할 것으로 예상되는 ref입니다.
|
||||
- `candidate_ref`: `queued -> thinking -> done`을 보여줄 것으로 예상되는 ref입니다.
|
||||
```bash
|
||||
pnpm openclaw qa mantis desktop-browser-smoke \
|
||||
--output-dir .artifacts/qa-e2e/mantis/desktop-browser
|
||||
```
|
||||
|
||||
워크플로 하네스 ref를 체크아웃하고, 별도의 기준 및 후보 워크트리를 빌드하고, 각 워크트리에 대해 `discord-status-reactions-tool-only`를 실행하며, `baseline/`, `candidate/`, `comparison.json`, `mantis-report.md`를 Actions 아티팩트로 업로드합니다.
|
||||
이 명령은 Crabbox desktop machine을 lease하거나 재사용하고, VNC session 안에서 보이는 browser를 시작하고,
|
||||
desktop을 캡처하고, artifact를 local output directory로 다시 가져오며,
|
||||
reconnect command를 report에 씁니다. 이 명령은 Hetzner provider를 기본값으로 사용합니다.
|
||||
Mantis lane에서 작동하는 desktop/VNC coverage를 가진 첫 provider이기 때문입니다.
|
||||
다른 Crabbox fleet에 대해 실행할 때는 `--provider`, `--crabbox-bin`, 또는
|
||||
`OPENCLAW_MANTIS_CRABBOX_PROVIDER`로 재정의하세요.
|
||||
|
||||
PR 댓글에서 status-reactions 실행을 직접 트리거할 수도 있습니다.
|
||||
유용한 desktop smoke flag:
|
||||
|
||||
- `--lease-id <cbx_...>` 또는 `OPENCLAW_MANTIS_CRABBOX_LEASE_ID`는 warmed desktop을 재사용합니다.
|
||||
- `--browser-url <url>`은 보이는 browser에서 여는 page를 변경합니다.
|
||||
- `--html-file <path>`는 repo-local HTML artifact를 보이는 browser에서 렌더링합니다. Mantis는 실제 Crabbox desktop을 통해 생성된 Discord status-reaction timeline을 캡처하는 데 이것을 사용합니다.
|
||||
- `--keep-lease` 또는 `OPENCLAW_MANTIS_KEEP_VM=1`은 새로 만든 passing lease를 VNC inspection을 위해 열린 상태로 유지합니다. 실패한 실행은 lease가 생성된 경우 operator가 reconnect할 수 있도록 기본적으로 lease를 유지합니다.
|
||||
- `--class`, `--idle-timeout`, `--ttl`은 machine size와 lease lifetime을 조정합니다.
|
||||
|
||||
GitHub smoke workflow는 `Mantis Discord Smoke`입니다. 첫 실제 시나리오의 before/after GitHub
|
||||
workflow는 `Mantis Discord Status Reactions`입니다. 이 workflow는 다음을 받습니다:
|
||||
|
||||
- `baseline_ref`: queued-only behavior를 재현할 것으로 예상되는 ref.
|
||||
- `candidate_ref`: `queued -> thinking -> done`을 보여 줄 것으로 예상되는 ref.
|
||||
|
||||
이 workflow는 workflow harness ref를 checkout하고, 별도의 baseline 및 candidate
|
||||
worktree를 build하고, 각 worktree에 대해 `discord-status-reactions-tool-only`를 실행한 뒤,
|
||||
`baseline/`, `candidate/`, `comparison.json`, `mantis-report.md`를
|
||||
Actions artifact로 업로드합니다. 또한 각 lane의 timeline HTML을 Crabbox
|
||||
desktop browser에서 렌더링하고, PR comment의 결정적
|
||||
timeline PNG 옆에 해당 VNC screenshot을 게시합니다. 이 workflow는
|
||||
다음 Crabbox binary release가 만들어지기 전에 현재 desktop/browser lease flag를 사용할 수 있도록
|
||||
`openclaw/crabbox` main에서 Crabbox CLI를 build합니다.
|
||||
|
||||
PR comment에서 status-reactions 실행을 직접 trigger할 수도 있습니다:
|
||||
|
||||
```text
|
||||
@Mantis discord status reactions
|
||||
```
|
||||
|
||||
댓글 트리거는 의도적으로 좁습니다. 쓰기, 유지 관리 또는 관리자 접근 권한이 있는 사용자의 pull request 댓글에서만 실행되며, Discord status-reaction 요청만 인식합니다. 기본적으로 알려진 불량 기준 ref와 현재 PR head SHA를 후보로 사용합니다. 관리자는 어느 ref든 재정의할 수 있습니다.
|
||||
comment trigger는 의도적으로 좁습니다. write, maintain, admin access가 있는 사용자의 pull request
|
||||
comment에서만 실행되며, Discord status-reaction request만 인식합니다. 기본적으로 알려진 나쁜 baseline ref와
|
||||
현재 PR head SHA를 candidate로 사용합니다. Maintainer는 어느 ref든 재정의할 수 있습니다:
|
||||
|
||||
```text
|
||||
@Mantis discord status reactions baseline=origin/main candidate=HEAD
|
||||
```
|
||||
|
||||
ClawSweeper 명령 예시:
|
||||
ClawSweeper command example:
|
||||
|
||||
```text
|
||||
@clawsweeper mantis discord discord-status-reactions-tool-only
|
||||
@clawsweeper verify e2e discord
|
||||
```
|
||||
|
||||
첫 번째 명령은 명시적이며 시나리오에 초점을 둡니다. 두 번째 명령은 나중에 라벨, 변경된 파일, ClawSweeper 리뷰 결과를 바탕으로 PR 또는 이슈를 권장 Mantis 시나리오에 매핑할 수 있습니다.
|
||||
첫 명령은 명시적이며 scenario-focused입니다. 두 번째 명령은 나중에 label, changed file,
|
||||
ClawSweeper review finding을 바탕으로 PR 또는 issue를 추천 Mantis scenario에 매핑할 수 있습니다.
|
||||
|
||||
## 실행 수명 주기
|
||||
|
||||
1. 자격 증명을 획득합니다.
|
||||
1. credential을 획득합니다.
|
||||
2. VM을 할당하거나 재사용합니다.
|
||||
3. 기준 ref를 위한 깨끗한 체크아웃을 준비합니다.
|
||||
4. 종속성을 설치하고 시나리오에 필요한 것만 빌드합니다.
|
||||
5. 격리된 상태 디렉터리로 하위 OpenClaw Gateway를 시작합니다.
|
||||
6. 라이브 전송 계층, 공급자, 모델, 브라우저 프로필을 구성합니다.
|
||||
7. 시나리오를 실행하고 기준 증거를 캡처합니다.
|
||||
8. Gateway를 중지하고 로그를 보존합니다.
|
||||
9. 같은 VM에서 후보 ref를 준비합니다.
|
||||
10. 같은 시나리오를 실행하고 후보 증거를 캡처합니다.
|
||||
11. 오라클 결과와 시각적 증거를 비교합니다.
|
||||
12. Markdown, JSON, 로그, 스크린샷, 선택적 추적 아티팩트를 작성합니다.
|
||||
13. GitHub Actions 아티팩트를 업로드합니다.
|
||||
14. 간결한 PR 또는 Discord 상태 메시지를 게시합니다.
|
||||
3. scenario에 UI evidence가 필요할 때 desktop/browser profile을 준비합니다.
|
||||
4. baseline ref의 clean checkout을 준비합니다.
|
||||
5. dependency를 설치하고 scenario에 필요한 것만 build합니다.
|
||||
6. isolated state directory로 child OpenClaw Gateway를 시작합니다.
|
||||
7. live transport, provider, model, browser profile을 구성합니다.
|
||||
8. scenario를 실행하고 baseline evidence를 캡처합니다.
|
||||
9. gateway를 중지하고 log를 보존합니다.
|
||||
10. 같은 VM에서 candidate ref를 준비합니다.
|
||||
11. 같은 scenario를 실행하고 candidate evidence를 캡처합니다.
|
||||
12. oracle result와 visual evidence를 비교합니다.
|
||||
13. Markdown, JSON, log, screenshot, optional trace artifact를 씁니다.
|
||||
14. GitHub Actions artifact를 업로드합니다.
|
||||
15. 간결한 PR 또는 Discord status message를 게시합니다.
|
||||
|
||||
시나리오는 두 가지 방식으로 실패할 수 있어야 합니다.
|
||||
scenario는 서로 다른 두 방식으로 실패할 수 있어야 합니다:
|
||||
|
||||
- **버그 재현됨**: 기준이 예상한 방식으로 실패했습니다.
|
||||
- **하네스 실패**: 버그 오라클이 의미를 갖기 전에 환경 설정, 자격 증명, Discord API, 브라우저 또는 공급자가 실패했습니다.
|
||||
- **버그 재현됨**: baseline이 예상한 방식으로 실패했습니다.
|
||||
- **Harness failure**: bug oracle이 의미 있기 전에 environment setup, credential, Discord API, browser, 또는
|
||||
provider가 실패했습니다.
|
||||
|
||||
최종 보고서는 관리자가 불안정한 환경을 제품 동작과 혼동하지 않도록 이러한 경우를 분리해야 합니다.
|
||||
최종 report는 maintainer가 flaky environment와 product behavior를 혼동하지 않도록
|
||||
이 case들을 분리해야 합니다.
|
||||
|
||||
## Discord MVP
|
||||
|
||||
첫 번째 시나리오는 소스 답장 전달 모드가 `message_tool_only`인 길드 채널의 Discord 상태 반응을 대상으로 해야 합니다.
|
||||
첫 scenario는 source reply delivery mode가 `message_tool_only`인 guild channel의 Discord status reaction을 대상으로 해야 합니다.
|
||||
|
||||
Mantis 시드로 적합한 이유:
|
||||
좋은 Mantis seed인 이유:
|
||||
|
||||
- 트리거 메시지의 반응으로 Discord에 표시됩니다.
|
||||
- Discord 메시지 반응 상태를 통한 강력한 REST 오라클이 있습니다.
|
||||
- 실제 OpenClaw Gateway, Discord 봇 인증, 메시지 디스패치, 소스 답장 전달 모드, 상태 반응 상태, 모델 턴 수명 주기를 실행합니다.
|
||||
- 첫 구현을 정직하게 유지할 만큼 범위가 좁습니다.
|
||||
- triggering message의 reaction으로 Discord에 보입니다.
|
||||
- Discord message reaction state를 통한 강력한 REST oracle이 있습니다.
|
||||
- 실제 OpenClaw Gateway, Discord bot auth, message dispatch,
|
||||
source reply delivery mode, status reaction state, model turn lifecycle을 실행합니다.
|
||||
- 첫 구현이 명확하게 유지될 만큼 범위가 좁습니다.
|
||||
|
||||
예상 시나리오 형태:
|
||||
예상 scenario 형식:
|
||||
|
||||
```yaml
|
||||
id: discord-status-reactions-tool-only
|
||||
@ -166,9 +214,11 @@ evidence:
|
||||
screenshotMessageRow: true
|
||||
```
|
||||
|
||||
기준 증거는 queued 승인 반응은 표시하지만 tool-only 모드에서 수명 주기 전환은 없어야 합니다. 후보 증거는 `messages.statusReactions.enabled`가 명시적으로 true일 때 수명 주기 상태 반응이 실행되는 것을 보여야 합니다.
|
||||
Baseline evidence는 queued acknowledgement reaction은 보이지만 tool-only mode에서 lifecycle transition은 없음을 보여야 합니다.
|
||||
Candidate evidence는 `messages.statusReactions.enabled`가 명시적으로 true일 때 lifecycle
|
||||
status reaction이 실행됨을 보여야 합니다.
|
||||
|
||||
실행 가능한 첫 번째 단위는 옵트인 Discord 라이브 QA 시나리오입니다.
|
||||
실행 가능한 첫 slice는 opt-in Discord live QA scenario입니다:
|
||||
|
||||
```bash
|
||||
pnpm openclaw qa discord \
|
||||
@ -180,24 +230,30 @@ pnpm openclaw qa discord \
|
||||
--output-dir .artifacts/qa-e2e/mantis/discord-status-reactions-candidate
|
||||
```
|
||||
|
||||
이 시나리오는 SUT를 항상 켜진 길드 처리, `visibleReplies:
|
||||
"message_tool"`, `ackReaction: "👀"`, 명시적 상태 반응으로 구성합니다. 오라클은 실제 Discord 트리거 메시지를 폴링하고 관찰된 순서 `👀 -> 🤔 -> 👍`를 기대합니다. 아티팩트에는 `discord-qa-reaction-timelines.json`, `discord-status-reactions-tool-only-timeline.html`, `discord-status-reactions-tool-only-timeline.png`가 포함됩니다.
|
||||
이 명령은 SUT를 always-on guild handling, `visibleReplies:
|
||||
"message_tool"`, `ackReaction: "👀"`, explicit status reaction으로 구성합니다. oracle은
|
||||
실제 Discord triggering message를 poll하고 관찰된 sequence
|
||||
`👀 -> 🤔 -> 👍`를 기대합니다. Artifact에는 `discord-qa-reaction-timelines.json`,
|
||||
`discord-status-reactions-tool-only-timeline.html`, 그리고
|
||||
`discord-status-reactions-tool-only-timeline.png`가 포함됩니다.
|
||||
|
||||
## 기존 QA 구성 요소
|
||||
|
||||
Mantis는 처음부터 시작하는 대신 기존 비공개 QA 스택을 기반으로 해야 합니다.
|
||||
Mantis는 처음부터 시작하는 대신 기존 private QA stack을 기반으로 해야 합니다:
|
||||
|
||||
- `pnpm openclaw qa discord`는 이미 드라이버 및 SUT 봇이 있는 라이브 Discord 레인을 실행합니다.
|
||||
- 라이브 전송 계층 러너는 이미 `.artifacts/qa-e2e/` 아래에 보고서와 관찰된 메시지 아티팩트를 작성합니다.
|
||||
- Convex 자격 증명 임대는 이미 공유 라이브 전송 계층 자격 증명에 대한 독점 접근을 제공합니다.
|
||||
- 브라우저 제어 서비스는 이미 스크린샷, 스냅샷, 헤드리스 관리 프로필, 원격 CDP 프로필을 지원합니다.
|
||||
- QA Lab에는 이미 전송 계층 형태의 테스트를 위한 디버거 UI와 버스가 있습니다.
|
||||
- `pnpm openclaw qa discord`는 이미 driver 및 SUT bot으로 live Discord lane을 실행합니다.
|
||||
- live transport runner는 이미 `.artifacts/qa-e2e/` 아래에 report와 observed-message artifact를 씁니다.
|
||||
- Convex credential lease는 이미 shared live transport credential에 대한 exclusive access를 제공합니다.
|
||||
- browser control service는 이미 screenshot, snapshot,
|
||||
headless managed profile, remote CDP profile을 지원합니다.
|
||||
- QA Lab은 이미 transport-shaped testing을 위한 debugger UI와 bus를 갖고 있습니다.
|
||||
|
||||
첫 Mantis 구현은 이러한 구성 요소 위의 얇은 이전/이후 러너와 하나의 시각적 증거 계층으로 만들 수 있습니다.
|
||||
첫 Mantis 구현은 이러한 구성 요소 위에 얇은 before/after runner와
|
||||
하나의 visual evidence layer를 더한 형태일 수 있습니다.
|
||||
|
||||
## 증거 모델
|
||||
## Evidence Model
|
||||
|
||||
모든 실행은 안정적인 아티팩트 디렉터리를 작성합니다.
|
||||
모든 실행은 stable artifact directory를 씁니다:
|
||||
|
||||
```text
|
||||
.artifacts/qa-e2e/mantis/<run-id>/
|
||||
@ -217,65 +273,70 @@ Mantis는 처음부터 시작하는 대신 기존 비공개 QA 스택을 기반
|
||||
run.log
|
||||
```
|
||||
|
||||
`mantis-summary.json`은 기계가 읽을 수 있는 단일 진실 공급원이어야 합니다. Markdown 보고서는 PR 댓글과 사람의 검토를 위한 것입니다.
|
||||
`mantis-summary.json`은 machine-readable source of truth여야 합니다.
|
||||
Markdown report는 PR comment와 human review를 위한 것입니다.
|
||||
|
||||
요약에는 다음이 포함되어야 합니다.
|
||||
summary에는 다음이 포함되어야 합니다:
|
||||
|
||||
- 테스트한 ref 및 SHA
|
||||
- 전송 계층 및 시나리오 id
|
||||
- 머신 공급자와 머신 id 또는 임대 id
|
||||
- 시크릿 값 없는 자격 증명 출처
|
||||
- 기준 결과
|
||||
- 후보 결과
|
||||
- 기준에서 버그가 재현되었는지 여부
|
||||
- 후보가 이를 수정했는지 여부
|
||||
- 아티팩트 경로
|
||||
- 정제된 설정 또는 정리 문제
|
||||
- 테스트한 ref와 SHA
|
||||
- transport와 scenario id
|
||||
- machine provider와 machine id 또는 lease id
|
||||
- secret value 없는 credential source
|
||||
- baseline result
|
||||
- candidate result
|
||||
- baseline에서 버그가 재현되었는지 여부
|
||||
- candidate가 이를 수정했는지 여부
|
||||
- artifact path
|
||||
- sanitized setup 또는 cleanup issue
|
||||
|
||||
스크린샷은 증거이지 시크릿이 아닙니다. 그래도 비공개 채널 이름, 사용자 이름 또는 메시지 내용이 나타날 수 있으므로 정제 규율이 필요합니다. 공개 PR에서는 정제 방식이 더 강해질 때까지 인라인 이미지보다 GitHub Actions 아티팩트 링크를 선호합니다.
|
||||
Screenshot은 evidence이지 secret이 아닙니다. 그래도 redaction discipline이 필요합니다:
|
||||
private channel name, user name, message content가 나타날 수 있습니다. public PR에서는
|
||||
redaction story가 더 강해질 때까지 inline image보다 GitHub Actions artifact link를 선호하세요.
|
||||
|
||||
## 브라우저와 VNC
|
||||
## Browser 및 VNC
|
||||
|
||||
브라우저 레인에는 두 가지 모드가 있습니다.
|
||||
browser lane에는 두 가지 mode가 있습니다:
|
||||
|
||||
- **헤드리스 자동화**: CI의 기본값입니다. Chrome은 CDP가 활성화된 상태로 실행되며, Playwright 또는 OpenClaw 브라우저 제어가 스크린샷을 캡처합니다.
|
||||
- **VNC 복구**: 로그인, MFA, Discord 자동화 방지 또는 시각적 디버깅에 사람이 필요할 때 같은 VM에서 활성화됩니다.
|
||||
- **Headless automation**: CI의 기본값입니다. Chrome은 CDP가 활성화된 상태로 실행되고,
|
||||
Playwright 또는 OpenClaw browser control이 screenshot을 캡처합니다.
|
||||
- **VNC rescue**: login, MFA, Discord anti-automation,
|
||||
또는 visual debugging에 사람이 필요할 때 같은 VM에서 활성화됩니다.
|
||||
|
||||
Discord 관찰자 브라우저 프로필은 매 실행마다 로그인하지 않아도 될 만큼 지속적이어야 하지만, 개인 브라우저 상태와는 격리되어야 합니다. 프로필은 개발자 노트북이 아니라 Mantis 머신 풀에 속합니다.
|
||||
Discord 옵저버 브라우저 프로필은 매 실행마다 로그인하지 않아도 될 만큼 지속되어야 하지만, 개인 브라우저 상태와는 격리되어야 합니다. 프로필은 개발자 노트북이 아니라 Mantis 머신 풀에 속합니다.
|
||||
|
||||
Mantis가 막히면 다음을 포함하는 Discord 상태 메시지를 게시합니다.
|
||||
Mantis가 멈추면 다음 내용을 포함한 Discord 상태 메시지를 게시합니다.
|
||||
|
||||
- 실행 id
|
||||
- 시나리오 id
|
||||
- 머신 공급자
|
||||
- 실행 ID
|
||||
- 시나리오 ID
|
||||
- 머신 제공자
|
||||
- 아티팩트 디렉터리
|
||||
- 사용 가능한 경우 VNC 또는 noVNC 연결 지침
|
||||
- 짧은 차단 사유 텍스트
|
||||
- 짧은 차단 원인 텍스트
|
||||
|
||||
첫 비공개 배포에서는 이러한 메시지를 기존 운영자 채널에 게시하고, 나중에 전용 Mantis 채널로 이동할 수 있습니다.
|
||||
첫 번째 비공개 배포는 이러한 메시지를 기존 운영자 채널에 게시하고, 나중에 전용 Mantis 채널로 이동할 수 있습니다.
|
||||
|
||||
## 머신
|
||||
|
||||
Mantis는 첫 원격 구현에서 Crabbox를 통한 AWS를 선호해야 합니다. Crabbox는 예열된 머신, 임대 추적, 하이드레이션, 로그, 결과, 정리를 제공합니다. AWS 용량이 너무 느리거나 사용할 수 없으면 같은 머신 인터페이스 뒤에 Hetzner 공급자를 추가합니다.
|
||||
Mantis는 첫 번째 원격 구현에서 Crabbox를 통한 AWS를 우선 사용해야 합니다. Crabbox는 준비된 머신, 임대 추적, 하이드레이션, 로그, 결과, 정리를 제공합니다. AWS 용량이 너무 느리거나 사용할 수 없으면 동일한 머신 인터페이스 뒤에 Hetzner 제공자를 추가하세요.
|
||||
|
||||
최소 VM 요구 사항:
|
||||
|
||||
- 데스크톱 가능 Chrome 또는 Chromium 설치가 있는 Linux
|
||||
- 브라우저 자동화를 위한 CDP 접근
|
||||
- 데스크톱 사용이 가능한 Chrome 또는 Chromium 설치가 있는 Linux
|
||||
- 브라우저 자동화를 위한 CDP 액세스
|
||||
- 복구를 위한 VNC 또는 noVNC
|
||||
- Node 22 및 pnpm
|
||||
- OpenClaw 체크아웃 및 종속성 캐시
|
||||
- Playwright를 사용할 때 Playwright Chromium 브라우저 캐시
|
||||
- OpenClaw Gateway 하나, 브라우저 하나, 모델 실행 하나에 충분한 CPU와 메모리
|
||||
- Discord, GitHub, 모델 공급자, 자격 증명 브로커에 대한 아웃바운드 접근
|
||||
- OpenClaw 체크아웃 및 의존성 캐시
|
||||
- Playwright를 사용하는 경우 Playwright Chromium 브라우저 캐시
|
||||
- OpenClaw Gateway 하나, 브라우저 하나, 모델 실행 하나를 감당할 충분한 CPU 및 메모리
|
||||
- Discord, GitHub, 모델 제공자, 자격 증명 브로커에 대한 아웃바운드 액세스
|
||||
|
||||
VM은 예상되는 자격 증명 또는 브라우저 프로필 저장소 외부에 장기 원시 시크릿을 보관해서는 안 됩니다.
|
||||
VM은 예상된 자격 증명 또는 브라우저 프로필 저장소 밖에 장기 보관되는 원시 비밀을 유지해서는 안 됩니다.
|
||||
|
||||
## 시크릿
|
||||
## 비밀
|
||||
|
||||
시크릿은 원격 실행의 경우 GitHub 조직 또는 저장소 시크릿에, 로컬 실행의 경우 로컬 운영자가 제어하는 시크릿 파일에 둡니다.
|
||||
비밀은 원격 실행의 경우 GitHub 조직 또는 저장소 비밀에, 로컬 실행의 경우 로컬 운영자가 제어하는 비밀 파일에 둡니다.
|
||||
|
||||
권장 시크릿 이름:
|
||||
권장 비밀 이름:
|
||||
|
||||
- `OPENCLAW_QA_DISCORD_MANTIS_BOT_TOKEN`
|
||||
- `OPENCLAW_QA_DISCORD_DRIVER_BOT_TOKEN`
|
||||
@ -283,58 +344,62 @@ VM은 예상되는 자격 증명 또는 브라우저 프로필 저장소 외부
|
||||
- `OPENCLAW_QA_DISCORD_GUILD_ID`
|
||||
- `OPENCLAW_QA_DISCORD_CHANNEL_ID`
|
||||
- `OPENCLAW_QA_DISCORD_NOTIFY_CHANNEL_ID`
|
||||
- 공개 GitHub 아티팩트 업로드용 `OPENCLAW_QA_REDACT_PUBLIC_METADATA=1`
|
||||
- 공개 GitHub 아티팩트 업로드를 위한 `OPENCLAW_QA_REDACT_PUBLIC_METADATA=1`
|
||||
- `OPENCLAW_QA_CONVEX_SITE_URL`
|
||||
- `OPENCLAW_QA_CONVEX_SECRET_CI`
|
||||
- `OPENCLAW_QA_MANTIS_CRABBOX_COORDINATOR`
|
||||
- `OPENCLAW_QA_MANTIS_CRABBOX_COORDINATOR_TOKEN`
|
||||
|
||||
장기적으로 Convex 자격 증명 풀은 라이브 전송 자격 증명의 일반적인 소스로 남아 있어야 합니다. GitHub secrets는 브로커와 폴백 레인을 부트스트랩합니다.
|
||||
장기적으로 Convex 자격 증명 풀은 라이브 전송 자격 증명의 일반 소스로 유지되어야 합니다. GitHub 비밀은 브로커와 폴백 레인을 부트스트랩합니다. Discord 상태 반응 워크플로는 Mantis Crabbox 비밀을 Crabbox CLI가 기대하는 `CRABBOX_COORDINATOR` 및 `CRABBOX_COORDINATOR_TOKEN` 환경 변수로 다시 매핑합니다. 일반 `CRABBOX_*` GitHub 비밀 이름은 호환성 폴백으로 계속 허용됩니다.
|
||||
|
||||
Mantis 러너는 절대 다음을 출력해서는 안 됩니다.
|
||||
Mantis 러너는 절대로 다음을 출력해서는 안 됩니다.
|
||||
|
||||
- Discord 봇 토큰
|
||||
- 공급자 API 키
|
||||
- 제공자 API 키
|
||||
- 브라우저 쿠키
|
||||
- 인증 프로필 내용
|
||||
- VNC 비밀번호
|
||||
- 원시 자격 증명 페이로드
|
||||
|
||||
공개 아티팩트 업로드는 봇, 길드, 채널, 메시지 ID 같은 Discord 대상 메타데이터도 삭제해야 합니다. 이러한 이유로 GitHub 스모크 워크플로는 `OPENCLAW_QA_REDACT_PUBLIC_METADATA=1`을 활성화합니다.
|
||||
공개 아티팩트 업로드는 봇, 길드, 채널, 메시지 ID 같은 Discord 대상 메타데이터도 삭제해야 합니다. GitHub 스모크 워크플로는 이러한 이유로 `OPENCLAW_QA_REDACT_PUBLIC_METADATA=1`을 활성화합니다.
|
||||
|
||||
토큰이 실수로 이슈, PR, 채팅 또는 로그에 붙여넣어진 경우, 새 시크릿이 저장된 뒤 해당 토큰을 교체하세요.
|
||||
토큰이 실수로 이슈, PR, 채팅, 로그에 붙여넣어진 경우 새 비밀을 저장한 뒤 해당 토큰을 교체하세요.
|
||||
|
||||
## GitHub 아티팩트 및 PR 댓글
|
||||
|
||||
Mantis 워크플로는 전체 증거 번들을 수명이 짧은 Actions 아티팩트로 업로드해야 합니다. 버그 보고서 또는 수정 PR에 대해 워크플로를 실행하는 경우, 삭제 처리된 PNG 스크린샷도 `qa-artifacts` 브랜치에 게시하고 해당 버그 또는 수정 PR에 전후 스크린샷이 인라인으로 포함된 댓글을 업서트해야 합니다. 기본 증거를 일반 QA 자동화 PR에만 게시하지 마세요. 원시 로그, 관찰된 메시지 및 기타 큰 증거는 Actions 아티팩트에 보관합니다.
|
||||
Mantis 워크플로는 전체 증거 번들을 수명이 짧은 Actions 아티팩트로 업로드해야 합니다. 워크플로가 버그 보고서 또는 수정 PR에 대해 실행될 때는 삭제 처리된 PNG 스크린샷도 `qa-artifacts` 브랜치에 게시하고, 해당 버그 또는 수정 PR에 전후 스크린샷을 인라인으로 포함한 댓글을 upsert해야 합니다. 기본 증거를 일반 QA 자동화 PR에만 게시하지 마세요. 원시 로그, 관찰된 메시지, 기타 큰 증거는 Actions 아티팩트에 남겨 둡니다.
|
||||
|
||||
프로덕션 워크플로는 `github-actions[bot]`이 아니라 Mantis GitHub App으로 이러한 댓글을 게시해야 합니다. 앱 ID와 비공개 키를 `MANTIS_GITHUB_APP_ID` 및 `MANTIS_GITHUB_APP_PRIVATE_KEY` GitHub Actions secrets로 저장하세요. 워크플로는 숨겨진 마커를 업서트 키로 사용하고, 토큰이 수정할 수 있으면 해당 댓글을 업데이트하며, 이전 봇 소유 마커를 수정할 수 없으면 새로운 Mantis 소유 댓글을 생성합니다.
|
||||
프로덕션 워크플로는 `github-actions[bot]`이 아니라 Mantis GitHub App으로 해당 댓글을 게시해야 합니다. 앱 ID와 비공개 키를 `MANTIS_GITHUB_APP_ID` 및 `MANTIS_GITHUB_APP_PRIVATE_KEY` GitHub Actions 비밀로 저장하세요. 워크플로는 숨김 마커를 upsert 키로 사용하고, 토큰이 편집할 수 있으면 해당 댓글을 업데이트하며, 이전 봇 소유 마커를 편집할 수 없으면 Mantis 소유 댓글을 새로 만듭니다.
|
||||
|
||||
PR 댓글은 짧고 시각적이어야 합니다.
|
||||
|
||||
```md
|
||||
Mantis Discord 상태 반응 QA
|
||||
Mantis Discord Status Reactions QA
|
||||
|
||||
요약: Mantis는 알려진 불량 기준선과 후보 수정본에 대해 보고된 Discord 상태 반응 버그를 다시 실행했습니다. 기준선은 버그를 재현했고, 후보는 예상된 queued -> thinking -> done 순서를 보여주었습니다.
|
||||
Summary: Mantis reran the reported Discord status-reaction bug against the known
|
||||
bad baseline and the candidate fix. The baseline reproduced the bug, while the
|
||||
candidate showed the expected queued -> thinking -> done sequence.
|
||||
|
||||
- 시나리오: `discord-status-reactions-tool-only`
|
||||
- 실행: <workflow run link>
|
||||
- 아티팩트: <artifact link>
|
||||
- 기준선: `<status>` at `<sha>`
|
||||
- 후보: `<status>` at `<sha>`
|
||||
- Scenario: `discord-status-reactions-tool-only`
|
||||
- Run: <workflow run link>
|
||||
- Artifact: <artifact link>
|
||||
- Baseline: `<status>` at `<sha>`
|
||||
- Candidate: `<status>` at `<sha>`
|
||||
|
||||
| 기준선 | 후보 |
|
||||
| Baseline | Candidate |
|
||||
| ------------------- | ------------------- |
|
||||
| <inline screenshot> | <inline screenshot> |
|
||||
```
|
||||
|
||||
하니스 실패로 인해 실행이 실패한 경우, 댓글은 후보가 실패했다고 암시하는 대신 그 사실을 말해야 합니다.
|
||||
하네스 실패로 실행이 실패한 경우, 댓글은 후보가 실패했다는 뜻을 암시하지 말고 그 사실을 명시해야 합니다.
|
||||
|
||||
## 비공개 배포 참고 사항
|
||||
|
||||
비공개 배포에는 이미 Mantis Discord 애플리케이션이 있을 수 있습니다. 올바른 봇 권한이 있고 안전하게 교체할 수 있다면 다른 앱을 만들지 말고 해당 애플리케이션을 재사용하세요.
|
||||
|
||||
초기 운영자 알림 채널은 secrets 또는 배포 구성을 통해 설정하세요. 먼저 기존 유지관리자 또는 운영 채널을 가리키게 한 다음, 전용 Mantis 채널이 생기면 그곳으로 이동할 수 있습니다.
|
||||
초기 운영자 알림 채널은 비밀 또는 배포 구성으로 설정하세요. 처음에는 기존 유지관리자 또는 운영 채널을 가리키고, 전용 Mantis 채널이 생기면 그쪽으로 이동할 수 있습니다.
|
||||
|
||||
길드 ID, 채널 ID, 봇 토큰, 브라우저 쿠키 또는 VNC 비밀번호를 이 문서에 넣지 마세요. GitHub secrets, 자격 증명 브로커 또는 운영자의 로컬 시크릿 저장소에 저장하세요.
|
||||
이 문서에 길드 ID, 채널 ID, 봇 토큰, 브라우저 쿠키, VNC 비밀번호를 넣지 마세요. GitHub 비밀, 자격 증명 브로커 또는 운영자의 로컬 비밀 저장소에 저장하세요.
|
||||
|
||||
## 시나리오 추가
|
||||
|
||||
@ -343,18 +408,18 @@ Mantis 시나리오는 다음을 선언해야 합니다.
|
||||
- ID 및 제목
|
||||
- 전송
|
||||
- 필요한 자격 증명
|
||||
- 기준선 ref 정책
|
||||
- 기준 ref 정책
|
||||
- 후보 ref 정책
|
||||
- OpenClaw 구성 패치
|
||||
- 설정 단계
|
||||
- 자극
|
||||
- 예상 기준선 오라클
|
||||
- 예상 기준 오라클
|
||||
- 예상 후보 오라클
|
||||
- 시각적 캡처 대상
|
||||
- 시간 제한 예산
|
||||
- 제한 시간 예산
|
||||
- 정리 단계
|
||||
|
||||
시나리오는 작고 형식이 지정된 오라클을 선호해야 합니다.
|
||||
시나리오는 작고 타입이 지정된 오라클을 선호해야 합니다.
|
||||
|
||||
- 반응 버그의 경우 Discord 반응 상태
|
||||
- 스레딩 버그의 경우 Discord 메시지 참조
|
||||
@ -362,24 +427,24 @@ Mantis 시나리오는 다음을 선언해야 합니다.
|
||||
- 이메일 버그의 경우 이메일 메시지 ID 및 헤더
|
||||
- UI가 유일하게 신뢰할 수 있는 관찰 대상인 경우 브라우저 스크린샷
|
||||
|
||||
비전 검사는 추가적이어야 합니다. 플랫폼 API가 버그를 증명할 수 있다면 API를 통과/실패 오라클로 사용하고, 스크린샷은 사람이 확인하는 데 참고하도록 유지하세요.
|
||||
비전 검사는 추가적인 성격이어야 합니다. 플랫폼 API가 버그를 증명할 수 있다면 API를 통과/실패 오라클로 사용하고, 스크린샷은 사람이 확인할 신뢰도를 위해 유지하세요.
|
||||
|
||||
## 공급자 확장
|
||||
## 제공자 확장
|
||||
|
||||
Discord 이후 동일한 러너는 다음을 추가할 수 있습니다.
|
||||
|
||||
- Slack: 반응, 스레드, 앱 멘션, 모달, 파일 업로드.
|
||||
- 이메일: 커넥터만으로 충분하지 않은 경우 `gog`를 사용한 Gmail 인증 및 메시지 스레딩.
|
||||
- WhatsApp: QR 로그인, 재식별, 메시지 전달, 미디어, 반응.
|
||||
- Telegram: 그룹 멘션 게이팅, 명령, 가능한 경우 반응.
|
||||
- Matrix: 암호화된 방, 스레드 또는 답장 관계, 재시작 재개.
|
||||
- Telegram: 사용 가능한 경우 그룹 멘션 게이팅, 명령, 반응.
|
||||
- Matrix: 암호화된 룸, 스레드 또는 답장 관계, 재시작 재개.
|
||||
|
||||
각 전송에는 저렴한 스모크 시나리오 하나와 하나 이상의 버그 클래스 시나리오가 있어야 합니다. 비용이 큰 시각적 시나리오는 옵트인으로 유지해야 합니다.
|
||||
|
||||
## 열린 질문
|
||||
|
||||
- 기존 Mantis 봇을 재사용할 때 어떤 Discord 봇을 드라이버로, 어떤 봇을 SUT로 사용해야 하나요?
|
||||
- 관찰자 브라우저 로그인은 첫 단계에서 사람 Discord 계정, 테스트 계정 또는 봇이 읽을 수 있는 REST 증거만 사용해야 하나요?
|
||||
- GitHub는 PR에 대한 Mantis 아티팩트를 얼마나 오래 보존해야 하나요?
|
||||
- ClawSweeper는 유지관리자 명령을 기다리는 대신 언제 Mantis를 자동으로 권장해야 하나요?
|
||||
- 공개 PR의 경우 업로드 전에 스크린샷을 삭제 처리하거나 잘라내야 하나요?
|
||||
- 기존 Mantis 봇을 재사용할 때 어떤 Discord 봇을 드라이버로, 어떤 봇을 SUT로 사용해야 합니까?
|
||||
- 옵저버 브라우저 로그인은 첫 단계에서 사람 Discord 계정, 테스트 계정 또는 봇이 읽을 수 있는 REST 증거만 사용해야 합니까?
|
||||
- GitHub는 PR용 Mantis 아티팩트를 얼마나 오래 보관해야 합니까?
|
||||
- ClawSweeper는 유지관리자 명령을 기다리는 대신 언제 Mantis를 자동으로 권장해야 합니까?
|
||||
- 공개 PR에 업로드하기 전에 스크린샷을 삭제 처리하거나 자르기 해야 합니까?
|
||||
|
||||
@ -1,36 +1,36 @@
|
||||
---
|
||||
read_when:
|
||||
- 장시간 실행되는 채팅 턴에 표시되는 진행 상황 업데이트 구성
|
||||
- 부분, 블록, 진행률 스트리밍 모드 중 선택하기
|
||||
- 작업이 진행 중일 때 OpenClaw가 하나의 채널 메시지를 업데이트하는 방식을 설명합니다
|
||||
- 진행 상황 초안, 독립 실행형 진행 상황 메시지 또는 최종화 폴백 문제 해결
|
||||
summary: '진행 초안: 에이전트가 실행되는 동안 업데이트되는 하나의 표시되는 작업 진행 중 메시지'
|
||||
- 부분, 블록 및 진행 상황 스트리밍 모드 중 선택
|
||||
- 작업이 진행되는 동안 OpenClaw가 하나의 채널 메시지를 업데이트하는 방법 설명
|
||||
- 진행 초안, 독립형 진행 메시지 또는 최종화 폴백 문제 해결
|
||||
summary: '진행 초안: 에이전트가 실행되는 동안 업데이트되는 표시 가능한 작업 진행 중 메시지 하나'
|
||||
title: 진행 중인 초안
|
||||
x-i18n:
|
||||
generated_at: "2026-05-03T21:30:47Z"
|
||||
generated_at: "2026-05-04T02:23:08Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 0fc0dff38232228b49872d66f4498f065675cdd3abf3a0f4003cb34fcbb7de8c
|
||||
source_hash: 8ce19262800f1c3c3e505a3cf1d41ed5c3dffcbca168ad7b7afabdce62eee8fe
|
||||
source_path: concepts/progress-drafts.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
진행 상황 초안은 오래 실행되는 에이전트 턴이 채팅에서 살아 움직이는 것처럼 느껴지게 하면서도
|
||||
대화를 임시 상태 답장 더미로 만들지 않습니다.
|
||||
진행 상황 초안은 장시간 실행되는 에이전트 턴이 채팅에서 살아 움직이는 것처럼 느껴지게 하면서도
|
||||
대화를 임시 상태 답글 더미로 만들지 않습니다.
|
||||
|
||||
진행 상황 초안을 활성화하면 OpenClaw는 보이는 작업 중 메시지를 하나 만들고,
|
||||
에이전트가 읽고, 계획하고, 도구를 호출하거나, 승인을 기다리는 동안 이를 업데이트한 뒤,
|
||||
채널에서 안전하게 처리할 수 있으면 그 초안을 최종 답변으로 전환합니다.
|
||||
진행 상황 초안을 활성화하면 OpenClaw는 턴이 실제 작업을 하고 있음이 확인된 뒤에만
|
||||
보이는 작업 진행 중 메시지를 하나 만들고, 에이전트가 읽기, 계획 수립, 도구 호출 또는 승인 대기를 하는 동안 이를 업데이트한 다음,
|
||||
채널이 안전하게 처리할 수 있으면 그 초안을 최종 답변으로 전환합니다.
|
||||
|
||||
```text
|
||||
Shelling
|
||||
- reading recent channel context
|
||||
- checking matching issues
|
||||
- preparing reply
|
||||
Shelling...
|
||||
📖 Read: from docs/concepts/progress-drafts.md
|
||||
🔎 Web Search: for "discord edit message"
|
||||
🛠️ Exec: run tests
|
||||
```
|
||||
|
||||
도구 사용이 많은 작업 중에는 깔끔한 상태 메시지 하나를 보여 주고,
|
||||
턴이 끝나면 최종 답변을 보여 주고 싶을 때 진행 상황 초안을 사용하세요.
|
||||
도구 사용이 많은 작업 중에는 깔끔한 상태 메시지 하나를 보여 주고
|
||||
턴이 끝나면 최종 답변을 표시하고 싶을 때 진행 상황 초안을 사용하세요.
|
||||
|
||||
## 빠른 시작
|
||||
|
||||
@ -48,70 +48,69 @@ Shelling
|
||||
}
|
||||
```
|
||||
|
||||
대부분은 이것으로 충분합니다. OpenClaw는 자동으로 한 단어 라벨을 선택하고,
|
||||
유용한 작업이 진행되는 동안 간결한 진행 줄을 추가하며,
|
||||
해당 턴의 중복 단독 진행 상황 잡담을 억제합니다.
|
||||
대개 이것만으로 충분합니다. OpenClaw는 자동 한 단어 라벨을 선택하고, 작업이 최소 5초 동안 지속되거나 두 번째 작업 이벤트가 발생할 때까지 기다린 뒤, 유용한 작업이 진행되는 동안 간결한 진행 상황 줄을 추가하며, 해당 턴의 중복된 독립 실행형 진행 상황 잡담을 억제합니다.
|
||||
|
||||
## 사용자가 보는 내용
|
||||
## 사용자에게 보이는 내용
|
||||
|
||||
진행 상황 초안은 두 부분으로 구성됩니다.
|
||||
|
||||
| 부분 | 목적 |
|
||||
| ---------- | ------------------------------------------------------------- |
|
||||
| 라벨 | `Thinking` 또는 `Shelling` 같은 짧은 제목입니다. |
|
||||
| 진행 줄 | 도구 호출, 작업 단계, 승인 같은 간결한 실행 업데이트입니다. |
|
||||
| 부분 | 목적 |
|
||||
| -------------- | --------------------------------------------------------------------------- |
|
||||
| 라벨 | `Thinking...` 또는 `Shelling...` 같은 짧은 제목. |
|
||||
| 진행 상황 줄 | 상세 출력과 동일한 도구 라벨 및 아이콘을 사용하는 간결한 실행 업데이트. |
|
||||
|
||||
라벨은 에이전트가 답장을 시작하면 즉시 표시됩니다. 진행 줄은 에이전트가 유용한 작업 업데이트를 내보낼 때만
|
||||
추가됩니다. 가능하면 최종 답변이 초안을 대체합니다. 그렇지 않으면 OpenClaw는 최종 답변을 일반 방식으로 보내고,
|
||||
채널의 전송 방식에 따라 초안을 정리하거나 업데이트를 중단합니다.
|
||||
라벨은 에이전트가 의미 있는 작업을 시작한 뒤 5초 동안 계속 바쁘거나 두 번째 작업 이벤트를 발생시키면 표시됩니다. 일반 텍스트만 있는 답글에는 진행 상황 초안이 표시되지 않습니다. 진행 상황 줄은 에이전트가 유용한 작업 업데이트를 발생시킬 때만 추가됩니다. 예를 들어 `🛠️ Exec`, `🔎 Web Search`, `✍️ Write: to /tmp/file` 같은 항목입니다.
|
||||
기본적으로 `/verbose`와 동일한 간결한 설명 모드를 사용합니다. 디버깅 중이고 원시 명령/세부 정보도 추가하고 싶다면
|
||||
`agents.defaults.toolProgressDetail: "raw"`를 설정하세요.
|
||||
가능하면 최종 답변이 초안을 대체합니다. 그렇지 않으면
|
||||
OpenClaw는 최종 답변을 일반 방식으로 보내고 채널 전송 방식에 따라
|
||||
초안을 정리하거나 업데이트를 중단합니다.
|
||||
|
||||
## 모드 선택
|
||||
|
||||
`channels.<channel>.streaming.mode`는 보이는 진행 중 동작을 제어합니다.
|
||||
|
||||
| 모드 | 적합한 경우 | 채팅에 표시되는 내용 |
|
||||
| ---------- | --------------------------------- | ----------------------------------------------------- |
|
||||
| `off` | 조용한 채널 | 최종 답변만 표시됩니다. |
|
||||
| `partial` | 답변 텍스트가 나타나는 것을 보기 | 최신 답변 텍스트로 편집되는 초안 하나입니다. |
|
||||
| `block` | 더 큰 답변 미리보기 청크 | 더 큰 청크로 업데이트되거나 추가되는 미리보기 하나입니다. |
|
||||
| `progress` | 도구 사용이 많거나 오래 걸리는 턴 | 상태 초안 하나와 이후 최종 답변입니다. |
|
||||
| 모드 | 적합한 경우 | 채팅에 표시되는 내용 |
|
||||
| ---------- | -------------------------------- | ------------------------------------------------- |
|
||||
| `off` | 조용한 채널 | 최종 답변만 표시. |
|
||||
| `partial` | 답변 텍스트가 나타나는 과정을 보고 싶을 때 | 최신 답변 텍스트로 편집되는 초안 하나. |
|
||||
| `block` | 더 큰 답변 미리보기 청크 | 더 큰 청크 단위로 업데이트되거나 추가되는 미리보기 하나. |
|
||||
| `progress` | 도구 사용이 많거나 장시간 실행되는 턴 | 상태 초안 하나, 이후 최종 답변. |
|
||||
|
||||
사용자가 답변 텍스트가 토큰 단위로 스트리밍되는 것보다 “무슨 일이 일어나고 있는지”를 더 중요하게 여길 때
|
||||
`progress`를 선택하세요.
|
||||
사용자가 답변 텍스트가 토큰 단위로 스트리밍되는 것보다 "무슨 일이 일어나고 있는지"에 더 관심이 있을 때 `progress`를 선택하세요.
|
||||
|
||||
답변 자체가 진행 상황 신호라면 `partial`을 선택하세요.
|
||||
|
||||
더 큰 텍스트 청크로 초안 미리보기 업데이트를 원하면 `block`을 선택하세요. Discord와 Telegram에서
|
||||
`streaming.mode: "block"`은 여전히 미리보기 스트리밍이며, 일반 블록 전달이 아닙니다.
|
||||
일반 블록 답장을 원하면 `streaming.block.enabled` 또는 레거시 `blockStreaming`을 사용하세요.
|
||||
더 큰 텍스트 청크로 초안 미리보기 업데이트를 원할 때는 `block`을 선택하세요. Discord와 Telegram에서 `streaming.mode: "block"`은 여전히 일반 블록 전달이 아니라 미리보기 스트리밍입니다. 일반 블록 답글을 원할 때는 `streaming.block.enabled` 또는 레거시 `blockStreaming`을 사용하세요.
|
||||
|
||||
## 라벨 구성
|
||||
|
||||
진행 상황 라벨은 `channels.<channel>.streaming.progress` 아래에 있습니다.
|
||||
|
||||
기본 라벨은 `auto`이며, OpenClaw의 기본 제공 한 단어 라벨 풀에서 선택합니다.
|
||||
기본 라벨은 `auto`이며, OpenClaw의 내장
|
||||
줄임표가 붙은 한 단어 라벨 풀에서 선택합니다.
|
||||
|
||||
```text
|
||||
Thinking
|
||||
Shelling
|
||||
Scuttling
|
||||
Clawing
|
||||
Pinching
|
||||
Molting
|
||||
Bubbling
|
||||
Tiding
|
||||
Reefing
|
||||
Cracking
|
||||
Sifting
|
||||
Brining
|
||||
Nautiling
|
||||
Krilling
|
||||
Barnacling
|
||||
Lobstering
|
||||
Tidepooling
|
||||
Pearling
|
||||
Snapping
|
||||
Surfacing
|
||||
Thinking...
|
||||
Shelling...
|
||||
Scuttling...
|
||||
Clawing...
|
||||
Pinching...
|
||||
Molting...
|
||||
Bubbling...
|
||||
Tiding...
|
||||
Reefing...
|
||||
Cracking...
|
||||
Sifting...
|
||||
Brining...
|
||||
Nautiling...
|
||||
Krilling...
|
||||
Barnacling...
|
||||
Lobstering...
|
||||
Tidepooling...
|
||||
Pearling...
|
||||
Snapping...
|
||||
Surfacing...
|
||||
```
|
||||
|
||||
고정 라벨을 사용합니다.
|
||||
@ -131,7 +130,7 @@ Surfacing
|
||||
}
|
||||
```
|
||||
|
||||
직접 만든 자동 라벨 풀을 사용합니다.
|
||||
직접 정의한 자동 라벨 풀을 사용합니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -149,7 +148,7 @@ Surfacing
|
||||
}
|
||||
```
|
||||
|
||||
라벨을 숨기고 진행 줄만 표시합니다.
|
||||
라벨을 숨기고 진행 상황 줄만 표시합니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -166,12 +165,32 @@ Surfacing
|
||||
}
|
||||
```
|
||||
|
||||
## 진행 줄 제어
|
||||
## 진행 상황 줄 제어
|
||||
|
||||
진행 줄은 진행 상황 모드에서 기본적으로 활성화됩니다. 이는 실제 실행 이벤트에서 나옵니다.
|
||||
도구 시작, 항목 업데이트, 작업 계획, 승인, 명령 출력, 패치 요약 및 유사한 에이전트 활동이 해당됩니다.
|
||||
진행 상황 줄은 진행 상황 모드에서 기본적으로 활성화됩니다. 이 줄은 실제 실행 이벤트에서 생성됩니다. 도구 시작, 항목 업데이트, 작업 계획, 승인, 명령 출력, 패치 요약 및 이와 유사한 에이전트 활동이 여기에 포함됩니다.
|
||||
|
||||
계속 보이도록 유지할 줄 수를 제한합니다.
|
||||
OpenClaw는 진행 상황 초안과 `/verbose`에 동일한 포매터를 사용합니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
toolProgressDetail: "explain", // explain | raw
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
`"explain"`은 기본값이며 `🛠️ Exec: check JS syntax for /tmp/app.js` 같은 간결한 라벨로 초안을 안정적으로 유지합니다. `"raw"`는 사용할 수 있을 때 내부 명령/세부 정보를 추가하므로 디버깅 중에는 유용하지만 채팅에서는 더 시끄럽습니다.
|
||||
|
||||
예를 들어 동일한 명령도 세부 정보 모드에 따라 다르게 표시됩니다.
|
||||
|
||||
| 모드 | 진행 상황 줄 |
|
||||
| --------- | -------------------------------------------------------------------- |
|
||||
| `explain` | `🛠️ Exec: check JS syntax for /tmp/app.js` |
|
||||
| `raw` | `🛠️ Exec: check JS syntax for /tmp/app.js, node --check /tmp/app.js` |
|
||||
|
||||
보이는 상태로 유지할 줄 수를 제한합니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -205,71 +224,59 @@ Surfacing
|
||||
}
|
||||
```
|
||||
|
||||
`toolProgress: false`를 설정해도 OpenClaw는 해당 턴의 이전 단독
|
||||
도구 진행 상황 메시지를 계속 억제합니다. 라벨이 구성되어 있는 경우를 제외하면,
|
||||
채널은 최종 답변이 나올 때까지 시각적으로 조용하게 유지됩니다.
|
||||
`toolProgress: false`를 설정해도 OpenClaw는 해당 턴의 이전 독립 실행형
|
||||
도구 진행 상황 메시지를 계속 억제합니다. 라벨이 구성된 경우를 제외하면 채널은 최종 답변이 나올 때까지 시각적으로 조용하게 유지됩니다.
|
||||
|
||||
## 채널 동작
|
||||
|
||||
각 채널은 지원하는 가장 깔끔한 전송 방식을 사용합니다.
|
||||
|
||||
| 채널 | 진행 상황 전송 방식 | 참고 |
|
||||
| 채널 | 진행 상황 전송 방식 | 참고 |
|
||||
| --------------- | -------------------------------------- | --------------------------------------------------------------------- |
|
||||
| Discord | 메시지 하나를 보낸 뒤 편집합니다. | 하나의 안전한 미리보기 메시지에 들어가면 최종 텍스트를 제자리에서 편집합니다. |
|
||||
| Matrix | 이벤트 하나를 보낸 뒤 편집합니다. | 계정 수준 스트리밍 구성이 계정 수준 초안을 제어합니다. |
|
||||
| Microsoft Teams | 개인 채팅에서 네이티브 Teams 스트림을 사용합니다. | `streaming.mode: "block"`은 Teams 블록 전달에 매핑됩니다. |
|
||||
| Slack | 네이티브 스트림 또는 편집 가능한 초안 게시물입니다. | 스레드 사용 가능 여부가 네이티브 스트리밍 사용 가능 여부에 영향을 줍니다. |
|
||||
| Telegram | 메시지 하나를 보낸 뒤 편집합니다. | 최종 타임스탬프가 유용하게 유지되도록 이전에 보이던 초안이 대체될 수 있습니다. |
|
||||
| Mattermost | 편집 가능한 초안 게시물입니다. | 도구 활동이 동일한 초안 스타일 게시물에 접힙니다. |
|
||||
| Discord | 메시지 하나를 보낸 뒤 편집. | 하나의 안전한 미리보기 메시지에 들어갈 때 최종 텍스트를 제자리에서 편집. |
|
||||
| Matrix | 이벤트 하나를 보낸 뒤 편집. | 계정 수준 스트리밍 구성이 계정 수준 초안을 제어. |
|
||||
| Microsoft Teams | 개인 채팅에서 네이티브 Teams 스트림. | `streaming.mode: "block"`은 Teams 블록 전달에 매핑됨. |
|
||||
| Slack | 네이티브 스트림 또는 편집 가능한 초안 게시물. | 스레드 사용 가능 여부가 네이티브 스트리밍 사용 가능 여부에 영향을 줌. |
|
||||
| Telegram | 메시지 하나를 보낸 뒤 편집. | 최종 타임스탬프가 유용하게 유지되도록 이전의 보이는 초안이 대체될 수 있음. |
|
||||
| Mattermost | 편집 가능한 초안 게시물. | 도구 활동은 동일한 초안 스타일 게시물에 접힘. |
|
||||
|
||||
안전한 편집 지원이 없는 채널은 보통 입력 표시기 또는 최종 답변만 전달하는 방식으로 대체됩니다.
|
||||
안전한 편집 지원이 없는 채널은 일반적으로 입력 표시기 또는 최종 답변만 전달하는 방식으로 대체됩니다.
|
||||
|
||||
## 최종화
|
||||
## 마무리
|
||||
|
||||
최종 답변이 준비되면 OpenClaw는 채팅을 깔끔하게 유지하려고 합니다.
|
||||
|
||||
- 초안을 안전하게 최종 답변으로 만들 수 있으면 OpenClaw가 제자리에서 편집합니다.
|
||||
- 채널이 네이티브 진행 상황 스트리밍을 사용하는 경우, 네이티브 전송 방식이 최종 텍스트를 수락하면 OpenClaw가 해당 스트림을 최종화합니다.
|
||||
- 최종 답변에 미디어, 승인 프롬프트, 명시적인 답장 대상, 너무 많은 청크가 있거나 편집/전송에 실패하면 OpenClaw는 일반 채널 전달 경로를 통해 최종 답변을 보냅니다.
|
||||
- 초안을 최종 답변으로 안전하게 전환할 수 있으면 OpenClaw는 이를 제자리에서 편집합니다.
|
||||
- 채널이 네이티브 진행 상황 스트리밍을 사용하면 OpenClaw는 네이티브 전송이 최종 텍스트를 수락할 때 해당 스트림을 마무리합니다.
|
||||
- 최종 답변에 미디어, 승인 프롬프트, 명시적 답글 대상, 너무 많은 청크가 있거나 편집/전송 실패가 발생하면 OpenClaw는 일반 채널 전달 경로를 통해 최종 답변을 보냅니다.
|
||||
|
||||
대체 경로는 의도된 동작입니다. 텍스트를 잃거나, 답장을 잘못된 스레드에 붙이거나,
|
||||
채널이 안전하게 표현할 수 없는 페이로드로 초안을 덮어쓰는 것보다
|
||||
새 최종 답변을 보내는 편이 낫습니다.
|
||||
대체 경로는 의도된 동작입니다. 텍스트를 잃거나, 답글이 잘못된 스레드에 달리거나, 채널이 안전하게 표현할 수 없는 페이로드로 초안을 덮어쓰는 것보다 새 최종 답변을 보내는 편이 낫습니다.
|
||||
|
||||
## 문제 해결
|
||||
|
||||
**최종 답변만 보입니다.**
|
||||
|
||||
메시지를 처리한 계정 또는 채널에 대해 `channels.<channel>.streaming.mode`가 `progress`로 설정되어 있는지 확인하세요.
|
||||
일부 그룹 또는 인용 답장 경로에서는 채널이 올바른 메시지를 안전하게 편집할 수 없을 때
|
||||
해당 턴의 초안 미리보기가 비활성화될 수 있습니다.
|
||||
메시지를 처리한 계정 또는 채널에 대해 `channels.<channel>.streaming.mode`가 `progress`로 설정되어 있는지 확인하세요. 일부 그룹 또는 인용 답글 경로에서는 채널이 올바른 메시지를 안전하게 편집할 수 없을 때 해당 턴의 초안 미리보기가 비활성화될 수 있습니다.
|
||||
|
||||
**라벨은 보이지만 도구 줄은 보이지 않습니다.**
|
||||
**라벨은 보이지만 도구 줄이 보이지 않습니다.**
|
||||
|
||||
`streaming.progress.toolProgress`를 확인하세요. 값이 `false`이면 OpenClaw는
|
||||
단일 초안 동작을 유지하지만 도구 및 작업 진행 줄을 숨깁니다.
|
||||
`streaming.progress.toolProgress`를 확인하세요. `false`이면 OpenClaw는 단일 초안 동작은 유지하지만 도구 및 작업 진행 상황 줄을 숨깁니다.
|
||||
|
||||
**편집된 초안 대신 새 최종 메시지가 보입니다.**
|
||||
|
||||
이는 안전 대체 동작입니다. 미디어 답장, 긴 답변,
|
||||
명시적인 답장 대상, 오래된 Telegram 초안, 누락된 Slack 스레드 대상,
|
||||
삭제된 미리보기 메시지 또는 네이티브 스트림 최종화 실패에서 발생할 수 있습니다.
|
||||
이는 안전 대체 동작입니다. 미디어 답글, 긴 답변, 명시적 답글 대상, 오래된 Telegram 초안, 누락된 Slack 스레드 대상, 삭제된 미리보기 메시지 또는 네이티브 스트림 마무리 실패에서 발생할 수 있습니다.
|
||||
|
||||
**단독 진행 상황 메시지가 계속 보입니다.**
|
||||
**독립 실행형 진행 상황 메시지가 계속 보입니다.**
|
||||
|
||||
초안이 활성화되어 있으면 진행 상황 모드는 기본 단독 도구 진행 상황 메시지를 억제합니다.
|
||||
단독 메시지가 계속 나타나면 해당 턴이 실제로 진행 상황 모드를 사용하고 있는지,
|
||||
그리고 `streaming.mode: "off"`나 해당 메시지에 초안을 만들 수 없는 채널 경로를 사용 중이 아닌지 확인하세요.
|
||||
진행 상황 모드는 초안이 활성화되어 있을 때 기본 독립 실행형 도구 진행 상황 메시지를 억제합니다. 독립 실행형 메시지가 계속 표시된다면 해당 턴이 실제로 진행 상황 모드를 사용하고 있는지, 그리고 `streaming.mode: "off"`나 해당 메시지에 대해 초안을 만들 수 없는 채널 경로를 사용하고 있지 않은지 확인하세요.
|
||||
|
||||
**Teams가 Discord 또는 Telegram과 다르게 동작합니다.**
|
||||
|
||||
Microsoft Teams는 개인 채팅에서 일반적인 보내고 편집하는 미리보기 전송 방식 대신
|
||||
네이티브 스트림을 사용합니다. 또한 Teams는 `streaming.mode: "block"`을 Teams 블록 전달로 처리합니다.
|
||||
Discord와 Telegram에서 사용하는 같은 초안 미리보기 블록 모드가 없기 때문입니다.
|
||||
Microsoft Teams는 일반적인 보내기-편집 미리보기 전송 방식 대신 개인 채팅에서 네이티브 스트림을 사용합니다. 또한 Teams는 Discord와 Telegram에서 사용하는 것과 같은 초안 미리보기 블록 모드가 없기 때문에 `streaming.mode: "block"`을 Teams 블록 전달로 처리합니다.
|
||||
|
||||
## 관련 항목
|
||||
|
||||
- [스트리밍 및 청크 처리](/ko/concepts/streaming)
|
||||
- [스트리밍 및 청킹](/ko/concepts/streaming)
|
||||
- [메시지](/ko/concepts/messages)
|
||||
- [채널 구성](/ko/gateway/config-channels)
|
||||
- [Discord](/ko/channels/discord)
|
||||
|
||||
@ -1,67 +1,68 @@
|
||||
---
|
||||
read_when:
|
||||
- QA 스택이 어떻게 맞물리는지 이해하기
|
||||
- qa-lab, qa-channel 또는 전송 어댑터 확장
|
||||
- QA 스택이 어떻게 서로 맞물리는지 이해하기
|
||||
- qa-lab, qa-channel 또는 전송 어댑터 확장하기
|
||||
- 리포지토리 기반 QA 시나리오 추가
|
||||
- Gateway 대시보드를 중심으로 더 현실성 높은 QA 자동화 구축
|
||||
summary: 'QA 스택 개요: qa-lab, qa-channel, 저장소 기반 시나리오, 실시간 전송 레인, 전송 어댑터, 보고.'
|
||||
- Gateway 대시보드를 중심으로 더 현실적인 QA 자동화 구축
|
||||
summary: 'QA 스택 개요: qa-lab, qa-channel, 리포지토리 기반 시나리오, 라이브 전송 레인, 전송 어댑터, 보고.'
|
||||
title: QA 개요
|
||||
x-i18n:
|
||||
generated_at: "2026-05-03T21:30:51Z"
|
||||
generated_at: "2026-05-04T02:23:08Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 6a1446fddb00855634d34662a0a47be1e5054a9e7bfed5bc9ae21185d87094d8
|
||||
source_hash: 0b376767b967a51cc8a45ca5ce420f78067b52e6368d2abe921ffed533f6f9ba
|
||||
source_path: concepts/qa-e2e-automation.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
비공개 QA 스택은 단일 단위 테스트보다 더 현실적인,
|
||||
채널 형태의 방식으로 OpenClaw를 검증하기 위한 것입니다.
|
||||
비공개 QA 스택은 단일 단위 테스트보다 더 현실적이고,
|
||||
채널 형태에 가까운 방식으로 OpenClaw를 검증하기 위한 것입니다.
|
||||
|
||||
현재 구성 요소:
|
||||
|
||||
- `extensions/qa-channel`: DM, 채널, 스레드,
|
||||
반응, 편집, 삭제 표면을 갖춘 합성 메시지 채널.
|
||||
- `extensions/qa-lab`: 트랜스크립트 관찰,
|
||||
인바운드 메시지 주입, Markdown 보고서 내보내기를 위한 디버거 UI와 QA 버스.
|
||||
- `extensions/qa-matrix`, 향후 러너 Plugin: 하위 QA Gateway 안에서
|
||||
- `extensions/qa-lab`: 트랜스크립트를 관찰하고,
|
||||
인바운드 메시지를 주입하며, Markdown 보고서를 내보내기 위한 디버거 UI와 QA 버스.
|
||||
- `extensions/qa-matrix`, 향후 runner Plugin: 하위 QA Gateway 안에서
|
||||
실제 채널을 구동하는 라이브 전송 어댑터.
|
||||
- `qa/`: 시작 작업과 기준 QA
|
||||
시나리오를 위한 리포지터리 기반 시드 자산.
|
||||
- `qa/`: 시작 태스크와 기준 QA
|
||||
시나리오를 위한 저장소 기반 시드 자산.
|
||||
- [Mantis](/ko/concepts/mantis): 실제 전송, 브라우저 스크린샷, VM 상태, PR 증거가
|
||||
필요한 버그를 위한 라이브 검증 전후 비교.
|
||||
필요한 버그에 대한 라이브 검증 전후 절차.
|
||||
|
||||
## 명령 표면
|
||||
## 명령 인터페이스
|
||||
|
||||
모든 QA 흐름은 `pnpm openclaw qa <subcommand>` 아래에서 실행됩니다. 많은 명령에 `pnpm qa:*`
|
||||
스크립트 별칭이 있으며, 두 형식 모두 지원됩니다.
|
||||
모든 QA 흐름은 `pnpm openclaw qa <subcommand>` 아래에서 실행됩니다. 다수는 `pnpm qa:*`
|
||||
스크립트 별칭을 가지고 있으며, 두 형식 모두 지원됩니다.
|
||||
|
||||
| 명령 | 목적 |
|
||||
| --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `qa run` | 번들된 QA 자체 점검입니다. Markdown 보고서를 작성합니다. |
|
||||
| `qa suite` | 리포지터리 기반 시나리오를 QA Gateway 레인에 대해 실행합니다. 별칭: 일회용 Linux VM에는 `pnpm openclaw qa suite --runner multipass`를 사용합니다. |
|
||||
| `qa coverage` | Markdown 시나리오 커버리지 인벤토리를 출력합니다(기계 출력에는 `--json`). |
|
||||
| `qa parity-report` | 두 `qa-suite-summary.json` 파일을 비교하고 에이전트형 패리티 보고서를 작성합니다. |
|
||||
| `qa character-eval` | 판정된 보고서와 함께 여러 라이브 모델에서 캐릭터 QA 시나리오를 실행합니다. [보고](#reporting)를 참조하세요. |
|
||||
| `qa manual` | 선택한 공급자/모델 레인에 대해 일회성 프롬프트를 실행합니다. |
|
||||
| `qa ui` | QA 디버거 UI와 로컬 QA 버스를 시작합니다(별칭: `pnpm qa:lab:ui`). |
|
||||
| `qa docker-build-image` | 미리 구운 QA Docker 이미지를 빌드합니다. |
|
||||
| `qa docker-scaffold` | QA 대시보드 + Gateway 레인을 위한 docker-compose 스캐폴드를 작성합니다. |
|
||||
| 명령 | 목적 |
|
||||
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `qa run` | 번들된 QA 자체 점검이며, Markdown 보고서를 작성합니다. |
|
||||
| `qa suite` | 저장소 기반 시나리오를 QA Gateway 레인에 대해 실행합니다. 별칭: 일회용 Linux VM에는 `pnpm openclaw qa suite --runner multipass`. |
|
||||
| `qa coverage` | Markdown 시나리오 커버리지 인벤토리를 출력합니다(기계 출력은 `--json`). |
|
||||
| `qa parity-report` | 두 `qa-suite-summary.json` 파일을 비교하고 agentic 패리티 보고서를 작성합니다. |
|
||||
| `qa character-eval` | 여러 라이브 모델에 걸쳐 캐릭터 QA 시나리오를 실행하고 판정된 보고서를 생성합니다. [보고](#reporting)를 참조하세요. |
|
||||
| `qa manual` | 선택한 provider/model 레인에 대해 일회성 프롬프트를 실행합니다. |
|
||||
| `qa ui` | QA 디버거 UI와 로컬 QA 버스를 시작합니다(별칭: `pnpm qa:lab:ui`). |
|
||||
| `qa docker-build-image` | 미리 빌드된 QA Docker 이미지를 빌드합니다. |
|
||||
| `qa docker-scaffold` | QA 대시보드 + Gateway 레인을 위한 docker-compose 스캐폴드를 작성합니다. |
|
||||
| `qa up` | QA 사이트를 빌드하고, Docker 기반 스택을 시작하고, URL을 출력합니다(별칭: `pnpm qa:lab:up`; `:fast` 변형은 `--use-prebuilt-image --bind-ui-dist --skip-ui-build`를 추가). |
|
||||
| `qa aimock` | AIMock 공급자 서버만 시작합니다. |
|
||||
| `qa mock-openai` | 시나리오 인식 `mock-openai` 공급자 서버만 시작합니다. |
|
||||
| `qa credentials doctor` / `add` / `list` / `remove` | 공유 Convex 자격 증명 풀을 관리합니다. |
|
||||
| `qa matrix` | 일회용 Tuwunel 홈서버에 대한 라이브 전송 레인입니다. [Matrix QA](/ko/concepts/qa-matrix)를 참조하세요. |
|
||||
| `qa telegram` | 실제 비공개 Telegram 그룹에 대한 라이브 전송 레인입니다. |
|
||||
| `qa discord` | 실제 비공개 Discord 길드 채널에 대한 라이브 전송 레인입니다. |
|
||||
| `qa mantis` | 첫 번째 Discord 상태 반응 시나리오와 함께 라이브 전송 버그의 전후 검증 러너입니다. [Mantis](/ko/concepts/mantis)를 참조하세요. |
|
||||
| `qa aimock` | AIMock provider 서버만 시작합니다. |
|
||||
| `qa mock-openai` | 시나리오 인식 `mock-openai` provider 서버만 시작합니다. |
|
||||
| `qa credentials doctor` / `add` / `list` / `remove` | 공유 Convex 자격 증명 풀을 관리합니다. |
|
||||
| `qa matrix` | 일회용 Tuwunel homeserver에 대한 라이브 전송 레인입니다. [Matrix QA](/ko/concepts/qa-matrix)를 참조하세요. |
|
||||
| `qa telegram` | 실제 비공개 Telegram 그룹에 대한 라이브 전송 레인입니다. |
|
||||
| `qa discord` | 실제 비공개 Discord 길드 채널에 대한 라이브 전송 레인입니다. |
|
||||
| `qa slack` | 실제 비공개 Slack 채널에 대한 라이브 전송 레인입니다. |
|
||||
| `qa mantis` | 라이브 전송 버그를 위한 검증 전후 runner이며, Discord 상태 반응 증거와 Crabbox 데스크톱/브라우저 smoke를 포함합니다. [Mantis](/ko/concepts/mantis)를 참조하세요. |
|
||||
|
||||
## 운영자 흐름
|
||||
|
||||
현재 QA 운영자 흐름은 2분할 QA 사이트입니다.
|
||||
현재 QA 운영자 흐름은 두 패널 QA 사이트입니다.
|
||||
|
||||
- 왼쪽: 에이전트가 포함된 Gateway 대시보드(Control UI).
|
||||
- 오른쪽: Slack 스타일 트랜스크립트와 시나리오 계획을 보여 주는 QA Lab.
|
||||
- 오른쪽: Slack과 유사한 트랜스크립트와 시나리오 계획을 보여 주는 QA Lab.
|
||||
|
||||
다음으로 실행합니다.
|
||||
|
||||
@ -69,12 +70,11 @@ x-i18n:
|
||||
pnpm qa:lab:up
|
||||
```
|
||||
|
||||
이 명령은 QA 사이트를 빌드하고, Docker 기반 Gateway 레인을 시작하며,
|
||||
운영자 또는 자동화 루프가 에이전트에 QA
|
||||
임무를 부여하고, 실제 채널 동작을 관찰하고, 성공한 내용, 실패한 내용,
|
||||
또는 차단 상태로 남은 내용을 기록할 수 있는 QA Lab 페이지를 노출합니다.
|
||||
이 명령은 QA 사이트를 빌드하고, Docker 기반 Gateway 레인을 시작하며, 운영자나 자동화 루프가 에이전트에 QA
|
||||
미션을 부여하고, 실제 채널 동작을 관찰하며, 작동한 것, 실패한 것, 또는
|
||||
차단 상태로 남은 것을 기록할 수 있는 QA Lab 페이지를 노출합니다.
|
||||
|
||||
매번 Docker 이미지를 다시 빌드하지 않고 더 빠르게 QA Lab UI를 반복하려면,
|
||||
매번 Docker 이미지를 다시 빌드하지 않고 더 빠르게 QA Lab UI를 반복 작업하려면,
|
||||
바인드 마운트된 QA Lab 번들로 스택을 시작하세요.
|
||||
|
||||
```bash
|
||||
@ -84,47 +84,47 @@ pnpm qa:lab:up:fast
|
||||
pnpm qa:lab:watch
|
||||
```
|
||||
|
||||
`qa:lab:up:fast`는 Docker 서비스를 미리 빌드된 이미지에서 유지하고
|
||||
`qa:lab:up:fast`는 Docker 서비스를 미리 빌드된 이미지에 유지하고
|
||||
`extensions/qa-lab/web/dist`를 `qa-lab` 컨테이너에 바인드 마운트합니다. `qa:lab:watch`는
|
||||
변경 시 해당 번들을 다시 빌드하며, QA Lab
|
||||
자산 해시가 바뀌면 브라우저가 자동으로 다시 로드됩니다.
|
||||
자산 해시가 변경되면 브라우저가 자동으로 다시 로드됩니다.
|
||||
|
||||
로컬 OpenTelemetry 추적 스모크에는 다음을 실행하세요.
|
||||
로컬 OpenTelemetry trace smoke의 경우 다음을 실행하세요.
|
||||
|
||||
```bash
|
||||
pnpm qa:otel:smoke
|
||||
```
|
||||
|
||||
이 스크립트는 로컬 OTLP/HTTP 추적 수신기를 시작하고,
|
||||
이 스크립트는 로컬 OTLP/HTTP trace receiver를 시작하고,
|
||||
`diagnostics-otel` Plugin을 활성화한 상태로 `otel-trace-smoke` QA 시나리오를 실행한 다음,
|
||||
내보낸 protobuf span을 디코드하고 릴리스에 중요한 형태를 검증합니다.
|
||||
내보낸 protobuf span을 디코딩하고 릴리스에 중요한 형태를 단언합니다.
|
||||
`openclaw.run`, `openclaw.harness.run`, `openclaw.model.call`,
|
||||
`openclaw.context.assembled`, `openclaw.message.delivery`가 반드시 있어야 하며,
|
||||
성공한 턴에서 모델 호출은 `StreamAbandoned`를 내보내면 안 되고, 원시 진단 ID와
|
||||
`openclaw.content.*` 속성은 추적에 포함되지 않아야 합니다. 이 스크립트는
|
||||
성공한 턴의 모델 호출은 `StreamAbandoned`를 내보내면 안 됩니다. 원시 진단 ID와
|
||||
`openclaw.content.*` 속성은 trace에 포함되지 않아야 합니다. 이 스크립트는
|
||||
QA suite 아티팩트 옆에 `otel-smoke-summary.json`을 작성합니다.
|
||||
|
||||
Observability QA는 소스 체크아웃에서만 유지됩니다. npm tarball은 의도적으로
|
||||
QA Lab을 제외하므로 패키지 Docker 릴리스 레인은 `qa` 명령을 실행하지 않습니다.
|
||||
진단 계측을 변경할 때는 빌드된 소스 체크아웃에서
|
||||
`pnpm qa:otel:smoke`를 사용하세요.
|
||||
관측성 QA는 소스 체크아웃 전용으로 유지됩니다. npm tarball은 의도적으로
|
||||
QA Lab을 생략하므로 패키지 Docker 릴리스 레인은 `qa` 명령을 실행하지 않습니다. 진단
|
||||
계측을 변경할 때는 빌드된 소스 체크아웃에서 `pnpm qa:otel:smoke`를 사용하세요.
|
||||
|
||||
전송이 실제인 Matrix 스모크 레인에는 다음을 실행하세요.
|
||||
실제 전송 Matrix smoke 레인의 경우 다음을 실행하세요.
|
||||
|
||||
```bash
|
||||
pnpm openclaw qa matrix --profile fast --fail-fast
|
||||
```
|
||||
|
||||
이 레인의 전체 CLI 참조, 프로필/시나리오 카탈로그, env vars, 아티팩트 레이아웃은 [Matrix QA](/ko/concepts/qa-matrix)에 있습니다. 한눈에 보면, Docker에서 일회용 Tuwunel 홈서버를 프로비저닝하고, 임시 드라이버/SUT/관찰자 사용자를 등록하고, 해당 전송으로 범위가 제한된 하위 QA Gateway 안에서 실제 Matrix Plugin을 실행하며(`qa-channel` 없음), 그런 다음 Markdown 보고서, JSON 요약, 관찰된 이벤트 아티팩트, 결합 출력 로그를 `.artifacts/qa-e2e/matrix-<timestamp>/` 아래에 작성합니다.
|
||||
이 레인의 전체 CLI 참조, profile/scenario 카탈로그, env vars, 아티팩트 레이아웃은 [Matrix QA](/ko/concepts/qa-matrix)에 있습니다. 요약하면 Docker에서 일회용 Tuwunel homeserver를 프로비저닝하고, 임시 driver/SUT/observer 사용자를 등록하며, 해당 전송에 범위가 지정된 하위 QA Gateway 안에서 실제 Matrix Plugin을 실행하고(`qa-channel` 없음), 이후 `.artifacts/qa-e2e/matrix-<timestamp>/` 아래에 Markdown 보고서, JSON 요약, observed-events 아티팩트, 결합된 출력 로그를 작성합니다.
|
||||
|
||||
전송이 실제인 Telegram 및 Discord 스모크 레인:
|
||||
실제 전송 Telegram, Discord, Slack smoke 레인의 경우:
|
||||
|
||||
```bash
|
||||
pnpm openclaw qa telegram
|
||||
pnpm openclaw qa discord
|
||||
pnpm openclaw qa slack
|
||||
```
|
||||
|
||||
둘 다 두 봇(드라이버 + SUT)이 있는 기존 실제 채널을 대상으로 합니다. 필수 env vars, 시나리오 목록, 출력 아티팩트, Convex 자격 증명 풀은 아래 [Telegram 및 Discord QA 참조](#telegram-and-discord-qa-reference)에 문서화되어 있습니다.
|
||||
이들은 두 봇(driver + SUT)이 있는 기존 실제 채널을 대상으로 합니다. 필수 env vars, 시나리오 목록, 출력 아티팩트, Convex 자격 증명 풀은 아래 [Telegram, Discord, Slack QA 참조](#telegram-discord-and-slack-qa-reference)에 문서화되어 있습니다.
|
||||
|
||||
풀링된 라이브 자격 증명을 사용하기 전에 다음을 실행하세요.
|
||||
|
||||
@ -132,64 +132,64 @@ pnpm openclaw qa discord
|
||||
pnpm openclaw qa credentials doctor
|
||||
```
|
||||
|
||||
doctor는 Convex 브로커 env를 확인하고, 엔드포인트 설정을 검증하며, 유지관리자 secret이 있을 때 admin/list 도달 가능성을 확인합니다. secret에 대해서는 설정됨/누락 상태만 보고합니다.
|
||||
doctor는 Convex broker 환경을 확인하고, 엔드포인트 설정을 검증하며, 유지관리자 secret이 있을 때 admin/list 도달 가능성을 확인합니다. secret에 대해서는 설정됨/누락 상태만 보고합니다.
|
||||
|
||||
## 라이브 전송 커버리지
|
||||
|
||||
라이브 전송 레인은 각자 고유한 시나리오 목록 형태를 발명하는 대신 하나의 계약을 공유합니다. `qa-channel`은 넓은 합성 제품 동작 suite이며 라이브 전송 커버리지 매트릭스의 일부가 아닙니다.
|
||||
라이브 전송 레인은 각자 고유한 시나리오 목록 형태를 만들지 않고 하나의 계약을 공유합니다. `qa-channel`은 광범위한 합성 제품 동작 suite이며 라이브 전송 커버리지 매트릭스의 일부가 아닙니다.
|
||||
|
||||
| 레인 | 카나리아 | 멘션 게이팅 | 봇 간 | 허용 목록 차단 | 최상위 응답 | 재시작 재개 | 스레드 후속 응답 | 스레드 격리 | 반응 관찰 | 도움말 명령 | 네이티브 명령 등록 |
|
||||
| -------- | -------- | ----------- | ----- | -------------- | ----------- | ----------- | ---------------- | ----------- | --------- | ----------- | ------------------ |
|
||||
| Matrix | x | x | x | x | x | x | x | x | x | | |
|
||||
| Telegram | x | x | x | | | | | | | x | |
|
||||
| Discord | x | x | x | | | | | | | | x |
|
||||
| 레인 | Canary | 멘션 게이팅 | 봇 간 통신 | 허용 목록 차단 | 최상위 답글 | 재시작 재개 | 스레드 후속 조치 | 스레드 격리 | 반응 관찰 | 도움말 명령 | 네이티브 명령 등록 |
|
||||
| -------- | ------ | ----------- | ---------- | --------------- | ----------- | ----------- | ---------------- | ----------- | --------- | ----------- | ------------------ |
|
||||
| Matrix | x | x | x | x | x | x | x | x | x | | |
|
||||
| Telegram | x | x | x | | | | | | | x | |
|
||||
| Discord | x | x | x | | | | | | | | x |
|
||||
| Slack | x | x | x | | | | | | | | |
|
||||
|
||||
이를 통해 `qa-channel`은 넓은 제품 동작 suite로 유지하면서 Matrix,
|
||||
Telegram, 그리고 향후 라이브 전송이 하나의 명시적 전송 계약
|
||||
체크리스트를 공유하게 됩니다.
|
||||
이렇게 하면 `qa-channel`은 광범위한 제품 동작 suite로 유지되는 한편 Matrix,
|
||||
Telegram, 향후 라이브 전송은 하나의 명시적 전송 계약
|
||||
체크리스트를 공유합니다.
|
||||
|
||||
Docker를 QA 경로에 들이지 않는 일회용 Linux VM 레인에는 다음을 실행하세요.
|
||||
QA 경로에 Docker를 포함하지 않는 일회용 Linux VM 레인의 경우 다음을 실행하세요.
|
||||
|
||||
```bash
|
||||
pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline
|
||||
```
|
||||
|
||||
이 명령은 새 Multipass 게스트를 부팅하고, 종속성을 설치하고, 게스트 안에서 OpenClaw를
|
||||
빌드하고, `qa suite`를 실행한 다음, 일반 QA 보고서와
|
||||
요약을 호스트의 `.artifacts/qa-e2e/...`로 다시 복사합니다.
|
||||
호스트에서 `qa suite`를 실행할 때와 동일한 시나리오 선택 동작을 재사용합니다.
|
||||
호스트와 Multipass suite 실행은 기본적으로 격리된 Gateway 워커로
|
||||
선택된 여러 시나리오를 병렬 실행합니다. `qa-channel`의 기본 동시성은
|
||||
4이며, 선택된 시나리오 수로 제한됩니다. 워커 수를 조정하려면
|
||||
`--concurrency <count>`를 사용하거나, 직렬 실행에는 `--concurrency 1`을 사용하세요.
|
||||
시나리오가 하나라도 실패하면 명령은 0이 아닌 코드로 종료됩니다. 실패 종료 코드 없이
|
||||
이 명령은 새 Multipass guest를 부팅하고, 의존성을 설치하고, guest 안에서 OpenClaw를
|
||||
빌드하고, `qa suite`를 실행한 다음 일반 QA 보고서와
|
||||
요약을 host의 `.artifacts/qa-e2e/...`로 다시 복사합니다.
|
||||
host에서의 `qa suite`와 동일한 시나리오 선택 동작을 재사용합니다.
|
||||
host 및 Multipass suite 실행은 기본적으로 격리된 Gateway worker로 선택한 여러 시나리오를 병렬로 실행합니다. `qa-channel`의 기본 concurrency는
|
||||
4이며, 선택된 시나리오 수로 제한됩니다. worker 수를 조정하려면 `--concurrency <count>`를 사용하고,
|
||||
직렬 실행에는 `--concurrency 1`을 사용하세요.
|
||||
어떤 시나리오든 실패하면 명령은 0이 아닌 코드로 종료됩니다. 실패 종료 코드 없이
|
||||
아티팩트를 원할 때는 `--allow-failures`를 사용하세요.
|
||||
라이브 실행은 게스트에 실용적인 지원 QA 인증 입력을 전달합니다.
|
||||
env 기반 공급자 키, QA 라이브 공급자 구성 경로, 그리고
|
||||
있을 경우 `CODEX_HOME`입니다. 게스트가 마운트된 워크스페이스를 통해 다시 쓸 수 있도록
|
||||
`--output-dir`를 리포지터리 루트 아래에 유지하세요.
|
||||
라이브 실행은 guest에 실용적으로 전달 가능한 지원 QA auth 입력을 전달합니다.
|
||||
env 기반 provider 키, QA 라이브 provider config 경로,
|
||||
그리고 있을 경우 `CODEX_HOME`입니다. guest가 마운트된 workspace를 통해 다시 쓸 수 있도록
|
||||
`--output-dir`를 저장소 루트 아래에 두세요.
|
||||
|
||||
## Telegram 및 Discord QA 참조
|
||||
## Telegram, Discord, Slack QA 참조
|
||||
|
||||
Matrix는 시나리오 수와 Docker 기반 홈서버 프로비저닝 때문에 [전용 페이지](/ko/concepts/qa-matrix)가 있습니다. Telegram과 Discord는 더 작습니다. 각각 몇 개의 시나리오만 있고, 프로필 시스템이 없으며, 기존 실제 채널을 대상으로 하므로 참조는 여기에 있습니다.
|
||||
Matrix는 시나리오 수와 Docker 기반 homeserver 프로비저닝 때문에 [전용 페이지](/ko/concepts/qa-matrix)가 있습니다. Telegram, Discord, Slack은 더 작습니다. 각각 몇 개의 시나리오만 있고, profile 시스템이 없으며, 기존 실제 채널을 대상으로 하므로 참조는 여기에 있습니다.
|
||||
|
||||
### 공유 CLI 플래그
|
||||
### 공유 CLI flags
|
||||
|
||||
두 레인은 모두 `extensions/qa-lab/src/live-transports/shared/live-transport-cli.ts`를 통해 등록되며 동일한 플래그를 허용합니다.
|
||||
이 레인들은 `extensions/qa-lab/src/live-transports/shared/live-transport-cli.ts`를 통해 등록되며 동일한 flags를 허용합니다.
|
||||
|
||||
| 플래그 | 기본값 | 설명 |
|
||||
| ------------------------------------- | --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--scenario <id>` | — | 이 시나리오만 실행합니다. 반복 지정할 수 있습니다. |
|
||||
| `--output-dir <path>` | `<repo>/.artifacts/qa-e2e/{telegram,discord}-<timestamp>` | 보고서/요약/관찰된 메시지와 출력 로그가 작성되는 위치입니다. 상대 경로는 `--repo-root`를 기준으로 해석됩니다. |
|
||||
| `--repo-root <path>` | `process.cwd()` | 중립적인 cwd에서 호출할 때의 저장소 루트입니다. |
|
||||
| `--sut-account <id>` | `sut` | QA gateway 구성 내부의 임시 계정 id입니다. |
|
||||
| `--provider-mode <mode>` | `live-frontier` | `mock-openai` 또는 `live-frontier`입니다. 레거시 `live-openai`도 여전히 동작합니다. |
|
||||
| `--model <ref>` / `--alt-model <ref>` | provider default | 기본/대체 모델 ref입니다. |
|
||||
| `--fast` | 꺼짐 | 지원되는 경우 Provider 빠른 모드입니다. |
|
||||
| `--credential-source <env\|convex>` | `env` | [Convex 자격 증명 풀](#convex-credential-pool)을 참고하세요. |
|
||||
| `--credential-role <maintainer\|ci>` | CI에서는 `ci`, 그 외에는 `maintainer` | `--credential-source convex`일 때 사용되는 역할입니다. |
|
||||
| 플래그 | 기본값 | 설명 |
|
||||
| ------------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--scenario <id>` | — | 이 시나리오만 실행합니다. 반복해서 지정할 수 있습니다. |
|
||||
| `--output-dir <path>` | `<repo>/.artifacts/qa-e2e/{telegram,discord,slack}-<timestamp>` | 보고서/요약/관찰된 메시지와 출력 로그가 기록되는 위치입니다. 상대 경로는 `--repo-root`를 기준으로 해석됩니다. |
|
||||
| `--repo-root <path>` | `process.cwd()` | 중립적인 cwd에서 호출할 때의 저장소 루트입니다. |
|
||||
| `--sut-account <id>` | `sut` | QA Gateway 설정 내부의 임시 계정 ID입니다. |
|
||||
| `--provider-mode <mode>` | `live-frontier` | `mock-openai` 또는 `live-frontier`입니다. 기존 `live-openai`도 계속 작동합니다. |
|
||||
| `--model <ref>` / `--alt-model <ref>` | 프로바이더 기본값 | 기본/대체 모델 참조입니다. |
|
||||
| `--fast` | 꺼짐 | 지원되는 경우 프로바이더 빠른 모드입니다. |
|
||||
| `--credential-source <env\|convex>` | `env` | [Convex 자격 증명 풀](#convex-credential-pool)을 참조하세요. |
|
||||
| `--credential-role <maintainer\|ci>` | CI에서는 `ci`, 그 외에는 `maintainer` | `--credential-source convex`일 때 사용되는 역할입니다. |
|
||||
|
||||
어떤 시나리오라도 실패하면 둘 다 0이 아닌 코드로 종료됩니다. `--allow-failures`는 실패 종료 코드를 설정하지 않고 아티팩트를 작성합니다.
|
||||
각 레인은 실패한 시나리오가 있으면 0이 아닌 값으로 종료됩니다. `--allow-failures`는 실패 종료 코드를 설정하지 않고 아티팩트를 기록합니다.
|
||||
|
||||
### Telegram QA
|
||||
|
||||
@ -197,17 +197,17 @@ Matrix는 시나리오 수와 Docker 기반 홈서버 프로비저닝 때문에
|
||||
pnpm openclaw qa telegram
|
||||
```
|
||||
|
||||
서로 다른 두 bot(driver + SUT)이 있는 실제 비공개 Telegram 그룹 하나를 대상으로 합니다. SUT bot에는 Telegram 사용자 이름이 있어야 합니다. 두 bot 모두 `@BotFather`에서 **Bot-to-Bot Communication Mode**가 활성화되어 있을 때 bot 간 관찰이 가장 잘 동작합니다.
|
||||
두 개의 서로 다른 봇(driver + SUT)이 있는 실제 비공개 Telegram 그룹 하나를 대상으로 합니다. SUT 봇에는 Telegram 사용자 이름이 있어야 합니다. 두 봇 모두 `@BotFather`에서 **Bot-to-Bot Communication Mode**를 활성화하면 봇 간 관찰이 가장 잘 작동합니다.
|
||||
|
||||
`--credential-source env`일 때 필요한 env:
|
||||
|
||||
- `OPENCLAW_QA_TELEGRAM_GROUP_ID` — 숫자 chat id(문자열).
|
||||
- `OPENCLAW_QA_TELEGRAM_GROUP_ID` — 숫자 채팅 ID(문자열)입니다.
|
||||
- `OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN`
|
||||
- `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`
|
||||
|
||||
선택 사항:
|
||||
|
||||
- `OPENCLAW_QA_TELEGRAM_CAPTURE_CONTENT=1`은 관찰된 메시지 아티팩트에 메시지 본문을 유지합니다(기본값은 삭제).
|
||||
- `OPENCLAW_QA_TELEGRAM_CAPTURE_CONTENT=1`은 관찰된 메시지 아티팩트에 메시지 본문을 유지합니다. 기본값은 비식별 처리입니다.
|
||||
|
||||
시나리오(`extensions/qa-lab/src/live-transports/telegram/telegram-live.runtime.ts:44`):
|
||||
|
||||
@ -223,8 +223,8 @@ pnpm openclaw qa telegram
|
||||
출력 아티팩트:
|
||||
|
||||
- `telegram-qa-report.md`
|
||||
- `telegram-qa-summary.json` — canary부터 시작해 reply별 RTT(driver 전송 → 관찰된 SUT reply)를 포함합니다.
|
||||
- `telegram-qa-observed-messages.json` — `OPENCLAW_QA_TELEGRAM_CAPTURE_CONTENT=1`이 아니면 본문이 삭제됩니다.
|
||||
- `telegram-qa-summary.json` — 카나리부터 시작해 응답별 RTT(driver 전송 → 관찰된 SUT 응답)를 포함합니다.
|
||||
- `telegram-qa-observed-messages.json` — `OPENCLAW_QA_TELEGRAM_CAPTURE_CONTENT=1`이 아니면 본문은 비식별 처리됩니다.
|
||||
|
||||
### Discord QA
|
||||
|
||||
@ -232,7 +232,7 @@ pnpm openclaw qa telegram
|
||||
pnpm openclaw qa discord
|
||||
```
|
||||
|
||||
두 bot이 있는 실제 비공개 Discord guild channel 하나를 대상으로 합니다. 하나는 하네스가 제어하는 driver bot이고, 다른 하나는 번들된 Discord Plugin을 통해 자식 OpenClaw gateway가 시작하는 SUT bot입니다. channel mention 처리, SUT bot이 Discord에 네이티브 `/help` 명령을 등록했는지, opt-in Mantis 증거 시나리오를 검증합니다.
|
||||
두 개의 봇이 있는 실제 비공개 Discord 길드 채널 하나를 대상으로 합니다. 하나는 하네스가 제어하는 driver 봇이고, 다른 하나는 번들 Discord Plugin을 통해 자식 OpenClaw Gateway가 시작하는 SUT 봇입니다. 채널 멘션 처리, SUT 봇이 Discord에 네이티브 `/help` 명령을 등록했는지, 옵트인 Mantis 증거 시나리오를 검증합니다.
|
||||
|
||||
`--credential-source env`일 때 필요한 env:
|
||||
|
||||
@ -240,7 +240,7 @@ pnpm openclaw qa discord
|
||||
- `OPENCLAW_QA_DISCORD_CHANNEL_ID`
|
||||
- `OPENCLAW_QA_DISCORD_DRIVER_BOT_TOKEN`
|
||||
- `OPENCLAW_QA_DISCORD_SUT_BOT_TOKEN`
|
||||
- `OPENCLAW_QA_DISCORD_SUT_APPLICATION_ID` — Discord가 반환한 SUT bot user id와 일치해야 합니다(그렇지 않으면 lane이 빠르게 실패합니다).
|
||||
- `OPENCLAW_QA_DISCORD_SUT_APPLICATION_ID` — Discord가 반환한 SUT 봇 사용자 ID와 일치해야 합니다. 그렇지 않으면 레인이 빠르게 실패합니다.
|
||||
|
||||
선택 사항:
|
||||
|
||||
@ -251,9 +251,9 @@ pnpm openclaw qa discord
|
||||
- `discord-canary`
|
||||
- `discord-mention-gating`
|
||||
- `discord-native-help-command-registration`
|
||||
- `discord-status-reactions-tool-only` — opt-in Mantis 시나리오입니다. SUT를 `messages.statusReactions.enabled=true`가 설정된 always-on, tool-only guild reply로 전환한 뒤 REST reaction timeline과 HTML/PNG 시각 아티팩트를 캡처하기 때문에 단독으로 실행됩니다.
|
||||
- `discord-status-reactions-tool-only` — 옵트인 Mantis 시나리오입니다. SUT를 항상 켜진 도구 전용 길드 응답으로 전환하고 `messages.statusReactions.enabled=true`를 설정한 뒤, REST 반응 타임라인과 HTML/PNG 시각적 아티팩트를 캡처하므로 단독으로 실행됩니다.
|
||||
|
||||
Mantis status-reaction 시나리오를 명시적으로 실행합니다.
|
||||
Mantis 상태 반응 시나리오를 명시적으로 실행합니다.
|
||||
|
||||
```bash
|
||||
pnpm openclaw qa discord \
|
||||
@ -268,134 +268,153 @@ pnpm openclaw qa discord \
|
||||
|
||||
- `discord-qa-report.md`
|
||||
- `discord-qa-summary.json`
|
||||
- `discord-qa-observed-messages.json` — `OPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1`이 아니면 본문이 삭제됩니다.
|
||||
- status-reaction 시나리오가 실행될 때 `discord-qa-reaction-timelines.json` 및 `discord-status-reactions-tool-only-timeline.png`.
|
||||
- `discord-qa-observed-messages.json` — `OPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1`이 아니면 본문은 비식별 처리됩니다.
|
||||
- 상태 반응 시나리오가 실행될 때 `discord-qa-reaction-timelines.json` 및 `discord-status-reactions-tool-only-timeline.png`.
|
||||
|
||||
### Slack QA
|
||||
|
||||
```bash
|
||||
pnpm openclaw qa slack
|
||||
```
|
||||
|
||||
두 개의 서로 다른 봇이 있는 실제 비공개 Slack 채널 하나를 대상으로 합니다. 하나는 하네스가 제어하는 driver 봇이고, 다른 하나는 번들 Slack Plugin을 통해 자식 OpenClaw Gateway가 시작하는 SUT 봇입니다.
|
||||
|
||||
`--credential-source env`일 때 필요한 env:
|
||||
|
||||
- `OPENCLAW_QA_SLACK_CHANNEL_ID`
|
||||
- `OPENCLAW_QA_SLACK_DRIVER_BOT_TOKEN`
|
||||
- `OPENCLAW_QA_SLACK_SUT_BOT_TOKEN`
|
||||
- `OPENCLAW_QA_SLACK_SUT_APP_TOKEN`
|
||||
|
||||
선택 사항:
|
||||
|
||||
- `OPENCLAW_QA_SLACK_CAPTURE_CONTENT=1`은 관찰된 메시지 아티팩트에 메시지 본문을 유지합니다.
|
||||
|
||||
시나리오(`extensions/qa-lab/src/live-transports/slack/slack-live.runtime.ts:39`):
|
||||
|
||||
- `slack-canary`
|
||||
- `slack-mention-gating`
|
||||
|
||||
출력 아티팩트:
|
||||
|
||||
- `slack-qa-report.md`
|
||||
- `slack-qa-summary.json`
|
||||
- `slack-qa-observed-messages.json` — `OPENCLAW_QA_SLACK_CAPTURE_CONTENT=1`이 아니면 본문은 비식별 처리됩니다.
|
||||
|
||||
### Convex 자격 증명 풀
|
||||
|
||||
Telegram 및 Discord lane은 위 env var를 읽는 대신 공유 Convex 풀에서 자격 증명을 임대할 수 있습니다. `--credential-source convex`를 전달하거나 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`를 설정하세요. QA Lab은 배타적 임대를 획득하고, 실행 동안 Heartbeat를 보내며, 종료 시 임대를 해제합니다. 풀 종류는 `"telegram"` 및 `"discord"`입니다.
|
||||
Telegram, Discord, Slack 레인은 위의 env vars를 읽는 대신 공유 Convex 풀에서 자격 증명을 임대할 수 있습니다. `--credential-source convex`를 전달하거나 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`를 설정하세요. QA Lab은 독점 임대를 획득하고 실행 중에는 Heartbeat를 보내며, 종료 시 임대를 해제합니다. 풀 종류는 `"telegram"`, `"discord"`, `"slack"`입니다.
|
||||
|
||||
브로커가 `admin/add`에서 검증하는 Payload 형태:
|
||||
브로커가 `admin/add`에서 검증하는 페이로드 형태:
|
||||
|
||||
- Telegram(`kind: "telegram"`): `{ groupId: string, driverToken: string, sutToken: string }` — `groupId`는 숫자 chat-id 문자열이어야 합니다.
|
||||
- Telegram(`kind: "telegram"`): `{ groupId: string, driverToken: string, sutToken: string }` — `groupId`는 숫자 채팅 ID 문자열이어야 합니다.
|
||||
- Discord(`kind: "discord"`): `{ guildId: string, channelId: string, driverBotToken: string, sutBotToken: string, sutApplicationId: string }`.
|
||||
|
||||
운영 env var와 Convex 브로커 endpoint 계약은 [테스트 → Convex를 통한 공유 Telegram 자격 증명](/ko/help/testing#shared-telegram-credentials-via-convex-v1)에 있습니다(섹션 이름은 Discord 지원보다 앞서 만들어졌지만, 브로커 의미 체계는 두 종류 모두 동일합니다).
|
||||
운영 env vars와 Convex 브로커 엔드포인트 계약은 [테스트 → Convex를 통한 공유 Telegram 자격 증명](/ko/help/testing#shared-telegram-credentials-via-convex-v1)에 있습니다. 섹션 이름은 Discord 지원보다 먼저 만들어졌지만, 브로커 의미론은 두 종류 모두 동일합니다.
|
||||
|
||||
## 저장소 기반 seed
|
||||
## 저장소 기반 시드
|
||||
|
||||
Seed asset은 `qa/`에 있습니다.
|
||||
시드 자산은 `qa/`에 있습니다.
|
||||
|
||||
- `qa/scenarios/index.md`
|
||||
- `qa/scenarios/<theme>/*.md`
|
||||
|
||||
이 항목들은 QA 계획이 사람과 agent 모두에게 보이도록 의도적으로 git에 포함되어 있습니다.
|
||||
이 파일들은 의도적으로 git에 포함되어 QA 계획이 사람과 에이전트 모두에게 보이도록 합니다.
|
||||
|
||||
`qa-lab`은 generic markdown runner로 유지되어야 합니다. 각 scenario markdown 파일은
|
||||
하나의 테스트 실행에 대한 source of truth이며 다음을 정의해야 합니다.
|
||||
`qa-lab`은 일반적인 Markdown 실행기로 유지해야 합니다. 각 시나리오 Markdown 파일은 하나의 테스트 실행에 대한 신뢰할 수 있는 원천이어야 하며 다음을 정의해야 합니다.
|
||||
|
||||
- 시나리오 메타데이터
|
||||
- 선택적 category, capability, lane 및 risk 메타데이터
|
||||
- docs 및 code refs
|
||||
- 선택적 카테고리, 기능, 레인, 위험 메타데이터
|
||||
- 문서 및 코드 참조
|
||||
- 선택적 Plugin 요구 사항
|
||||
- 선택적 gateway config patch
|
||||
- 선택적 Gateway 설정 패치
|
||||
- 실행 가능한 `qa-flow`
|
||||
|
||||
`qa-flow`를 뒷받침하는 재사용 가능한 runtime surface는 generic 및 cross-cutting으로
|
||||
유지될 수 있습니다. 예를 들어, markdown 시나리오는 특별한 case runner를 추가하지 않고도
|
||||
Gateway `browser.request` seam을 통해 임베드된 Control UI를 구동하는 browser-side helper와
|
||||
transport-side helper를 조합할 수 있습니다.
|
||||
`qa-flow`를 뒷받침하는 재사용 가능한 런타임 표면은 일반적이고 교차 영역으로 유지될 수 있습니다. 예를 들어 Markdown 시나리오는 Gateway `browser.request` 경계면을 통해 내장 Control UI를 구동하는 브라우저 측 헬퍼와 트랜스포트 측 헬퍼를 결합할 수 있으며, 이를 위해 특수 사례 실행기를 추가할 필요는 없습니다.
|
||||
|
||||
시나리오 파일은 source tree 폴더가 아니라 제품 capability별로 그룹화해야 합니다.
|
||||
파일이 이동하더라도 시나리오 ID는 안정적으로 유지하세요. 구현 추적성에는 `docsRefs` 및 `codeRefs`를 사용하세요.
|
||||
시나리오 파일은 소스 트리 폴더가 아니라 제품 기능별로 그룹화해야 합니다. 파일이 이동해도 시나리오 ID를 안정적으로 유지하세요. 구현 추적 가능성을 위해 `docsRefs`와 `codeRefs`를 사용하세요.
|
||||
|
||||
baseline 목록은 다음을 다룰 수 있을 만큼 넓게 유지해야 합니다.
|
||||
기준 목록은 다음을 다룰 만큼 충분히 넓게 유지해야 합니다.
|
||||
|
||||
- DM 및 channel chat
|
||||
- thread behavior
|
||||
- message action lifecycle
|
||||
- cron callbacks
|
||||
- memory recall
|
||||
- model switching
|
||||
- subagent handoff
|
||||
- repo-reading 및 docs-reading
|
||||
- Lobster Invaders 같은 작은 build task 하나
|
||||
- DM 및 채널 채팅
|
||||
- 스레드 동작
|
||||
- 메시지 작업 수명 주기
|
||||
- Cron 콜백
|
||||
- 메모리 회상
|
||||
- 모델 전환
|
||||
- 하위 에이전트 인계
|
||||
- 저장소 읽기 및 문서 읽기
|
||||
- Lobster Invaders 같은 작은 빌드 작업 하나
|
||||
|
||||
## Provider mock lanes
|
||||
## 프로바이더 목 레인
|
||||
|
||||
`qa suite`에는 두 개의 local provider mock lane이 있습니다.
|
||||
`qa suite`에는 두 개의 로컬 프로바이더 목 레인이 있습니다.
|
||||
|
||||
- `mock-openai`는 시나리오 인식 OpenClaw mock입니다. 저장소 기반 QA 및 parity gate를 위한
|
||||
기본 deterministic mock lane으로 유지됩니다.
|
||||
- `aimock`은 experimental protocol, fixture, record/replay 및 chaos coverage를 위해
|
||||
AIMock 기반 provider server를 시작합니다. 이는 additive이며 `mock-openai` 시나리오 dispatcher를
|
||||
대체하지 않습니다.
|
||||
- `mock-openai`는 시나리오 인식 OpenClaw 목입니다. 저장소 기반 QA와 패리티 게이트를 위한 기본 결정적 목 레인으로 유지됩니다.
|
||||
- `aimock`은 실험적 프로토콜, 픽스처, 기록/재생, 카오스 커버리지를 위해 AIMock 기반 프로바이더 서버를 시작합니다. 이는 추가적인 것이며 `mock-openai` 시나리오 디스패처를 대체하지 않습니다.
|
||||
|
||||
Provider-lane 구현은 `extensions/qa-lab/src/providers/` 아래에 있습니다.
|
||||
각 provider는 자체 기본값, local server startup, gateway model config,
|
||||
auth-profile staging 요구 사항, live/mock capability flag를 소유합니다. Shared suite 및
|
||||
gateway code는 provider name으로 분기하는 대신 provider registry를 통해 route해야 합니다.
|
||||
프로바이더 레인 구현은 `extensions/qa-lab/src/providers/` 아래에 있습니다. 각 프로바이더는 자체 기본값, 로컬 서버 시작, Gateway 모델 설정, 인증 프로필 스테이징 요구 사항, 라이브/목 기능 플래그를 소유합니다. 공유 스위트와 Gateway 코드는 프로바이더 이름으로 분기하는 대신 프로바이더 레지스트리를 통해 라우팅해야 합니다.
|
||||
|
||||
## Transport adapter
|
||||
## 트랜스포트 어댑터
|
||||
|
||||
`qa-lab`은 markdown QA 시나리오를 위한 generic transport seam을 소유합니다. `qa-channel`은 해당 seam의 첫 번째 adapter이지만, 설계 목표는 더 넓습니다. 향후 실제 또는 synthetic channel은 transport-specific QA runner를 추가하는 대신 동일한 suite runner에 연결되어야 합니다.
|
||||
`qa-lab`은 Markdown QA 시나리오를 위한 일반 트랜스포트 경계면을 소유합니다. `qa-channel`은 해당 경계면의 첫 번째 어댑터이지만, 설계 대상은 더 넓습니다. 향후 실제 또는 합성 채널은 트랜스포트별 QA 실행기를 추가하는 대신 동일한 스위트 실행기에 연결되어야 합니다.
|
||||
|
||||
architecture 수준에서 분리는 다음과 같습니다.
|
||||
아키텍처 수준에서 분리는 다음과 같습니다.
|
||||
|
||||
- `qa-lab`은 generic scenario execution, worker concurrency, artifact writing 및 reporting을 소유합니다.
|
||||
- transport adapter는 gateway config, readiness, inbound 및 outbound observation, transport actions, normalized transport state를 소유합니다.
|
||||
- `qa/scenarios/` 아래의 markdown scenario file은 테스트 실행을 정의하고, `qa-lab`은 이를 실행하는 재사용 가능한 runtime surface를 제공합니다.
|
||||
- `qa-lab`은 일반 시나리오 실행, 워커 동시성, 아티팩트 기록, 보고를 소유합니다.
|
||||
- 트랜스포트 어댑터는 Gateway 설정, 준비 상태, 인바운드 및 아웃바운드 관찰, 트랜스포트 작업, 정규화된 트랜스포트 상태를 소유합니다.
|
||||
- `qa/scenarios/` 아래의 Markdown 시나리오 파일은 테스트 실행을 정의합니다. `qa-lab`은 이를 실행하는 재사용 가능한 런타임 표면을 제공합니다.
|
||||
|
||||
### Channel 추가
|
||||
### 채널 추가
|
||||
|
||||
markdown QA system에 channel을 추가하려면 정확히 두 가지가 필요합니다.
|
||||
Markdown QA 시스템에 채널을 추가하려면 정확히 두 가지가 필요합니다.
|
||||
|
||||
1. channel용 transport adapter.
|
||||
2. channel contract를 실행하는 scenario pack.
|
||||
1. 해당 채널의 트랜스포트 어댑터.
|
||||
2. 채널 계약을 실행하는 시나리오 팩.
|
||||
|
||||
공유 `qa-lab` host가 flow를 소유할 수 있을 때 새 top-level QA command root를 추가하지 마세요.
|
||||
공유 `qa-lab` 호스트가 흐름을 소유할 수 있을 때는 새 최상위 QA 명령 루트를 추가하지 마세요.
|
||||
|
||||
`qa-lab`은 공유 host mechanics를 소유합니다.
|
||||
`qa-lab`은 공유 호스트 메커니즘을 소유합니다.
|
||||
|
||||
- `openclaw qa` command root
|
||||
- suite startup 및 teardown
|
||||
- worker concurrency
|
||||
- artifact writing
|
||||
- report generation
|
||||
- scenario execution
|
||||
- 이전 `qa-channel` 시나리오를 위한 compatibility alias
|
||||
- `openclaw qa` 명령 루트
|
||||
- 스위트 시작 및 종료
|
||||
- 워커 동시성
|
||||
- 아티팩트 기록
|
||||
- 보고서 생성
|
||||
- 시나리오 실행
|
||||
- 이전 `qa-channel` 시나리오에 대한 호환성 별칭
|
||||
|
||||
Runner Plugin은 transport contract를 소유합니다.
|
||||
실행기 Plugin은 트랜스포트 계약을 소유합니다.
|
||||
|
||||
- 공유 `qa` root 아래에 `openclaw qa <runner>`가 mount되는 방식
|
||||
- 해당 transport용 gateway가 구성되는 방식
|
||||
- readiness가 확인되는 방식
|
||||
- inbound event가 inject되는 방식
|
||||
- outbound message가 관찰되는 방식
|
||||
- transcript 및 normalized transport state가 노출되는 방식
|
||||
- transport-backed action이 실행되는 방식
|
||||
- transport-specific reset 또는 cleanup이 처리되는 방식
|
||||
- `openclaw qa <runner>`가 공유 `qa` 루트 아래에 마운트되는 방식
|
||||
- 해당 트랜스포트에 맞게 Gateway가 설정되는 방식
|
||||
- 준비 상태를 확인하는 방식
|
||||
- 인바운드 이벤트를 주입하는 방식
|
||||
- 아웃바운드 메시지를 관찰하는 방식
|
||||
- 트랜스크립트와 정규화된 트랜스포트 상태를 노출하는 방식
|
||||
- 트랜스포트 기반 작업을 실행하는 방식
|
||||
- 트랜스포트별 재설정 또는 정리를 처리하는 방식
|
||||
|
||||
새 channel의 최소 adoption 기준:
|
||||
새 채널의 최소 채택 기준:
|
||||
|
||||
1. 공유 `qa` root의 소유자로 `qa-lab`을 유지합니다.
|
||||
2. 공유 `qa-lab` host seam에서 transport runner를 구현합니다.
|
||||
3. transport-specific mechanics는 runner Plugin 또는 channel harness 내부에 유지합니다.
|
||||
4. 경쟁 root command를 등록하는 대신 runner를 `openclaw qa <runner>`로 mount합니다. Runner Plugin은 `openclaw.plugin.json`에서 `qaRunners`를 선언하고, `runtime-api.ts`에서 일치하는 `qaRunnerCliRegistrations` array를 export해야 합니다. `runtime-api.ts`는 가볍게 유지하세요. lazy CLI 및 runner execution은 별도 entrypoint 뒤에 있어야 합니다.
|
||||
5. 테마별 `qa/scenarios/` directory 아래에서 markdown scenario를 작성하거나 조정합니다.
|
||||
6. 새 시나리오에는 generic scenario helper를 사용합니다.
|
||||
7. 저장소가 의도적 migration을 수행하는 경우가 아니라면 기존 compatibility alias가 계속 동작하도록 유지합니다.
|
||||
1. 공유 `qa` 루트의 소유자는 `qa-lab`으로 유지합니다.
|
||||
2. 공유 `qa-lab` 호스트 seam에 전송 러너를 구현합니다.
|
||||
3. 전송별 메커니즘은 러너 Plugin 또는 채널 하네스 내부에 유지합니다.
|
||||
4. 경쟁 루트 명령을 등록하는 대신 러너를 `openclaw qa <runner>`로 마운트합니다. 러너 Plugin은 `openclaw.plugin.json`에서 `qaRunners`를 선언하고 `runtime-api.ts`에서 일치하는 `qaRunnerCliRegistrations` 배열을 내보내야 합니다. `runtime-api.ts`는 가볍게 유지하세요. 지연 CLI와 러너 실행은 별도 엔트리포인트 뒤에 있어야 합니다.
|
||||
5. 테마별 `qa/scenarios/` 디렉터리 아래에 Markdown 시나리오를 작성하거나 조정합니다.
|
||||
6. 새 시나리오에는 일반 시나리오 헬퍼를 사용합니다.
|
||||
7. 저장소가 의도적인 마이그레이션을 진행 중인 경우가 아니라면 기존 호환성 별칭이 계속 작동하도록 유지합니다.
|
||||
|
||||
결정 규칙은 엄격합니다.
|
||||
판단 규칙은 엄격합니다.
|
||||
|
||||
- 동작을 `qa-lab`에서 한 번 표현할 수 있으면 `qa-lab`에 넣으세요.
|
||||
- 동작이 하나의 channel transport에 의존하면 해당 runner Plugin 또는 Plugin harness에 유지하세요.
|
||||
- 시나리오에 여러 channel이 사용할 수 있는 새 capability가 필요하면 `suite.ts`에 channel-specific branch를 추가하는 대신 generic helper를 추가하세요.
|
||||
- 동작이 하나의 transport에만 의미가 있다면 시나리오를 transport-specific으로 유지하고 scenario contract에서 이를 명시하세요.
|
||||
- 동작을 `qa-lab`에서 한 번만 표현할 수 있다면 `qa-lab`에 넣습니다.
|
||||
- 동작이 하나의 채널 전송에 의존한다면 해당 러너 Plugin 또는 Plugin 하네스에 유지합니다.
|
||||
- 시나리오에 둘 이상의 채널에서 사용할 수 있는 새 기능이 필요하다면 `suite.ts`에 채널별 분기를 추가하는 대신 일반 헬퍼를 추가합니다.
|
||||
- 동작이 하나의 전송에서만 의미가 있다면 시나리오를 전송별로 유지하고 시나리오 계약에서 이를 명시합니다.
|
||||
|
||||
### Scenario helper name
|
||||
### 시나리오 헬퍼 이름
|
||||
|
||||
새 시나리오에 권장되는 generic helper:
|
||||
새 시나리오에 권장되는 일반 헬퍼:
|
||||
|
||||
- `waitForTransportReady`
|
||||
- `waitForChannelReady`
|
||||
@ -410,7 +429,7 @@ Runner Plugin은 transport contract를 소유합니다.
|
||||
- `formatTransportTranscript`
|
||||
- `resetTransport`
|
||||
|
||||
기존 시나리오를 위해 호환성 별칭인 `waitForQaChannelReady`, `waitForOutboundMessage`, `waitForNoOutbound`, `formatConversationTranscript`, `resetBus`는 계속 사용할 수 있지만, 새 시나리오 작성에는 일반 이름을 사용해야 합니다. 별칭은 앞으로의 모델이 아니라 일괄 마이그레이션을 피하기 위해 존재합니다.
|
||||
기존 시나리오를 위해 호환성 별칭인 `waitForQaChannelReady`, `waitForOutboundMessage`, `waitForNoOutbound`, `formatConversationTranscript`, `resetBus`도 계속 사용할 수 있습니다. 하지만 새 시나리오 작성에는 일반 이름을 사용해야 합니다. 이 별칭은 일괄 마이그레이션을 피하기 위해 존재하는 것이지, 앞으로의 모델로 쓰기 위한 것이 아닙니다.
|
||||
|
||||
## 보고
|
||||
|
||||
@ -419,13 +438,13 @@ Runner Plugin은 transport contract를 소유합니다.
|
||||
|
||||
- 작동한 것
|
||||
- 실패한 것
|
||||
- 차단된 상태로 남은 것
|
||||
- 계속 차단된 것
|
||||
- 추가할 가치가 있는 후속 시나리오
|
||||
|
||||
사용 가능한 시나리오 목록은 후속 작업 규모를 산정하거나 새 전송 방식을 연결할 때 유용하며, 확인하려면 `pnpm openclaw qa coverage`를 실행하세요(기계가 읽을 수 있는 출력을 원하면 `--json` 추가).
|
||||
사용 가능한 시나리오 목록을 확인하려면, 즉 후속 작업의 규모를 산정하거나 새 전송을 연결할 때 유용한 목록을 보려면 `pnpm openclaw qa coverage`를 실행하세요. 기계가 읽을 수 있는 출력이 필요하면 `--json`을 추가합니다.
|
||||
|
||||
문자와 스타일 검사를 위해, 동일한 시나리오를 여러 라이브 모델
|
||||
참조에서 실행하고 평가된 Markdown 보고서를 작성하세요.
|
||||
문자와 스타일 검사를 위해 동일한 시나리오를 여러 라이브 모델
|
||||
ref에서 실행하고 판정된 Markdown 보고서를 작성합니다.
|
||||
|
||||
```bash
|
||||
pnpm openclaw qa character-eval \
|
||||
@ -445,26 +464,24 @@ pnpm openclaw qa character-eval \
|
||||
```
|
||||
|
||||
이 명령은 Docker가 아니라 로컬 QA Gateway 자식 프로세스를 실행합니다. 문자 평가
|
||||
시나리오는 `SOUL.md`를 통해 페르소나를 설정한 다음 채팅, 작업공간 도움말, 작은 파일 작업 같은 일반 사용자 턴을 실행해야 합니다. 후보 모델에는 평가 중이라는 사실을 알려서는 안 됩니다. 이 명령은 각 전체
|
||||
트랜스크립트를 보존하고 기본 실행 통계를 기록한 다음, 지원되는 경우 `xhigh` 추론과 빠른 모드로 judge 모델에 실행 결과의 자연스러움, 분위기, 유머를 기준으로 순위를 매기도록 요청합니다.
|
||||
제공자를 비교할 때는 `--blind-judge-models`를 사용하세요. judge 프롬프트는 여전히 모든 트랜스크립트와 실행 상태를 받지만, 후보 참조는 `candidate-01` 같은 중립 레이블로 대체됩니다. 보고서는 파싱 후 순위를 실제 참조에 다시 매핑합니다.
|
||||
후보 실행은 기본적으로 `high` thinking을 사용하며, GPT-5.5에는 `medium`, 이를 지원하는 이전 OpenAI 평가 참조에는 `xhigh`를 사용합니다. 특정 후보를 인라인으로 재정의하려면
|
||||
`--model provider/model,thinking=<level>`을 사용하세요. `--thinking <level>`은 여전히 전역 폴백을 설정하며, 이전 `--model-thinking <provider/model=level>` 형식은 호환성을 위해 유지됩니다.
|
||||
OpenAI 후보 참조는 기본적으로 빠른 모드를 사용하므로 제공자가 지원하는 경우 우선 처리가 사용됩니다. 단일 후보나 judge에 재정의가 필요하면 인라인으로 `,fast`, `,no-fast`, 또는 `,fast=false`를 추가하세요. 모든 후보 모델에 빠른 모드를 강제로 켜려는 경우에만 `--fast`를 전달하세요. 후보와 judge의 소요 시간은 벤치마크 분석을 위해 보고서에 기록되지만, judge 프롬프트는 속도로 순위를 매기지 말라고 명시합니다.
|
||||
후보와 judge 모델 실행은 모두 기본 동시성 16을 사용합니다. 제공자 제한이나 로컬 Gateway
|
||||
부하로 인해 실행에 잡음이 너무 많아지면 `--concurrency` 또는 `--judge-concurrency`를 낮추세요.
|
||||
후보 `--model`이 전달되지 않으면 문자 평가는 기본적으로
|
||||
시나리오는 `SOUL.md`를 통해 페르소나를 설정한 다음, 채팅, workspace 도움말, 작은 파일 작업 같은 일반 사용자 턴을 실행해야 합니다. 후보 모델에는 평가 중이라는 사실을 알려서는 안 됩니다. 이 명령은 각 전체
|
||||
transcript를 보존하고 기본 실행 통계를 기록한 뒤, 지원되는 경우 `xhigh` 추론을 사용해 fast 모드의 judge 모델에 자연스러움, vibe, 유머 기준으로 실행 순위를 매기도록 요청합니다.
|
||||
제공자를 비교할 때는 `--blind-judge-models`를 사용하세요. judge 프롬프트는 여전히 모든 transcript와 실행 상태를 받지만, 후보 ref는 `candidate-01` 같은 중립 레이블로 대체됩니다. 보고서는 파싱 후 순위를 실제 ref에 다시 매핑합니다.
|
||||
후보 실행은 기본적으로 `high` thinking을 사용하며, GPT-5.5에는 `medium`, 이를 지원하는 이전 OpenAI 평가 ref에는 `xhigh`를 사용합니다. 특정 후보는 `--model provider/model,thinking=<level>`로 인라인 재정의하세요. `--thinking <level>`은 여전히 전역 fallback을 설정하며, 이전 `--model-thinking <provider/model=level>` 형식은 호환성을 위해 유지됩니다.
|
||||
OpenAI 후보 ref는 기본적으로 fast 모드로 실행되어 제공자가 지원하는 경우 priority processing이 사용됩니다. 단일 후보 또는 judge에 재정의가 필요하면 인라인으로 `,fast`, `,no-fast`, `,fast=false`를 추가하세요. 모든 후보 모델에 fast 모드를 강제로 켜고 싶을 때만 `--fast`를 전달합니다. 후보와 judge 실행 시간은 benchmark 분석을 위해 보고서에 기록되지만, judge 프롬프트는 속도로 순위를 매기지 말라고 명시합니다.
|
||||
후보와 judge 모델 실행은 모두 기본 동시성 16을 사용합니다. 제공자 제한이나 로컬 Gateway 압력 때문에 실행이 너무 잡음이 많아지면 `--concurrency` 또는 `--judge-concurrency`를 낮추세요.
|
||||
후보 `--model`이 전달되지 않으면 character eval은
|
||||
`openai/gpt-5.5`, `openai/gpt-5.2`, `openai/gpt-5`, `anthropic/claude-opus-4-6`,
|
||||
`anthropic/claude-sonnet-4-6`, `zai/glm-5.1`,
|
||||
`moonshot/kimi-k2.5`, 그리고
|
||||
`google/gemini-3.1-pro-preview`를 사용합니다.
|
||||
`--judge-model`이 전달되지 않으면 judge는 기본적으로
|
||||
`google/gemini-3.1-pro-preview`를 기본값으로 사용합니다.
|
||||
`--judge-model`이 전달되지 않으면 judge 기본값은
|
||||
`openai/gpt-5.5,thinking=xhigh,fast`와
|
||||
`anthropic/claude-opus-4-6,thinking=high`를 사용합니다.
|
||||
`anthropic/claude-opus-4-6,thinking=high`입니다.
|
||||
|
||||
## 관련 문서
|
||||
|
||||
- [Matrix QA](/ko/concepts/qa-matrix)
|
||||
- [QA 채널](/ko/channels/qa-channel)
|
||||
- [테스트](/ko/help/testing)
|
||||
- [대시보드](/ko/web/dashboard)
|
||||
- [Dashboard](/ko/web/dashboard)
|
||||
|
||||
@ -1,23 +1,23 @@
|
||||
---
|
||||
read_when:
|
||||
- 에이전트가 도구를 사용하는 동안 조정이 어떻게 동작하는지 설명하기
|
||||
- 에이전트가 도구를 사용하는 동안 제어가 어떻게 동작하는지 설명
|
||||
- 활성 실행 큐 동작 또는 런타임 제어 통합 변경
|
||||
- steer, queue, collect, followup 모드 비교
|
||||
- steer, queue, collect 및 followup 모드 비교
|
||||
summary: 활성 실행 조정이 런타임 경계에서 메시지를 큐에 넣는 방식
|
||||
title: 조정 대기열
|
||||
x-i18n:
|
||||
generated_at: "2026-04-30T06:28:22Z"
|
||||
generated_at: "2026-05-04T02:23:20Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 560390c8c26bcce95e0137f4336ad6e62bc3e2344cb15fd12ca3cfe4a85a8acc
|
||||
source_hash: c8df35b127ae0c1e1b3b684a1f63ce33874eb3d0b7bf9d0df7cb9dfce093090a
|
||||
source_path: concepts/queue-steering.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
메시지가 도착했을 때 세션 실행이 이미 스트리밍 중이면, OpenClaw는
|
||||
이미 세션 실행이 스트리밍 중일 때 메시지가 도착하면 OpenClaw는
|
||||
같은 세션에 대해 다른 실행을 시작하는 대신 해당 메시지를 활성 런타임으로
|
||||
보낼 수 있습니다. 공개 모드는 런타임에 중립적이며, Pi와 네이티브 Codex
|
||||
앱 서버 하네스는 전달 세부 방식을 다르게 구현합니다.
|
||||
보낼 수 있습니다. 공개 모드는 런타임 중립적이며, Pi와 네이티브 Codex
|
||||
앱 서버 하네스는 전달 세부 사항을 서로 다르게 구현합니다.
|
||||
|
||||
## 런타임 경계
|
||||
|
||||
@ -28,69 +28,73 @@ x-i18n:
|
||||
2. Pi가 현재 어시스턴트 메시지의 도구 호출 배치를 실행합니다.
|
||||
3. Pi가 턴 종료 이벤트를 내보냅니다.
|
||||
4. Pi가 대기 중인 스티어링 메시지를 비웁니다.
|
||||
5. Pi가 다음 LLM 호출 전에 해당 메시지를 사용자 메시지로 추가합니다.
|
||||
5. Pi가 다음 LLM 호출 전에 해당 메시지들을 사용자 메시지로 추가합니다.
|
||||
|
||||
이렇게 하면 도구 결과가 이를 요청한 어시스턴트 메시지와 짝을 이루도록
|
||||
유지한 다음, 다음 모델 호출이 최신 사용자 입력을 볼 수 있습니다.
|
||||
이렇게 하면 도구 결과가 이를 요청한 어시스턴트 메시지와 함께 유지되고,
|
||||
그 다음 다음 모델 호출이 최신 사용자 입력을 볼 수 있습니다.
|
||||
|
||||
네이티브 Codex 앱 서버 하네스는 Pi의 내부 스티어링 큐 대신 `turn/steer`를
|
||||
노출합니다. OpenClaw는 같은 모드를 여기에 맞게 조정합니다.
|
||||
노출합니다. OpenClaw는 그곳에서도 같은 모드를 적용합니다.
|
||||
|
||||
- `steer`는 구성된 조용한 창 동안 대기 중인 메시지를 배치한 다음, 수집된
|
||||
모든 사용자 입력을 도착 순서대로 포함하는 단일 `turn/steer` 요청을 보냅니다.
|
||||
- `queue`는 별도의 `turn/steer` 요청을 보내 기존의 직렬화된 형태를 유지합니다.
|
||||
- `followup`, `collect`, `steer-backlog`, `interrupt`는 활성 Codex 턴 주변에서
|
||||
OpenClaw가 소유하는 큐 동작으로 유지됩니다.
|
||||
- `steer`는 구성된 조용한 창 동안 대기 중인 메시지를 배치로 모은 뒤,
|
||||
도착 순서대로 수집된 모든 사용자 입력을 포함하는 단일 `turn/steer` 요청을 보냅니다.
|
||||
- `queue`는 별도의 `turn/steer` 요청을 보내 기존 직렬화된 형태를 유지합니다.
|
||||
- `followup`, `collect`, `steer-backlog`, `interrupt`는 활성 Codex 턴 주변의
|
||||
OpenClaw 소유 큐 동작으로 유지됩니다.
|
||||
|
||||
Codex 검토 및 수동 Compaction 턴은 동일 턴 스티어링을 거부합니다. 런타임이
|
||||
스티어링을 수락할 수 없으면, OpenClaw는 해당 모드가 허용하는 경우 후속 큐로
|
||||
대체합니다.
|
||||
Codex 리뷰와 수동 Compaction 턴은 같은 턴 스티어링을 거부합니다. 런타임이
|
||||
스티어링을 수락할 수 없으면, 해당 모드가 허용하는 경우 OpenClaw는 후속 큐로
|
||||
폴백합니다.
|
||||
|
||||
이 페이지는 일반 인바운드 메시지에 대한 큐 모드 스티어링을 설명합니다. 명시적
|
||||
`/steer <message>` 명령은 [스티어링](/ko/tools/steer)을 참조하세요.
|
||||
|
||||
## 모드
|
||||
|
||||
| 모드 | 활성 실행 동작 | 이후 후속 동작 |
|
||||
| 모드 | 활성 실행 동작 | 이후 후속 동작 |
|
||||
| --------------- | ---------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
|
||||
| `steer` | 대기 중인 모든 스티어링 메시지를 다음 런타임 경계에서 함께 주입합니다. 이것이 기본값입니다. | 스티어링을 사용할 수 없을 때만 후속으로 대체합니다. |
|
||||
| `queue` | 기존의 한 번에 하나씩 처리하는 스티어링입니다. Pi는 모델 경계마다 대기 중인 메시지를 하나씩 주입하고, Codex는 별도의 `turn/steer` 요청을 보냅니다. | 스티어링을 사용할 수 없을 때만 후속으로 대체합니다. |
|
||||
| `steer-backlog` | `steer`와 동일한 활성 실행 스티어링 동작입니다. | 나중의 후속 턴을 위해 동일한 메시지도 유지합니다. |
|
||||
| `followup` | 현재 실행을 스티어링하지 않습니다. | 대기 중인 메시지를 나중에 실행합니다. |
|
||||
| `collect` | 현재 실행을 스티어링하지 않습니다. | 디바운스 창 이후 호환되는 대기 메시지를 하나의 나중 턴으로 병합합니다. |
|
||||
| `interrupt` | 활성 실행을 중단한 다음 가장 최신 메시지를 시작합니다. | 없음. |
|
||||
| `steer` | 다음 런타임 경계에서 대기 중인 모든 스티어링 메시지를 함께 주입합니다. 이것이 기본값입니다. | 스티어링을 사용할 수 없을 때만 후속으로 폴백합니다. |
|
||||
| `queue` | 기존 한 번에 하나씩 처리하는 스티어링입니다. Pi는 모델 경계마다 대기 중인 메시지 하나를 주입하고, Codex는 별도의 `turn/steer` 요청을 보냅니다. | 스티어링을 사용할 수 없을 때만 후속으로 폴백합니다. |
|
||||
| `steer-backlog` | `steer`와 동일한 활성 실행 스티어링 동작입니다. | 나중의 후속 턴을 위해 같은 메시지도 유지합니다. |
|
||||
| `followup` | 현재 실행을 스티어링하지 않습니다. | 대기 중인 메시지를 나중에 실행합니다. |
|
||||
| `collect` | 현재 실행을 스티어링하지 않습니다. | 디바운스 창 이후 호환되는 대기 메시지를 하나의 이후 턴으로 병합합니다. |
|
||||
| `interrupt` | 활성 실행을 중단한 뒤 최신 메시지를 시작합니다. | 없음. |
|
||||
|
||||
## 버스트 예시
|
||||
|
||||
에이전트가 도구 호출을 실행하는 동안 네 명의 사용자가 메시지를 보내면:
|
||||
에이전트가 도구 호출을 실행하는 동안 네 명의 사용자가 메시지를 보내면 다음과 같습니다.
|
||||
|
||||
- `steer`: 활성 런타임은 다음 모델 결정 전에 네 개의 메시지를 모두 도착 순서대로
|
||||
받습니다. Pi는 다음 모델 경계에서 이를 비우고, Codex는 하나의 배치된
|
||||
`turn/steer`로 이를 받습니다.
|
||||
- `queue`: 기존의 직렬화된 스티어링입니다. Pi는 대기 중인 메시지를 한 번에 하나씩
|
||||
- `steer`: 활성 런타임은 다음 모델 결정을 내리기 전에 네 메시지를 모두 도착 순서대로
|
||||
받습니다. Pi는 다음 모델 경계에서 이를 비우고, Codex는 하나의 배치된 `turn/steer`로
|
||||
받습니다.
|
||||
- `queue`: 기존 직렬화된 스티어링입니다. Pi는 대기 중인 메시지를 한 번에 하나씩
|
||||
주입하고, Codex는 별도의 `turn/steer` 요청을 받습니다.
|
||||
- `collect`: OpenClaw는 활성 실행이 끝날 때까지 기다린 다음, 디바운스 창 이후
|
||||
- `collect`: OpenClaw는 활성 실행이 끝날 때까지 기다린 뒤, 디바운스 창 이후
|
||||
호환되는 대기 메시지로 후속 턴을 만듭니다.
|
||||
|
||||
## 범위
|
||||
|
||||
스티어링은 항상 현재 활성 세션 실행을 대상으로 합니다. 새 세션을 만들거나,
|
||||
활성 실행의 도구 정책을 변경하거나, 메시지를 발신자별로 나누지 않습니다.
|
||||
다중 사용자 채널에서는 인바운드 프롬프트에 이미 발신자와 라우트 컨텍스트가
|
||||
포함되어 있으므로, 다음 모델 호출은 각 메시지를 누가 보냈는지 볼 수 있습니다.
|
||||
활성 실행의 도구 정책을 변경하거나, 발신자별로 메시지를 분할하지 않습니다.
|
||||
다중 사용자 채널에서는 인바운드 프롬프트에 이미 발신자와 라우팅 컨텍스트가 포함되므로,
|
||||
다음 모델 호출은 각 메시지를 누가 보냈는지 볼 수 있습니다.
|
||||
|
||||
OpenClaw가 호환되는 메시지를 병합하고 후속 큐 드롭 정책을 보존할 수 있는
|
||||
나중의 후속 턴을 만들도록 하려면 `collect`를 사용하세요. 이전의 한 번에 하나씩
|
||||
OpenClaw가 호환되는 메시지를 병합하고 후속 큐 삭제 정책을 보존할 수 있는
|
||||
이후 후속 턴을 만들게 하려면 `collect`를 사용하세요. 이전의 한 번에 하나씩
|
||||
처리하는 스티어링 동작이 필요할 때만 `queue`를 사용하세요.
|
||||
|
||||
## 디바운스
|
||||
|
||||
`messages.queue.debounceMs`는 `collect`, `followup`, `steer-backlog` 및
|
||||
활성 실행 스티어링을 사용할 수 없을 때의 `steer` 대체를 포함한 후속 전달에
|
||||
`messages.queue.debounceMs`는 `collect`, `followup`, `steer-backlog`, 그리고
|
||||
활성 실행 스티어링을 사용할 수 없을 때의 `steer` 폴백을 포함한 후속 전달에
|
||||
적용됩니다. Pi의 경우 활성 `steer` 자체는 디바운스 타이머를 사용하지 않습니다.
|
||||
Pi는 다음 모델 경계까지 메시지를 자연스럽게 배치하기 때문입니다. 네이티브
|
||||
Pi가 다음 모델 경계까지 메시지를 자연스럽게 배치 처리하기 때문입니다. 네이티브
|
||||
Codex 하네스의 경우 OpenClaw는 배치된 `turn/steer`를 보내기 전 조용한 창으로
|
||||
동일한 디바운스 값을 사용합니다.
|
||||
|
||||
## 관련 항목
|
||||
|
||||
- [명령 큐](/ko/concepts/queue)
|
||||
- [스티어링](/ko/tools/steer)
|
||||
- [메시지](/ko/concepts/messages)
|
||||
- [에이전트 루프](/ko/concepts/agent-loop)
|
||||
|
||||
@ -1,60 +1,60 @@
|
||||
---
|
||||
read_when:
|
||||
- 자동 응답 실행 또는 동시성 변경
|
||||
- /queue 모드 또는 메시지 라우팅 동작 설명
|
||||
summary: 자동 응답 큐 모드, 기본값 및 세션별 재정의
|
||||
- /queue 모드 또는 메시지 조정 동작 설명
|
||||
summary: 자동 답장 대기열 모드, 기본값 및 세션별 재정의
|
||||
title: 명령 대기열
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T20:48:52Z"
|
||||
generated_at: "2026-05-04T02:23:09Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: c59ea6802d8bf526f4005db3b1baa87d96a23d561c916f91520e8e641fbaf74f
|
||||
source_hash: 085aebe7059020f027eb08bb382cce2d253ea117eed0ca77d6ffd208f295acb1
|
||||
source_path: concepts/queue.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
인바운드 자동 응답 실행(모든 채널)을 작은 프로세스 내 큐를 통해 직렬화하여 여러 에이전트 실행이 충돌하지 않도록 하면서, 세션 간에는 안전한 병렬 처리를 계속 허용합니다.
|
||||
인바운드 자동 응답 실행(모든 채널)을 작은 프로세스 내부 큐를 통해 직렬화하여 여러 에이전트 실행이 충돌하지 않도록 하면서도, 세션 간에는 안전한 병렬 처리를 허용합니다.
|
||||
|
||||
## 이유
|
||||
|
||||
- 자동 응답 실행은 비용이 클 수 있으며(LLM 호출), 여러 인바운드 메시지가 짧은 간격으로 도착하면 충돌할 수 있습니다.
|
||||
- 직렬화하면 공유 리소스(세션 파일, 로그, CLI stdin)를 두고 경쟁하는 일을 피하고 업스트림 속도 제한 가능성을 줄일 수 있습니다.
|
||||
- 자동 응답 실행은 비용이 클 수 있고(LLM 호출), 여러 인바운드 메시지가 짧은 간격으로 도착하면 충돌할 수 있습니다.
|
||||
- 직렬화하면 공유 리소스(세션 파일, 로그, CLI stdin) 경합을 피하고 업스트림 속도 제한 가능성을 줄일 수 있습니다.
|
||||
|
||||
## 작동 방식
|
||||
|
||||
- 레인 인식 FIFO 큐는 설정 가능한 동시성 한도에 따라 각 레인을 비웁니다(설정되지 않은 레인의 기본값은 1, main 기본값은 4, subagent 기본값은 8).
|
||||
- 레인 인식 FIFO 큐가 구성 가능한 동시성 한도(구성되지 않은 레인의 기본값은 1, main 기본값은 4, subagent는 8)로 각 레인을 비웁니다.
|
||||
- `runEmbeddedPiAgent`는 **세션 키**(레인 `session:<key>`)별로 큐에 넣어 세션당 활성 실행이 하나만 있도록 보장합니다.
|
||||
- 그런 다음 각 세션 실행은 **전역 레인**(기본값 `main`)에 큐잉되어 전체 병렬성이 `agents.defaults.maxConcurrent`로 제한됩니다.
|
||||
- 자세한 로깅이 활성화된 경우, 큐에 들어간 실행은 시작 전 대기 시간이 약 2초를 넘으면 짧은 알림을 내보냅니다.
|
||||
- 입력 표시기는 큐에 넣는 즉시 계속 실행되므로(채널에서 지원하는 경우) 순서를 기다리는 동안에도 사용자 경험은 변하지 않습니다.
|
||||
- 그런 다음 각 세션 실행은 **전역 레인**(기본값은 `main`)에 큐잉되어 전체 병렬 처리가 `agents.defaults.maxConcurrent`로 제한됩니다.
|
||||
- 상세 로깅이 활성화되면, 큐에 들어간 실행이 시작 전 약 2초 넘게 대기한 경우 짧은 알림을 출력합니다.
|
||||
- 입력 표시기는 큐에 들어가는 즉시 계속 발생하므로(채널에서 지원하는 경우), 순서를 기다리는 동안에도 사용자 경험은 변경되지 않습니다.
|
||||
|
||||
## 기본값
|
||||
|
||||
설정되지 않은 경우, 모든 인바운드 채널 표면은 다음을 사용합니다.
|
||||
설정하지 않으면 모든 인바운드 채널 표면은 다음을 사용합니다.
|
||||
|
||||
- `mode: "steer"`
|
||||
- `debounceMs: 500`
|
||||
- `cap: 20`
|
||||
- `drop: "summarize"`
|
||||
|
||||
`steer`는 활성 모델 턴의 응답성을 유지하면서 두 번째 세션 실행을 시작하지 않기 때문에 기본값입니다. 다음 모델 경계 전에 도착한 모든 조향 메시지를 비웁니다. 현재 실행이 조향을 받을 수 없는 경우 OpenClaw는 후속 큐 항목으로 폴백합니다.
|
||||
`steer`가 기본값인 이유는 두 번째 세션 실행을 시작하지 않고도 활성 모델 턴의 응답성을 유지하기 때문입니다. 다음 모델 경계 전에 도착한 모든 스티어링 메시지를 비웁니다. 현재 실행이 스티어링을 받을 수 없으면 OpenClaw는 후속 큐 항목으로 폴백합니다.
|
||||
|
||||
## 큐 모드
|
||||
|
||||
인바운드 메시지는 현재 실행을 조향하거나, 후속 턴을 기다리거나, 둘 다 수행할 수 있습니다.
|
||||
인바운드 메시지는 현재 실행을 스티어링하거나, 후속 턴을 기다리거나, 둘 다 수행할 수 있습니다.
|
||||
|
||||
- `steer`: 조향 메시지를 활성 런타임에 큐잉합니다. Pi는 다음 LLM 호출 전에 **현재 어시스턴트 턴이 도구 호출 실행을 마친 뒤** 모든 대기 중인 조향 메시지를 전달합니다. Codex 앱 서버는 배치된 `turn/steer` 하나를 받습니다. 실행이 활성 스트리밍 중이 아니거나 조향을 사용할 수 없는 경우 OpenClaw는 후속 큐 항목으로 폴백합니다.
|
||||
- `queue`(레거시): 기존의 한 번에 하나씩 처리하는 조향입니다. Pi는 각 모델 경계에서 큐잉된 조향 메시지 하나를 전달합니다. Codex 앱 서버는 별도의 `turn/steer` 요청을 받습니다. 이전의 직렬화된 동작이 필요한 경우가 아니라면 `steer`를 권장합니다.
|
||||
- `steer`: 스티어링 메시지를 활성 런타임에 큐잉합니다. Pi는 **현재 assistant 턴이 도구 호출 실행을 마친 후**, 다음 LLM 호출 전에 대기 중인 모든 스티어링 메시지를 전달합니다. Codex app-server는 배치된 `turn/steer` 하나를 받습니다. 실행이 활발하게 스트리밍 중이 아니거나 스티어링을 사용할 수 없으면 OpenClaw는 후속 큐 항목으로 폴백합니다.
|
||||
- `queue`(레거시): 이전의 한 번에 하나씩 처리하는 스티어링입니다. Pi는 각 모델 경계에서 큐에 있는 스티어링 메시지 하나를 전달합니다. Codex app-server는 별도의 `turn/steer` 요청을 받습니다. 이전의 직렬화된 동작이 필요한 경우가 아니면 `steer`를 권장합니다.
|
||||
- `followup`: 현재 실행이 끝난 뒤 나중의 에이전트 턴을 위해 각 메시지를 큐에 넣습니다.
|
||||
- `collect`: 조용한 기간 이후 큐잉된 메시지를 **단일** 후속 턴으로 병합합니다. 메시지가 서로 다른 채널/스레드를 대상으로 하는 경우 라우팅을 보존하기 위해 개별적으로 비워집니다.
|
||||
- `steer-backlog`(`steer+backlog`라고도 함): 지금 조향하고 **동시에** 같은 메시지를 후속 턴용으로 보존합니다.
|
||||
- `collect`: 조용한 구간 이후 큐에 있는 메시지를 **하나의** 후속 턴으로 병합합니다. 메시지가 서로 다른 채널/스레드를 대상으로 하면 라우팅을 보존하기 위해 개별적으로 비웁니다.
|
||||
- `steer-backlog`(`steer+backlog`라고도 함): 지금 스티어링하고 **동시에** 같은 메시지를 후속 턴용으로 보존합니다.
|
||||
- `interrupt`(레거시): 해당 세션의 활성 실행을 중단한 다음 최신 메시지를 실행합니다.
|
||||
|
||||
Steer-backlog를 사용하면 조향된 실행 이후 후속 응답을 받을 수 있으므로 스트리밍 표면에서는 중복처럼 보일 수 있습니다. 인바운드 메시지당 하나의 응답을 원한다면 `collect`/`steer`를 권장합니다.
|
||||
Steer-backlog는 스티어링된 실행 후 후속 응답을 받을 수 있음을 의미하므로 스트리밍 표면에서는 중복처럼 보일 수 있습니다. 인바운드 메시지당 응답 하나를 원하면 `collect`/`steer`를 권장합니다.
|
||||
|
||||
런타임별 타이밍 및 의존성 동작은 [조향 큐](/ko/concepts/queue-steering)를 참조하세요.
|
||||
런타임별 타이밍 및 의존성 동작은 [스티어링 큐](/ko/concepts/queue-steering)를 참조하세요. 명시적 `/steer <message>` 명령은 [스티어링](/ko/tools/steer)을 참조하세요.
|
||||
|
||||
`messages.queue`를 통해 전역 또는 채널별로 설정합니다.
|
||||
`messages.queue`를 통해 전역 또는 채널별로 구성합니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -72,12 +72,12 @@ Steer-backlog를 사용하면 조향된 실행 이후 후속 응답을 받을
|
||||
|
||||
## 큐 옵션
|
||||
|
||||
옵션은 `followup`, `collect`, `steer-backlog`에 적용됩니다(그리고 조향이 후속으로 폴백하는 경우 `steer` 또는 레거시 `queue`에도 적용됩니다).
|
||||
옵션은 `followup`, `collect`, `steer-backlog`에 적용됩니다(스티어링이 후속 항목으로 폴백하는 경우 `steer` 또는 레거시 `queue`에도 적용됨).
|
||||
|
||||
- `debounceMs`: 큐잉된 후속 항목을 비우기 전 조용한 기간입니다. 단위 없는 숫자는 밀리초이며, `/queue` 옵션은 `ms`, `s`, `m`, `h`, `d` 단위를 허용합니다.
|
||||
- `cap`: 세션당 큐잉 가능한 최대 메시지 수입니다. `1`보다 작은 값은 무시됩니다.
|
||||
- `drop: "summarize"`: 기본값입니다. 필요에 따라 가장 오래된 큐 항목을 버리고, 압축된 요약을 보관한 뒤 합성 후속 프롬프트로 주입합니다.
|
||||
- `drop: "old"`: 필요에 따라 가장 오래된 큐 항목을 버리며, 요약은 보존하지 않습니다.
|
||||
- `debounceMs`: 큐에 있는 후속 항목을 비우기 전의 조용한 구간입니다. 단위 없는 숫자는 밀리초입니다. `/queue` 옵션에서는 `ms`, `s`, `m`, `h`, `d` 단위를 사용할 수 있습니다.
|
||||
- `cap`: 세션당 큐에 넣을 수 있는 최대 메시지 수입니다. `1` 미만 값은 무시됩니다.
|
||||
- `drop: "summarize"`: 기본값입니다. 필요에 따라 가장 오래된 큐 항목을 삭제하고, 압축 요약을 보관한 뒤 합성 후속 프롬프트로 주입합니다.
|
||||
- `drop: "old"`: 필요에 따라 가장 오래된 큐 항목을 삭제하되, 요약은 보존하지 않습니다.
|
||||
- `drop: "new"`: 큐가 이미 가득 찬 경우 최신 메시지를 거부합니다.
|
||||
|
||||
기본값: `debounceMs: 500`, `cap: 20`, `drop: summarize`.
|
||||
@ -91,31 +91,32 @@ Steer-backlog를 사용하면 조향된 실행 이후 후속 응답을 받을
|
||||
3. `messages.queue.mode`.
|
||||
4. 기본값 `steer`.
|
||||
|
||||
옵션의 경우 인라인 또는 저장된 `/queue` 옵션이 설정보다 우선합니다. 그런 다음 채널별 디바운스(`messages.queue.debounceMsByChannel`), Plugin 디바운스 기본값, 전역 `messages.queue` 옵션, 내장 기본값이 적용됩니다. `cap`과 `drop`은 전역/세션 옵션이며 채널별 설정 키가 아닙니다.
|
||||
옵션의 경우 인라인 또는 저장된 `/queue` 옵션이 구성보다 우선합니다. 그런 다음 채널별 debounce(`messages.queue.debounceMsByChannel`), Plugin debounce 기본값, 전역 `messages.queue` 옵션, 내장 기본값이 적용됩니다. `cap`과 `drop`은 전역/세션 옵션이며, 채널별 구성 키가 아닙니다.
|
||||
|
||||
## 세션별 재정의
|
||||
|
||||
- 현재 세션의 모드를 저장하려면 `/queue <mode>`를 독립 실행 명령으로 보냅니다.
|
||||
- 옵션은 조합할 수 있습니다: `/queue collect debounce:0.5s cap:25 drop:summarize`
|
||||
- 현재 세션의 모드를 저장하려면 `/queue <mode>`를 독립 실행형 명령으로 보냅니다.
|
||||
- 옵션은 조합할 수 있습니다. `/queue collect debounce:0.5s cap:25 drop:summarize`
|
||||
- `/queue default` 또는 `/queue reset`은 세션 재정의를 지웁니다.
|
||||
|
||||
## 범위와 보장
|
||||
## 범위 및 보장
|
||||
|
||||
- Gateway 응답 파이프라인을 사용하는 모든 인바운드 채널의 자동 응답 에이전트 실행에 적용됩니다(WhatsApp 웹, Telegram, Slack, Discord, Signal, iMessage, 웹챗 등).
|
||||
- 기본 레인(`main`)은 인바운드 + main Heartbeat에 대해 프로세스 전체에 적용됩니다. 여러 세션을 병렬로 허용하려면 `agents.defaults.maxConcurrent`를 설정하세요.
|
||||
- 추가 레인이 존재할 수 있으므로(예: `cron`, `cron-nested`, `nested`, `subagent`) 백그라운드 작업은 인바운드 응답을 차단하지 않고 병렬로 실행될 수 있습니다. 격리된 cron 에이전트 턴은 내부 에이전트 실행이 `cron-nested`를 사용하는 동안 `cron` 슬롯을 보유합니다. 둘 다 `cron.maxConcurrentRuns`를 사용합니다. 공유 비 cron `nested` 흐름은 자체 레인 동작을 유지합니다. 이러한 분리된 실행은 [백그라운드 작업](/ko/automation/tasks)으로 추적됩니다.
|
||||
- Gateway 응답 파이프라인을 사용하는 모든 인바운드 채널(WhatsApp web, Telegram, Slack, Discord, Signal, iMessage, webchat 등)의 자동 응답 에이전트 실행에 적용됩니다.
|
||||
- 기본 레인(`main`)은 인바운드 및 기본 Heartbeat에 대해 프로세스 전체에서 공유됩니다. 여러 세션을 병렬로 허용하려면 `agents.defaults.maxConcurrent`를 설정하세요.
|
||||
- 추가 레인(예: `cron`, `cron-nested`, `nested`, `subagent`)이 있을 수 있으므로 백그라운드 작업은 인바운드 응답을 차단하지 않고 병렬로 실행될 수 있습니다. 격리된 Cron 에이전트 턴은 내부 에이전트 실행이 `cron-nested`를 사용하는 동안 `cron` 슬롯을 보유합니다. 둘 다 `cron.maxConcurrentRuns`를 사용합니다. 공유되는 비-Cron `nested` 흐름은 자체 레인 동작을 유지합니다. 이러한 분리된 실행은 [백그라운드 작업](/ko/automation/tasks)으로 추적됩니다.
|
||||
- 세션별 레인은 특정 세션을 한 번에 하나의 에이전트 실행만 건드리도록 보장합니다.
|
||||
- 외부 의존성이나 백그라운드 워커 스레드가 없습니다. 순수 TypeScript + promise만 사용합니다.
|
||||
- 외부 의존성이나 백그라운드 워커 스레드가 없습니다. 순수 TypeScript + promises입니다.
|
||||
|
||||
## 문제 해결
|
||||
|
||||
- 명령이 멈춘 것처럼 보이면 자세한 로그를 활성화하고 “queued for …ms” 줄을 찾아 큐가 비워지고 있는지 확인하세요.
|
||||
- 큐 깊이가 필요하면 자세한 로그를 활성화하고 큐 타이밍 줄을 확인하세요.
|
||||
- 턴을 수락한 뒤 진행 상황 내보내기를 중단하는 Codex 앱 서버 실행은 Codex 어댑터에 의해 중단되므로, 활성 세션 레인이 외부 실행 제한 시간을 기다리지 않고 해제될 수 있습니다.
|
||||
- 진단이 활성화된 경우 `diagnostics.stuckSessionWarnMs`가 지난 뒤에도 관찰된 응답, 도구, 상태, 블록 또는 ACP 진행이 없는 상태로 `processing`에 남아 있는 세션은 현재 활동별로 분류됩니다. 활성 작업은 `session.long_running`으로 기록됩니다. 최근 진행이 없는 활성 작업은 `session.stalled`로 기록됩니다. `session.stuck`은 활성 작업이 없는 오래된 세션 장부 처리에만 예약되며, 해당 경로만 영향을 받은 세션 레인을 해제해 큐잉된 작업이 비워지도록 할 수 있습니다. 반복되는 `session.stuck` 진단은 세션이 변경되지 않은 동안 백오프됩니다.
|
||||
- 명령이 멈춘 것처럼 보이면 상세 로그를 활성화하고 큐가 비워지고 있는지 확인하기 위해 “queued for …ms” 줄을 찾아보세요.
|
||||
- 큐 깊이가 필요하면 상세 로그를 활성화하고 큐 타이밍 줄을 확인하세요.
|
||||
- 턴을 수락한 뒤 진행 상황 출력을 멈춘 Codex app-server 실행은 Codex adapter에 의해 중단되어, 바깥쪽 실행 타임아웃을 기다리는 대신 활성 세션 레인이 해제될 수 있습니다.
|
||||
- 진단이 활성화된 경우, 관찰된 응답, 도구, 상태, 블록 또는 ACP 진행 없이 `diagnostics.stuckSessionWarnMs`를 지나 `processing` 상태로 남아 있는 세션은 현재 활동에 따라 분류됩니다. 활성 작업은 `session.long_running`으로 로깅됩니다. 최근 진행이 없는 활성 작업은 `session.stalled`로 로깅됩니다. `session.stuck`은 활성 작업이 없는 오래된 세션 장부 처리에만 사용되며, 해당 경로만 영향을 받은 세션 레인을 해제해 큐에 있는 작업이 비워지게 할 수 있습니다. 반복되는 `session.stuck` 진단은 세션이 변경되지 않은 동안 백오프됩니다.
|
||||
|
||||
## 관련 항목
|
||||
|
||||
- [세션 관리](/ko/concepts/session)
|
||||
- [조향 큐](/ko/concepts/queue-steering)
|
||||
- [스티어링 큐](/ko/concepts/queue-steering)
|
||||
- [스티어링](/ko/tools/steer)
|
||||
- [재시도 정책](/ko/concepts/retry)
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
---
|
||||
read_when:
|
||||
- 시스템 프롬프트 텍스트, 도구 목록 또는 시간/Heartbeat 섹션 편집
|
||||
- 워크스페이스 부트스트랩 또는 Skills 주입 동작 변경
|
||||
- 작업 영역 초기화 또는 Skills 주입 동작 변경
|
||||
summary: OpenClaw 시스템 프롬프트에 포함되는 내용과 구성 방식
|
||||
title: 시스템 프롬프트
|
||||
x-i18n:
|
||||
generated_at: "2026-05-03T21:30:47Z"
|
||||
generated_at: "2026-05-04T02:23:16Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 93533ac8090897a7b5fd82b80e542a4ad573670408314b3519c5e317d0408ade
|
||||
source_hash: 5e6067e760eccf58106f0a646c2656e902d5951580abd750f342d70b0568b81b
|
||||
source_path: concepts/system-prompt.md
|
||||
workflow: 16
|
||||
---
|
||||
@ -17,129 +17,91 @@ OpenClaw는 모든 에이전트 실행마다 사용자 지정 시스템 프롬
|
||||
|
||||
프롬프트는 OpenClaw가 조립하여 각 에이전트 실행에 주입합니다.
|
||||
|
||||
Provider Plugin은 전체 OpenClaw 소유 프롬프트를 대체하지 않고도 캐시를 고려한 프롬프트 지침을 제공할 수 있습니다. provider 런타임은 다음을 수행할 수 있습니다.
|
||||
Provider plugins는 전체 OpenClaw 소유 프롬프트를 대체하지 않고도 캐시 인식 프롬프트 지침을 제공할 수 있습니다. 제공자 런타임은 다음을 수행할 수 있습니다.
|
||||
|
||||
- 이름이 지정된 소수의 핵심 섹션(`interaction_style`, `tool_call_style`, `execution_bias`) 교체
|
||||
- 프롬프트 캐시 경계 위에 **안정적인 prefix** 주입
|
||||
- 프롬프트 캐시 경계 아래에 **동적인 suffix** 주입
|
||||
- 이름이 지정된 소수의 핵심 섹션(`interaction_style`,
|
||||
`tool_call_style`, `execution_bias`) 교체
|
||||
- 프롬프트 캐시 경계 위에 **안정적인 접두사** 주입
|
||||
- 프롬프트 캐시 경계 아래에 **동적 접미사** 주입
|
||||
|
||||
모델 계열별 튜닝에는 provider 소유 기여를 사용하세요. 레거시
|
||||
`before_prompt_build` 프롬프트 변경은 호환성이나 진정한 전역 프롬프트
|
||||
변경을 위해 남겨 두고, 일반적인 provider 동작에는 사용하지 마세요.
|
||||
모델 패밀리별 튜닝에는 제공자 소유 기여를 사용하세요. 기존
|
||||
`before_prompt_build` 프롬프트 변경은 호환성 또는 정말 전역적인 프롬프트
|
||||
변경에만 유지하고, 일반적인 제공자 동작에는 사용하지 마세요.
|
||||
|
||||
OpenAI GPT-5 계열 overlay는 핵심 실행 규칙을 작게 유지하고
|
||||
persona latching, 간결한 출력, 도구 규율, 병렬 조회, deliverable coverage,
|
||||
검증, 누락된 컨텍스트, terminal-tool 위생에 대한 모델별 지침을 추가합니다.
|
||||
OpenAI GPT-5 패밀리 오버레이는 핵심 실행 규칙을 작게 유지하고, 페르소나 고정, 간결한 출력, 도구 규율, 병렬 조회, 산출물 포괄성, 검증, 누락된 컨텍스트, 터미널 도구 위생에 대한 모델별 지침을 추가합니다.
|
||||
|
||||
## 구조
|
||||
|
||||
프롬프트는 의도적으로 간결하며 고정 섹션을 사용합니다.
|
||||
|
||||
- **도구 사용**: 구조화된 도구의 source-of-truth 알림과 런타임 도구 사용 지침입니다.
|
||||
- **실행 성향**: 실행 완료를 위한 간결한 지침입니다. 실행 가능한 요청은
|
||||
현재 턴에서 처리하고, 완료되거나 막힐 때까지 계속하며, 약한 도구
|
||||
결과에서 회복하고, 변경 가능한 상태를 실시간으로 확인하며, 최종화 전에 검증합니다.
|
||||
- **안전**: 권력 추구 행동이나 감독 우회를 피하라는 짧은 가드레일 알림입니다.
|
||||
- **Skills**(사용 가능할 때): 필요할 때 skill 지침을 로드하는 방법을 모델에 알려줍니다.
|
||||
- **OpenClaw 자체 업데이트**: `config.schema.lookup`으로 config를 안전하게 검사하고,
|
||||
`config.patch`로 config를 패치하며, `config.apply`로 전체 config를 교체하고,
|
||||
명시적인 사용자 요청이 있을 때만 `update.run`을 실행하는 방법입니다.
|
||||
owner-only `gateway` 도구도 레거시 `tools.bash.*` alias를 포함해
|
||||
보호된 exec 경로로 정규화되는 `tools.exec.ask` / `tools.exec.security`를
|
||||
재작성하는 것을 거부합니다.
|
||||
- **워크스페이스**: 작업 디렉터리(`agents.defaults.workspace`)입니다.
|
||||
- **문서**: OpenClaw 문서의 로컬 경로(repo 또는 npm package)와 읽어야 하는 시점입니다.
|
||||
- **워크스페이스 파일(주입됨)**: bootstrap 파일이 아래에 포함됨을 나타냅니다.
|
||||
- **샌드박스**(활성화된 경우): sandboxed 런타임, sandbox 경로, elevated exec 사용 가능 여부를 나타냅니다.
|
||||
- **현재 날짜 및 시간**: 사용자 로컬 시간, 시간대, 시간 형식입니다.
|
||||
- **답장 태그**: 지원되는 provider의 선택적 답장 태그 구문입니다.
|
||||
- **Heartbeat**: 기본 에이전트에 Heartbeat가 활성화된 경우 Heartbeat 프롬프트와 ack 동작입니다.
|
||||
- **런타임**: 호스트, OS, Node, 모델, repo root(감지된 경우), thinking level(한 줄)입니다.
|
||||
- **추론**: 현재 visibility level + /reasoning 토글 힌트입니다.
|
||||
- **도구 사용**: 구조화된 도구의 원본 정보 안내와 런타임 도구 사용 지침.
|
||||
- **실행 편향**: 간결한 후속 실행 지침: 실행 가능한 요청은 현재 턴에서 처리하고,
|
||||
완료되거나 막힐 때까지 계속하며, 약한 도구 결과에서 회복하고,
|
||||
변경 가능한 상태를 실시간으로 확인하며, 최종화 전에 검증합니다.
|
||||
- **안전**: 권력 추구 행동이나 감독 우회를 피하라는 짧은 보호 장치 알림.
|
||||
- **Skills**(사용 가능한 경우): 필요할 때 Skills 지침을 로드하는 방법을 모델에 알려줍니다.
|
||||
- **OpenClaw 자체 업데이트**: `config.schema.lookup`으로 구성을 안전하게 검사하고,
|
||||
`config.patch`로 구성을 패치하며, `config.apply`로 전체 구성을 교체하고,
|
||||
명시적인 사용자 요청이 있을 때만 `update.run`을 실행하는 방법. 소유자 전용
|
||||
`gateway` 도구도 보호된 exec 경로로 정규화되는 기존 `tools.bash.*`
|
||||
별칭을 포함해 `tools.exec.ask` / `tools.exec.security` 재작성을 거부합니다.
|
||||
- **작업 공간**: 작업 디렉터리(`agents.defaults.workspace`).
|
||||
- **문서**: OpenClaw 문서의 로컬 경로(저장소 또는 npm 패키지)와 문서를 읽어야 하는 시점.
|
||||
- **작업 공간 파일(주입됨)**: 부트스트랩 파일이 아래에 포함되었음을 나타냅니다.
|
||||
- **샌드박스**(활성화된 경우): 샌드박스 런타임, 샌드박스 경로, 상승된 exec 사용 가능 여부를 나타냅니다.
|
||||
- **현재 날짜 및 시간**: 사용자 로컬 시간, 시간대, 시간 형식.
|
||||
- **응답 태그**: 지원되는 제공자를 위한 선택적 응답 태그 구문.
|
||||
- **Heartbeat**: 기본 에이전트에 Heartbeat가 활성화된 경우 Heartbeat 프롬프트와 ack 동작.
|
||||
- **런타임**: 호스트, OS, Node, 모델, 저장소 루트(감지된 경우), 사고 수준(한 줄).
|
||||
- **추론**: 현재 가시성 수준 + /reasoning 토글 힌트.
|
||||
|
||||
OpenClaw는 **프로젝트 컨텍스트**를 포함한 큰 안정적 콘텐츠를 내부
|
||||
프롬프트 캐시 경계 위에 유지합니다. Control UI embed guidance, **메시징**,
|
||||
**음성**, **그룹 채팅 컨텍스트**, **반응**, **Heartbeat**, **런타임**처럼
|
||||
변동성이 큰 channel/session 섹션은 그 경계 아래에 추가되어, prefix 캐시가
|
||||
있는 로컬 backend가 channel 턴 전반에서 안정적인 workspace prefix를
|
||||
재사용할 수 있게 합니다. 마찬가지로 도구 설명은 허용된 schema가 이미
|
||||
해당 런타임 세부 정보를 담고 있다면 현재 channel 이름을 포함하지 않아야 합니다.
|
||||
OpenClaw는 **프로젝트 컨텍스트**를 포함한 대규모 안정 콘텐츠를 내부 프롬프트 캐시 경계 위에 둡니다. Control UI 임베드 지침, **메시징**, **음성**, **그룹 채팅 컨텍스트**, **반응**, **Heartbeat**, **런타임** 같은 변동성이 큰 채널/세션 섹션은 그 경계 아래에 추가되어, 접두사 캐시가 있는 로컬 백엔드가 채널 턴 사이에서 안정적인 작업 공간 접두사를 재사용할 수 있게 합니다. 도구 설명도 허용된 스키마가 이미 해당 런타임 세부 정보를 전달하는 경우 현재 채널 이름을 포함하지 않는 것이 좋습니다.
|
||||
|
||||
도구 사용 섹션에는 장기 실행 작업을 위한 런타임 지침도 포함됩니다.
|
||||
도구 사용 섹션에는 장시간 실행 작업을 위한 런타임 지침도 포함됩니다.
|
||||
|
||||
- 미래의 후속 작업(`check back later`, reminder, 반복 작업)에는
|
||||
`exec` sleep loop, `yieldMs` 지연 기법, 반복적인 `process` polling 대신 Cron을 사용합니다.
|
||||
- 지금 시작해 백그라운드에서 계속 실행되는 명령에만 `exec` / `process`를 사용합니다.
|
||||
- 자동 완료 wake가 활성화되어 있으면 명령을 한 번만 시작하고, 출력이 발생하거나 실패할 때
|
||||
push 기반 wake 경로에 의존합니다.
|
||||
- 미래 후속 작업(`check back later`, 알림, 반복 작업)에는 `exec` sleep 루프,
|
||||
`yieldMs` 지연 기법 또는 반복적인 `process` 폴링 대신 cron을 사용합니다.
|
||||
- 지금 시작되어 백그라운드에서 계속 실행되는 명령에만 `exec` / `process`를 사용합니다.
|
||||
- 자동 완료 깨우기가 활성화된 경우 명령을 한 번 시작하고, 출력이 발생하거나 실패할 때 push 기반 깨우기 경로에 의존합니다.
|
||||
- 실행 중인 명령을 검사해야 할 때 로그, 상태, 입력 또는 개입에는 `process`를 사용합니다.
|
||||
- 작업이 더 크면 `sessions_spawn`을 선호합니다. sub-agent 완료는 push 기반이며 requester에게 자동으로 알립니다.
|
||||
- 완료를 기다리기 위해 `subagents list` / `sessions_list`를 loop에서 polling하지 마세요.
|
||||
- 작업이 더 크면 `sessions_spawn`을 선호합니다. 하위 에이전트 완료는 push 기반이며 요청자에게 자동으로 알립니다.
|
||||
- 완료를 기다리기 위해 `subagents list` / `sessions_list`를 루프로 폴링하지 마세요.
|
||||
|
||||
실험적 `update_plan` 도구가 활성화된 경우, 도구 사용 섹션은 모델에
|
||||
중요한 다단계 작업에만 이를 사용하고, 정확히 하나의 `in_progress` 단계를
|
||||
유지하며, 각 업데이트 후 전체 계획을 반복하지 말라고도 알려줍니다.
|
||||
실험적 `update_plan` 도구가 활성화된 경우, 도구 사용 섹션은 모델에게 이를 사소하지 않은 다단계 작업에만 사용하고, 정확히 하나의 `in_progress` 단계만 유지하며, 각 업데이트 후 전체 계획을 반복하지 말라고도 알려줍니다.
|
||||
|
||||
시스템 프롬프트의 안전 가드레일은 조언입니다. 모델 동작을 안내하지만 정책을 강제하지는 않습니다. 강제 적용에는 도구 정책, exec 승인, sandboxing, channel allowlist를 사용하세요. 운영자는 설계상 이를 비활성화할 수 있습니다.
|
||||
시스템 프롬프트의 안전 보호 장치는 권고 사항입니다. 이는 모델 동작을 안내하지만 정책을 강제하지는 않습니다. 강제 적용에는 도구 정책, exec 승인, 샌드박싱, 채널 허용 목록을 사용하세요. 운영자는 설계상 이를 비활성화할 수 있습니다.
|
||||
|
||||
네이티브 승인 카드/버튼이 있는 channel에서는 런타임 프롬프트가 이제
|
||||
에이전트에게 해당 네이티브 승인 UI를 먼저 사용하라고 알려줍니다. 도구
|
||||
결과가 채팅 승인을 사용할 수 없거나 수동 승인이 유일한 경로라고 말할 때만
|
||||
수동 `/approve` 명령을 포함해야 합니다.
|
||||
네이티브 승인 카드/버튼이 있는 채널에서 런타임 프롬프트는 이제 에이전트가 해당 네이티브 승인 UI를 먼저 사용하도록 안내합니다. 도구 결과가 채팅 승인을 사용할 수 없거나 수동 승인이 유일한 경로라고 말할 때만 수동 `/approve` 명령을 포함해야 합니다.
|
||||
|
||||
## 프롬프트 모드
|
||||
|
||||
OpenClaw는 sub-agent용으로 더 작은 시스템 프롬프트를 렌더링할 수 있습니다. 런타임은
|
||||
각 실행에 대해 `promptMode`를 설정합니다(사용자 대상 config가 아님).
|
||||
OpenClaw는 하위 에이전트용으로 더 작은 시스템 프롬프트를 렌더링할 수 있습니다. 런타임은 각 실행에 대해 `promptMode`를 설정합니다(사용자용 구성 아님).
|
||||
|
||||
- `full`(기본값): 위의 모든 섹션을 포함합니다.
|
||||
- `minimal`: sub-agent에 사용됩니다. **Skills**, **메모리 회상**, **OpenClaw
|
||||
자체 업데이트**, **모델 alias**, **사용자 ID**, **답장 태그**,
|
||||
**메시징**, **무음 답장**, **Heartbeat**를 생략합니다. 도구 사용, **안전**,
|
||||
워크스페이스, 샌드박스, 현재 날짜 및 시간(알려진 경우), 런타임, 주입된
|
||||
- `minimal`: 하위 에이전트에 사용됩니다. **Skills**, **메모리 회상**, **OpenClaw
|
||||
자체 업데이트**, **모델 별칭**, **사용자 ID**, **응답 태그**,
|
||||
**메시징**, **무음 응답**, **Heartbeat**를 생략합니다. 도구 사용, **안전**,
|
||||
작업 공간, 샌드박스, 현재 날짜 및 시간(알려진 경우), 런타임, 주입된
|
||||
컨텍스트는 계속 사용할 수 있습니다.
|
||||
- `none`: 기본 identity line만 반환합니다.
|
||||
- `none`: 기본 ID 줄만 반환합니다.
|
||||
|
||||
`promptMode=minimal`일 때 추가 주입 프롬프트는 **그룹 채팅 컨텍스트** 대신
|
||||
**Subagent Context**로 표시됩니다.
|
||||
`promptMode=minimal`일 때 추가 주입 프롬프트는 **그룹 채팅 컨텍스트** 대신 **하위 에이전트 컨텍스트**로 레이블이 지정됩니다.
|
||||
|
||||
channel 자동 답장 실행의 경우, 직접/그룹 채팅 컨텍스트에 이미 확인된
|
||||
conversation-specific `NO_REPLY` 동작이 포함되어 있으면 OpenClaw는 일반적인
|
||||
**무음 답장** 섹션을 생략할 수 있습니다. 이렇게 하면 전역 시스템 프롬프트와
|
||||
channel 컨텍스트 양쪽에서 token mechanics를 반복하지 않습니다.
|
||||
채널 자동 응답 실행의 경우, 직접/그룹 채팅 컨텍스트에 이미 해결된 대화별 `NO_REPLY` 동작이 포함되어 있으면 OpenClaw는 일반 **무음 응답** 섹션을 생략할 수 있습니다. 이렇게 하면 전역 시스템 프롬프트와 채널 컨텍스트 양쪽에서 토큰 메커니즘을 반복하지 않습니다.
|
||||
|
||||
## 프롬프트 스냅샷
|
||||
|
||||
OpenClaw는 Codex 런타임 happy path용으로 커밋된 프롬프트 스냅샷을
|
||||
`test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/` 아래에
|
||||
유지합니다. 이 스냅샷은 선택된 app-server thread/turn params와 Telegram
|
||||
direct, Discord group, heartbeat 턴을 위한 재구성된 model-bound prompt
|
||||
layer stack을 렌더링합니다. 해당 stack에는 Codex의 모델 catalog/cache 형태에서
|
||||
생성된 고정 Codex `gpt-5.5` 모델 프롬프트 fixture, Codex happy-path permission
|
||||
developer text, OpenClaw developer instructions, OpenClaw가 제공하는 경우
|
||||
turn-scoped collaboration-mode instructions, 사용자 턴 입력, 동적 도구 spec에 대한
|
||||
참조가 포함됩니다.
|
||||
OpenClaw는 Codex 런타임 정상 경로에 대한 커밋된 프롬프트 스냅샷을 `test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/` 아래에 보관합니다. 이 스냅샷은 선택된 앱 서버 스레드/턴 매개변수와 Telegram 직접, Discord 그룹, Heartbeat 턴을 위한 재구성된 모델 바인딩 프롬프트 레이어 스택을 렌더링합니다. 이 스택에는 Codex 모델 카탈로그/캐시 형태에서 생성된 고정 Codex `gpt-5.5` 모델 프롬프트 fixture, Codex 정상 경로 권한 developer 텍스트, OpenClaw developer 지침, OpenClaw가 제공하는 경우 턴 범위 collaboration-mode 지침, 사용자 턴 입력, 동적 도구 사양에 대한 참조가 포함됩니다.
|
||||
|
||||
고정 Codex 모델 프롬프트 fixture는
|
||||
`pnpm prompt:snapshots:sync-codex-model`로 새로 고치세요. 기본적으로 스크립트는
|
||||
Codex 런타임 캐시를 `$CODEX_HOME/models_cache.json`, 그다음
|
||||
`~/.codex/models_cache.json`에서 찾고, 그 후에만 maintainer Codex checkout 규약인
|
||||
`~/code/codex/codex-rs/models-manager/models.json`으로 fallback합니다. 이 소스 중
|
||||
어느 것도 없으면 명령은 커밋된 fixture를 변경하지 않고 종료됩니다. 특정
|
||||
`models_cache.json` 또는 `models.json` 파일에서 새로 고치려면 `--catalog <path>`를 전달하세요.
|
||||
고정 Codex 모델 프롬프트 fixture는 `pnpm prompt:snapshots:sync-codex-model`로 새로 고치세요. 기본적으로 스크립트는 Codex의 런타임 캐시를 `$CODEX_HOME/models_cache.json`에서 찾은 다음 `~/.codex/models_cache.json`을 찾고, 그 다음에만 유지관리자 Codex 체크아웃 관례인 `~/code/codex/codex-rs/models-manager/models.json`으로 대체합니다. 해당 소스가 하나도 없으면 명령은 커밋된 fixture를 변경하지 않고 종료합니다. 특정 `models_cache.json` 또는 `models.json` 파일에서 새로 고치려면 `--catalog <path>`를 전달하세요.
|
||||
|
||||
이 스냅샷은 여전히 byte-for-byte 원시 OpenAI 요청 capture가 아닙니다. OpenClaw가
|
||||
thread 및 turn params를 보낸 뒤 Codex 런타임 내부에서 Codex는 `AGENTS.md`,
|
||||
환경 컨텍스트, memory, app/plugin instructions, 내장 Default collaboration-mode
|
||||
instructions 같은 runtime-owned workspace context를 추가할 수 있습니다.
|
||||
이 스냅샷은 여전히 원시 OpenAI 요청을 바이트 단위로 정확히 캡처한 것이 아닙니다. OpenClaw가 스레드 및 턴 매개변수를 보낸 후, Codex는 Codex 런타임 내부에서 `AGENTS.md`, 환경 컨텍스트, 메모리, 앱/Plugin 지침, 내장 Default collaboration-mode 지침 같은 런타임 소유 작업 공간 컨텍스트를 추가할 수 있습니다.
|
||||
|
||||
`pnpm prompt:snapshots:gen`으로 다시 생성하고 `pnpm prompt:snapshots:check`로
|
||||
drift를 검증하세요. CI는 additional boundary shard에서 drift check를 실행하므로
|
||||
프롬프트 변경과 스냅샷 업데이트가 같은 PR에 붙어 유지됩니다.
|
||||
`pnpm prompt:snapshots:gen`으로 다시 생성하고 `pnpm prompt:snapshots:check`로 드리프트를 검증하세요. CI는 추가 경계 샤드에서 드리프트 검사를 실행하여 프롬프트 변경과 스냅샷 업데이트가 같은 PR에 연결되어 유지되도록 합니다.
|
||||
|
||||
## 워크스페이스 bootstrap 주입
|
||||
## 작업 공간 부트스트랩 주입
|
||||
|
||||
Bootstrap 파일은 trim되어 **프로젝트 컨텍스트** 아래에 추가되므로 모델은 명시적으로 읽지 않아도 identity와 profile context를 볼 수 있습니다.
|
||||
부트스트랩 파일은 다듬어진 뒤 **프로젝트 컨텍스트** 아래에 추가되어, 명시적으로 읽을 필요 없이 모델이 ID와 프로필 컨텍스트를 볼 수 있게 합니다.
|
||||
|
||||
- `AGENTS.md`
|
||||
- `SOUL.md`
|
||||
@ -147,54 +109,32 @@ Bootstrap 파일은 trim되어 **프로젝트 컨텍스트** 아래에 추가되
|
||||
- `IDENTITY.md`
|
||||
- `USER.md`
|
||||
- `HEARTBEAT.md`
|
||||
- `BOOTSTRAP.md`(완전히 새로운 워크스페이스에서만)
|
||||
- 존재하는 경우 `MEMORY.md`
|
||||
- `BOOTSTRAP.md`(새 작업 공간에서만)
|
||||
- `MEMORY.md`가 있는 경우
|
||||
|
||||
이 모든 파일은 파일별 gate가 적용되지 않는 한 모든 턴에서 **컨텍스트 창에 주입**됩니다.
|
||||
기본 에이전트에 Heartbeat가 비활성화되어 있거나
|
||||
`agents.defaults.heartbeat.includeSystemPromptSection`이 false이면 일반 실행에서
|
||||
`HEARTBEAT.md`는 생략됩니다. 주입 파일은 간결하게 유지하세요. 특히
|
||||
`MEMORY.md`는 시간이 지나며 커질 수 있어 예상보다 높은 컨텍스트 사용량과
|
||||
더 잦은 Compaction으로 이어질 수 있습니다.
|
||||
이 파일들은 파일별 게이트가 적용되지 않는 한 모든 턴에서 **컨텍스트 창에 주입됩니다**. 기본 에이전트에 Heartbeat가 비활성화되어 있거나 `agents.defaults.heartbeat.includeSystemPromptSection`이 false인 경우, 일반 실행에서 `HEARTBEAT.md`는 생략됩니다. 주입된 파일은 간결하게 유지하세요. 특히 `MEMORY.md`는 시간이 지나며 커질 수 있어 예기치 않게 높은 컨텍스트 사용량과 더 잦은 Compaction으로 이어질 수 있습니다.
|
||||
|
||||
세션이 네이티브 Codex harness에서 실행될 때 Codex는 자체 project-doc discovery를 통해
|
||||
`AGENTS.md`를 로드합니다. OpenClaw는 여전히 나머지 bootstrap 파일을 확인하고 이를
|
||||
Codex config instructions로 전달하므로 `SOUL.md`, `TOOLS.md`, `IDENTITY.md`,
|
||||
`USER.md`, `HEARTBEAT.md`, `BOOTSTRAP.md`, `MEMORY.md`는 `AGENTS.md`를 중복하지
|
||||
않으면서 동일한 workspace-context 역할을 유지합니다.
|
||||
세션이 네이티브 Codex 하네스에서 실행될 때 Codex는 자체 프로젝트 문서 검색을 통해 `AGENTS.md`를 로드합니다. OpenClaw는 여전히 나머지 부트스트랩 파일을 해석해 Codex 구성 지침으로 전달하므로, `SOUL.md`, `TOOLS.md`, `IDENTITY.md`, `USER.md`, `HEARTBEAT.md`, `BOOTSTRAP.md`, `MEMORY.md`는 `AGENTS.md`를 중복하지 않고 동일한 작업 공간 컨텍스트 역할을 유지합니다.
|
||||
|
||||
<Note>
|
||||
`memory/*.md` daily 파일은 일반 bootstrap 프로젝트 컨텍스트의 일부가 **아닙니다**. 일반 턴에서는 `memory_search` 및 `memory_get` 도구를 통해 필요할 때 접근되므로, 모델이 명시적으로 읽지 않는 한 컨텍스트 창을 차지하지 않습니다. Bare `/new` 및 `/reset` 턴은 예외입니다. 런타임은 해당 첫 턴을 위해 최근 daily memory를 one-shot startup-context block으로 앞에 붙일 수 있습니다.
|
||||
`memory/*.md` 일일 파일은 일반 부트스트랩 프로젝트 컨텍스트의 일부가 **아닙니다**. 일반 턴에서는 `memory_search` 및 `memory_get` 도구를 통해 필요할 때 접근되므로, 모델이 명시적으로 읽지 않는 한 컨텍스트 창을 차지하지 않습니다. 단순 `/new` 및 `/reset` 턴은 예외입니다. 런타임은 해당 첫 턴에 대해 최근 일일 메모리를 일회성 시작 컨텍스트 블록으로 앞에 붙일 수 있습니다.
|
||||
</Note>
|
||||
|
||||
큰 파일은 marker와 함께 잘립니다. 파일당 최대 크기는
|
||||
`agents.defaults.bootstrapMaxChars`로 제어됩니다(기본값: 12000). 파일 전체에 걸쳐
|
||||
주입되는 bootstrap 콘텐츠 총량은 `agents.defaults.bootstrapTotalMaxChars`로 제한됩니다
|
||||
(기본값: 60000). 누락된 파일은 짧은 missing-file marker를 주입합니다. Truncation이
|
||||
발생하면 OpenClaw는 프로젝트 컨텍스트에 warning block을 주입할 수 있습니다. 이는
|
||||
`agents.defaults.bootstrapPromptTruncationWarning`(`off`, `once`, `always`;
|
||||
기본값: `once`)로 제어하세요.
|
||||
큰 파일은 마커와 함께 잘립니다. 파일별 최대 크기는 `agents.defaults.bootstrapMaxChars`(기본값: 12000)로 제어됩니다. 파일 전체에 걸쳐 주입되는 부트스트랩 콘텐츠 총량은 `agents.defaults.bootstrapTotalMaxChars`(기본값: 60000)로 제한됩니다. 누락된 파일은 짧은 누락 파일 마커를 주입합니다. 잘림이 발생하면 OpenClaw는 간결한 시스템 프롬프트 경고 알림을 주입할 수 있습니다. 이는 `agents.defaults.bootstrapPromptTruncationWarning`(`off`, `once`, `always`; 기본값: `once`)로 제어합니다. 자세한 원시/주입 카운트는 `/context`, `/status`, doctor, 로그 같은 진단 정보에 유지됩니다.
|
||||
|
||||
Sub-agent 세션은 `AGENTS.md`와 `TOOLS.md`만 주입합니다(다른 bootstrap 파일은
|
||||
sub-agent 컨텍스트를 작게 유지하기 위해 필터링됩니다).
|
||||
하위 에이전트 세션은 `AGENTS.md`와 `TOOLS.md`만 주입합니다(하위 에이전트 컨텍스트를 작게 유지하기 위해 다른 부트스트랩 파일은 필터링됩니다).
|
||||
|
||||
내부 hook은 `agent:bootstrap`을 통해 이 단계를 가로채 주입되는 bootstrap 파일을
|
||||
변경하거나 대체할 수 있습니다(예: `SOUL.md`를 대체 persona로 교체).
|
||||
내부 훅은 `agent:bootstrap`을 통해 이 단계를 가로채 주입된 부트스트랩 파일을 변경하거나 교체할 수 있습니다(예: `SOUL.md`를 대체 페르소나로 교체).
|
||||
|
||||
에이전트가 덜 일반적으로 들리게 만들고 싶다면
|
||||
[SOUL.md Personality Guide](/ko/concepts/soul)부터 시작하세요.
|
||||
에이전트가 덜 일반적으로 들리게 하려면 [SOUL.md 성격 가이드](/ko/concepts/soul)부터 시작하세요.
|
||||
|
||||
주입된 각 파일의 기여량(raw vs injected, truncation, 도구 schema overhead 포함)을
|
||||
검사하려면 `/context list` 또는 `/context detail`을 사용하세요. [컨텍스트](/ko/concepts/context)를 참조하세요.
|
||||
주입된 각 파일이 얼마나 기여하는지(원시 vs 주입, 잘림, 도구 스키마 오버헤드 포함) 확인하려면 `/context list` 또는 `/context detail`을 사용하세요. [컨텍스트](/ko/concepts/context)를 참조하세요.
|
||||
|
||||
## 시간 처리
|
||||
|
||||
사용자 시간대가 알려진 경우 시스템 프롬프트에는 전용 **현재 날짜 및 시간** 섹션이 포함됩니다.
|
||||
프롬프트 캐시를 안정적으로 유지하기 위해 이제 **시간대**만 포함합니다(동적 clock이나 시간 형식 없음).
|
||||
사용자 시간대가 알려진 경우 시스템 프롬프트에는 전용 **현재 날짜 및 시간** 섹션이 포함됩니다. 프롬프트 캐시를 안정적으로 유지하기 위해 이제 **시간대**만 포함합니다(동적 시계나 시간 형식은 포함하지 않음).
|
||||
|
||||
에이전트에 현재 시간이 필요할 때는 `session_status`를 사용하세요. status card에는 timestamp line이
|
||||
포함됩니다. 같은 도구는 선택적으로 session별 모델 override도 설정할 수 있습니다
|
||||
(`model=default`는 이를 지웁니다).
|
||||
에이전트가 현재 시간이 필요할 때는 `session_status`를 사용하세요. 상태 카드에는 타임스탬프 줄이 포함됩니다. 같은 도구로 세션별 모델 재정의도 선택적으로 설정할 수 있습니다(`model=default`는 이를 지웁니다).
|
||||
|
||||
다음으로 구성하세요.
|
||||
|
||||
@ -205,16 +145,11 @@ sub-agent 컨텍스트를 작게 유지하기 위해 필터링됩니다).
|
||||
|
||||
## Skills
|
||||
|
||||
적격 skill이 있으면 OpenClaw는 각 skill의 **파일 경로**를 포함하는 간결한
|
||||
**사용 가능한 skills 목록**(`formatSkillsForPrompt`)을 주입합니다. 프롬프트는
|
||||
모델에게 나열된 위치(workspace, managed, bundled)의 SKILL.md를 로드하기 위해
|
||||
`read`를 사용하라고 지시합니다. 적격 skill이 없으면 Skills 섹션은 생략됩니다.
|
||||
적격 Skills가 존재하면 OpenClaw는 각 Skill의 **파일 경로**를 포함하는 간결한 **사용 가능한 Skills 목록**(`formatSkillsForPrompt`)을 주입합니다. 프롬프트는 모델에게 나열된 위치(작업 공간, 관리형 또는 번들)의 SKILL.md를 로드하기 위해 `read`를 사용하라고 지시합니다. 적격 Skills가 없으면 Skills 섹션은 생략됩니다.
|
||||
|
||||
적격성에는 skill metadata gate, 런타임 environment/config check, 그리고
|
||||
`agents.defaults.skills` 또는 `agents.list[].skills`가 구성된 경우 effective agent skill allowlist가 포함됩니다.
|
||||
적격성에는 Skill 메타데이터 게이트, 런타임 환경/구성 검사, `agents.defaults.skills` 또는 `agents.list[].skills`가 구성된 경우 적용되는 에이전트 Skill 허용 목록이 포함됩니다.
|
||||
|
||||
Plugin-bundled skills는 소유 Plugin이 활성화된 경우에만 적격입니다. 이를 통해 tool Plugin은
|
||||
모든 도구 설명에 해당 지침을 직접 포함하지 않고도 더 깊은 운영 guide를 노출할 수 있습니다.
|
||||
Plugin 번들 Skills는 해당 소유 Plugin이 활성화된 경우에만 적격입니다. 이를 통해 도구 Plugin은 모든 도구 설명에 해당 지침을 직접 포함하지 않고도 더 깊은 운영 가이드를 노출할 수 있습니다.
|
||||
|
||||
```
|
||||
<available_skills>
|
||||
@ -226,28 +161,28 @@ Plugin-bundled skills는 소유 Plugin이 활성화된 경우에만 적격입니
|
||||
</available_skills>
|
||||
```
|
||||
|
||||
이렇게 하면 base prompt를 작게 유지하면서도 targeted skill usage가 가능합니다.
|
||||
이렇게 하면 기본 프롬프트를 작게 유지하면서도 대상 지정된 Skill 사용을 가능하게 합니다.
|
||||
|
||||
skills 목록 예산은 skills subsystem이 소유합니다.
|
||||
Skills 목록 예산은 Skills 하위 시스템이 소유합니다:
|
||||
|
||||
- 전역 기본값: `skills.limits.maxSkillsPromptChars`
|
||||
- 에이전트별 override: `agents.list[].skillsLimits.maxSkillsPromptChars`
|
||||
- 에이전트별 재정의: `agents.list[].skillsLimits.maxSkillsPromptChars`
|
||||
|
||||
일반적인 제한된 런타임 발췌에는 다른 인터페이스를 사용합니다.
|
||||
일반적인 제한된 런타임 발췌에는 다른 표면을 사용합니다.
|
||||
|
||||
- `agents.defaults.contextLimits.*`
|
||||
- `agents.list[].contextLimits.*`
|
||||
|
||||
이 구분은 `memory_get`, 실시간 도구 결과, Compaction 이후 AGENTS.md 새로 고침 같은 런타임 읽기/주입 크기 산정과 Skills 크기 산정을 분리합니다.
|
||||
이 분리는 Skills 크기 산정을 `memory_get`, 실시간 도구 결과, Compaction 이후 AGENTS.md 새로고침 같은 런타임 읽기/주입 크기 산정과 분리해 둡니다.
|
||||
|
||||
## 문서
|
||||
|
||||
시스템 프롬프트에는 **문서** 섹션이 포함됩니다. 로컬 문서를 사용할 수 있으면 로컬 OpenClaw 문서 디렉터리(Git 체크아웃의 `docs/` 또는 번들된 npm 패키지 문서)를 가리킵니다. 로컬 문서를 사용할 수 없으면 [https://docs.openclaw.ai](https://docs.openclaw.ai)로 폴백합니다.
|
||||
시스템 프롬프트에는 **문서** 섹션이 포함됩니다. 로컬 문서를 사용할 수 있으면 로컬 OpenClaw 문서 디렉터리(Git 체크아웃의 `docs/` 또는 번들된 npm 패키지 문서)를 가리킵니다. 로컬 문서를 사용할 수 없으면 [https://docs.openclaw.ai](https://docs.openclaw.ai)로 대체합니다.
|
||||
|
||||
같은 섹션에는 OpenClaw 소스 위치도 포함됩니다. Git 체크아웃은 에이전트가 코드를 직접 검사할 수 있도록 로컬 소스 루트를 노출합니다. 패키지 설치에는 GitHub 소스 URL이 포함되며, 문서가 불완전하거나 오래된 경우 에이전트에게 그곳에서 소스를 검토하라고 안내합니다. 프롬프트는 공개 문서 미러, 커뮤니티 Discord, Skills 탐색을 위한 ClawHub([https://clawhub.ai](https://clawhub.ai))도 언급합니다. 모델에게 OpenClaw 동작, 명령, 구성 또는 아키텍처에 대해서는 먼저 문서를 참고하고, 가능하면 `openclaw status`를 직접 실행하라고 안내합니다(접근 권한이 없을 때만 사용자에게 요청). 특히 구성의 경우, 정확한 필드 수준 문서와 제약 조건을 위해 에이전트를 `gateway` 도구 작업 `config.schema.lookup`으로 안내한 다음, 더 폭넓은 지침을 위해 `docs/gateway/configuration.md` 및 `docs/gateway/configuration-reference.md`를 안내합니다.
|
||||
같은 섹션에는 OpenClaw 소스 위치도 포함됩니다. Git 체크아웃은 에이전트가 코드를 직접 검사할 수 있도록 로컬 소스 루트를 노출합니다. 패키지 설치에는 GitHub 소스 URL이 포함되며, 문서가 불완전하거나 오래된 경우 에이전트에게 해당 위치에서 소스를 검토하라고 안내합니다. 프롬프트는 또한 공개 문서 미러, 커뮤니티 Discord, Skills 검색을 위한 ClawHub([https://clawhub.ai](https://clawhub.ai))도 언급합니다. 모델에게 OpenClaw 동작, 명령, 구성 또는 아키텍처에 대해서는 먼저 문서를 참조하고, 가능하면 `openclaw status`를 직접 실행하라고 안내합니다(액세스 권한이 없을 때만 사용자에게 요청). 특히 구성의 경우, 에이전트에게 정확한 필드 수준 문서와 제약 조건은 `gateway` 도구 작업 `config.schema.lookup`을, 더 넓은 지침은 `docs/gateway/configuration.md` 및 `docs/gateway/configuration-reference.md`를 참조하도록 안내합니다.
|
||||
|
||||
## 관련
|
||||
## 관련 항목
|
||||
|
||||
- [에이전트 런타임](/ko/concepts/agent)
|
||||
- [에이전트 작업 공간](/ko/concepts/agent-workspace)
|
||||
- [에이전트 작업 영역](/ko/concepts/agent-workspace)
|
||||
- [컨텍스트 엔진](/ko/concepts/context-engine)
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
---
|
||||
read_when:
|
||||
- 에이전트 기본값 조정(모델, 추론, 작업공간, Heartbeat, 미디어, Skills)
|
||||
- 에이전트 기본값 조정(모델, 사고, 작업공간, Heartbeat, 미디어, Skills)
|
||||
- 다중 에이전트 라우팅 및 바인딩 구성
|
||||
- 세션, 메시지 전달 및 대화 모드 동작 조정
|
||||
summary: 에이전트 기본값, 멀티 에이전트 라우팅, 세션, 메시지 및 대화 구성
|
||||
summary: 에이전트 기본값, 다중 에이전트 라우팅, 세션, 메시지 및 talk 구성
|
||||
title: 구성 — 에이전트
|
||||
x-i18n:
|
||||
generated_at: "2026-05-03T06:16:21Z"
|
||||
generated_at: "2026-05-04T02:24:06Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: b25371c34b9f8b0cacce021879e43e6a65b86d626dc87d5bfa05dcae80ac32e4
|
||||
source_hash: 9d339b82b8b3b82e55820ca6568b3ed569fe64135e698515fa7f316c3afbbfd9
|
||||
source_path: gateway/config-agents.md
|
||||
workflow: 16
|
||||
---
|
||||
@ -32,7 +32,7 @@ x-i18n:
|
||||
|
||||
### `agents.defaults.repoRoot`
|
||||
|
||||
시스템 프롬프트의 Runtime 줄에 표시되는 선택적 저장소 루트입니다. 설정하지 않으면 OpenClaw가 워크스페이스에서 위쪽으로 이동하며 자동 감지합니다.
|
||||
시스템 프롬프트의 Runtime 줄에 표시되는 선택적 리포지토리 루트입니다. 설정하지 않으면 OpenClaw가 작업 공간에서 위로 올라가며 자동으로 감지합니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -57,15 +57,15 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
- 기본적으로 Skills를 제한하지 않으려면 `agents.defaults.skills`를 생략하세요.
|
||||
- 기본적으로 제한 없는 Skills를 사용하려면 `agents.defaults.skills`를 생략하세요.
|
||||
- 기본값을 상속하려면 `agents.list[].skills`를 생략하세요.
|
||||
- Skills를 사용하지 않으려면 `agents.list[].skills: []`를 설정하세요.
|
||||
- Skills를 사용하지 않으려면 `agents.list[].skills: []`로 설정하세요.
|
||||
- 비어 있지 않은 `agents.list[].skills` 목록은 해당 에이전트의 최종 집합이며, 기본값과
|
||||
병합되지 않습니다.
|
||||
|
||||
### `agents.defaults.skipBootstrap`
|
||||
|
||||
워크스페이스 부트스트랩 파일(`AGENTS.md`, `SOUL.md`, `TOOLS.md`, `IDENTITY.md`, `USER.md`, `HEARTBEAT.md`, `BOOTSTRAP.md`)의 자동 생성을 비활성화합니다.
|
||||
작업 공간 부트스트랩 파일(`AGENTS.md`, `SOUL.md`, `TOOLS.md`, `IDENTITY.md`, `USER.md`, `HEARTBEAT.md`, `BOOTSTRAP.md`) 자동 생성을 비활성화합니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -75,7 +75,7 @@ x-i18n:
|
||||
|
||||
### `agents.defaults.skipOptionalBootstrapFiles`
|
||||
|
||||
필수 부트스트랩 파일은 계속 작성하면서 선택한 선택적 워크스페이스 파일 생성을 건너뜁니다. 유효한 값: `SOUL.md`, `USER.md`, `HEARTBEAT.md`, `IDENTITY.md`.
|
||||
필수 부트스트랩 파일은 계속 작성하면서 선택한 선택적 작업 공간 파일 생성을 건너뜁니다. 유효한 값: `SOUL.md`, `USER.md`, `HEARTBEAT.md`, `IDENTITY.md`.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -89,10 +89,10 @@ x-i18n:
|
||||
|
||||
### `agents.defaults.contextInjection`
|
||||
|
||||
워크스페이스 부트스트랩 파일을 시스템 프롬프트에 주입하는 시점을 제어합니다. 기본값: `"always"`.
|
||||
작업 공간 부트스트랩 파일을 시스템 프롬프트에 주입하는 시점을 제어합니다. 기본값: `"always"`.
|
||||
|
||||
- `"continuation-skip"`: 안전한 이어서 진행하는 턴(완료된 어시스턴트 응답 이후)에서는 워크스페이스 부트스트랩 재주입을 건너뛰어 프롬프트 크기를 줄입니다. Heartbeat 실행과 Compaction 이후 재시도는 여전히 컨텍스트를 다시 빌드합니다.
|
||||
- `"never"`: 모든 턴에서 워크스페이스 부트스트랩 및 컨텍스트 파일 주입을 비활성화합니다. 프롬프트 수명 주기를 완전히 자체 관리하는 에이전트(사용자 지정 컨텍스트 엔진, 자체 컨텍스트를 빌드하는 네이티브 런타임 또는 특수한 부트스트랩 없는 워크플로)에만 사용하세요. Heartbeat 및 Compaction 복구 턴도 주입을 건너뜁니다.
|
||||
- `"continuation-skip"`: 안전한 이어가기 턴(완료된 어시스턴트 응답 이후)에서는 작업 공간 부트스트랩 재주입을 건너뛰어 프롬프트 크기를 줄입니다. Heartbeat 실행과 Compaction 이후 재시도는 여전히 컨텍스트를 다시 빌드합니다.
|
||||
- `"never"`: 모든 턴에서 작업 공간 부트스트랩 및 컨텍스트 파일 주입을 비활성화합니다. 프롬프트 생명 주기를 완전히 자체적으로 소유하는 에이전트(사용자 지정 컨텍스트 엔진, 자체 컨텍스트를 빌드하는 네이티브 런타임, 또는 부트스트랩이 필요 없는 특수 워크플로)에만 사용하세요. Heartbeat 및 Compaction 복구 턴도 주입을 건너뜁니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -102,7 +102,7 @@ x-i18n:
|
||||
|
||||
### `agents.defaults.bootstrapMaxChars`
|
||||
|
||||
잘리기 전 워크스페이스 부트스트랩 파일당 최대 문자 수입니다. 기본값: `12000`.
|
||||
잘라내기 전 작업 공간 부트스트랩 파일당 최대 문자 수입니다. 기본값: `12000`.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -112,7 +112,7 @@ x-i18n:
|
||||
|
||||
### `agents.defaults.bootstrapTotalMaxChars`
|
||||
|
||||
모든 워크스페이스 부트스트랩 파일 전체에 주입되는 총 최대 문자 수입니다. 기본값: `60000`.
|
||||
모든 작업 공간 부트스트랩 파일에 걸쳐 주입되는 총 최대 문자 수입니다. 기본값: `60000`.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -122,12 +122,15 @@ x-i18n:
|
||||
|
||||
### `agents.defaults.bootstrapPromptTruncationWarning`
|
||||
|
||||
부트스트랩 컨텍스트가 잘릴 때 에이전트에 표시되는 경고 텍스트를 제어합니다.
|
||||
부트스트랩 컨텍스트가 잘릴 때 에이전트에 표시되는 시스템 프롬프트 알림을 제어합니다.
|
||||
기본값: `"once"`.
|
||||
|
||||
- `"off"`: 시스템 프롬프트에 경고 텍스트를 절대 주입하지 않습니다.
|
||||
- `"once"`: 고유한 잘림 시그니처마다 한 번 경고를 주입합니다(권장).
|
||||
- `"always"`: 잘림이 있을 때마다 모든 실행에서 경고를 주입합니다.
|
||||
- `"off"`: 잘라내기 알림 텍스트를 시스템 프롬프트에 주입하지 않습니다.
|
||||
- `"once"`: 고유한 잘라내기 시그니처마다 간결한 알림을 한 번 주입합니다(권장).
|
||||
- `"always"`: 잘라내기가 있을 때마다 모든 실행에서 간결한 알림을 주입합니다.
|
||||
|
||||
상세한 원본/주입 카운트와 구성 튜닝 필드는 컨텍스트/상태 보고서 및 로그 같은 진단 정보에 유지되며,
|
||||
일상적인 WebChat 사용자/런타임 컨텍스트에는 간결한 복구 알림만 제공됩니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -137,21 +140,21 @@ x-i18n:
|
||||
|
||||
### 컨텍스트 예산 소유권 맵
|
||||
|
||||
OpenClaw에는 여러 대용량 프롬프트/컨텍스트 예산이 있으며, 하나의 일반적인
|
||||
노브로 모두 흘러가게 하지 않고 하위 시스템별로 의도적으로 분리되어 있습니다.
|
||||
OpenClaw에는 대용량 프롬프트/컨텍스트 예산이 여러 개 있으며, 이들은 하나의 일반
|
||||
노브를 통해 모두 흐르지 않고 의도적으로 하위 시스템별로 분리되어 있습니다.
|
||||
|
||||
- `agents.defaults.bootstrapMaxChars` /
|
||||
`agents.defaults.bootstrapTotalMaxChars`:
|
||||
일반 워크스페이스 부트스트랩 주입.
|
||||
일반 작업 공간 부트스트랩 주입.
|
||||
- `agents.defaults.startupContext.*`:
|
||||
최근 일일 `memory/*.md` 파일을 포함한 일회성 재설정/시작 모델 실행 프렐류드입니다. 순수 채팅 `/new` 및 `/reset` 명령은
|
||||
모델을 호출하지 않고 확인됩니다.
|
||||
최근 일일 `memory/*.md` 파일을 포함한 일회성 재설정/시작 모델 실행 프렐류드. 단순 채팅 `/new` 및 `/reset` 명령은
|
||||
모델을 호출하지 않고 확인 처리됩니다.
|
||||
- `skills.limits.*`:
|
||||
시스템 프롬프트에 주입되는 압축된 Skills 목록입니다.
|
||||
시스템 프롬프트에 주입되는 압축 Skills 목록.
|
||||
- `agents.defaults.contextLimits.*`:
|
||||
제한된 런타임 발췌와 주입된 런타임 소유 블록입니다.
|
||||
제한된 런타임 발췌와 주입된 런타임 소유 블록.
|
||||
- `memory.qmd.limits.*`:
|
||||
인덱싱된 메모리 검색 스니펫 및 주입 크기입니다.
|
||||
인덱싱된 메모리 검색 스니펫 및 주입 크기.
|
||||
|
||||
한 에이전트에 다른 예산이 필요할 때만 일치하는 에이전트별 재정의를 사용하세요.
|
||||
|
||||
@ -160,8 +163,8 @@ OpenClaw에는 여러 대용량 프롬프트/컨텍스트 예산이 있으며,
|
||||
|
||||
#### `agents.defaults.startupContext`
|
||||
|
||||
재설정/시작 모델 실행에서 주입되는 첫 번째 턴 시작 프렐류드를 제어합니다.
|
||||
순수 채팅 `/new` 및 `/reset` 명령은 모델을 호출하지 않고 재설정을 확인하므로
|
||||
재설정/시작 모델 실행 시 첫 턴 시작 프렐류드 주입을 제어합니다.
|
||||
단순 채팅 `/new` 및 `/reset` 명령은 모델을 호출하지 않고 재설정을 확인 처리하므로
|
||||
이 프렐류드를 로드하지 않습니다.
|
||||
|
||||
```json5
|
||||
@ -200,9 +203,9 @@ OpenClaw에는 여러 대용량 프롬프트/컨텍스트 예산이 있으며,
|
||||
}
|
||||
```
|
||||
|
||||
- `memoryGetMaxChars`: 잘림 메타데이터와 이어보기 알림이 추가되기 전 기본 `memory_get` 발췌 상한입니다.
|
||||
- `memoryGetDefaultLines`: `lines`가 생략되었을 때 기본 `memory_get` 줄 범위입니다.
|
||||
- `toolResultMaxChars`: 영속화된 결과와 오버플로 복구에 사용되는 라이브 도구 결과 상한입니다.
|
||||
- `memoryGetMaxChars`: 잘라내기 메타데이터와 이어가기 알림이 추가되기 전 기본 `memory_get` 발췌 상한입니다.
|
||||
- `memoryGetDefaultLines`: `lines`가 생략되었을 때 기본 `memory_get` 줄 창입니다.
|
||||
- `toolResultMaxChars`: 영구 저장된 결과와 오버플로 복구에 사용되는 실시간 도구 결과 상한입니다.
|
||||
- `postCompactionMaxChars`: Compaction 이후 새로고침 주입 중 사용되는 AGENTS.md 발췌 상한입니다.
|
||||
|
||||
#### `agents.list[].contextLimits`
|
||||
@ -234,8 +237,7 @@ OpenClaw에는 여러 대용량 프롬프트/컨텍스트 예산이 있으며,
|
||||
|
||||
#### `skills.limits.maxSkillsPromptChars`
|
||||
|
||||
시스템 프롬프트에 주입되는 압축된 Skills 목록의 전역 상한입니다. 이는
|
||||
필요할 때 `SKILL.md` 파일을 읽는 데 영향을 주지 않습니다.
|
||||
시스템 프롬프트에 주입되는 압축 Skills 목록의 전역 상한입니다. 이는 필요 시 `SKILL.md` 파일을 읽는 것에는 영향을 주지 않습니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -268,11 +270,11 @@ Skills 프롬프트 예산에 대한 에이전트별 재정의입니다.
|
||||
|
||||
### `agents.defaults.imageMaxDimensionPx`
|
||||
|
||||
제공자 호출 전 대화 기록/도구 이미지 블록에서 가장 긴 이미지 변의 최대 픽셀 크기입니다.
|
||||
프로바이더 호출 전 대화 기록/도구 이미지 블록에서 가장 긴 이미지 변의 최대 픽셀 크기입니다.
|
||||
기본값: `1200`.
|
||||
|
||||
값이 낮을수록 보통 스크린샷이 많은 실행의 비전 토큰 사용량과 요청 페이로드 크기가 줄어듭니다.
|
||||
값이 높을수록 더 많은 시각적 세부 정보를 보존합니다.
|
||||
낮은 값은 일반적으로 스크린샷이 많은 실행에서 비전 토큰 사용량과 요청 페이로드 크기를 줄입니다.
|
||||
높은 값은 더 많은 시각적 세부 정보를 보존합니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -282,7 +284,7 @@ Skills 프롬프트 예산에 대한 에이전트별 재정의입니다.
|
||||
|
||||
### `agents.defaults.userTimezone`
|
||||
|
||||
시스템 프롬프트 컨텍스트의 시간대입니다(메시지 타임스탬프 아님). 호스트 시간대로 폴백합니다.
|
||||
시스템 프롬프트 컨텍스트의 시간대입니다(메시지 타임스탬프가 아님). 호스트 시간대로 대체됩니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -292,7 +294,7 @@ Skills 프롬프트 예산에 대한 에이전트별 재정의입니다.
|
||||
|
||||
### `agents.defaults.timeFormat`
|
||||
|
||||
시스템 프롬프트의 시간 형식입니다. 기본값: `auto`(OS 기본 설정).
|
||||
시스템 프롬프트의 시간 형식입니다. 기본값: `auto`(OS 환경설정).
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -338,6 +340,7 @@ Skills 프롬프트 예산에 대한 에이전트별 재정의입니다.
|
||||
pdfMaxPages: 20,
|
||||
thinkingDefault: "low",
|
||||
verboseDefault: "off",
|
||||
toolProgressDetail: "explain",
|
||||
reasoningDefault: "off",
|
||||
elevatedDefault: "on",
|
||||
timeoutSeconds: 600,
|
||||
@ -355,52 +358,53 @@ Skills 프롬프트 예산에 대한 에이전트별 재정의입니다.
|
||||
- `imageModel`: 문자열(`"provider/model"`) 또는 객체(`{ primary, fallbacks }`)를 허용합니다.
|
||||
- `image` 도구 경로에서 비전 모델 구성으로 사용됩니다.
|
||||
- 선택된/기본 모델이 이미지 입력을 받을 수 없을 때 대체 라우팅으로도 사용됩니다.
|
||||
- 명시적인 `provider/model` 참조를 권장합니다. 호환성을 위해 단독 ID도 허용됩니다. 단독 ID가 `models.providers.*.models`에 구성된 이미지 지원 항목과 고유하게 일치하면 OpenClaw가 해당 provider로 한정합니다. 구성된 일치 항목이 모호한 경우 명시적인 provider 접두사가 필요합니다.
|
||||
- 명시적인 `provider/model` 참조를 권장합니다. 호환성을 위해 단독 ID도 허용됩니다. 단독 ID가 `models.providers.*.models`에 구성된 이미지 지원 항목과 고유하게 일치하면 OpenClaw가 해당 제공자로 한정합니다. 구성된 일치 항목이 모호하면 명시적인 제공자 접두사가 필요합니다.
|
||||
- `imageGenerationModel`: 문자열(`"provider/model"`) 또는 객체(`{ primary, fallbacks }`)를 허용합니다.
|
||||
- 공유 이미지 생성 기능과 이미지를 생성하는 향후 모든 도구/Plugin 표면에서 사용됩니다.
|
||||
- 일반적인 값: 네이티브 Gemini 이미지 생성의 경우 `google/gemini-3.1-flash-image-preview`, fal의 경우 `fal/fal-ai/flux/dev`, OpenAI Images의 경우 `openai/gpt-image-2`, 투명 배경 OpenAI PNG/WebP 출력의 경우 `openai/gpt-image-1.5`.
|
||||
- provider/model을 직접 선택하는 경우 일치하는 provider 인증도 구성하세요(예: `google/*`에는 `GEMINI_API_KEY` 또는 `GOOGLE_API_KEY`, `openai/gpt-image-2` / `openai/gpt-image-1.5`에는 `OPENAI_API_KEY` 또는 OpenAI Codex OAuth, `fal/*`에는 `FAL_KEY`).
|
||||
- 생략하면 `image_generate`는 인증 기반 provider 기본값을 여전히 추론할 수 있습니다. 현재 기본 provider를 먼저 시도한 다음, provider ID 순서대로 나머지 등록된 이미지 생성 provider를 시도합니다.
|
||||
- 공유 이미지 생성 기능과 이미지를 생성하는 향후 도구/Plugin 표면에서 사용됩니다.
|
||||
- 일반적인 값: 네이티브 Gemini 이미지 생성에는 `google/gemini-3.1-flash-image-preview`, fal에는 `fal/fal-ai/flux/dev`, OpenAI Images에는 `openai/gpt-image-2`, 투명 배경 OpenAI PNG/WebP 출력에는 `openai/gpt-image-1.5`.
|
||||
- 제공자/모델을 직접 선택하는 경우 일치하는 제공자 인증도 구성하세요(예: `google/*`에는 `GEMINI_API_KEY` 또는 `GOOGLE_API_KEY`, `openai/gpt-image-2` / `openai/gpt-image-1.5`에는 `OPENAI_API_KEY` 또는 OpenAI Codex OAuth, `fal/*`에는 `FAL_KEY`).
|
||||
- 생략하면 `image_generate`가 인증 기반 제공자 기본값을 계속 추론할 수 있습니다. 먼저 현재 기본 제공자를 시도한 다음, 나머지 등록된 이미지 생성 제공자를 제공자 ID 순서대로 시도합니다.
|
||||
- `musicGenerationModel`: 문자열(`"provider/model"`) 또는 객체(`{ primary, fallbacks }`)를 허용합니다.
|
||||
- 공유 음악 생성 기능과 내장 `music_generate` 도구에서 사용됩니다.
|
||||
- 일반적인 값: `google/lyria-3-clip-preview`, `google/lyria-3-pro-preview` 또는 `minimax/music-2.6`.
|
||||
- 생략하면 `music_generate`는 인증 기반 provider 기본값을 여전히 추론할 수 있습니다. 현재 기본 provider를 먼저 시도한 다음, provider ID 순서대로 나머지 등록된 음악 생성 provider를 시도합니다.
|
||||
- provider/model을 직접 선택하는 경우 일치하는 provider 인증/API 키도 구성하세요.
|
||||
- 생략하면 `music_generate`가 인증 기반 제공자 기본값을 계속 추론할 수 있습니다. 먼저 현재 기본 제공자를 시도한 다음, 나머지 등록된 음악 생성 제공자를 제공자 ID 순서대로 시도합니다.
|
||||
- 제공자/모델을 직접 선택하는 경우 일치하는 제공자 인증/API 키도 구성하세요.
|
||||
- `videoGenerationModel`: 문자열(`"provider/model"`) 또는 객체(`{ primary, fallbacks }`)를 허용합니다.
|
||||
- 공유 비디오 생성 기능과 내장 `video_generate` 도구에서 사용됩니다.
|
||||
- 공유 동영상 생성 기능과 내장 `video_generate` 도구에서 사용됩니다.
|
||||
- 일반적인 값: `qwen/wan2.6-t2v`, `qwen/wan2.6-i2v`, `qwen/wan2.6-r2v`, `qwen/wan2.6-r2v-flash` 또는 `qwen/wan2.7-r2v`.
|
||||
- 생략하면 `video_generate`는 인증 기반 provider 기본값을 여전히 추론할 수 있습니다. 현재 기본 provider를 먼저 시도한 다음, provider ID 순서대로 나머지 등록된 비디오 생성 provider를 시도합니다.
|
||||
- provider/model을 직접 선택하는 경우 일치하는 provider 인증/API 키도 구성하세요.
|
||||
- 번들 Qwen 비디오 생성 provider는 출력 비디오 최대 1개, 입력 이미지 1개, 입력 비디오 4개, 길이 10초, provider 수준 `size`, `aspectRatio`, `resolution`, `audio`, `watermark` 옵션을 지원합니다.
|
||||
- 생략하면 `video_generate`가 인증 기반 제공자 기본값을 계속 추론할 수 있습니다. 먼저 현재 기본 제공자를 시도한 다음, 나머지 등록된 동영상 생성 제공자를 제공자 ID 순서대로 시도합니다.
|
||||
- 제공자/모델을 직접 선택하는 경우 일치하는 제공자 인증/API 키도 구성하세요.
|
||||
- 번들 Qwen 동영상 생성 제공자는 출력 동영상 최대 1개, 입력 이미지 1개, 입력 동영상 4개, 길이 10초, 제공자 수준 `size`, `aspectRatio`, `resolution`, `audio`, `watermark` 옵션을 지원합니다.
|
||||
- `pdfModel`: 문자열(`"provider/model"`) 또는 객체(`{ primary, fallbacks }`)를 허용합니다.
|
||||
- `pdf` 도구에서 모델 라우팅에 사용됩니다.
|
||||
- 생략하면 PDF 도구는 `imageModel`로, 그다음에는 해석된 세션/기본 모델로 대체합니다.
|
||||
- `pdfMaxBytesMb`: 호출 시 `maxBytesMb`가 전달되지 않은 경우 `pdf` 도구의 기본 PDF 크기 제한입니다.
|
||||
- 모델 라우팅을 위해 `pdf` 도구에서 사용됩니다.
|
||||
- 생략하면 PDF 도구는 `imageModel`로 대체한 다음, 해석된 세션/기본 모델로 대체합니다.
|
||||
- `pdfMaxBytesMb`: 호출 시 `maxBytesMb`가 전달되지 않았을 때 `pdf` 도구의 기본 PDF 크기 제한입니다.
|
||||
- `pdfMaxPages`: `pdf` 도구의 추출 대체 모드에서 고려하는 기본 최대 페이지 수입니다.
|
||||
- `verboseDefault`: 에이전트의 기본 상세 출력 수준입니다. 값: `"off"`, `"on"`, `"full"`. 기본값: `"off"`.
|
||||
- `reasoningDefault`: 에이전트의 기본 reasoning 표시 여부입니다. 값: `"off"`, `"on"`, `"stream"`. 에이전트별 `agents.list[].reasoningDefault`가 이 기본값을 재정의합니다. 구성된 reasoning 기본값은 메시지별 또는 세션 reasoning 재정의가 설정되지 않은 경우, 소유자, 승인된 발신자 또는 operator-admin Gateway 컨텍스트에만 적용됩니다.
|
||||
- `elevatedDefault`: 에이전트의 기본 elevated-output 수준입니다. 값: `"off"`, `"on"`, `"ask"`, `"full"`. 기본값: `"on"`.
|
||||
- `model.primary`: 형식은 `provider/model`입니다(예: API 키 접근의 경우 `openai/gpt-5.5`, Codex OAuth의 경우 `openai-codex/gpt-5.5`). provider를 생략하면 OpenClaw는 먼저 별칭을 시도한 다음, 해당 정확한 모델 ID와 고유하게 일치하는 구성된 provider를 시도하고, 그다음에야 구성된 기본 provider로 대체합니다(더 이상 권장되지 않는 호환성 동작이므로 명시적인 `provider/model`을 권장). 해당 provider가 구성된 기본 모델을 더 이상 노출하지 않으면 OpenClaw는 오래된 제거된 provider 기본값을 표시하는 대신 첫 번째 구성된 provider/model로 대체합니다.
|
||||
- `models`: `/model`의 구성된 모델 카탈로그 및 허용 목록입니다. 각 항목에는 `alias`(단축키)와 `params`(provider별, 예: `temperature`, `maxTokens`, `cacheRetention`, `context1m`, `responsesServerCompaction`, `responsesCompactThreshold`, `chat_template_kwargs`, `extra_body`/`extraBody`)가 포함될 수 있습니다.
|
||||
- `toolProgressDetail`: `/verbose` 도구 요약 및 진행 초안 도구 줄의 세부 정보 모드입니다. 값: `"explain"`(기본값, 간결한 사람이 읽기 쉬운 라벨) 또는 `"raw"`(가능한 경우 원시 명령/세부 정보 추가). 에이전트별 `agents.list[].toolProgressDetail`은 이 기본값을 재정의합니다.
|
||||
- `reasoningDefault`: 에이전트의 기본 추론 표시 여부입니다. 값: `"off"`, `"on"`, `"stream"`. 에이전트별 `agents.list[].reasoningDefault`는 이 기본값을 재정의합니다. 구성된 추론 기본값은 메시지별 또는 세션별 추론 재정의가 설정되지 않은 경우에만 소유자, 승인된 발신자 또는 운영자 관리자 Gateway 컨텍스트에 적용됩니다.
|
||||
- `elevatedDefault`: 에이전트의 기본 승격 출력 수준입니다. 값: `"off"`, `"on"`, `"ask"`, `"full"`. 기본값: `"on"`.
|
||||
- `model.primary`: 형식은 `provider/model`입니다(예: API 키 접근에는 `openai/gpt-5.5`, Codex OAuth에는 `openai-codex/gpt-5.5`). 제공자를 생략하면 OpenClaw는 먼저 별칭을 시도하고, 그다음 해당 정확한 모델 ID에 대해 고유하게 구성된 제공자 일치를 시도한 뒤, 마지막으로 구성된 기본 제공자로 대체합니다(사용 중단된 호환성 동작이므로 명시적인 `provider/model`을 권장). 해당 제공자가 구성된 기본 모델을 더 이상 노출하지 않으면 OpenClaw는 오래된 제거된 제공자 기본값을 표시하는 대신 처음 구성된 제공자/모델로 대체합니다.
|
||||
- `models`: `/model`에 대해 구성된 모델 카탈로그 및 허용 목록입니다. 각 항목에는 `alias`(단축 이름)와 `params`(제공자별, 예: `temperature`, `maxTokens`, `cacheRetention`, `context1m`, `responsesServerCompaction`, `responsesCompactThreshold`, `chat_template_kwargs`, `extra_body`/`extraBody`)를 포함할 수 있습니다.
|
||||
- 안전한 편집: 항목을 추가하려면 `openclaw config set agents.defaults.models '<json>' --strict-json --merge`를 사용하세요. `config set`은 `--replace`를 전달하지 않는 한 기존 허용 목록 항목을 제거하는 대체를 거부합니다.
|
||||
- provider 범위 구성/온보딩 흐름은 선택한 provider 모델을 이 맵에 병합하고 이미 구성된 관련 없는 provider를 보존합니다.
|
||||
- 직접 OpenAI Responses 모델의 경우 서버 측 Compaction이 자동으로 활성화됩니다. `context_management` 주입을 중지하려면 `params.responsesServerCompaction: false`를 사용하고, 임곗값을 재정의하려면 `params.responsesCompactThreshold`를 사용하세요. [OpenAI 서버 측 Compaction](/ko/providers/openai#server-side-compaction-responses-api)을 참조하세요.
|
||||
- `params`: 모든 모델에 적용되는 전역 기본 provider 매개변수입니다. `agents.defaults.params`에 설정합니다(예: `{ cacheRetention: "long" }`).
|
||||
- `params` 병합 우선순위(구성): `agents.defaults.params`(전역 기준)는 `agents.defaults.models["provider/model"].params`(모델별)에 의해 재정의되고, 그다음 `agents.list[].params`(일치하는 에이전트 ID)가 키별로 재정의합니다. 자세한 내용은 [Prompt Caching](/ko/reference/prompt-caching)을 참조하세요.
|
||||
- `params.extra_body`/`params.extraBody`: OpenAI 호환 프록시의 `api: "openai-completions"` 요청 본문에 병합되는 고급 통과 JSON입니다. 생성된 요청 키와 충돌하면 추가 본문이 우선합니다. 비네이티브 completions 경로는 이후에도 OpenAI 전용 `store`를 제거합니다.
|
||||
- `params.chat_template_kwargs`: 최상위 `api: "openai-completions"` 요청 본문에 병합되는 vLLM/OpenAI 호환 채팅 템플릿 인수입니다. thinking이 꺼진 `vllm/nemotron-3-*`의 경우, 번들 vLLM Plugin은 자동으로 `enable_thinking: false`와 `force_nonempty_content: true`를 보냅니다. 명시적인 `chat_template_kwargs`는 생성된 기본값을 재정의하며, `extra_body.chat_template_kwargs`가 여전히 최종 우선순위를 가집니다. vLLM Qwen thinking 제어의 경우 해당 모델 항목에서 `params.qwenThinkingFormat`을 `"chat-template"` 또는 `"top-level"`로 설정하세요.
|
||||
- `compat.supportedReasoningEfforts`: 모델별 OpenAI 호환 reasoning effort 목록입니다. 실제로 이를 허용하는 사용자 지정 엔드포인트에는 `"xhigh"`를 포함하세요. 그러면 OpenClaw가 명령 메뉴, Gateway 세션 행, 세션 패치 검증, 에이전트 CLI 검증, 그리고 해당 구성된 provider/model의 `llm-task` 검증에서 `/think xhigh`를 노출합니다. 백엔드가 표준 수준에 대해 provider별 값을 원하는 경우 `compat.reasoningEffortMap`을 사용하세요.
|
||||
- `params.preserveThinking`: 보존된 thinking을 위한 Z.AI 전용 옵트인입니다. 활성화되고 thinking이 켜져 있으면 OpenClaw는 `thinking.clear_thinking: false`를 보내고 이전 `reasoning_content`를 재생합니다. [Z.AI thinking 및 보존된 thinking](/ko/providers/zai#thinking-and-preserved-thinking)을 참조하세요.
|
||||
- `agentRuntime`: 기본 저수준 에이전트 런타임 정책입니다. ID를 생략하면 기본값은 OpenClaw Pi입니다. 내장 PI 하네스를 강제하려면 `id: "pi"`를 사용하고, 등록된 Plugin 하네스가 지원되는 모델을 클레임하고 일치 항목이 없을 때 PI를 사용하게 하려면 `id: "auto"`를 사용하고, 해당 하네스를 요구하려면 `id: "codex"` 같은 등록된 하네스 ID를 사용하거나, `id: "claude-cli"` 같은 지원되는 CLI 백엔드 별칭을 사용하세요. 명시적인 Plugin 런타임은 하네스를 사용할 수 없거나 실패하면 닫힌 상태로 실패합니다. 모델 참조는 `provider/model`로 표준화해 유지하세요. 레거시 런타임 provider 접두사 대신 런타임 구성을 통해 Codex, Claude CLI, Gemini CLI 및 기타 실행 백엔드를 선택하세요. 이것이 provider/model 선택과 어떻게 다른지는 [에이전트 런타임](/ko/concepts/agent-runtimes)을 참조하세요.
|
||||
- 이러한 필드를 변경하는 구성 작성기(예: `/models set`, `/models set-image`, 대체 추가/제거 명령)는 표준 객체 형식으로 저장하고 가능하면 기존 대체 목록을 보존합니다.
|
||||
- 제공자 범위의 구성/온보딩 흐름은 선택된 제공자 모델을 이 맵에 병합하고 이미 구성된 관련 없는 제공자를 보존합니다.
|
||||
- 직접 OpenAI Responses 모델의 경우 서버 측 Compaction이 자동으로 활성화됩니다. `context_management` 주입을 중지하려면 `params.responsesServerCompaction: false`를 사용하고, 임계값을 재정의하려면 `params.responsesCompactThreshold`를 사용하세요. [OpenAI 서버 측 Compaction](/ko/providers/openai#server-side-compaction-responses-api)을 참조하세요.
|
||||
- `params`: 모든 모델에 적용되는 전역 기본 제공자 매개변수입니다. `agents.defaults.params`에서 설정합니다(예: `{ cacheRetention: "long" }`).
|
||||
- `params` 병합 우선순위(구성): `agents.defaults.params`(전역 기반)는 `agents.defaults.models["provider/model"].params`(모델별)로 재정의되고, 그다음 `agents.list[].params`(일치하는 에이전트 ID)가 키별로 재정의합니다. 자세한 내용은 [프롬프트 캐싱](/ko/reference/prompt-caching)을 참조하세요.
|
||||
- `params.extra_body`/`params.extraBody`: OpenAI 호환 프록시의 `api: "openai-completions"` 요청 본문에 병합되는 고급 통과 JSON입니다. 생성된 요청 키와 충돌하면 추가 본문이 우선합니다. 네이티브가 아닌 completions 경로는 이후에도 OpenAI 전용 `store`를 제거합니다.
|
||||
- `params.chat_template_kwargs`: 최상위 `api: "openai-completions"` 요청 본문에 병합되는 vLLM/OpenAI 호환 채팅 템플릿 인수입니다. thinking이 꺼진 `vllm/nemotron-3-*`의 경우 번들 vLLM Plugin이 자동으로 `enable_thinking: false`와 `force_nonempty_content: true`를 전송합니다. 명시적인 `chat_template_kwargs`는 생성된 기본값을 재정의하고, `extra_body.chat_template_kwargs`가 여전히 최종 우선순위를 갖습니다. vLLM Qwen thinking 제어의 경우 해당 모델 항목에서 `params.qwenThinkingFormat`을 `"chat-template"` 또는 `"top-level"`로 설정하세요.
|
||||
- `compat.supportedReasoningEfforts`: 모델별 OpenAI 호환 추론 노력 목록입니다. 실제로 이를 허용하는 사용자 지정 엔드포인트에는 `"xhigh"`를 포함하세요. 그러면 OpenClaw가 해당 구성된 제공자/모델에 대해 명령 메뉴, Gateway 세션 행, 세션 패치 검증, 에이전트 CLI 검증, `llm-task` 검증에서 `/think xhigh`를 노출합니다. 백엔드가 표준 수준에 대해 제공자별 값을 원하는 경우 `compat.reasoningEffortMap`을 사용하세요.
|
||||
- `params.preserveThinking`: 보존된 thinking을 위한 Z.AI 전용 옵트인입니다. 활성화되고 thinking이 켜져 있으면 OpenClaw는 `thinking.clear_thinking: false`를 전송하고 이전 `reasoning_content`를 재생합니다. [Z.AI thinking 및 보존된 thinking](/ko/providers/zai#thinking-and-preserved-thinking)을 참조하세요.
|
||||
- `agentRuntime`: 기본 저수준 에이전트 런타임 정책입니다. 생략된 ID는 기본적으로 OpenClaw Pi가 됩니다. 내장 PI 하네스를 강제하려면 `id: "pi"`를 사용하고, 등록된 Plugin 하네스가 지원되는 모델을 처리하도록 하고 일치 항목이 없을 때 PI를 사용하려면 `id: "auto"`를 사용하며, 해당 하네스를 요구하려면 `id: "codex"` 같은 등록된 하네스 ID를 사용하거나 `id: "claude-cli"` 같은 지원되는 CLI 백엔드 별칭을 사용하세요. 명시적 Plugin 런타임은 하네스를 사용할 수 없거나 실패하면 닫힌 상태로 실패합니다. 모델 참조는 `provider/model`로 표준화해 유지하세요. 레거시 런타임 제공자 접두사 대신 런타임 구성을 통해 Codex, Claude CLI, Gemini CLI 및 기타 실행 백엔드를 선택하세요. 이것이 제공자/모델 선택과 어떻게 다른지는 [에이전트 런타임](/ko/concepts/agent-runtimes)을 참조하세요.
|
||||
- 이러한 필드를 변경하는 구성 작성기(예: `/models set`, `/models set-image`, 대체 추가/제거 명령)는 표준 객체 형식으로 저장하고 가능한 경우 기존 대체 목록을 보존합니다.
|
||||
- `maxConcurrent`: 세션 전체의 최대 병렬 에이전트 실행 수입니다(각 세션은 여전히 직렬화됨). 기본값: 4.
|
||||
|
||||
### `agents.defaults.agentRuntime`
|
||||
|
||||
`agentRuntime`은 어떤 저수준 실행기가 에이전트 턴을 실행하는지 제어합니다. 대부분의
|
||||
배포에서는 기본 OpenClaw Pi 런타임을 유지해야 합니다. 번들 Codex app-server 하네스처럼
|
||||
신뢰할 수 있는 Plugin이 네이티브 하네스를 제공하거나, Claude CLI 같은 지원되는 CLI 백엔드를
|
||||
원할 때 사용하세요. 개념 모델은 [에이전트 런타임](/ko/concepts/agent-runtimes)을 참조하세요.
|
||||
`agentRuntime`은 에이전트 턴을 실행하는 저수준 실행기를 제어합니다. 대부분의
|
||||
배포는 기본 OpenClaw Pi 런타임을 유지해야 합니다. 번들 Codex 앱 서버 하네스와 같이 신뢰할 수 있는
|
||||
Plugin이 네이티브 하네스를 제공하거나, Claude CLI 같은 지원되는 CLI 백엔드를 사용하려는 경우 사용하세요. 멘탈
|
||||
모델은 [에이전트 런타임](/ko/concepts/agent-runtimes)을 참조하세요.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -415,22 +419,22 @@ Skills 프롬프트 예산에 대한 에이전트별 재정의입니다.
|
||||
}
|
||||
```
|
||||
|
||||
- `id`: `"auto"`, `"pi"`, 등록된 Plugin 하네스 ID 또는 지원되는 CLI 백엔드 별칭입니다. 번들 Codex Plugin은 `codex`를 등록합니다. 번들 Anthropic Plugin은 `claude-cli` CLI 백엔드를 제공합니다.
|
||||
- `id: "auto"`는 등록된 Plugin 하네스가 지원되는 턴을 클레임하도록 하고, 일치하는 하네스가 없으면 PI를 사용합니다. `id: "codex"` 같은 명시적인 Plugin 런타임은 해당 하네스를 요구하며, 사용할 수 없거나 실패하면 닫힌 상태로 실패합니다.
|
||||
- `id`: `"auto"`, `"pi"`, 등록된 Plugin 하네스 ID 또는 지원되는 CLI 백엔드 별칭입니다. 번들 Codex Plugin은 `codex`를 등록하고, 번들 Anthropic Plugin은 `claude-cli` CLI 백엔드를 제공합니다.
|
||||
- `id: "auto"`는 등록된 Plugin 하네스가 지원되는 턴을 처리하게 하고, 일치하는 하네스가 없으면 PI를 사용합니다. `id: "codex"` 같은 명시적 Plugin 런타임은 해당 하네스를 요구하며, 사용할 수 없거나 실패하면 닫힌 상태로 실패합니다.
|
||||
- 환경 재정의: `OPENCLAW_AGENT_RUNTIME=<id|auto|pi>`는 해당 프로세스의 `id`를 재정의합니다.
|
||||
- Codex 전용 배포의 경우 `model: "openai/gpt-5.5"` 및 `agentRuntime.id: "codex"`를 설정하세요.
|
||||
- Claude CLI 배포의 경우 `model: "anthropic/claude-opus-4-7"`와 `agentRuntime.id: "claude-cli"`를 권장합니다. 레거시 `claude-cli/claude-opus-4-7` 모델 참조도 호환성을 위해 계속 작동하지만, 새 구성은 provider/model 선택을 표준 형식으로 유지하고 실행 백엔드를 `agentRuntime.id`에 넣어야 합니다.
|
||||
- Codex 전용 배포의 경우 `model: "openai/gpt-5.5"`와 `agentRuntime.id: "codex"`를 설정하세요.
|
||||
- Claude CLI 배포의 경우 `model: "anthropic/claude-opus-4-7"`와 `agentRuntime.id: "claude-cli"`를 권장합니다. 레거시 `claude-cli/claude-opus-4-7` 모델 참조도 호환성을 위해 계속 작동하지만, 새 구성은 제공자/모델 선택을 표준 형식으로 유지하고 실행 백엔드는 `agentRuntime.id`에 넣어야 합니다.
|
||||
- 이전 런타임 정책 키는 `openclaw doctor --fix`에 의해 `agentRuntime`으로 다시 작성됩니다.
|
||||
- 하네스 선택은 첫 번째 임베디드 실행 후 세션 ID별로 고정됩니다. 구성/env 변경은 기존 transcript가 아닌 신규 또는 재설정된 세션에 영향을 줍니다. transcript 기록은 있지만 기록된 고정값이 없는 레거시 세션은 PI에 고정된 것으로 처리됩니다. `/status`는 유효한 런타임을 보고합니다(예: `Runtime: OpenClaw Pi Default` 또는 `Runtime: OpenAI Codex`).
|
||||
- 이는 텍스트 에이전트 턴 실행만 제어합니다. 미디어 생성, 비전, PDF, 음악, 비디오 및 TTS는 여전히 각 provider/model 설정을 사용합니다.
|
||||
- 하네스 선택은 첫 번째 임베디드 실행 이후 세션 ID별로 고정됩니다. 구성/env 변경은 새 세션 또는 재설정된 세션에 영향을 주며, 기존 transcript에는 영향을 주지 않습니다. transcript 기록은 있지만 기록된 고정값이 없는 레거시 세션은 PI 고정으로 처리됩니다. `/status`는 유효 런타임을 보고합니다. 예: `Runtime: OpenClaw Pi Default` 또는 `Runtime: OpenAI Codex`.
|
||||
- 이는 텍스트 에이전트 턴 실행만 제어합니다. 미디어 생성, 비전, PDF, 음악, 동영상, TTS는 계속 해당 제공자/모델 설정을 사용합니다.
|
||||
|
||||
**내장 별칭 단축 표기**(`agents.defaults.models`에 모델이 있을 때만 적용):
|
||||
**내장 별칭 단축형**(`agents.defaults.models`에 모델이 있을 때만 적용됨):
|
||||
|
||||
| 별칭 | 모델 |
|
||||
| ------------------- | ------------------------------------------ |
|
||||
| `opus` | `anthropic/claude-opus-4-6` |
|
||||
| `sonnet` | `anthropic/claude-sonnet-4-6` |
|
||||
| `gpt` | `openai/gpt-5.5` 또는 `openai-codex/gpt-5.5` |
|
||||
| `gpt` | `openai/gpt-5.5` or `openai-codex/gpt-5.5` |
|
||||
| `gpt-mini` | `openai/gpt-5.4-mini` |
|
||||
| `gpt-nano` | `openai/gpt-5.4-nano` |
|
||||
| `gemini` | `google/gemini-3.1-pro-preview` |
|
||||
@ -439,9 +443,9 @@ Skills 프롬프트 예산에 대한 에이전트별 재정의입니다.
|
||||
|
||||
구성한 별칭은 항상 기본값보다 우선합니다.
|
||||
|
||||
Z.AI GLM-4.x 모델은 `--thinking off`를 설정하거나 `agents.defaults.models["zai/<model>"].params.thinking`을 직접 정의하지 않는 한 생각 모드를 자동으로 활성화합니다.
|
||||
Z.AI GLM-4.x 모델은 `--thinking off`를 설정하거나 `agents.defaults.models["zai/<model>"].params.thinking`을 직접 정의하지 않는 한 thinking 모드를 자동으로 활성화합니다.
|
||||
Z.AI 모델은 도구 호출 스트리밍을 위해 기본적으로 `tool_stream`을 활성화합니다. 비활성화하려면 `agents.defaults.models["zai/<model>"].params.tool_stream`을 `false`로 설정하세요.
|
||||
Anthropic Claude 4.6 모델은 명시적인 생각 수준이 설정되지 않은 경우 기본값으로 `adaptive` 생각을 사용합니다.
|
||||
Anthropic Claude 4.6 모델은 명시적인 thinking 수준이 설정되지 않은 경우 기본값으로 `adaptive` thinking을 사용합니다.
|
||||
|
||||
### `agents.defaults.cliBackends`
|
||||
|
||||
@ -474,13 +478,13 @@ Anthropic Claude 4.6 모델은 명시적인 생각 수준이 설정되지 않은
|
||||
}
|
||||
```
|
||||
|
||||
- CLI 백엔드는 텍스트 우선입니다. 도구는 항상 비활성화됩니다.
|
||||
- CLI 백엔드는 텍스트 우선이며, 도구는 항상 비활성화됩니다.
|
||||
- `sessionArg`가 설정된 경우 세션이 지원됩니다.
|
||||
- `imageArg`가 파일 경로를 허용하는 경우 이미지 패스스루가 지원됩니다.
|
||||
- `imageArg`가 파일 경로를 허용하는 경우 이미지 전달이 지원됩니다.
|
||||
|
||||
### `agents.defaults.systemPromptOverride`
|
||||
|
||||
OpenClaw가 조립한 전체 시스템 프롬프트를 고정 문자열로 대체합니다. 기본 수준(`agents.defaults.systemPromptOverride`) 또는 에이전트별(`agents.list[].systemPromptOverride`)로 설정하세요. 에이전트별 값이 우선하며, 비어 있거나 공백만 있는 값은 무시됩니다. 제어된 프롬프트 실험에 유용합니다.
|
||||
OpenClaw가 조립한 전체 시스템 프롬프트를 고정 문자열로 교체합니다. 기본 수준(`agents.defaults.systemPromptOverride`) 또는 에이전트별(`agents.list[].systemPromptOverride`)로 설정하세요. 에이전트별 값이 우선합니다. 비어 있거나 공백만 있는 값은 무시됩니다. 제어된 프롬프트 실험에 유용합니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -494,7 +498,7 @@ OpenClaw가 조립한 전체 시스템 프롬프트를 고정 문자열로 대
|
||||
|
||||
### `agents.defaults.promptOverlays`
|
||||
|
||||
모델 제품군별로 적용되는 공급자 독립적 프롬프트 오버레이입니다. GPT-5 제품군 모델 ID는 공급자 전반에서 공유 동작 계약을 받으며, `personality`는 친화적인 상호작용 스타일 레이어만 제어합니다.
|
||||
모델 계열별로 적용되는 공급자 독립 프롬프트 오버레이입니다. GPT-5 계열 모델 ID는 공급자 전반에서 공유 동작 계약을 받으며, `personality`는 친근한 상호작용 스타일 계층만 제어합니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -510,9 +514,9 @@ OpenClaw가 조립한 전체 시스템 프롬프트를 고정 문자열로 대
|
||||
}
|
||||
```
|
||||
|
||||
- `"friendly"`(기본값)와 `"on"`은 친화적인 상호작용 스타일 레이어를 활성화합니다.
|
||||
- `"off"`는 친화적인 레이어만 비활성화합니다. 태그가 지정된 GPT-5 동작 계약은 계속 활성화됩니다.
|
||||
- 이 공유 설정이 설정되지 않은 경우에도 레거시 `plugins.entries.openai.config.personality`가 계속 읽힙니다.
|
||||
- `"friendly"`(기본값)와 `"on"`은 친근한 상호작용 스타일 계층을 활성화합니다.
|
||||
- `"off"`는 친근한 계층만 비활성화합니다. 태그가 지정된 GPT-5 동작 계약은 계속 활성화됩니다.
|
||||
- 이 공유 설정이 설정되지 않은 경우 레거시 `plugins.entries.openai.config.personality`도 여전히 읽습니다.
|
||||
|
||||
### `agents.defaults.heartbeat`
|
||||
|
||||
@ -544,16 +548,16 @@ OpenClaw가 조립한 전체 시스템 프롬프트를 고정 문자열로 대
|
||||
}
|
||||
```
|
||||
|
||||
- `every`: 기간 문자열(ms/s/m/h). 기본값: `30m`(API 키 인증) 또는 `1h`(OAuth 인증). 비활성화하려면 `0m`으로 설정하세요.
|
||||
- `every`: 기간 문자열(ms/s/m/h)입니다. 기본값은 `30m`(API 키 인증) 또는 `1h`(OAuth 인증)입니다. 비활성화하려면 `0m`으로 설정하세요.
|
||||
- `includeSystemPromptSection`: false이면 시스템 프롬프트에서 Heartbeat 섹션을 생략하고 부트스트랩 컨텍스트에 `HEARTBEAT.md`를 주입하지 않습니다. 기본값: `true`.
|
||||
- `suppressToolErrorWarnings`: true이면 Heartbeat 실행 중 도구 오류 경고 페이로드를 억제합니다.
|
||||
- `timeoutSeconds`: Heartbeat 에이전트 턴이 중단되기 전에 허용되는 최대 시간(초)입니다. 설정하지 않으면 `agents.defaults.timeoutSeconds`를 사용합니다.
|
||||
- `timeoutSeconds`: Heartbeat 에이전트 턴이 중단되기 전 허용되는 최대 시간(초)입니다. 설정하지 않으면 `agents.defaults.timeoutSeconds`를 사용합니다.
|
||||
- `directPolicy`: 직접/DM 전달 정책입니다. `allow`(기본값)는 직접 대상 전달을 허용합니다. `block`은 직접 대상 전달을 억제하고 `reason=dm-blocked`를 내보냅니다.
|
||||
- `lightContext`: true이면 Heartbeat 실행이 경량 부트스트랩 컨텍스트를 사용하고 워크스페이스 부트스트랩 파일 중 `HEARTBEAT.md`만 유지합니다.
|
||||
- `isolatedSession`: true이면 각 Heartbeat가 이전 대화 기록이 없는 새 세션에서 실행됩니다. cron `sessionTarget: "isolated"`와 같은 격리 패턴입니다. Heartbeat당 토큰 비용을 약 100K에서 약 2-5K 토큰으로 줄입니다.
|
||||
- `skipWhenBusy`: true이면 Heartbeat 실행이 추가로 바쁜 레인, 즉 서브에이전트 또는 중첩 명령 작업에서도 지연됩니다. Cron 레인은 이 플래그가 없어도 항상 Heartbeat를 지연합니다.
|
||||
- 에이전트별: `agents.list[].heartbeat`를 설정하세요. 에이전트가 `heartbeat`를 정의하면 **해당 에이전트만** Heartbeat를 실행합니다.
|
||||
- Heartbeat는 전체 에이전트 턴을 실행합니다. 간격이 짧을수록 더 많은 토큰을 소모합니다.
|
||||
- `isolatedSession`: true이면 각 Heartbeat가 이전 대화 기록이 없는 새 세션에서 실행됩니다. cron `sessionTarget: "isolated"`와 동일한 격리 패턴입니다. Heartbeat당 토큰 비용을 약 100K에서 약 2-5K 토큰으로 줄입니다.
|
||||
- `skipWhenBusy`: true이면 Heartbeat 실행이 추가 사용 중 lane, 즉 서브에이전트 또는 중첩 명령 작업에서도 지연됩니다. Cron lane은 이 플래그가 없어도 항상 Heartbeat를 지연합니다.
|
||||
- 에이전트별: `agents.list[].heartbeat`를 설정하세요. 어떤 에이전트든 `heartbeat`를 정의하면 **해당 에이전트만** Heartbeat를 실행합니다.
|
||||
- Heartbeat는 전체 에이전트 턴을 실행하므로, 간격이 짧을수록 더 많은 토큰을 소모합니다.
|
||||
|
||||
### `agents.defaults.compaction`
|
||||
|
||||
@ -589,23 +593,23 @@ OpenClaw가 조립한 전체 시스템 프롬프트를 고정 문자열로 대
|
||||
}
|
||||
```
|
||||
|
||||
- `mode`: `default` 또는 `safeguard`(긴 기록을 위한 청크 기반 요약). [Compaction](/ko/concepts/compaction)을 참조하세요.
|
||||
- `provider`: 등록된 Compaction 공급자 Plugin의 ID입니다. 설정하면 내장 LLM 요약 대신 공급자의 `summarize()`가 호출됩니다. 실패 시 내장 방식으로 대체됩니다. 공급자를 설정하면 `mode: "safeguard"`가 강제됩니다. [Compaction](/ko/concepts/compaction)을 참조하세요.
|
||||
- `timeoutSeconds`: OpenClaw가 단일 Compaction 작업을 중단하기 전에 허용하는 최대 시간(초)입니다. 기본값: `900`.
|
||||
- `keepRecentTokens`: 가장 최근 transcript 꼬리를 원문 그대로 유지하기 위한 Pi 절단 지점 예산입니다. 수동 `/compact`는 이 값이 명시적으로 설정된 경우 이를 준수하며, 그렇지 않으면 수동 Compaction은 강제 체크포인트입니다.
|
||||
- `identifierPolicy`: `strict`(기본값), `off`, 또는 `custom`입니다. `strict`는 Compaction 요약 중 내장 불투명 식별자 보존 지침을 앞에 추가합니다.
|
||||
- `mode`: `default` 또는 `safeguard`(긴 기록을 위한 청크 기반 요약)입니다. [Compaction](/ko/concepts/compaction)을 참조하세요.
|
||||
- `provider`: 등록된 Compaction 공급자 Plugin의 ID입니다. 설정하면 기본 제공 LLM 요약 대신 공급자의 `summarize()`가 호출됩니다. 실패 시 기본 제공 방식으로 폴백합니다. 공급자를 설정하면 `mode: "safeguard"`가 강제됩니다. [Compaction](/ko/concepts/compaction)을 참조하세요.
|
||||
- `timeoutSeconds`: OpenClaw가 단일 Compaction 작업을 중단하기 전 허용하는 최대 초입니다. 기본값: `900`.
|
||||
- `keepRecentTokens`: 가장 최근 transcript tail을 그대로 유지하기 위한 Pi 절단 지점 예산입니다. 수동 `/compact`는 명시적으로 설정된 경우 이를 따르며, 그렇지 않으면 수동 Compaction은 하드 체크포인트입니다.
|
||||
- `identifierPolicy`: `strict`(기본값), `off`, 또는 `custom`입니다. `strict`는 Compaction 요약 중 기본 제공 불투명 식별자 보존 지침을 앞에 추가합니다.
|
||||
- `identifierInstructions`: `identifierPolicy=custom`일 때 사용되는 선택적 사용자 지정 식별자 보존 텍스트입니다.
|
||||
- `qualityGuard`: safeguard 요약에 대한 형식 오류 출력 재시도 검사입니다. safeguard 모드에서는 기본적으로 활성화됩니다. 감사를 건너뛰려면 `enabled: false`를 설정하세요.
|
||||
- `midTurnPrecheck`: 선택적 Pi 도구 루프 압력 검사입니다. `enabled: true`이면 OpenClaw는 도구 결과가 추가된 뒤 다음 모델 호출 전에 컨텍스트 압력을 확인합니다. 컨텍스트가 더 이상 맞지 않으면 프롬프트를 제출하기 전에 현재 시도를 중단하고 기존 사전 검사 복구 경로를 재사용하여 도구 결과를 잘라내거나 Compaction 후 재시도합니다. `default`와 `safeguard` Compaction 모드 모두에서 작동합니다. 기본값: 비활성화.
|
||||
- `postCompactionSections`: Compaction 후 다시 주입할 선택적 AGENTS.md H2/H3 섹션 이름입니다. 기본값은 `["Session Startup", "Red Lines"]`입니다. 재주입을 비활성화하려면 `[]`로 설정하세요. 설정되지 않았거나 명시적으로 해당 기본 쌍으로 설정된 경우, 이전 `Every Session`/`Safety` 제목도 레거시 대체값으로 허용됩니다.
|
||||
- `qualityGuard`: safeguard 요약에 대한 잘못된 출력 시 재시도 검사입니다. safeguard 모드에서 기본적으로 활성화되며, 감사를 건너뛰려면 `enabled: false`를 설정하세요.
|
||||
- `midTurnPrecheck`: 선택적 Pi 도구 루프 압력 검사입니다. `enabled: true`이면 OpenClaw는 도구 결과가 추가된 뒤 다음 모델 호출 전에 컨텍스트 압력을 확인합니다. 컨텍스트가 더 이상 맞지 않으면 프롬프트를 제출하기 전에 현재 시도를 중단하고 기존 사전 검사 복구 경로를 재사용하여 도구 결과를 자르거나 compact한 뒤 재시도합니다. `default`와 `safeguard` Compaction 모드 모두에서 작동합니다. 기본값: 비활성화.
|
||||
- `postCompactionSections`: Compaction 후 다시 주입할 선택적 AGENTS.md H2/H3 섹션 이름입니다. 기본값은 `["Session Startup", "Red Lines"]`입니다. 재주입을 비활성화하려면 `[]`로 설정하세요. 설정되지 않았거나 해당 기본 쌍으로 명시적으로 설정된 경우, 이전 `Every Session`/`Safety` 제목도 레거시 폴백으로 허용됩니다.
|
||||
- `model`: Compaction 요약에만 적용되는 선택적 `provider/model-id` 재정의입니다. 기본 세션은 한 모델을 유지하되 Compaction 요약은 다른 모델에서 실행해야 할 때 사용하세요. 설정하지 않으면 Compaction은 세션의 기본 모델을 사용합니다.
|
||||
- `maxActiveTranscriptBytes`: 활성 JSONL이 임계값을 초과해 커졌을 때 실행 전에 일반 로컬 Compaction을 트리거하는 선택적 바이트 임계값(`number` 또는 `"20mb"` 같은 문자열)입니다. 성공적인 Compaction이 더 작은 후속 transcript로 회전할 수 있도록 `truncateAfterCompaction`이 필요합니다. 설정되지 않았거나 `0`이면 비활성화됩니다.
|
||||
- `notifyUser`: `true`이면 Compaction이 시작될 때와 완료될 때 사용자에게 짧은 알림을 보냅니다(예: "Compacting context..." 및 "Compaction complete"). Compaction을 조용히 유지하기 위해 기본적으로 비활성화됩니다.
|
||||
- `memoryFlush`: 자동 Compaction 전에 durable memory를 저장하기 위한 조용한 에이전트 턴입니다. 이 housekeeping 턴이 로컬 모델에 머물러야 할 때 `model`을 `ollama/qwen3:8b` 같은 정확한 공급자/모델로 설정하세요. 재정의는 활성 세션 대체 체인을 상속하지 않습니다. 워크스페이스가 읽기 전용이면 건너뜁니다.
|
||||
- `maxActiveTranscriptBytes`: 활성 JSONL이 임계값을 넘으면 실행 전에 일반 로컬 Compaction을 트리거하는 선택적 바이트 임계값(`number` 또는 `"20mb"` 같은 문자열)입니다. 성공적인 Compaction이 더 작은 후속 transcript로 회전할 수 있도록 `truncateAfterCompaction`이 필요합니다. 설정되지 않았거나 `0`이면 비활성화됩니다.
|
||||
- `notifyUser`: `true`이면 Compaction이 시작될 때와 완료될 때 사용자에게 짧은 알림을 보냅니다(예: "컨텍스트를 Compact하는 중..." 및 "Compaction 완료"). Compaction을 조용히 유지하기 위해 기본적으로 비활성화됩니다.
|
||||
- `memoryFlush`: 자동 Compaction 전에 지속 메모리를 저장하기 위한 조용한 에이전트 턴입니다. 이 관리 턴을 로컬 모델에 유지해야 하는 경우 `model`을 `ollama/qwen3:8b` 같은 정확한 공급자/모델로 설정하세요. 이 재정의는 활성 세션 폴백 체인을 상속하지 않습니다. 워크스페이스가 읽기 전용이면 건너뜁니다.
|
||||
|
||||
### `agents.defaults.contextPruning`
|
||||
|
||||
LLM으로 보내기 전에 메모리 내 컨텍스트에서 **오래된 도구 결과**를 정리합니다. 디스크의 세션 기록은 수정하지 **않습니다**.
|
||||
LLM에 보내기 전에 메모리 내 컨텍스트에서 **오래된 도구 결과**를 정리합니다. 디스크의 세션 기록은 수정하지 **않습니다**.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -630,17 +634,17 @@ LLM으로 보내기 전에 메모리 내 컨텍스트에서 **오래된 도구
|
||||
<Accordion title="cache-ttl 모드 동작">
|
||||
|
||||
- `mode: "cache-ttl"`은 정리 패스를 활성화합니다.
|
||||
- `ttl`은 마지막 캐시 터치 이후 정리를 다시 실행할 수 있는 빈도를 제어합니다.
|
||||
- 정리는 먼저 너무 큰 도구 결과를 소프트 트림한 다음, 필요한 경우 더 오래된 도구 결과를 하드 클리어합니다.
|
||||
- `ttl`은 정리를 다시 실행할 수 있는 빈도(마지막 캐시 접촉 이후)를 제어합니다.
|
||||
- 정리는 먼저 크기가 큰 도구 결과를 soft-trim한 다음, 필요한 경우 더 오래된 도구 결과를 hard-clear합니다.
|
||||
|
||||
**소프트 트림**은 시작 + 끝을 유지하고 가운데에 `...`를 삽입합니다.
|
||||
**Soft-trim**은 시작 부분과 끝 부분을 유지하고 중간에 `...`을 삽입합니다.
|
||||
|
||||
**하드 클리어**는 전체 도구 결과를 플레이스홀더로 대체합니다.
|
||||
**Hard-clear**는 전체 도구 결과를 자리 표시자로 교체합니다.
|
||||
|
||||
참고:
|
||||
|
||||
- 이미지 블록은 절대 트림/클리어되지 않습니다.
|
||||
- 비율은 문자 기반(근사치)이며, 정확한 토큰 수가 아닙니다.
|
||||
- 이미지 블록은 절대 trim/clear되지 않습니다.
|
||||
- 비율은 정확한 토큰 수가 아니라 문자 기준(근사치)입니다.
|
||||
- `keepLastAssistants`보다 적은 assistant 메시지만 있으면 정리를 건너뜁니다.
|
||||
|
||||
</Accordion>
|
||||
@ -663,13 +667,13 @@ LLM으로 보내기 전에 메모리 내 컨텍스트에서 **오래된 도구
|
||||
}
|
||||
```
|
||||
|
||||
- Telegram이 아닌 채널은 블록 답장을 활성화하려면 명시적인 `*.blockStreaming: true`가 필요합니다.
|
||||
- 채널 재정의: `channels.<channel>.blockStreamingCoalesce`(및 계정별 변형). Signal/Slack/Discord/Google Chat 기본값은 `minChars: 1500`입니다.
|
||||
- `humanDelay`: 블록 답장 사이의 무작위 일시 중지입니다. `natural` = 800–2500ms. 에이전트별 재정의: `agents.list[].humanDelay`.
|
||||
- Telegram이 아닌 채널은 블록 응답을 활성화하려면 명시적으로 `*.blockStreaming: true`가 필요합니다.
|
||||
- 채널 재정의: `channels.<channel>.blockStreamingCoalesce`(및 계정별 변형). Signal/Slack/Discord/Google Chat의 기본값은 `minChars: 1500`입니다.
|
||||
- `humanDelay`: 블록 응답 사이의 무작위 일시 중지입니다. `natural` = 800–2500ms. 에이전트별 재정의: `agents.list[].humanDelay`.
|
||||
|
||||
동작 및 청크 처리 세부 정보는 [스트리밍](/ko/concepts/streaming)을 참조하세요.
|
||||
동작 및 청킹 세부 정보는 [스트리밍](/ko/concepts/streaming)을 참조하세요.
|
||||
|
||||
### 타이핑 표시기
|
||||
### 입력 중 표시기
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -685,13 +689,13 @@ LLM으로 보내기 전에 메모리 내 컨텍스트에서 **오래된 도구
|
||||
- 기본값: 직접 채팅/멘션에는 `instant`, 멘션되지 않은 그룹 채팅에는 `message`.
|
||||
- 세션별 재정의: `session.typingMode`, `session.typingIntervalSeconds`.
|
||||
|
||||
[입력 표시기](/ko/concepts/typing-indicators)를 참조하세요.
|
||||
[입력 표시기](/ko/concepts/typing-indicators)를 참고하세요.
|
||||
|
||||
<a id="agentsdefaultssandbox"></a>
|
||||
|
||||
### `agents.defaults.sandbox`
|
||||
|
||||
임베디드 에이전트를 위한 선택적 샌드박싱입니다. 전체 가이드는 [샌드박싱](/ko/gateway/sandboxing)을 참조하세요.
|
||||
내장 에이전트를 위한 선택적 샌드박싱입니다. 전체 가이드는 [샌드박싱](/ko/gateway/sandboxing)을 참고하세요.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -803,35 +807,35 @@ LLM으로 보내기 전에 메모리 내 컨텍스트에서 **오래된 도구
|
||||
- `command`: SSH 클라이언트 명령(기본값: `ssh`)
|
||||
- `workspaceRoot`: 범위별 워크스페이스에 사용되는 절대 원격 루트
|
||||
- `identityFile` / `certificateFile` / `knownHostsFile`: OpenSSH에 전달되는 기존 로컬 파일
|
||||
- `identityData` / `certificateData` / `knownHostsData`: OpenClaw가 런타임에 임시 파일로 구체화하는 인라인 콘텐츠 또는 SecretRefs
|
||||
- `strictHostKeyChecking` / `updateHostKeys`: OpenSSH 호스트 키 정책 조정 옵션
|
||||
- `identityData` / `certificateData` / `knownHostsData`: OpenClaw가 런타임에 임시 파일로 구체화하는 인라인 콘텐츠 또는 SecretRef
|
||||
- `strictHostKeyChecking` / `updateHostKeys`: OpenSSH 호스트 키 정책 조정 항목
|
||||
|
||||
**SSH 인증 우선순위:**
|
||||
|
||||
- `identityData`가 `identityFile`보다 우선합니다
|
||||
- `certificateData`가 `certificateFile`보다 우선합니다
|
||||
- `knownHostsData`가 `knownHostsFile`보다 우선합니다
|
||||
- SecretRef 기반 `*Data` 값은 샌드박스 세션이 시작되기 전에 활성 비밀 런타임 스냅샷에서 해석됩니다
|
||||
- SecretRef 기반 `*Data` 값은 샌드박스 세션이 시작되기 전에 활성 시크릿 런타임 스냅샷에서 확인됩니다
|
||||
|
||||
**SSH 백엔드 동작:**
|
||||
|
||||
- 생성 또는 재생성 후 원격 워크스페이스를 한 번 시드합니다
|
||||
- 그런 다음 원격 SSH 워크스페이스를 표준으로 유지합니다
|
||||
- 이후 원격 SSH 워크스페이스를 기준으로 유지합니다
|
||||
- `exec`, 파일 도구, 미디어 경로를 SSH를 통해 라우팅합니다
|
||||
- 원격 변경 사항을 호스트로 자동 동기화하지 않습니다
|
||||
- 샌드박스 브라우저 컨테이너를 지원하지 않습니다
|
||||
|
||||
**워크스페이스 액세스:**
|
||||
**워크스페이스 접근:**
|
||||
|
||||
- `none`: `~/.openclaw/sandboxes` 아래의 범위별 샌드박스 워크스페이스
|
||||
- `ro`: `/workspace`의 샌드박스 워크스페이스, `/agent`에 읽기 전용으로 마운트된 에이전트 워크스페이스
|
||||
- `rw`: `/workspace`에 읽기/쓰기 권한으로 마운트된 에이전트 워크스페이스
|
||||
- `rw`: `/workspace`에 읽기/쓰기 가능으로 마운트된 에이전트 워크스페이스
|
||||
|
||||
**범위:**
|
||||
|
||||
- `session`: 세션별 컨테이너 + 워크스페이스
|
||||
- `agent`: 에이전트별 컨테이너 + 워크스페이스 하나(기본값)
|
||||
- `shared`: 공유 컨테이너 및 워크스페이스(교차 세션 격리 없음)
|
||||
- `agent`: 에이전트별 컨테이너 + 워크스페이스 1개(기본값)
|
||||
- `shared`: 공유 컨테이너 및 워크스페이스(세션 간 격리 없음)
|
||||
|
||||
**OpenShell Plugin 구성:**
|
||||
|
||||
@ -861,29 +865,29 @@ LLM으로 보내기 전에 메모리 내 컨텍스트에서 **오래된 도구
|
||||
|
||||
**OpenShell 모드:**
|
||||
|
||||
- `mirror`: 실행 전에 로컬에서 원격으로 시드하고 실행 후 다시 동기화합니다. 로컬 워크스페이스가 표준으로 유지됩니다
|
||||
- `remote`: 샌드박스가 생성될 때 원격을 한 번 시드한 다음 원격 워크스페이스를 표준으로 유지합니다
|
||||
- `mirror`: 실행 전 로컬에서 원격으로 시드하고, 실행 후 다시 동기화합니다. 로컬 워크스페이스가 기준으로 유지됩니다
|
||||
- `remote`: 샌드박스가 생성될 때 원격을 한 번 시드한 다음, 원격 워크스페이스를 기준으로 유지합니다
|
||||
|
||||
`remote` 모드에서는 시드 단계 이후 OpenClaw 외부에서 수행된 호스트 로컬 편집이 샌드박스로 자동 동기화되지 않습니다.
|
||||
전송은 OpenShell 샌드박스로 SSH를 통해 이루어지지만, 샌드박스 수명 주기와 선택적 미러 동기화는 Plugin이 소유합니다.
|
||||
`remote` 모드에서는 OpenClaw 외부에서 이루어진 호스트 로컬 편집이 시드 단계 이후 샌드박스로 자동 동기화되지 않습니다.
|
||||
전송은 OpenShell 샌드박스로의 SSH를 사용하지만, Plugin이 샌드박스 수명 주기와 선택적 미러 동기화를 소유합니다.
|
||||
|
||||
**`setupCommand`**는 컨테이너 생성 후 한 번 실행됩니다(`sh -lc`를 통해). 네트워크 송신, 쓰기 가능한 루트, 루트 사용자가 필요합니다.
|
||||
|
||||
**컨테이너의 기본값은 `network: "none"`입니다**. 에이전트에 아웃바운드 액세스가 필요하면 `"bridge"`(또는 사용자 지정 브리지 네트워크)로 설정하세요.
|
||||
`"host"`는 차단됩니다. `"container:<id>"`는 명시적으로
|
||||
`sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true`(비상용)를 설정하지 않는 한 기본적으로 차단됩니다.
|
||||
**컨테이너의 기본값은 `network: "none"`입니다** — 에이전트에 아웃바운드 접근이 필요하면 `"bridge"`(또는 사용자 지정 브리지 네트워크)로 설정하세요.
|
||||
`"host"`는 차단됩니다. `"container:<id>"`는
|
||||
`sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true`(비상용)를 명시적으로 설정하지 않는 한 기본적으로 차단됩니다.
|
||||
|
||||
**인바운드 첨부 파일**은 활성 워크스페이스의 `media/inbound/*`에 스테이징됩니다.
|
||||
|
||||
**`docker.binds`**는 추가 호스트 디렉터리를 마운트합니다. 전역 바인드와 에이전트별 바인드가 병합됩니다.
|
||||
**`docker.binds`**는 추가 호스트 디렉터리를 마운트합니다. 전역 바인드와 에이전트별 바인드는 병합됩니다.
|
||||
|
||||
**샌드박스 브라우저**(`sandbox.browser.enabled`): 컨테이너 안의 Chromium + CDP입니다. noVNC URL이 시스템 프롬프트에 삽입됩니다. `openclaw.json`에서 `browser.enabled`가 필요하지 않습니다.
|
||||
noVNC 관찰자 액세스는 기본적으로 VNC 인증을 사용하며, OpenClaw는 공유 URL에 암호를 노출하는 대신 수명이 짧은 토큰 URL을 내보냅니다.
|
||||
**샌드박스 브라우저**(`sandbox.browser.enabled`): 컨테이너의 Chromium + CDP입니다. noVNC URL이 시스템 프롬프트에 주입됩니다. `openclaw.json`의 `browser.enabled`가 필요하지 않습니다.
|
||||
noVNC 관찰자 접근은 기본적으로 VNC 인증을 사용하며, OpenClaw는 공유 URL에 비밀번호를 노출하는 대신 수명이 짧은 토큰 URL을 내보냅니다.
|
||||
|
||||
- `allowHostControl: false`(기본값)는 샌드박스 세션이 호스트 브라우저를 대상으로 삼지 못하게 차단합니다.
|
||||
- `network`의 기본값은 `openclaw-sandbox-browser`(전용 브리지 네트워크)입니다. 전역 브리지 연결을 명시적으로 원하는 경우에만 `bridge`로 설정하세요.
|
||||
- `cdpSourceRange`는 선택적으로 컨테이너 경계에서 CDP 인그레스를 CIDR 범위(예: `172.21.0.1/32`)로 제한합니다.
|
||||
- `sandbox.browser.binds`는 추가 호스트 디렉터리를 샌드박스 브라우저 컨테이너에만 마운트합니다. 설정된 경우(`[]` 포함) 브라우저 컨테이너의 `docker.binds`를 대체합니다.
|
||||
- `sandbox.browser.binds`는 추가 호스트 디렉터리를 샌드박스 브라우저 컨테이너에만 마운트합니다. 설정된 경우(`[]` 포함) 브라우저 컨테이너에 대해 `docker.binds`를 대체합니다.
|
||||
- 실행 기본값은 `scripts/sandbox-browser-entrypoint.sh`에 정의되어 있으며 컨테이너 호스트에 맞게 조정되어 있습니다.
|
||||
- `--remote-debugging-address=127.0.0.1`
|
||||
- `--remote-debugging-port=<derived from OPENCLAW_BROWSER_CDP_PORT>`
|
||||
@ -901,17 +905,16 @@ noVNC 관찰자 액세스는 기본적으로 VNC 인증을 사용하며, OpenCla
|
||||
- `--renderer-process-limit=2`
|
||||
- `--no-zygote`
|
||||
- `--metrics-recording-only`
|
||||
- `--disable-extensions`(기본 활성화)
|
||||
- `--disable-extensions`(기본적으로 활성화됨)
|
||||
- `--disable-3d-apis`, `--disable-software-rasterizer`, `--disable-gpu`는
|
||||
기본적으로 활성화되며 WebGL/3D 사용에 필요하면
|
||||
기본적으로 활성화되며 WebGL/3D 사용에 필요한 경우
|
||||
`OPENCLAW_BROWSER_DISABLE_GRAPHICS_FLAGS=0`으로 비활성화할 수 있습니다.
|
||||
- 워크플로가 확장 프로그램에 의존하는 경우 `OPENCLAW_BROWSER_DISABLE_EXTENSIONS=0`으로
|
||||
확장 프로그램을 다시 활성화할 수 있습니다.
|
||||
- 워크플로가 확장 프로그램에 의존하는 경우 `OPENCLAW_BROWSER_DISABLE_EXTENSIONS=0`으로 확장 프로그램을 다시 활성화합니다.
|
||||
- `--renderer-process-limit=2`는
|
||||
`OPENCLAW_BROWSER_RENDERER_PROCESS_LIMIT=<N>`으로 변경할 수 있습니다. Chromium의
|
||||
기본 프로세스 제한을 사용하려면 `0`으로 설정하세요.
|
||||
- `noSandbox`가 활성화된 경우 `--no-sandbox`가 추가됩니다.
|
||||
- 기본값은 컨테이너 이미지 기준값입니다. 컨테이너 기본값을 변경하려면 사용자 지정
|
||||
- `noSandbox`가 활성화된 경우 `--no-sandbox`도 추가됩니다.
|
||||
- 기본값은 컨테이너 이미지 기준선입니다. 컨테이너 기본값을 변경하려면 사용자 지정
|
||||
엔트리포인트가 있는 사용자 지정 브라우저 이미지를 사용하세요.
|
||||
|
||||
</Accordion>
|
||||
@ -925,17 +928,17 @@ scripts/sandbox-setup.sh # main sandbox image
|
||||
scripts/sandbox-browser-setup.sh # optional browser image
|
||||
```
|
||||
|
||||
소스 체크아웃 없이 npm 설치를 사용하는 경우 인라인 `docker build` 명령은 [샌드박싱 § 이미지 및 설정](/ko/gateway/sandboxing#images-and-setup)을 참조하세요.
|
||||
소스 체크아웃 없이 npm 설치를 사용하는 경우, 인라인 `docker build` 명령은 [샌드박싱 § 이미지 및 설정](/ko/gateway/sandboxing#images-and-setup)을 참고하세요.
|
||||
|
||||
### `agents.list`(에이전트별 재정의)
|
||||
|
||||
`agents.list[].tts`를 사용해 에이전트에 자체 TTS 제공자, 음성, 모델,
|
||||
스타일 또는 자동 TTS 모드를 지정하세요. 에이전트 블록은 전역
|
||||
`messages.tts` 위에 깊은 병합을 수행하므로 공유 자격 증명은 한 곳에 유지하면서 개별
|
||||
`messages.tts` 위에 딥 머지되므로, 공유 자격 증명은 한곳에 두고 개별
|
||||
에이전트는 필요한 음성 또는 제공자 필드만 재정의할 수 있습니다. 활성 에이전트의
|
||||
재정의는 자동 음성 답변, `/tts audio`, `/tts status`, 그리고
|
||||
`tts` 에이전트 도구에 적용됩니다. 제공자 예시와 우선순위는 [텍스트 음성 변환](/ko/tools/tts#per-agent-voice-overrides)을
|
||||
참조하세요.
|
||||
참고하세요.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -989,22 +992,22 @@ scripts/sandbox-browser-setup.sh # optional browser image
|
||||
}
|
||||
```
|
||||
|
||||
- `id`: 안정적인 에이전트 id(필수).
|
||||
- `default`: 여러 개가 설정되면 첫 번째가 적용됩니다(경고가 기록됨). 설정된 항목이 없으면 목록의 첫 번째 항목이 기본값입니다.
|
||||
- `model`: 문자열 형식은 모델 fallback 없이 에이전트별 기본 모델을 엄격하게 설정합니다. 객체 형식 `{ primary }`도 `fallbacks`를 추가하지 않는 한 엄격합니다. 해당 에이전트에서 fallback을 사용하도록 하려면 `{ primary, fallbacks: [...] }`를 사용하고, 엄격한 동작을 명시하려면 `{ primary, fallbacks: [] }`를 사용하세요. `primary`만 재정의하는 Cron 작업은 `fallbacks: []`를 설정하지 않는 한 여전히 기본 fallback을 상속합니다.
|
||||
- `id`: 안정적인 에이전트 ID(필수).
|
||||
- `default`: 여러 개가 설정된 경우 첫 번째 항목이 우선합니다(경고가 기록됨). 아무것도 설정되지 않으면 목록의 첫 번째 항목이 기본값입니다.
|
||||
- `model`: 문자열 형식은 모델 대체 없이 엄격한 에이전트별 기본 모델을 설정합니다. 객체 형식 `{ primary }`도 `fallbacks`를 추가하지 않는 한 엄격합니다. 해당 에이전트에 대체 모델을 사용하려면 `{ primary, fallbacks: [...] }`를 사용하고, 엄격한 동작을 명시하려면 `{ primary, fallbacks: [] }`를 사용하세요. `primary`만 재정의하는 Cron 작업은 `fallbacks: []`를 설정하지 않는 한 기본 대체 모델을 계속 상속합니다.
|
||||
- `params`: `agents.defaults.models`에서 선택된 모델 항목 위에 병합되는 에이전트별 스트림 매개변수입니다. 전체 모델 카탈로그를 복제하지 않고 `cacheRetention`, `temperature`, `maxTokens` 같은 에이전트별 재정의에 사용하세요.
|
||||
- `tts`: 선택 사항인 에이전트별 텍스트 음성 변환 재정의입니다. 이 블록은 `messages.tts` 위에 깊게 병합되므로, 공유 Provider 자격 증명과 fallback 정책은 `messages.tts`에 두고 provider, voice, model, style, auto mode 같은 페르소나별 값만 여기에서 설정하세요.
|
||||
- `skills`: 선택 사항인 에이전트별 Skills 허용 목록입니다. 생략하면 설정된 경우 에이전트가 `agents.defaults.skills`를 상속합니다. 명시적인 목록은 기본값과 병합하는 대신 대체하며, `[]`는 Skills가 없음을 의미합니다.
|
||||
- `thinkingDefault`: 선택 사항인 에이전트별 기본 thinking level(`off | minimal | low | medium | high | xhigh | adaptive | max`)입니다. 메시지별 또는 세션별 재정의가 설정되지 않은 경우 이 에이전트에 대해 `agents.defaults.thinkingDefault`를 재정의합니다. 선택된 Provider/model profile이 유효한 값을 제어합니다. Google Gemini의 경우 `adaptive`는 Provider 소유의 동적 thinking을 유지합니다(Gemini 3/3.1에서는 `thinkingLevel` 생략, Gemini 2.5에서는 `thinkingBudget: -1`).
|
||||
- `reasoningDefault`: 선택 사항인 에이전트별 기본 추론 표시 방식(`on | off | stream`)입니다. 메시지별 또는 세션별 reasoning 재정의가 설정되지 않은 경우 이 에이전트에 대해 `agents.defaults.reasoningDefault`를 재정의합니다.
|
||||
- `fastModeDefault`: 선택 사항인 fast mode의 에이전트별 기본값(`true | false`)입니다. 메시지별 또는 세션별 fast-mode 재정의가 설정되지 않은 경우 적용됩니다.
|
||||
- `agentRuntime`: 선택 사항인 에이전트별 저수준 runtime 정책 재정의입니다. 다른 에이전트는 `auto` 모드에서 기본 PI fallback을 유지하면서 한 에이전트만 Codex 전용으로 만들려면 `{ id: "codex" }`를 사용하세요.
|
||||
- `runtime`: 선택 사항인 에이전트별 runtime descriptor입니다. 에이전트가 ACP harness 세션을 기본값으로 사용해야 하는 경우 `runtime.acp` 기본값(`agent`, `backend`, `mode`, `cwd`)과 함께 `type: "acp"`를 사용하세요.
|
||||
- `identity.avatar`: 작업 영역 기준 상대 경로, `http(s)` URL 또는 `data:` URI입니다.
|
||||
- `tts`: 선택적 에이전트별 텍스트 음성 변환 재정의입니다. 이 블록은 `messages.tts` 위에 깊게 병합되므로 공유 공급자 자격 증명과 대체 정책은 `messages.tts`에 두고, 공급자, 음성, 모델, 스타일 또는 자동 모드 같은 페르소나별 값만 여기에서 설정하세요.
|
||||
- `skills`: 선택적 에이전트별 Skills 허용 목록입니다. 생략하면 에이전트는 설정된 경우 `agents.defaults.skills`를 상속합니다. 명시적 목록은 기본값과 병합하지 않고 대체하며, `[]`는 Skills가 없음을 의미합니다.
|
||||
- `thinkingDefault`: 선택적 에이전트별 기본 사고 수준(`off | minimal | low | medium | high | xhigh | adaptive | max`)입니다. 메시지별 또는 세션 재정의가 설정되지 않은 경우 이 에이전트에 대해 `agents.defaults.thinkingDefault`를 재정의합니다. 선택된 공급자/모델 프로필이 유효한 값을 제어합니다. Google Gemini의 경우 `adaptive`는 공급자가 소유한 동적 사고를 유지합니다(Gemini 3/3.1에서는 `thinkingLevel` 생략, Gemini 2.5에서는 `thinkingBudget: -1`).
|
||||
- `reasoningDefault`: 선택적 에이전트별 기본 추론 표시 방식(`on | off | stream`)입니다. 메시지별 또는 세션 추론 재정의가 설정되지 않은 경우 이 에이전트에 대해 `agents.defaults.reasoningDefault`를 재정의합니다.
|
||||
- `fastModeDefault`: 선택적 에이전트별 빠른 모드 기본값(`true | false`)입니다. 메시지별 또는 세션 빠른 모드 재정의가 설정되지 않은 경우 적용됩니다.
|
||||
- `agentRuntime`: 선택적 에이전트별 저수준 런타임 정책 재정의입니다. 다른 에이전트는 `auto` 모드에서 기본 PI 대체를 유지하면서 한 에이전트만 Codex 전용으로 만들려면 `{ id: "codex" }`를 사용하세요.
|
||||
- `runtime`: 선택적 에이전트별 런타임 설명자입니다. 에이전트가 기본적으로 ACP 하네스 세션을 사용해야 할 때 `runtime.acp` 기본값(`agent`, `backend`, `mode`, `cwd`)과 함께 `type: "acp"`를 사용하세요.
|
||||
- `identity.avatar`: 작업 공간 기준 상대 경로, `http(s)` URL 또는 `data:` URI입니다.
|
||||
- `identity`는 기본값을 파생합니다. `emoji`에서 `ackReaction`을, `name`/`emoji`에서 `mentionPatterns`를 파생합니다.
|
||||
- `subagents.allowAgents`: 명시적인 `sessions_spawn.agentId` 대상에 대한 에이전트 id 허용 목록입니다(`["*"]` = 모두, 기본값: 같은 에이전트만). self-targeted `agentId` 호출을 허용해야 하는 경우 requester id를 포함하세요.
|
||||
- Sandbox 상속 가드: requester 세션이 sandboxed 상태이면 `sessions_spawn`은 sandbox 없이 실행될 대상을 거부합니다.
|
||||
- `subagents.requireAgentId`: true이면 `agentId`를 생략한 `sessions_spawn` 호출을 차단합니다(명시적인 프로필 선택을 강제함, 기본값: false).
|
||||
- `subagents.allowAgents`: 명시적 `sessions_spawn.agentId` 대상에 대한 에이전트 ID 허용 목록입니다(`["*"]` = 모두, 기본값: 동일 에이전트만). 자기 자신을 대상으로 하는 `agentId` 호출을 허용해야 하는 경우 요청자 ID를 포함하세요.
|
||||
- 샌드박스 상속 가드: 요청자 세션이 샌드박스 처리된 경우 `sessions_spawn`은 샌드박스 없이 실행될 대상을 거부합니다.
|
||||
- `subagents.requireAgentId`: true이면 `agentId`를 생략하는 `sessions_spawn` 호출을 차단합니다(명시적 프로필 선택 강제, 기본값: false).
|
||||
|
||||
---
|
||||
|
||||
@ -1027,16 +1030,16 @@ scripts/sandbox-browser-setup.sh # optional browser image
|
||||
}
|
||||
```
|
||||
|
||||
### Binding match 필드
|
||||
### 바인딩 일치 필드
|
||||
|
||||
- `type`(선택 사항): 일반 라우팅에는 `route`(type이 없으면 route가 기본값), 지속 ACP conversation binding에는 `acp`.
|
||||
- `type`(선택 사항): 일반 라우팅에는 `route`(누락된 type의 기본값은 route), 지속 ACP 대화 바인딩에는 `acp`.
|
||||
- `match.channel`(필수)
|
||||
- `match.accountId`(선택 사항, `*` = 모든 계정, 생략 = 기본 계정)
|
||||
- `match.peer`(선택 사항, `{ kind: direct|group|channel, id }`)
|
||||
- `match.guildId` / `match.teamId`(선택 사항, 채널별)
|
||||
- `acp`(선택 사항, `type: "acp"`에만 해당): `{ mode, label, cwd, backend }`
|
||||
- `match.accountId`(선택 사항; `*` = 모든 계정, 생략 = 기본 계정)
|
||||
- `match.peer`(선택 사항; `{ kind: direct|group|channel, id }`)
|
||||
- `match.guildId` / `match.teamId`(선택 사항; 채널별)
|
||||
- `acp`(선택 사항; `type: "acp"`에만 해당): `{ mode, label, cwd, backend }`
|
||||
|
||||
**결정론적 match 순서:**
|
||||
**결정적 일치 순서:**
|
||||
|
||||
1. `match.peer`
|
||||
2. `match.guildId`
|
||||
@ -1045,13 +1048,13 @@ scripts/sandbox-browser-setup.sh # optional browser image
|
||||
5. `match.accountId: "*"`(채널 전체)
|
||||
6. 기본 에이전트
|
||||
|
||||
각 계층 안에서는 처음 일치하는 `bindings` 항목이 적용됩니다.
|
||||
각 단계 안에서는 처음 일치하는 `bindings` 항목이 우선합니다.
|
||||
|
||||
`type: "acp"` 항목의 경우 OpenClaw는 정확한 conversation identity(`match.channel` + 계정 + `match.peer.id`)로 해석하며, 위의 route binding 계층 순서를 사용하지 않습니다.
|
||||
`type: "acp"` 항목의 경우 OpenClaw는 정확한 대화 ID(`match.channel` + 계정 + `match.peer.id`)로 확인하며, 위의 route 바인딩 단계 순서를 사용하지 않습니다.
|
||||
|
||||
### 에이전트별 접근 프로필
|
||||
### 에이전트별 액세스 프로필
|
||||
|
||||
<Accordion title="전체 접근 권한( sandbox 없음)">
|
||||
<Accordion title="Full access (no sandbox)">
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -1069,7 +1072,7 @@ scripts/sandbox-browser-setup.sh # optional browser image
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="읽기 전용 도구 + 작업 영역">
|
||||
<Accordion title="Read-only tools + workspace">
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -1098,7 +1101,7 @@ scripts/sandbox-browser-setup.sh # optional browser image
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="파일 시스템 접근 없음(메시징만)">
|
||||
<Accordion title="No filesystem access (messaging only)">
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -1144,7 +1147,7 @@ scripts/sandbox-browser-setup.sh # optional browser image
|
||||
|
||||
</Accordion>
|
||||
|
||||
우선순위 세부 정보는 [Multi-Agent Sandbox & Tools](/ko/tools/multi-agent-sandbox-tools)를 참조하세요.
|
||||
우선순위 세부 정보는 [멀티 에이전트 샌드박스 및 도구](/ko/tools/multi-agent-sandbox-tools)를 참조하세요.
|
||||
|
||||
---
|
||||
|
||||
@ -1193,36 +1196,36 @@ scripts/sandbox-browser-setup.sh # optional browser image
|
||||
}
|
||||
```
|
||||
|
||||
<Accordion title="세션 필드 세부 정보">
|
||||
<Accordion title="Session field details">
|
||||
|
||||
- **`scope`**: 그룹 채팅 컨텍스트의 기본 세션 그룹화 전략입니다.
|
||||
- `per-sender`(기본값): 각 발신자가 채널 컨텍스트 안에서 격리된 세션을 받습니다.
|
||||
- `per-sender`(기본값): 각 발신자는 채널 컨텍스트 안에서 격리된 세션을 받습니다.
|
||||
- `global`: 채널 컨텍스트의 모든 참여자가 단일 세션을 공유합니다(공유 컨텍스트가 의도된 경우에만 사용).
|
||||
- **`dmScope`**: DM이 그룹화되는 방식입니다.
|
||||
- `main`: 모든 DM이 main 세션을 공유합니다.
|
||||
- `per-peer`: 채널 전반에서 발신자 id별로 격리합니다.
|
||||
- `per-channel-peer`: 채널 + 발신자별로 격리합니다(다중 사용자 받은 편지함에 권장).
|
||||
- **`dmScope`**: DM을 그룹화하는 방식입니다.
|
||||
- `main`: 모든 DM이 기본 세션을 공유합니다.
|
||||
- `per-peer`: 채널 전반에서 발신자 ID별로 격리합니다.
|
||||
- `per-channel-peer`: 채널 + 발신자별로 격리합니다(다중 사용자 받은편지함에 권장).
|
||||
- `per-account-channel-peer`: 계정 + 채널 + 발신자별로 격리합니다(다중 계정에 권장).
|
||||
- **`identityLinks`**: 교차 채널 세션 공유를 위해 정규 id를 제공자 접두사가 붙은 피어에 매핑합니다. `/dock_discord` 같은 Dock 명령은 동일한 맵을 사용하여 활성 세션의 응답 경로를 연결된 다른 채널 피어로 전환합니다. [채널 도킹](/ko/concepts/channel-docking)을 참조하세요.
|
||||
- **`reset`**: 기본 재설정 정책입니다. `daily`는 현지 시간 `atHour`에 재설정되고, `idle`은 `idleMinutes` 후에 재설정됩니다. 둘 다 구성된 경우 먼저 만료되는 쪽이 적용됩니다. 일일 재설정 최신성은 세션 행의 `sessionStartedAt`을 사용하고, 유휴 재설정 최신성은 `lastInteractionAt`을 사용합니다. Heartbeat, Cron 깨우기, exec 알림, Gateway 장부 기록 같은 백그라운드/시스템 이벤트 쓰기는 `updatedAt`을 갱신할 수 있지만, 일일/유휴 세션을 최신 상태로 유지하지는 않습니다.
|
||||
- **`identityLinks`**: 채널 간 세션 공유를 위해 정식 ID를 공급자 접두사가 붙은 피어에 매핑합니다. `/dock_discord` 같은 도킹 명령은 동일한 맵을 사용해 활성 세션의 답장 경로를 연결된 다른 채널 피어로 전환합니다. [채널 도킹](/ko/concepts/channel-docking)을 참조하세요.
|
||||
- **`reset`**: 기본 재설정 정책입니다. `daily`는 로컬 시간 `atHour`에 재설정하고, `idle`은 `idleMinutes` 이후 재설정합니다. 둘 다 구성된 경우 먼저 만료되는 쪽이 적용됩니다. 일일 재설정 신선도는 세션 행의 `sessionStartedAt`을 사용하고, 유휴 재설정 신선도는 `lastInteractionAt`을 사용합니다. Heartbeat, Cron 깨우기, exec 알림, Gateway 장부 관리 같은 백그라운드/시스템 이벤트 쓰기는 `updatedAt`을 갱신할 수 있지만, 일일/유휴 세션을 신선하게 유지하지는 않습니다.
|
||||
- **`resetByType`**: 유형별 재정의(`direct`, `group`, `thread`)입니다. 레거시 `dm`은 `direct`의 별칭으로 허용됩니다.
|
||||
- **`mainKey`**: 레거시 필드입니다. 런타임은 main 직접 채팅 버킷에 항상 `"main"`을 사용합니다.
|
||||
- **`agentToAgent.maxPingPongTurns`**: 에이전트 간 교환 중 에이전트 사이의 최대 왕복 응답 턴 수입니다(정수, 범위: `0`-`5`). `0`은 핑퐁 체인을 비활성화합니다.
|
||||
- **`sendPolicy`**: `channel`, `chatType`(`direct|group|channel`, 레거시 `dm` 별칭 포함), `keyPrefix` 또는 `rawKeyPrefix`로 일치시킵니다. 첫 번째 거부가 적용됩니다.
|
||||
- **`maintenance`**: 세션 저장소 정리 + 보존 제어입니다.
|
||||
- `mode`: `warn`은 경고만 내보내고, `enforce`는 정리를 적용합니다.
|
||||
- `pruneAfter`: 오래된 항목의 기간 기준값입니다(기본값 `30d`).
|
||||
- `maxEntries`: `sessions.json`의 최대 항목 수입니다(기본값 `500`). 런타임은 프로덕션 규모의 상한을 위해 작은 상한 여유 버퍼와 함께 배치 정리를 기록합니다. `openclaw sessions cleanup --enforce`는 상한을 즉시 적용합니다.
|
||||
- **`mainKey`**: 레거시 필드입니다. 런타임은 기본 직접 채팅 버킷에 항상 `"main"`을 사용합니다.
|
||||
- **`agentToAgent.maxPingPongTurns`**: 에이전트 간 교환 중 에이전트 사이의 최대 답장 왕복 턴 수입니다(정수, 범위: `0`–`5`). `0`은 핑퐁 체이닝을 비활성화합니다.
|
||||
- **`sendPolicy`**: `channel`, `chatType`(`direct|group|channel`, 레거시 `dm` 별칭 포함), `keyPrefix` 또는 `rawKeyPrefix`로 매칭합니다. 첫 번째 거부가 우선합니다.
|
||||
- **`maintenance`**: 세션 저장소 정리 및 보존 제어입니다.
|
||||
- `mode`: `warn`은 경고만 출력하고, `enforce`는 정리를 적용합니다.
|
||||
- `pruneAfter`: 오래된 항목의 나이 기준입니다(기본값 `30d`).
|
||||
- `maxEntries`: `sessions.json`의 최대 항목 수입니다(기본값 `500`). 런타임은 프로덕션 규모 상한을 위해 작은 high-water 버퍼로 배치 정리를 기록하며, `openclaw sessions cleanup --enforce`는 상한을 즉시 적용합니다.
|
||||
- `rotateBytes`: 더 이상 사용되지 않으며 무시됩니다. `openclaw doctor --fix`는 이전 구성에서 이를 제거합니다.
|
||||
- `resetArchiveRetention`: `*.reset.<timestamp>` 트랜스크립트 아카이브의 보존 기간입니다. 기본값은 `pruneAfter`이며, 비활성화하려면 `false`로 설정합니다.
|
||||
- `resetArchiveRetention`: `*.reset.<timestamp>` 대화록 아카이브의 보존 기간입니다. 기본값은 `pruneAfter`이며, 비활성화하려면 `false`로 설정합니다.
|
||||
- `maxDiskBytes`: 선택적 세션 디렉터리 디스크 예산입니다. `warn` 모드에서는 경고를 기록하고, `enforce` 모드에서는 가장 오래된 아티팩트/세션부터 제거합니다.
|
||||
- `highWaterBytes`: 예산 정리 후 선택적 목표값입니다. 기본값은 `maxDiskBytes`의 `80%`입니다.
|
||||
- `highWaterBytes`: 예산 정리 후의 선택적 목표값입니다. 기본값은 `maxDiskBytes`의 `80%`입니다.
|
||||
- **`threadBindings`**: 스레드 바인딩 세션 기능의 전역 기본값입니다.
|
||||
- `enabled`: 마스터 기본 스위치입니다(제공자가 재정의할 수 있으며, Discord는 `channels.discord.threadBindings.enabled`를 사용).
|
||||
- `idleHours`: 시간 단위의 기본 비활성 자동 포커스 해제입니다(`0`은 비활성화, 제공자가 재정의 가능).
|
||||
- `maxAgeHours`: 시간 단위의 기본 하드 최대 수명입니다(`0`은 비활성화, 제공자가 재정의 가능).
|
||||
- `spawnSessions`: `sessions_spawn` 및 ACP 스레드 스폰에서 스레드 바인딩 작업 세션 생성을 위한 기본 게이트입니다. 스레드 바인딩이 활성화된 경우 기본값은 `true`이며, 제공자/계정이 재정의할 수 있습니다.
|
||||
- `defaultSpawnContext`: 스레드 바인딩 스폰의 기본 네이티브 서브에이전트 컨텍스트입니다(`"fork"` 또는 `"isolated"`). 기본값은 `"fork"`입니다.
|
||||
- `enabled`: 마스터 기본 스위치입니다(공급자가 재정의할 수 있으며, Discord는 `channels.discord.threadBindings.enabled`를 사용).
|
||||
- `idleHours`: 기본 비활성 자동 포커스 해제 시간(`0`은 비활성화, 공급자가 재정의 가능).
|
||||
- `maxAgeHours`: 기본 하드 최대 수명 시간(`0`은 비활성화, 공급자가 재정의 가능).
|
||||
- `spawnSessions`: `sessions_spawn` 및 ACP 스레드 스폰에서 스레드 바인딩 작업 세션 생성을 위한 기본 게이트입니다. 스레드 바인딩이 활성화된 경우 기본값은 `true`이며, 공급자/계정이 재정의할 수 있습니다.
|
||||
- `defaultSpawnContext`: 스레드 바인딩 스폰의 기본 네이티브 하위 에이전트 컨텍스트입니다(`"fork"` 또는 `"isolated"`). 기본값은 `"fork"`입니다.
|
||||
|
||||
</Accordion>
|
||||
|
||||
@ -1262,36 +1265,36 @@ scripts/sandbox-browser-setup.sh # optional browser image
|
||||
|
||||
채널/계정별 재정의: `channels.<channel>.responsePrefix`, `channels.<channel>.accounts.<id>.responsePrefix`.
|
||||
|
||||
해결 방식(가장 구체적인 값이 우선): 계정 → 채널 → 전역. `""`는 비활성화하고 cascade를 중단합니다. `"auto"`는 `[{identity.name}]`에서 파생됩니다.
|
||||
해결 방식(가장 구체적인 항목이 우선): 계정 → 채널 → 전역. `""`는 비활성화하고 연쇄 적용을 중지합니다. `"auto"`는 `[{identity.name}]`에서 파생됩니다.
|
||||
|
||||
**템플릿 변수:**
|
||||
|
||||
| 변수 | 설명 | 예시 |
|
||||
| ----------------- | ------------------ | --------------------------- |
|
||||
| `{model}` | 짧은 모델 이름 | `claude-opus-4-6` |
|
||||
| `{modelFull}` | 전체 모델 식별자 | `anthropic/claude-opus-4-6` |
|
||||
| `{provider}` | 제공자 이름 | `anthropic` |
|
||||
| `{thinkingLevel}` | 현재 thinking 수준 | `high`, `low`, `off` |
|
||||
| `{identity.name}` | 에이전트 identity 이름 | (`"auto"`와 동일) |
|
||||
| 변수 | 설명 | 예시 |
|
||||
| ----------------- | -------------------- | --------------------------- |
|
||||
| `{model}` | 짧은 모델 이름 | `claude-opus-4-6` |
|
||||
| `{modelFull}` | 전체 모델 식별자 | `anthropic/claude-opus-4-6` |
|
||||
| `{provider}` | 제공자 이름 | `anthropic` |
|
||||
| `{thinkingLevel}` | 현재 사고 수준 | `high`, `low`, `off` |
|
||||
| `{identity.name}` | 에이전트 ID 이름 | (`"auto"`와 동일) |
|
||||
|
||||
변수는 대소문자를 구분하지 않습니다. `{think}`는 `{thinkingLevel}`의 별칭입니다.
|
||||
|
||||
### 확인 반응
|
||||
|
||||
- 기본값은 활성 에이전트의 `identity.emoji`이고, 없으면 `"👀"`입니다. 비활성화하려면 `""`로 설정합니다.
|
||||
- 기본값은 활성 에이전트의 `identity.emoji`이며, 없으면 `"👀"`입니다. 비활성화하려면 `""`로 설정합니다.
|
||||
- 채널별 재정의: `channels.<channel>.ackReaction`, `channels.<channel>.accounts.<id>.ackReaction`.
|
||||
- 해결 순서: 계정 → 채널 → `messages.ackReaction` → identity fallback.
|
||||
- 해결 순서: 계정 → 채널 → `messages.ackReaction` → ID 대체값.
|
||||
- 범위: `group-mentions`(기본값), `group-all`, `direct`, `all`.
|
||||
- `removeAckAfterReply`: Slack, Discord, Telegram, WhatsApp, BlueBubbles처럼 반응을 지원하는 채널에서 답장 후 확인 반응을 제거합니다.
|
||||
- `messages.statusReactions.enabled`: Slack, Discord, Telegram에서 수명 주기 상태 반응을 활성화합니다.
|
||||
Slack과 Discord에서는, 확인 반응이 활성 상태일 때 값을 설정하지 않으면 상태 반응이 계속 활성화됩니다.
|
||||
Slack과 Discord에서는 확인 반응이 활성 상태일 때 설정하지 않으면 상태 반응이 계속 활성화됩니다.
|
||||
Telegram에서는 수명 주기 상태 반응을 활성화하려면 명시적으로 `true`로 설정합니다.
|
||||
|
||||
### 인바운드 디바운스
|
||||
|
||||
같은 발신자가 빠르게 보낸 텍스트 전용 메시지를 하나의 에이전트 턴으로 묶습니다. 미디어/첨부 파일은 즉시 플러시됩니다. 제어 명령은 디바운스를 우회합니다.
|
||||
동일한 발신자가 빠르게 보낸 텍스트 전용 메시지를 하나의 에이전트 턴으로 묶습니다. 미디어/첨부 파일은 즉시 플러시됩니다. 제어 명령은 디바운스를 우회합니다.
|
||||
|
||||
### TTS(텍스트 음성 변환)
|
||||
### TTS (텍스트 음성 변환)
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -1339,19 +1342,19 @@ scripts/sandbox-browser-setup.sh # optional browser image
|
||||
}
|
||||
```
|
||||
|
||||
- `auto`는 기본 자동 TTS 모드를 제어합니다: `off`, `always`, `inbound`, `tagged`. `/tts on|off`는 로컬 기본 설정을 재정의할 수 있고, `/tts status`는 유효한 상태를 표시합니다.
|
||||
- `auto`는 기본 자동 TTS 모드를 제어합니다: `off`, `always`, `inbound`, 또는 `tagged`. `/tts on|off`로 로컬 환경설정을 재정의할 수 있으며, `/tts status`는 유효한 상태를 표시합니다.
|
||||
- `summaryModel`은 자동 요약에 대해 `agents.defaults.model.primary`를 재정의합니다.
|
||||
- `modelOverrides`는 기본적으로 활성화되어 있습니다. `modelOverrides.allowProvider`의 기본값은 `false`입니다(옵트인).
|
||||
- API 키는 `ELEVENLABS_API_KEY`/`XI_API_KEY` 및 `OPENAI_API_KEY`로 fallback됩니다.
|
||||
- 번들 음성 제공자는 Plugin이 소유합니다. `plugins.allow`가 설정되어 있으면 사용하려는 각 TTS 제공자 Plugin을 포함합니다. 예를 들어 Edge TTS에는 `microsoft`를 포함합니다. 레거시 `edge` 제공자 id는 `microsoft`의 별칭으로 허용됩니다.
|
||||
- `modelOverrides`는 기본적으로 활성화되어 있으며, `modelOverrides.allowProvider`의 기본값은 `false`(옵트인)입니다.
|
||||
- API 키는 `ELEVENLABS_API_KEY`/`XI_API_KEY` 및 `OPENAI_API_KEY`로 대체됩니다.
|
||||
- 번들 음성 제공자는 Plugin 소유입니다. `plugins.allow`가 설정되어 있으면 사용하려는 각 TTS 제공자 Plugin을 포함하세요. 예를 들어 Edge TTS의 경우 `microsoft`를 포함합니다. 레거시 `edge` 제공자 ID는 `microsoft`의 별칭으로 허용됩니다.
|
||||
- `providers.openai.baseUrl`은 OpenAI TTS 엔드포인트를 재정의합니다. 해결 순서는 구성, 그다음 `OPENAI_TTS_BASE_URL`, 그다음 `https://api.openai.com/v1`입니다.
|
||||
- `providers.openai.baseUrl`이 OpenAI가 아닌 엔드포인트를 가리키면, OpenClaw는 이를 OpenAI 호환 TTS 서버로 취급하고 모델/음성 검증을 완화합니다.
|
||||
- `providers.openai.baseUrl`이 OpenAI가 아닌 엔드포인트를 가리키면 OpenClaw는 이를 OpenAI 호환 TTS 서버로 취급하고 모델/음성 검증을 완화합니다.
|
||||
|
||||
---
|
||||
|
||||
## Talk
|
||||
## 대화
|
||||
|
||||
Talk 모드(macOS/iOS/Android)의 기본값입니다.
|
||||
대화 모드(macOS/iOS/Android)의 기본값입니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -1380,16 +1383,16 @@ Talk 모드(macOS/iOS/Android)의 기본값입니다.
|
||||
}
|
||||
```
|
||||
|
||||
- 여러 Talk 제공자가 구성된 경우 `talk.provider`는 `talk.providers`의 키와 일치해야 합니다.
|
||||
- 레거시 플랫 Talk 키(`talk.voiceId`, `talk.voiceAliases`, `talk.modelId`, `talk.outputFormat`, `talk.apiKey`)는 호환성 전용이며 `talk.providers.<provider>`로 자동 마이그레이션됩니다.
|
||||
- 음성 ID는 `ELEVENLABS_VOICE_ID` 또는 `SAG_VOICE_ID`로 fallback됩니다.
|
||||
- `providers.*.apiKey`는 일반 텍스트 문자열 또는 SecretRef 객체를 허용합니다.
|
||||
- `ELEVENLABS_API_KEY` fallback은 Talk API 키가 구성되지 않은 경우에만 적용됩니다.
|
||||
- `providers.*.voiceAliases`를 사용하면 Talk 지시문에서 친숙한 이름을 사용할 수 있습니다.
|
||||
- `providers.mlx.modelId`는 macOS 로컬 MLX helper에서 사용하는 Hugging Face 저장소를 선택합니다. 생략하면 macOS는 `mlx-community/Soprano-80M-bf16`을 사용합니다.
|
||||
- macOS MLX 재생은 존재하는 경우 번들 `openclaw-mlx-tts` helper를 통해 실행되고, 없으면 `PATH`의 실행 파일을 통해 실행됩니다. `OPENCLAW_MLX_TTS_BIN`은 개발용 helper 경로를 재정의합니다.
|
||||
- `speechLocale`은 iOS/macOS Talk 음성 인식에서 사용하는 BCP 47 로케일 id를 설정합니다. 기기 기본값을 사용하려면 설정하지 않은 채로 둡니다.
|
||||
- `silenceTimeoutMs`는 사용자 침묵 후 Talk 모드가 transcript를 보내기 전에 기다리는 시간을 제어합니다. 설정하지 않으면 플랫폼 기본 일시 중지 창(`macOS 및 Android에서는 700 ms, iOS에서는 900 ms`)을 유지합니다.
|
||||
- 여러 대화 제공자가 구성된 경우 `talk.provider`는 `talk.providers`의 키와 일치해야 합니다.
|
||||
- 레거시 플랫 대화 키(`talk.voiceId`, `talk.voiceAliases`, `talk.modelId`, `talk.outputFormat`, `talk.apiKey`)는 호환성 전용이며 `talk.providers.<provider>`로 자동 마이그레이션됩니다.
|
||||
- 음성 ID는 `ELEVENLABS_VOICE_ID` 또는 `SAG_VOICE_ID`로 대체됩니다.
|
||||
- `providers.*.apiKey`는 평문 문자열 또는 SecretRef 객체를 허용합니다.
|
||||
- `ELEVENLABS_API_KEY` 대체값은 대화 API 키가 구성되지 않은 경우에만 적용됩니다.
|
||||
- `providers.*.voiceAliases`를 사용하면 대화 지시문에서 친숙한 이름을 사용할 수 있습니다.
|
||||
- `providers.mlx.modelId`는 macOS 로컬 MLX 헬퍼가 사용하는 Hugging Face 저장소를 선택합니다. 생략하면 macOS는 `mlx-community/Soprano-80M-bf16`을 사용합니다.
|
||||
- macOS MLX 재생은 번들 `openclaw-mlx-tts` 헬퍼가 있으면 이를 통해 실행되며, 없으면 `PATH`의 실행 파일을 통해 실행됩니다. `OPENCLAW_MLX_TTS_BIN`은 개발용 헬퍼 경로를 재정의합니다.
|
||||
- `speechLocale`은 iOS/macOS 대화 음성 인식에서 사용하는 BCP 47 로캘 ID를 설정합니다. 설정하지 않으면 기기 기본값을 사용합니다.
|
||||
- `silenceTimeoutMs`는 사용자 침묵 후 대화 모드가 전사문을 보내기 전까지 기다리는 시간을 제어합니다. 설정하지 않으면 플랫폼 기본 일시 중지 시간(`macOS 및 Android에서는 700 ms, iOS에서는 900 ms`)을 유지합니다.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -3,54 +3,54 @@ read_when:
|
||||
- 채널 Plugin 구성(인증, 접근 제어, 다중 계정)
|
||||
- 채널별 구성 키 문제 해결
|
||||
- DM 정책, 그룹 정책 또는 멘션 게이팅 감사
|
||||
summary: '채널 설정: Slack, Discord, Telegram, WhatsApp, Matrix, iMessage 등에서의 액세스 제어, 페어링, 채널별 키'
|
||||
summary: '채널 구성: Slack, Discord, Telegram, WhatsApp, Matrix, iMessage 등에서의 접근 제어, 페어링, 채널별 키'
|
||||
title: 구성 — 채널
|
||||
x-i18n:
|
||||
generated_at: "2026-05-03T21:31:25Z"
|
||||
generated_at: "2026-05-04T02:24:05Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 366bcee632c649219bbf6cf44d64cc13d966ec813abc74d54088d89de640b47c
|
||||
source_hash: 57dcc0b5148324ea6fdee51b7b6e97ec7bd7dc3ca89518ab0816fe4172feefbc
|
||||
source_path: gateway/config-channels.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
`channels.*` 아래의 채널별 구성 키입니다. DM 및 그룹 접근,
|
||||
다중 계정 설정, 멘션 게이트, 그리고 Slack, Discord,
|
||||
`channels.*` 아래의 채널별 구성 키입니다. DM 및 그룹 액세스,
|
||||
다중 계정 설정, 멘션 게이팅, Slack, Discord,
|
||||
Telegram, WhatsApp, Matrix, iMessage 및 기타 번들 채널 Plugin의 채널별 키를 다룹니다.
|
||||
|
||||
에이전트, 도구, gateway 런타임 및 기타 최상위 키는
|
||||
에이전트, 도구, Gateway 런타임 및 기타 최상위 키는
|
||||
[구성 참조](/ko/gateway/configuration-reference)를 참조하세요.
|
||||
|
||||
## 채널
|
||||
|
||||
각 채널은 해당 구성 섹션이 있으면 자동으로 시작됩니다(`enabled: false`인 경우 제외).
|
||||
각 채널은 구성 섹션이 있으면 자동으로 시작됩니다(`enabled: false`가 아닌 경우).
|
||||
|
||||
### DM 및 그룹 접근
|
||||
### DM 및 그룹 액세스
|
||||
|
||||
모든 채널은 DM 정책과 그룹 정책을 지원합니다.
|
||||
|
||||
| DM 정책 | 동작 |
|
||||
| ------------------- | --------------------------------------------------------------- |
|
||||
| `pairing` (기본값) | 알 수 없는 발신자는 일회성 페어링 코드를 받으며, 소유자가 승인해야 함 |
|
||||
| `allowlist` | `allowFrom`에 있는 발신자만 허용(또는 페어링된 허용 저장소) |
|
||||
| `open` | 모든 인바운드 DM 허용(`allowFrom: ["*"]` 필요) |
|
||||
| `disabled` | 모든 인바운드 DM 무시 |
|
||||
| `pairing` (기본값) | 알 수 없는 발신자는 일회용 페어링 코드를 받으며, 소유자가 승인해야 함 |
|
||||
| `allowlist` | `allowFrom`(또는 페어링된 허용 저장소)의 발신자만 허용 |
|
||||
| `open` | 모든 인바운드 DM 허용(`allowFrom: ["*"]` 필요) |
|
||||
| `disabled` | 모든 인바운드 DM 무시 |
|
||||
|
||||
| 그룹 정책 | 동작 |
|
||||
| --------------------- | ------------------------------------------------------ |
|
||||
| `allowlist` (기본값) | 구성된 허용 목록과 일치하는 그룹만 허용 |
|
||||
| `open` | 그룹 허용 목록을 우회함(멘션 게이트는 계속 적용됨) |
|
||||
| `open` | 그룹 허용 목록 우회(멘션 게이팅은 계속 적용됨) |
|
||||
| `disabled` | 모든 그룹/방 메시지 차단 |
|
||||
|
||||
<Note>
|
||||
`channels.defaults.groupPolicy`는 provider의 `groupPolicy`가 설정되지 않았을 때의 기본값을 설정합니다.
|
||||
`channels.defaults.groupPolicy`는 프로바이더의 `groupPolicy`가 설정되지 않았을 때 기본값을 설정합니다.
|
||||
페어링 코드는 1시간 후 만료됩니다. 대기 중인 DM 페어링 요청은 **채널당 3개**로 제한됩니다.
|
||||
provider 블록이 완전히 누락된 경우(`channels.<provider>` 없음), 런타임 그룹 정책은 시작 경고와 함께 `allowlist`(fail-closed)로 대체됩니다.
|
||||
프로바이더 블록이 완전히 누락된 경우(`channels.<provider>` 없음), 런타임 그룹 정책은 시작 경고와 함께 `allowlist`(실패 시 닫힘)로 대체됩니다.
|
||||
</Note>
|
||||
|
||||
### 채널 모델 재정의
|
||||
|
||||
`channels.modelByChannel`을 사용해 특정 채널 ID를 모델에 고정합니다. 값은 `provider/model` 또는 구성된 모델 별칭을 허용합니다. 채널 매핑은 세션에 이미 모델 재정의가 없는 경우(예: `/model`로 설정) 적용됩니다.
|
||||
`channels.modelByChannel`을 사용해 특정 채널 ID를 모델에 고정합니다. 값은 `provider/model` 또는 구성된 모델 별칭을 허용합니다. 채널 매핑은 세션에 이미 모델 재정의가 없을 때 적용됩니다(예: `/model`로 설정된 경우).
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -73,7 +73,7 @@ provider 블록이 완전히 누락된 경우(`channels.<provider>` 없음), 런
|
||||
|
||||
### 채널 기본값 및 Heartbeat
|
||||
|
||||
provider 전반의 공유 그룹 정책 및 Heartbeat 동작에는 `channels.defaults`를 사용합니다.
|
||||
프로바이더 전반의 공유 그룹 정책 및 Heartbeat 동작에는 `channels.defaults`를 사용합니다:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -91,15 +91,15 @@ provider 전반의 공유 그룹 정책 및 Heartbeat 동작에는 `channels.def
|
||||
}
|
||||
```
|
||||
|
||||
- `channels.defaults.groupPolicy`: provider 수준의 `groupPolicy`가 설정되지 않았을 때의 대체 그룹 정책입니다.
|
||||
- `channels.defaults.contextVisibility`: 모든 채널의 기본 보조 컨텍스트 표시 모드입니다. 값: `all`(기본값, 인용/스레드/기록 컨텍스트 모두 포함), `allowlist`(허용 목록에 있는 발신자의 컨텍스트만 포함), `allowlist_quote`(allowlist와 동일하지만 명시적 인용/답장 컨텍스트는 유지). 채널별 재정의: `channels.<channel>.contextVisibility`.
|
||||
- `channels.defaults.heartbeat.showOk`: Heartbeat 출력에 정상 채널 상태를 포함합니다.
|
||||
- `channels.defaults.heartbeat.showAlerts`: Heartbeat 출력에 성능 저하/오류 상태를 포함합니다.
|
||||
- `channels.defaults.heartbeat.useIndicator`: 간결한 표시기 스타일 Heartbeat 출력을 렌더링합니다.
|
||||
- `channels.defaults.groupPolicy`: 프로바이더 수준 `groupPolicy`가 설정되지 않았을 때의 대체 그룹 정책입니다.
|
||||
- `channels.defaults.contextVisibility`: 모든 채널의 기본 보조 컨텍스트 표시 모드입니다. 값: `all`(기본값, 인용/스레드/기록 컨텍스트 모두 포함), `allowlist`(허용 목록의 발신자 컨텍스트만 포함), `allowlist_quote`(allowlist와 동일하지만 명시적 인용/답장 컨텍스트 유지). 채널별 재정의: `channels.<channel>.contextVisibility`.
|
||||
- `channels.defaults.heartbeat.showOk`: 정상 채널 상태를 Heartbeat 출력에 포함합니다.
|
||||
- `channels.defaults.heartbeat.showAlerts`: 성능 저하/오류 상태를 Heartbeat 출력에 포함합니다.
|
||||
- `channels.defaults.heartbeat.useIndicator`: 간결한 표시기 스타일의 Heartbeat 출력을 렌더링합니다.
|
||||
|
||||
### WhatsApp
|
||||
|
||||
WhatsApp은 gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결된 세션이 있으면 자동으로 시작됩니다.
|
||||
WhatsApp은 Gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결된 세션이 있으면 자동으로 시작됩니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -155,7 +155,7 @@ WhatsApp은 gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결
|
||||
}
|
||||
```
|
||||
|
||||
- 아웃바운드 명령은 `default` 계정이 있으면 기본적으로 해당 계정을 사용하며, 없으면 구성된 첫 번째 계정 ID(정렬됨)를 사용합니다.
|
||||
- 아웃바운드 명령은 계정 `default`가 있으면 이를 기본으로 사용하고, 그렇지 않으면 첫 번째로 구성된 계정 ID(정렬 기준)를 사용합니다.
|
||||
- 선택적 `channels.whatsapp.defaultAccount`는 구성된 계정 ID와 일치할 때 해당 대체 기본 계정 선택을 재정의합니다.
|
||||
- 레거시 단일 계정 Baileys 인증 디렉터리는 `openclaw doctor`에 의해 `whatsapp/default`로 마이그레이션됩니다.
|
||||
- 계정별 재정의: `channels.whatsapp.accounts.<id>.sendReadReceipts`, `channels.whatsapp.accounts.<id>.dmPolicy`, `channels.whatsapp.accounts.<id>.allowFrom`.
|
||||
@ -217,13 +217,13 @@ WhatsApp은 gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결
|
||||
}
|
||||
```
|
||||
|
||||
- 봇 토큰: `channels.telegram.botToken` 또는 `channels.telegram.tokenFile`(일반 파일만 허용, 심볼릭 링크 거부)이며, 기본 계정에는 `TELEGRAM_BOT_TOKEN`이 대체값으로 사용됩니다.
|
||||
- `apiRoot`는 Telegram Bot API 루트 전용입니다. `https://api.telegram.org/bot<TOKEN>`이 아니라 `https://api.telegram.org` 또는 자체 호스팅/프록시 루트를 사용하세요. `openclaw doctor --fix`는 실수로 붙은 후행 `/bot<TOKEN>` 접미사를 제거합니다.
|
||||
- 봇 토큰: `channels.telegram.botToken` 또는 `channels.telegram.tokenFile`(일반 파일만 허용, 심볼릭 링크 거부), 기본 계정의 대체 값으로 `TELEGRAM_BOT_TOKEN` 사용.
|
||||
- `apiRoot`는 Telegram Bot API 루트만 의미합니다. `https://api.telegram.org/bot<TOKEN>`이 아니라 `https://api.telegram.org` 또는 자체 호스팅/프록시 루트를 사용하세요. `openclaw doctor --fix`는 실수로 붙은 후행 `/bot<TOKEN>` 접미사를 제거합니다.
|
||||
- 선택적 `channels.telegram.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다.
|
||||
- 다중 계정 설정(계정 ID 2개 이상)에서는 대체 라우팅을 피하기 위해 명시적 기본값(`channels.telegram.defaultAccount` 또는 `channels.telegram.accounts.default`)을 설정하세요. 이것이 누락되었거나 잘못된 경우 `openclaw doctor`가 경고합니다.
|
||||
- 다중 계정 설정(계정 ID 2개 이상)에서는 대체 라우팅을 피하려면 명시적 기본값(`channels.telegram.defaultAccount` 또는 `channels.telegram.accounts.default`)을 설정하세요. 이 값이 없거나 유효하지 않으면 `openclaw doctor`가 경고합니다.
|
||||
- `configWrites: false`는 Telegram에서 시작된 구성 쓰기(슈퍼그룹 ID 마이그레이션, `/config set|unset`)를 차단합니다.
|
||||
- `type: "acp"`가 있는 최상위 `bindings[]` 항목은 포럼 주제에 대한 영구 ACP 바인딩을 구성합니다(`match.peer.id`에서 정식 `chatId:topic:topicId` 사용). 필드 의미는 [ACP 에이전트](/ko/tools/acp-agents#persistent-channel-bindings)에서 공유됩니다.
|
||||
- Telegram 스트림 미리보기는 `sendMessage` + `editMessageText`를 사용합니다(직접 채팅과 그룹 채팅에서 작동).
|
||||
- `type: "acp"`가 있는 최상위 `bindings[]` 항목은 포럼 토픽의 영구 ACP 바인딩을 구성합니다(`match.peer.id`에서 정식 `chatId:topic:topicId` 사용). 필드 의미는 [ACP 에이전트](/ko/tools/acp-agents#persistent-channel-bindings)에서 공유됩니다.
|
||||
- Telegram 스트림 미리보기는 `sendMessage` + `editMessageText`를 사용합니다(직접 및 그룹 채팅에서 동작).
|
||||
- 재시도 정책: [재시도 정책](/ko/concepts/retry)을 참조하세요.
|
||||
|
||||
### Discord
|
||||
@ -329,41 +329,41 @@ WhatsApp은 gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결
|
||||
}
|
||||
```
|
||||
|
||||
- 토큰: `channels.discord.token`, 기본 계정의 대체값은 `DISCORD_BOT_TOKEN`입니다.
|
||||
- 토큰: `channels.discord.token`, 기본 계정의 대체값으로 `DISCORD_BOT_TOKEN`을 사용합니다.
|
||||
- 명시적인 Discord `token`을 제공하는 직접 아웃바운드 호출은 해당 토큰을 호출에 사용합니다. 계정 재시도/정책 설정은 여전히 활성 런타임 스냅샷에서 선택된 계정에서 가져옵니다.
|
||||
- 선택 사항인 `channels.discord.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다.
|
||||
- 전달 대상에는 `user:<id>`(DM) 또는 `channel:<id>`(길드 채널)를 사용하세요. 숫자 ID만 단독으로 쓰는 형식은 거부됩니다.
|
||||
- 선택적 `channels.discord.defaultAccount`는 구성된 계정 id와 일치할 때 기본 계정 선택을 재정의합니다.
|
||||
- 전달 대상에는 `user:<id>`(DM) 또는 `channel:<id>`(길드 채널)를 사용합니다. 숫자 ID만 있는 값은 거부됩니다.
|
||||
- 길드 슬러그는 소문자이며 공백은 `-`로 대체됩니다. 채널 키는 슬러그 처리된 이름을 사용합니다(`#` 없음). 길드 ID를 권장합니다.
|
||||
- 봇이 작성한 메시지는 기본적으로 무시됩니다. `allowBots: true`로 활성화할 수 있습니다. 봇을 멘션한 봇 메시지만 허용하려면 `allowBots: "mentions"`를 사용하세요(자기 메시지는 계속 필터링됨).
|
||||
- `channels.discord.guilds.<id>.ignoreOtherMentions`(및 채널 재정의)는 다른 사용자나 역할을 멘션하지만 봇은 멘션하지 않는 메시지를 삭제합니다(@everyone/@here 제외).
|
||||
- `channels.discord.mentionAliases`는 전송 전에 안정적인 아웃바운드 `@handle` 텍스트를 Discord 사용자 ID에 매핑하므로, 일시적인 디렉터리 캐시가 비어 있어도 알려진 팀원을 결정적으로 멘션할 수 있습니다. 계정별 재정의는 `channels.discord.accounts.<accountId>.mentionAliases` 아래에 있습니다.
|
||||
- `maxLinesPerMessage`(기본값 17)는 2000자 미만이어도 줄 수가 많은 메시지를 분할합니다.
|
||||
- `channels.discord.threadBindings`는 Discord 스레드 바인딩 라우팅을 제어합니다:
|
||||
- `enabled`: 스레드 바인딩 세션 기능(`/focus`, `/unfocus`, `/agents`, `/session idle`, `/session max-age`, 및 바인딩된 전달/라우팅)에 대한 Discord 재정의
|
||||
- `idleHours`: 비활성 자동 언포커스 시간(시간 단위)에 대한 Discord 재정의(`0`은 비활성화)
|
||||
- `maxAgeHours`: 하드 최대 수명(시간 단위)에 대한 Discord 재정의(`0`은 비활성화)
|
||||
- `spawnSessions`: `sessions_spawn({ thread: true })` 및 ACP 스레드 생성 자동 스레드 생성/바인딩 스위치(기본값: `true`)
|
||||
- 봇이 작성한 메시지는 기본적으로 무시됩니다. `allowBots: true`는 이를 활성화합니다. 봇을 멘션한 봇 메시지만 허용하려면 `allowBots: "mentions"`를 사용하세요(자기 메시지는 계속 필터링됨).
|
||||
- `channels.discord.guilds.<id>.ignoreOtherMentions`(및 채널 재정의)는 봇은 멘션하지 않고 다른 사용자나 역할을 멘션한 메시지를 삭제합니다(@everyone/@here 제외).
|
||||
- `channels.discord.mentionAliases`는 전송 전에 안정적인 아웃바운드 `@handle` 텍스트를 Discord 사용자 ID에 매핑하므로, 임시 디렉터리 캐시가 비어 있어도 알려진 팀원을 결정적으로 멘션할 수 있습니다. 계정별 재정의는 `channels.discord.accounts.<accountId>.mentionAliases` 아래에 있습니다.
|
||||
- `maxLinesPerMessage`(기본값 17)는 2000자 미만이어도 긴 메시지를 분할합니다.
|
||||
- `channels.discord.threadBindings`는 Discord 스레드 바인딩 라우팅을 제어합니다.
|
||||
- `enabled`: 스레드 바인딩 세션 기능(`/focus`, `/unfocus`, `/agents`, `/session idle`, `/session max-age`, 바인딩된 전달/라우팅)에 대한 Discord 재정의
|
||||
- `idleHours`: 비활성 상태 자동 포커스 해제 시간(시간 단위)에 대한 Discord 재정의(`0`은 비활성화)
|
||||
- `maxAgeHours`: 강제 최대 수명(시간 단위)에 대한 Discord 재정의(`0`은 비활성화)
|
||||
- `spawnSessions`: `sessions_spawn({ thread: true })` 및 ACP 스레드 생성 자동 스레드 생성/바인딩을 위한 스위치(기본값: `true`)
|
||||
- `defaultSpawnContext`: 스레드 바인딩 생성의 네이티브 하위 에이전트 컨텍스트(기본값 `"fork"`)
|
||||
- `type: "acp"`가 있는 최상위 `bindings[]` 항목은 채널 및 스레드의 영구 ACP 바인딩을 구성합니다(`match.peer.id`에 채널/스레드 ID 사용). 필드 의미는 [ACP Agents](/ko/tools/acp-agents#persistent-channel-bindings)에서 공유됩니다.
|
||||
- `type: "acp"`인 최상위 `bindings[]` 항목은 채널과 스레드에 대한 영구 ACP 바인딩을 구성합니다(`match.peer.id`에 채널/스레드 id 사용). 필드 의미는 [ACP 에이전트](/ko/tools/acp-agents#persistent-channel-bindings)에서 공유됩니다.
|
||||
- `channels.discord.ui.components.accentColor`는 Discord 컴포넌트 v2 컨테이너의 강조 색상을 설정합니다.
|
||||
- `channels.discord.voice`는 Discord 음성 채널 대화와 선택적 자동 참여 + LLM + TTS 재정의를 활성화합니다. 텍스트 전용 Discord 구성은 기본적으로 음성을 꺼 둡니다. 사용하려면 `channels.discord.voice.enabled=true`를 설정하세요.
|
||||
- `channels.discord.voice`는 Discord 음성 채널 대화와 선택적 자동 참여 + LLM + TTS 재정의를 활성화합니다. 텍스트 전용 Discord 구성은 기본적으로 음성을 끕니다. 사용하려면 `channels.discord.voice.enabled=true`를 설정하세요.
|
||||
- `channels.discord.voice.model`은 Discord 음성 채널 응답에 사용되는 LLM 모델을 선택적으로 재정의합니다.
|
||||
- `channels.discord.voice.daveEncryption` 및 `channels.discord.voice.decryptionFailureTolerance`는 `@discordjs/voice` DAVE 옵션으로 전달됩니다(기본값은 `true` 및 `24`).
|
||||
- `channels.discord.voice.connectTimeoutMs`는 `/vc join` 및 자동 참여 시도의 초기 `@discordjs/voice` Ready 대기 시간을 제어합니다(기본값 `30000`).
|
||||
- `channels.discord.voice.reconnectGraceMs`는 연결이 끊긴 음성 세션이 재연결 신호 상태에 들어가기까지 허용되는 시간을 제어하며, 이 시간을 넘기면 OpenClaw가 세션을 제거합니다(기본값 `15000`).
|
||||
- OpenClaw는 반복되는 복호화 실패 후 음성 세션을 나갔다가 다시 참여하여 음성 수신 복구도 시도합니다.
|
||||
- `channels.discord.streaming`은 표준 스트림 모드 키입니다. 레거시 `streamMode` 및 불리언 `streaming` 값은 자동 마이그레이션됩니다.
|
||||
- `channels.discord.autoPresence`는 런타임 가용성을 봇 프레즌스에 매핑하며(healthy => online, degraded => idle, exhausted => dnd), 선택적 상태 텍스트 재정의를 허용합니다.
|
||||
- `channels.discord.dangerouslyAllowNameMatching`은 변경 가능한 이름/태그 매칭을 다시 활성화합니다(긴급 호환성 모드).
|
||||
- `channels.discord.execApprovals`: Discord 네이티브 실행 승인 전달 및 승인자 권한 부여.
|
||||
- `enabled`: `true`, `false` 또는 `"auto"`(기본값). 자동 모드에서는 `approvers` 또는 `commands.ownerAllowFrom`에서 승인자를 해석할 수 있을 때 실행 승인이 활성화됩니다.
|
||||
- `approvers`: 실행 요청을 승인할 수 있는 Discord 사용자 ID입니다. 생략하면 `commands.ownerAllowFrom`으로 대체됩니다.
|
||||
- `agentFilter`: 선택적 에이전트 ID 허용 목록입니다. 모든 에이전트의 승인을 전달하려면 생략하세요.
|
||||
- `sessionFilter`: 선택적 세션 키 패턴(부분 문자열 또는 정규식)입니다.
|
||||
- `target`: 승인 프롬프트를 보낼 위치입니다. `"dm"`(기본값)은 승인자 DM으로 보내고, `"channel"`은 원본 채널로 보내며, `"both"`는 둘 다로 보냅니다. 대상에 `"channel"`이 포함된 경우 버튼은 해석된 승인자만 사용할 수 있습니다.
|
||||
- `channels.discord.voice.connectTimeoutMs`는 `/vc join` 및 자동 참여 시도에 대한 초기 `@discordjs/voice` Ready 대기를 제어합니다(기본값 `30000`).
|
||||
- `channels.discord.voice.reconnectGraceMs`는 연결이 끊긴 음성 세션이 OpenClaw에 의해 제거되기 전에 재연결 신호 상태에 진입할 수 있는 시간을 제어합니다(기본값 `15000`).
|
||||
- OpenClaw는 반복된 복호화 실패 후 음성 세션을 나갔다가 다시 참여하여 음성 수신 복구도 시도합니다.
|
||||
- `channels.discord.streaming`은 표준 스트림 모드 키입니다. 기존 `streamMode` 및 boolean `streaming` 값은 자동 마이그레이션됩니다.
|
||||
- `channels.discord.autoPresence`는 런타임 가용성을 봇 프레즌스에 매핑하고(healthy => online, degraded => idle, exhausted => dnd), 선택적 상태 텍스트 재정의를 허용합니다.
|
||||
- `channels.discord.dangerouslyAllowNameMatching`은 변경 가능한 이름/태그 매칭을 다시 활성화합니다(비상 호환성 모드).
|
||||
- `channels.discord.execApprovals`: Discord 네이티브 exec 승인 전달 및 승인자 권한 부여.
|
||||
- `enabled`: `true`, `false` 또는 `"auto"`(기본값). 자동 모드에서는 `approvers` 또는 `commands.ownerAllowFrom`에서 승인자를 확인할 수 있을 때 exec 승인이 활성화됩니다.
|
||||
- `approvers`: exec 요청을 승인할 수 있는 Discord 사용자 ID입니다. 생략하면 `commands.ownerAllowFrom`으로 대체됩니다.
|
||||
- `agentFilter`: 선택적 에이전트 ID 허용 목록입니다. 생략하면 모든 에이전트의 승인이 전달됩니다.
|
||||
- `sessionFilter`: 선택적 세션 키 패턴(부분 문자열 또는 정규식).
|
||||
- `target`: 승인 프롬프트를 보낼 위치입니다. `"dm"`(기본값)은 승인자 DM으로 보내고, `"channel"`은 원본 채널로 보내며, `"both"`는 둘 다로 보냅니다. 대상에 `"channel"`이 포함되면 버튼은 확인된 승인자만 사용할 수 있습니다.
|
||||
- `cleanupAfterResolve`: `true`이면 승인, 거부 또는 시간 초과 후 승인 DM을 삭제합니다.
|
||||
|
||||
**반응 알림 모드:** `off`(없음), `own`(봇의 메시지, 기본값), `all`(모든 메시지), `allowlist`(모든 메시지에서 `guilds.<id>.users` 기준).
|
||||
**반응 알림 모드:** `off`(없음), `own`(봇의 메시지, 기본값), `all`(모든 메시지), `allowlist`(모든 메시지에서 `guilds.<id>.users` 기반).
|
||||
|
||||
### Google Chat
|
||||
|
||||
@ -396,9 +396,9 @@ WhatsApp은 gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결
|
||||
|
||||
- 서비스 계정 JSON: 인라인(`serviceAccount`) 또는 파일 기반(`serviceAccountFile`).
|
||||
- 서비스 계정 SecretRef도 지원됩니다(`serviceAccountRef`).
|
||||
- 환경 변수 대체값: `GOOGLE_CHAT_SERVICE_ACCOUNT` 또는 `GOOGLE_CHAT_SERVICE_ACCOUNT_FILE`.
|
||||
- 전달 대상에는 `spaces/<spaceId>` 또는 `users/<userId>`를 사용하세요.
|
||||
- `channels.googlechat.dangerouslyAllowNameMatching`은 변경 가능한 이메일 주체 매칭을 다시 활성화합니다(긴급 호환성 모드).
|
||||
- env 대체값: `GOOGLE_CHAT_SERVICE_ACCOUNT` 또는 `GOOGLE_CHAT_SERVICE_ACCOUNT_FILE`.
|
||||
- 전달 대상에는 `spaces/<spaceId>` 또는 `users/<userId>`를 사용합니다.
|
||||
- `channels.googlechat.dangerouslyAllowNameMatching`은 변경 가능한 이메일 주체 매칭을 다시 활성화합니다(비상 호환성 모드).
|
||||
|
||||
### Slack
|
||||
|
||||
@ -470,44 +470,43 @@ WhatsApp은 gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결
|
||||
}
|
||||
```
|
||||
|
||||
- **소켓 모드**에는 `botToken` 및 `appToken`이 모두 필요합니다(기본 계정 환경 변수 대체값은 `SLACK_BOT_TOKEN` + `SLACK_APP_TOKEN`).
|
||||
- **소켓 모드**에는 `botToken`과 `appToken`이 모두 필요합니다(기본 계정 env 대체값은 `SLACK_BOT_TOKEN` + `SLACK_APP_TOKEN`).
|
||||
- **HTTP 모드**에는 `botToken`과 `signingSecret`이 필요합니다(루트 또는 계정별).
|
||||
- `socketMode`는 Slack SDK 소켓 모드 전송 튜닝을 공개 Bolt 수신기 API로 전달합니다. ping/pong 시간 초과 또는 오래된 웹소켓 동작을 조사할 때만 사용하세요.
|
||||
- `botToken`, `appToken`, `signingSecret`, `userToken`은 일반 텍스트
|
||||
- `socketMode`는 Slack SDK Socket Mode 전송 튜닝을 공개 Bolt 수신기 API로 전달합니다. ping/pong 시간 초과 또는 오래된 websocket 동작을 조사할 때만 사용하세요.
|
||||
- `botToken`, `appToken`, `signingSecret`, `userToken`은 평문
|
||||
문자열 또는 SecretRef 객체를 허용합니다.
|
||||
- Slack 계정 스냅샷은 `botTokenSource`, `botTokenStatus`,
|
||||
`appTokenStatus` 및 HTTP 모드의 `signingSecretStatus` 같은
|
||||
자격 증명별 소스/상태 필드를 노출합니다. `configured_unavailable`은 계정이
|
||||
SecretRef를 통해 구성되었지만 현재 명령/런타임 경로가 비밀 값을
|
||||
해석할 수 없었음을 의미합니다.
|
||||
- Slack 계정 스냅샷은 `botTokenSource`, `botTokenStatus`, `appTokenStatus`와 같은 자격 증명별 소스/상태 필드 및 HTTP 모드의
|
||||
`signingSecretStatus`를 노출합니다. `configured_unavailable`은 계정이
|
||||
SecretRef를 통해 구성되었지만 현재 명령/런타임 경로가
|
||||
시크릿 값을 확인할 수 없었음을 의미합니다.
|
||||
- `configWrites: false`는 Slack에서 시작된 구성 쓰기를 차단합니다.
|
||||
- 선택 사항인 `channels.slack.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다.
|
||||
- `channels.slack.streaming.mode`는 표준 Slack 스트림 모드 키입니다. `channels.slack.streaming.nativeTransport`는 Slack의 네이티브 스트리밍 전송을 제어합니다. 레거시 `streamMode`, 불리언 `streaming`, `nativeStreaming` 값은 자동 마이그레이션됩니다.
|
||||
- 전달 대상에는 `user:<id>`(DM) 또는 `channel:<id>`를 사용하세요.
|
||||
- 선택적 `channels.slack.defaultAccount`는 구성된 계정 id와 일치할 때 기본 계정 선택을 재정의합니다.
|
||||
- `channels.slack.streaming.mode`는 표준 Slack 스트림 모드 키입니다. `channels.slack.streaming.nativeTransport`는 Slack의 네이티브 스트리밍 전송을 제어합니다. 기존 `streamMode`, boolean `streaming`, `nativeStreaming` 값은 자동 마이그레이션됩니다.
|
||||
- 전달 대상에는 `user:<id>`(DM) 또는 `channel:<id>`를 사용합니다.
|
||||
|
||||
**반응 알림 모드:** `off`, `own`(기본값), `all`, `allowlist`(`reactionAllowlist` 기준).
|
||||
**반응 알림 모드:** `off`, `own`(기본값), `all`, `allowlist`(`reactionAllowlist` 기반).
|
||||
|
||||
**스레드 세션 격리:** `thread.historyScope`는 스레드별(기본값) 또는 채널 전체 공유입니다. `thread.inheritParent`는 부모 채널 대화 기록을 새 스레드로 복사합니다.
|
||||
**스레드 세션 격리:** `thread.historyScope`는 스레드별(기본값) 또는 채널 전체 공유입니다. `thread.inheritParent`는 상위 채널 대화 기록을 새 스레드로 복사합니다.
|
||||
|
||||
- Slack 네이티브 스트리밍과 Slack 어시스턴트 스타일의 "is typing..." 스레드 상태에는 답장 스레드 대상이 필요합니다. 최상위 DM은 기본적으로 스레드 밖에 유지되므로, 스레드 스타일 네이티브 스트림/상태 미리보기를 표시하는 대신 Slack 초안 게시 및 편집 미리보기를 통해 계속 스트리밍할 수 있습니다.
|
||||
- `typingReaction`은 답장이 실행되는 동안 인바운드 Slack 메시지에 임시 반응을 추가한 뒤, 완료 시 제거합니다. `"hourglass_flowing_sand"` 같은 Slack 이모지 단축 코드를 사용하세요.
|
||||
- `channels.slack.execApprovals`: Slack 네이티브 실행 승인 전달 및 승인자 권한 부여. Discord와 동일한 스키마입니다: `enabled`(`true`/`false`/`"auto"`), `approvers`(Slack 사용자 ID), `agentFilter`, `sessionFilter`, `target`(`"dm"`, `"channel"` 또는 `"both"`).
|
||||
- Slack 네이티브 스트리밍과 Slack 어시스턴트 스타일의 "입력 중..." 스레드 상태에는 답장 스레드 대상이 필요합니다. 최상위 DM은 기본적으로 스레드 밖에 유지되므로, 스레드 스타일의 네이티브 스트림/상태 미리보기를 표시하는 대신 Slack 초안 게시 및 편집 미리보기를 통해 계속 스트리밍할 수 있습니다.
|
||||
- `typingReaction`은 답장이 실행되는 동안 인바운드 Slack 메시지에 임시 반응을 추가한 뒤 완료 시 제거합니다. `"hourglass_flowing_sand"`와 같은 Slack 이모지 shortcode를 사용하세요.
|
||||
- `channels.slack.execApprovals`: Slack 네이티브 exec 승인 전달 및 승인자 권한 부여. Discord와 동일한 스키마입니다: `enabled`(`true`/`false`/`"auto"`), `approvers`(Slack 사용자 ID), `agentFilter`, `sessionFilter`, `target`(`"dm"`, `"channel"` 또는 `"both"`).
|
||||
|
||||
| 작업 그룹 | 기본값 | 참고 |
|
||||
| 작업 그룹 | 기본값 | 참고 |
|
||||
| ------------ | ------- | ---------------------- |
|
||||
| reactions | 활성화 | 반응 추가 + 반응 목록 |
|
||||
| messages | 활성화 | 읽기/전송/편집/삭제 |
|
||||
| pins | 활성화 | 고정/고정 해제/목록 |
|
||||
| memberInfo | 활성화 | 멤버 정보 |
|
||||
| emojiList | 활성화 | 사용자 지정 이모지 목록 |
|
||||
| reactions | 활성화됨 | 반응 추가 + 반응 목록 |
|
||||
| messages | 활성화됨 | 읽기/보내기/편집/삭제 |
|
||||
| pins | 활성화됨 | 고정/고정 해제/목록 |
|
||||
| memberInfo | 활성화됨 | 멤버 정보 |
|
||||
| emojiList | 활성화됨 | 사용자 지정 이모지 목록 |
|
||||
|
||||
### Mattermost
|
||||
|
||||
Mattermost는 현재 OpenClaw 릴리스에서 번들 Plugin으로 제공됩니다. 더 오래된 빌드 또는
|
||||
사용자 지정 빌드는 현재 npm 패키지를
|
||||
`openclaw plugins install @openclaw/mattermost`로 설치할 수 있습니다. 버전을 고정하기 전에
|
||||
현재 dist-tag는
|
||||
[npmjs.com/package/@openclaw/mattermost](https://www.npmjs.com/package/@openclaw/mattermost)에서 확인하세요.
|
||||
Mattermost는 현재 OpenClaw 릴리스에서 번들 Plugin으로 제공됩니다. 이전 또는
|
||||
사용자 지정 빌드는 다음 명령으로 현재 npm 패키지를 설치할 수 있습니다.
|
||||
`openclaw plugins install @openclaw/mattermost`. 버전을 고정하기 전에 현재 dist-tag는
|
||||
[npmjs.com/package/@openclaw/mattermost](https://www.npmjs.com/package/@openclaw/mattermost)에서
|
||||
확인하세요.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -537,20 +536,15 @@ Mattermost는 현재 OpenClaw 릴리스에서 번들 Plugin으로 제공됩니
|
||||
}
|
||||
```
|
||||
|
||||
채팅 모드: `oncall`(@멘션 시 응답, 기본값), `onmessage`(모든 메시지), `onchar`(트리거 접두사로 시작하는 메시지).
|
||||
채팅 모드: `oncall`(@멘션에 응답, 기본값), `onmessage`(모든 메시지), `onchar`(트리거 접두사로 시작하는 메시지).
|
||||
|
||||
Mattermost 네이티브 명령이 활성화된 경우:
|
||||
|
||||
- `commands.callbackPath`는 전체 URL이 아니라 경로(예: `/api/channels/mattermost/command`)여야 합니다.
|
||||
- `commands.callbackUrl`은 OpenClaw gateway 엔드포인트로 해석되어야 하며 Mattermost 서버에서 접근 가능해야 합니다.
|
||||
- 네이티브 슬래시 콜백은 슬래시 명령 등록 중 Mattermost가 반환한
|
||||
명령별 토큰으로 인증됩니다. 등록에 실패하거나 활성화된
|
||||
명령이 없으면 OpenClaw는 다음 오류로 콜백을 거부합니다.
|
||||
`Unauthorized: invalid command token.`
|
||||
- 프라이빗/tailnet/내부 콜백 호스트의 경우 Mattermost에서
|
||||
`ServiceSettings.AllowedUntrustedInternalConnections`에 콜백 호스트/도메인을 포함해야 할 수 있습니다.
|
||||
전체 URL이 아니라 호스트/도메인 값을 사용하세요.
|
||||
- `channels.mattermost.configWrites`: Mattermost가 시작한 config 쓰기를 허용하거나 거부합니다.
|
||||
- `commands.callbackPath`는 전체 URL이 아니라 경로여야 합니다(예: `/api/channels/mattermost/command`).
|
||||
- `commands.callbackUrl`은 OpenClaw Gateway 엔드포인트로 확인되어야 하며 Mattermost 서버에서 접근 가능해야 합니다.
|
||||
- 네이티브 슬래시 콜백은 슬래시 명령 등록 중 Mattermost가 반환한 명령별 토큰으로 인증됩니다. 등록에 실패하거나 활성화된 명령이 없으면 OpenClaw는 `Unauthorized: invalid command token.`으로 콜백을 거부합니다.
|
||||
- 비공개/tailnet/내부 콜백 호스트의 경우 Mattermost에서 `ServiceSettings.AllowedUntrustedInternalConnections`에 콜백 호스트/도메인을 포함해야 할 수 있습니다. 전체 URL이 아니라 호스트/도메인 값을 사용하세요.
|
||||
- `channels.mattermost.configWrites`: Mattermost에서 시작한 구성 쓰기를 허용하거나 거부합니다.
|
||||
- `channels.mattermost.requireMention`: 채널에서 답장하기 전에 `@mention`을 요구합니다.
|
||||
- `channels.mattermost.groups.<channelId>.requireMention`: 채널별 멘션 게이팅 재정의(기본값은 `"*"`).
|
||||
- 선택 사항인 `channels.mattermost.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다.
|
||||
@ -574,15 +568,15 @@ Mattermost 네이티브 명령이 활성화된 경우:
|
||||
}
|
||||
```
|
||||
|
||||
**반응 알림 모드:** `off`, `own`(기본값), `all`, `allowlist`(`reactionAllowlist`에서).
|
||||
**반응 알림 모드:** `off`, `own`(기본값), `all`, `allowlist`(`reactionAllowlist`에서 가져옴).
|
||||
|
||||
- `channels.signal.account`: 채널 시작을 특정 Signal 계정 ID에 고정합니다.
|
||||
- `channels.signal.configWrites`: Signal이 시작한 config 쓰기를 허용하거나 거부합니다.
|
||||
- `channels.signal.configWrites`: Signal에서 시작한 구성 쓰기를 허용하거나 거부합니다.
|
||||
- 선택 사항인 `channels.signal.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다.
|
||||
|
||||
### BlueBubbles
|
||||
|
||||
BlueBubbles는 권장 iMessage 경로입니다(Plugin 기반, `channels.bluebubbles` 아래에서 구성).
|
||||
BlueBubbles는 권장되는 iMessage 경로입니다(Plugin 기반, `channels.bluebubbles` 아래에서 구성).
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -599,12 +593,12 @@ BlueBubbles는 권장 iMessage 경로입니다(Plugin 기반, `channels.bluebubb
|
||||
|
||||
- 여기서 다루는 핵심 키 경로: `channels.bluebubbles`, `channels.bluebubbles.dmPolicy`.
|
||||
- 선택 사항인 `channels.bluebubbles.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다.
|
||||
- `type: "acp"`가 있는 최상위 `bindings[]` 항목은 BlueBubbles 대화를 영구 ACP 세션에 바인딩할 수 있습니다. `match.peer.id`에 BlueBubbles 핸들 또는 대상 문자열(`chat_id:*`, `chat_guid:*`, `chat_identifier:*`)을 사용하세요. 공유 필드 의미 체계: [ACP 에이전트](/ko/tools/acp-agents#persistent-channel-bindings).
|
||||
- `type: "acp"`가 있는 최상위 `bindings[]` 항목은 BlueBubbles 대화를 지속 ACP 세션에 바인딩할 수 있습니다. `match.peer.id`에서 BlueBubbles 핸들 또는 대상 문자열(`chat_id:*`, `chat_guid:*`, `chat_identifier:*`)을 사용하세요. 공유 필드 의미 체계: [ACP 에이전트](/ko/tools/acp-agents#persistent-channel-bindings).
|
||||
- 전체 BlueBubbles 채널 구성은 [BlueBubbles](/ko/channels/bluebubbles)에 문서화되어 있습니다.
|
||||
|
||||
### iMessage
|
||||
|
||||
OpenClaw는 `imsg rpc`(stdio를 통한 JSON-RPC)를 실행합니다. 데몬이나 포트는 필요하지 않습니다.
|
||||
OpenClaw는 `imsg rpc`(표준 입출력을 통한 JSON-RPC)를 생성합니다. 데몬이나 포트는 필요하지 않습니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -631,12 +625,12 @@ OpenClaw는 `imsg rpc`(stdio를 통한 JSON-RPC)를 실행합니다. 데몬이
|
||||
- 선택 사항인 `channels.imessage.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다.
|
||||
|
||||
- Messages DB에 대한 전체 디스크 접근 권한이 필요합니다.
|
||||
- `chat_id:<id>` 대상을 권장합니다. 채팅을 나열하려면 `imsg chats --limit 20`을 사용하세요.
|
||||
- `chat_id:<id>` 대상을 선호하세요. 채팅을 나열하려면 `imsg chats --limit 20`을 사용하세요.
|
||||
- `cliPath`는 SSH 래퍼를 가리킬 수 있습니다. SCP 첨부 파일 가져오기를 위해 `remoteHost`(`host` 또는 `user@host`)를 설정하세요.
|
||||
- `attachmentRoots`와 `remoteAttachmentRoots`는 인바운드 첨부 파일 경로를 제한합니다(기본값: `/Users/*/Library/Messages/Attachments`).
|
||||
- SCP는 엄격한 호스트 키 확인을 사용하므로 릴레이 호스트 키가 이미 `~/.ssh/known_hosts`에 있는지 확인하세요.
|
||||
- `channels.imessage.configWrites`: iMessage가 시작한 config 쓰기를 허용하거나 거부합니다.
|
||||
- `type: "acp"`가 있는 최상위 `bindings[]` 항목은 iMessage 대화를 영구 ACP 세션에 바인딩할 수 있습니다. `match.peer.id`에 정규화된 핸들 또는 명시적 채팅 대상(`chat_id:*`, `chat_guid:*`, `chat_identifier:*`)을 사용하세요. 공유 필드 의미 체계: [ACP 에이전트](/ko/tools/acp-agents#persistent-channel-bindings).
|
||||
- `attachmentRoots` 및 `remoteAttachmentRoots`는 수신 첨부 파일 경로를 제한합니다(기본값: `/Users/*/Library/Messages/Attachments`).
|
||||
- SCP는 엄격한 호스트 키 검사를 사용하므로 릴레이 호스트 키가 이미 `~/.ssh/known_hosts`에 있는지 확인하세요.
|
||||
- `channels.imessage.configWrites`: iMessage에서 시작한 구성 쓰기를 허용하거나 거부합니다.
|
||||
- `type: "acp"`가 있는 최상위 `bindings[]` 항목은 iMessage 대화를 지속 ACP 세션에 바인딩할 수 있습니다. `match.peer.id`에서 정규화된 핸들 또는 명시적 채팅 대상(`chat_id:*`, `chat_guid:*`, `chat_identifier:*`)을 사용하세요. 공유 필드 의미 체계: [ACP 에이전트](/ko/tools/acp-agents#persistent-channel-bindings).
|
||||
|
||||
<Accordion title="iMessage SSH 래퍼 예시">
|
||||
|
||||
@ -681,19 +675,19 @@ Matrix는 Plugin 기반이며 `channels.matrix` 아래에서 구성됩니다.
|
||||
|
||||
- 토큰 인증은 `accessToken`을 사용하고, 비밀번호 인증은 `userId` + `password`를 사용합니다.
|
||||
- `channels.matrix.proxy`는 Matrix HTTP 트래픽을 명시적 HTTP(S) 프록시를 통해 라우팅합니다. 명명된 계정은 `channels.matrix.accounts.<id>.proxy`로 이를 재정의할 수 있습니다.
|
||||
- `channels.matrix.network.dangerouslyAllowPrivateNetwork`는 프라이빗/내부 홈서버를 허용합니다. `proxy`와 이 네트워크 옵트인은 독립적인 제어 항목입니다.
|
||||
- `channels.matrix.network.dangerouslyAllowPrivateNetwork`는 비공개/내부 홈서버를 허용합니다. `proxy`와 이 네트워크 옵트인은 독립적인 제어 항목입니다.
|
||||
- `channels.matrix.defaultAccount`는 다중 계정 설정에서 선호 계정을 선택합니다.
|
||||
- `channels.matrix.autoJoin`의 기본값은 `off`이므로, `autoJoinAllowlist`와 함께 `autoJoin: "allowlist"`를 설정하거나 `autoJoin: "always"`를 설정할 때까지 초대된 방과 새 DM 스타일 초대는 무시됩니다.
|
||||
- `channels.matrix.execApprovals`: Matrix 네이티브 exec 승인 전달 및 승인자 권한 부여.
|
||||
- `enabled`: `true`, `false` 또는 `"auto"`(기본값). 자동 모드에서는 `approvers` 또는 `commands.ownerAllowFrom`에서 승인자를 확인할 수 있을 때 exec 승인이 활성화됩니다.
|
||||
- `approvers`: exec 요청을 승인할 수 있는 Matrix 사용자 ID(예: `@owner:example.org`).
|
||||
- `agentFilter`: 선택 사항인 에이전트 ID 허용 목록. 생략하면 모든 에이전트의 승인을 전달합니다.
|
||||
- `sessionFilter`: 선택 사항인 세션 키 패턴(부분 문자열 또는 정규식).
|
||||
- `target`: 승인 프롬프트를 보낼 위치. `"dm"`(기본값), `"channel"`(원본 방) 또는 `"both"`.
|
||||
- `channels.matrix.autoJoin`의 기본값은 `off`이므로 `autoJoinAllowlist`와 함께 `autoJoin: "allowlist"`를 설정하거나 `autoJoin: "always"`를 설정할 때까지 초대된 방과 새 DM 스타일 초대는 무시됩니다.
|
||||
- `channels.matrix.execApprovals`: Matrix 네이티브 실행 승인 전달 및 승인자 권한 부여입니다.
|
||||
- `enabled`: `true`, `false` 또는 `"auto"`(기본값). 자동 모드에서는 `approvers` 또는 `commands.ownerAllowFrom`에서 승인자를 확인할 수 있을 때 실행 승인이 활성화됩니다.
|
||||
- `approvers`: 실행 요청을 승인할 수 있는 Matrix 사용자 ID(예: `@owner:example.org`)입니다.
|
||||
- `agentFilter`: 선택 사항인 에이전트 ID 허용 목록입니다. 모든 에이전트에 대한 승인을 전달하려면 생략하세요.
|
||||
- `sessionFilter`: 선택 사항인 세션 키 패턴(부분 문자열 또는 정규식)입니다.
|
||||
- `target`: 승인 프롬프트를 보낼 위치입니다. `"dm"`(기본값), `"channel"`(원본 방) 또는 `"both"`입니다.
|
||||
- 계정별 재정의: `channels.matrix.accounts.<id>.execApprovals`.
|
||||
- `channels.matrix.dm.sessionScope`는 Matrix DM이 세션으로 그룹화되는 방식을 제어합니다. `per-user`(기본값)는 라우팅된 피어별로 공유하고, `per-room`은 각 DM 방을 격리합니다.
|
||||
- Matrix 상태 프로브와 라이브 디렉터리 조회는 런타임 트래픽과 동일한 프록시 정책을 사용합니다.
|
||||
- 전체 Matrix 구성, 대상 지정 규칙, 설정 예시는 [Matrix](/ko/channels/matrix)에 문서화되어 있습니다.
|
||||
- Matrix 상태 프로브와 실시간 디렉터리 조회는 런타임 트래픽과 동일한 프록시 정책을 사용합니다.
|
||||
- 전체 Matrix 구성, 대상 지정 규칙 및 설정 예시는 [Matrix](/ko/channels/matrix)에 문서화되어 있습니다.
|
||||
|
||||
### Microsoft Teams
|
||||
|
||||
@ -713,7 +707,7 @@ Microsoft Teams는 Plugin 기반이며 `channels.msteams` 아래에서 구성됩
|
||||
```
|
||||
|
||||
- 여기서 다루는 핵심 키 경로: `channels.msteams`, `channels.msteams.configWrites`.
|
||||
- 전체 Teams config(자격 증명, webhook, DM/그룹 정책, 팀별/채널별 재정의)는 [Microsoft Teams](/ko/channels/msteams)에 문서화되어 있습니다.
|
||||
- 전체 Teams 구성(자격 증명, Webhook, DM/그룹 정책, 팀별/채널별 재정의)은 [Microsoft Teams](/ko/channels/msteams)에 문서화되어 있습니다.
|
||||
|
||||
### IRC
|
||||
|
||||
@ -744,7 +738,7 @@ IRC는 Plugin 기반이며 `channels.irc` 아래에서 구성됩니다.
|
||||
|
||||
### 다중 계정(모든 채널)
|
||||
|
||||
채널당 여러 계정을 실행합니다(각각 자체 `accountId` 사용).
|
||||
채널별로 여러 계정을 실행합니다(각각 고유한 `accountId` 사용).
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -766,12 +760,12 @@ IRC는 Plugin 기반이며 `channels.irc` 아래에서 구성됩니다.
|
||||
```
|
||||
|
||||
- `accountId`가 생략되면 `default`가 사용됩니다(CLI + 라우팅).
|
||||
- 환경 토큰은 **기본** 계정에만 적용됩니다.
|
||||
- 환경 변수 토큰은 **기본** 계정에만 적용됩니다.
|
||||
- 기본 채널 설정은 계정별로 재정의하지 않는 한 모든 계정에 적용됩니다.
|
||||
- 각 계정을 다른 에이전트로 라우팅하려면 `bindings[].match.accountId`를 사용하세요.
|
||||
- 단일 계정 최상위 채널 config에 있는 상태에서 `openclaw channels add`(또는 채널 온보딩)로 기본이 아닌 계정을 추가하면, OpenClaw는 원래 계정이 계속 작동하도록 계정 범위 최상위 단일 계정 값을 먼저 채널 계정 맵으로 승격합니다. 대부분의 채널은 이를 `channels.<channel>.accounts.default`로 이동합니다. Matrix는 기존에 일치하는 명명된/기본 대상을 대신 보존할 수 있습니다.
|
||||
- 단일 계정 최상위 채널 구성 상태에서 `openclaw channels add`(또는 채널 온보딩)를 통해 기본이 아닌 계정을 추가하면, OpenClaw는 원래 계정이 계속 작동하도록 먼저 계정 범위의 최상위 단일 계정 값을 채널 계정 맵으로 승격합니다. 대부분의 채널은 이를 `channels.<channel>.accounts.default`로 이동합니다. Matrix는 기존의 일치하는 명명된/기본 대상을 대신 보존할 수 있습니다.
|
||||
- 기존 채널 전용 바인딩(`accountId` 없음)은 기본 계정과 계속 일치합니다. 계정 범위 바인딩은 계속 선택 사항입니다.
|
||||
- `openclaw doctor --fix`도 계정 범위 최상위 단일 계정 값을 해당 채널에 대해 선택된 승격 계정으로 이동하여 혼합 형태를 복구합니다. 대부분의 채널은 `accounts.default`를 사용합니다. Matrix는 기존에 일치하는 명명된/기본 대상을 대신 보존할 수 있습니다.
|
||||
- `openclaw doctor --fix`도 해당 채널에 대해 선택된 승격 계정으로 계정 범위의 최상위 단일 계정 값을 이동하여 혼합 형태를 복구합니다. 대부분의 채널은 `accounts.default`를 사용합니다. Matrix는 기존의 일치하는 명명된/기본 대상을 대신 보존할 수 있습니다.
|
||||
|
||||
### 기타 Plugin 채널
|
||||
|
||||
@ -780,18 +774,20 @@ IRC는 Plugin 기반이며 `channels.irc` 아래에서 구성됩니다.
|
||||
|
||||
### 그룹 채팅 멘션 게이팅
|
||||
|
||||
그룹 메시지는 기본적으로 **멘션 필요**(메타데이터 멘션 또는 안전한 정규식 패턴)입니다. WhatsApp, Telegram, Discord, Google Chat, iMessage 그룹 채팅에 적용됩니다.
|
||||
그룹 메시지는 기본적으로 **멘션 필요**입니다(메타데이터 멘션 또는 안전한 정규식 패턴). WhatsApp, Telegram, Discord, Google Chat 및 iMessage 그룹 채팅에 적용됩니다.
|
||||
|
||||
표시되는 답장은 별도로 제어됩니다. 그룹/채널 방의 기본값은 `messages.groupChat.visibleReplies: "message_tool"`입니다. OpenClaw는 여전히 턴을 처리하지만, 일반 최종 답장은 비공개로 유지되며 방에 표시되는 출력에는 `message(action=send)`가 필요합니다. 일반 답장이 방에 다시 게시되는 레거시 동작을 원하는 경우에만 `"automatic"`을 설정하세요. 동일한 도구 전용 표시 답장 동작을 직접 채팅에도 적용하려면 `messages.visibleReplies: "message_tool"`을 설정하세요. Codex 하네스도 설정되지 않은 직접 채팅 기본값으로 해당 도구 전용 동작을 사용합니다.
|
||||
보이는 답장은 별도로 제어됩니다. 그룹/채널 방의 기본값은 `messages.groupChat.visibleReplies: "message_tool"`입니다. OpenClaw는 여전히 턴을 처리하지만, 일반적인 최종 답장은 비공개로 유지되며 보이는 방 출력에는 `message(action=send)`가 필요합니다. 일반 답장이 방에 다시 게시되는 레거시 동작을 원할 때만 `"automatic"`으로 설정하세요. 동일한 도구 전용 보이는 답장 동작을 직접 채팅에도 적용하려면 `messages.visibleReplies: "message_tool"`을 설정하세요. Codex 하네스도 설정되지 않은 직접 채팅 기본값으로 이 도구 전용 동작을 사용합니다.
|
||||
|
||||
활성 도구 정책에서 메시지 도구를 사용할 수 없으면 OpenClaw는 응답을 조용히 억제하는 대신 자동 표시 답장으로 폴백합니다. `openclaw doctor`는 이 불일치에 대해 경고합니다.
|
||||
도구 전용 보이는 답장에는 도구를 안정적으로 호출하는 모델/런타임이 필요합니다. 세션 로그에 `didSendViaMessagingTool: false`가 있는 어시스턴트 텍스트가 표시되면 모델이 메시지 도구를 호출하는 대신 비공개 최종 답변을 생성한 것입니다. 해당 채널에 더 강력한 도구 호출 모델로 전환하거나, 레거시 보이는 최종 답장을 복원하려면 `messages.groupChat.visibleReplies: "automatic"`을 설정하세요.
|
||||
|
||||
Gateway는 파일이 저장된 후 `messages` config를 핫 리로드합니다. 배포에서 파일 감시 또는 config 리로드가 비활성화된 경우에만 다시 시작하세요.
|
||||
활성 도구 정책에서 메시지 도구를 사용할 수 없는 경우 OpenClaw는 응답을 조용히 억제하는 대신 자동 보이는 답장으로 대체합니다. `openclaw doctor`는 이 불일치에 대해 경고합니다.
|
||||
|
||||
파일이 저장된 후 Gateway는 `messages` 구성을 핫 리로드합니다. 배포에서 파일 감시 또는 구성 리로드가 비활성화된 경우에만 다시 시작하세요.
|
||||
|
||||
**멘션 유형:**
|
||||
|
||||
- **메타데이터 멘션**: 네이티브 플랫폼 @-멘션. WhatsApp 셀프 채팅 모드에서는 무시됩니다.
|
||||
- **텍스트 패턴**: `agents.list[].groupChat.mentionPatterns`의 안전한 정규식 패턴. 잘못된 패턴과 안전하지 않은 중첩 반복은 무시됩니다.
|
||||
- **메타데이터 멘션**: 네이티브 플랫폼 @-멘션입니다. WhatsApp 셀프 채팅 모드에서는 무시됩니다.
|
||||
- **텍스트 패턴**: `agents.list[].groupChat.mentionPatterns`의 안전한 정규식 패턴입니다. 잘못된 패턴과 안전하지 않은 중첩 반복은 무시됩니다.
|
||||
- 멘션 게이팅은 감지가 가능한 경우에만 적용됩니다(네이티브 멘션 또는 하나 이상의 패턴).
|
||||
|
||||
```json5
|
||||
@ -809,9 +805,9 @@ Gateway는 파일이 저장된 후 `messages` config를 핫 리로드합니다.
|
||||
}
|
||||
```
|
||||
|
||||
`messages.groupChat.historyLimit`는 전역 기본값을 설정합니다. 채널은 `channels.<channel>.historyLimit`로 재정의할 수 있습니다(또는 계정별로). 비활성화하려면 `0`으로 설정하세요.
|
||||
`messages.groupChat.historyLimit`는 전역 기본값을 설정합니다. 채널은 `channels.<channel>.historyLimit`(또는 계정별 설정)로 재정의할 수 있습니다. 비활성화하려면 `0`으로 설정하세요.
|
||||
|
||||
`messages.visibleReplies`는 전역 소스 턴 기본값입니다. `messages.groupChat.visibleReplies`는 그룹/채널 소스 턴에 대해 이를 재정의합니다. `messages.visibleReplies`가 설정되지 않은 경우 하네스가 자체 직접/소스 기본값을 제공할 수 있습니다. Codex 하네스의 기본값은 `message_tool`입니다. 채널 허용 목록과 멘션 게이팅은 여전히 턴을 처리할지 결정합니다.
|
||||
`messages.visibleReplies`는 전역 소스 턴 기본값입니다. `messages.groupChat.visibleReplies`는 그룹/채널 소스 턴에서 이를 재정의합니다. `messages.visibleReplies`가 설정되지 않은 경우, 하네스는 자체 direct/source 기본값을 제공할 수 있습니다. Codex 하네스는 기본값으로 `message_tool`을 사용합니다. 채널 허용 목록과 멘션 게이팅은 여전히 턴을 처리할지 결정합니다.
|
||||
|
||||
#### DM 기록 제한
|
||||
|
||||
@ -828,13 +824,13 @@ Gateway는 파일이 저장된 후 `messages` config를 핫 리로드합니다.
|
||||
}
|
||||
```
|
||||
|
||||
해결 순서: DM별 재정의 → 제공자 기본값 → 제한 없음(모두 유지).
|
||||
해결 순서: DM별 재정의 → 제공자 기본값 → 제한 없음(모두 보존).
|
||||
|
||||
지원됨: `telegram`, `whatsapp`, `discord`, `slack`, `signal`, `imessage`, `msteams`.
|
||||
|
||||
#### 셀프 채팅 모드
|
||||
|
||||
셀프 채팅 모드를 활성화하려면 `allowFrom`에 자신의 번호를 포함하세요(네이티브 @-멘션은 무시하고 텍스트 패턴에만 응답).
|
||||
셀프 채팅 모드를 활성화하려면 `allowFrom`에 자신의 번호를 포함하세요(네이티브 @-멘션을 무시하고 텍스트 패턴에만 응답함).
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -884,27 +880,27 @@ Gateway는 파일이 저장된 후 `messages` config를 핫 리로드합니다.
|
||||
|
||||
<Accordion title="명령 세부 정보">
|
||||
|
||||
- 이 블록은 명령 표면을 구성합니다. 현재 기본 제공 + 번들 명령 카탈로그는 [슬래시 명령](/ko/tools/slash-commands)을 참조하세요.
|
||||
- 이 페이지는 전체 명령 카탈로그가 아니라 **설정 키 참조**입니다. QQ Bot `/bot-ping` `/bot-help` `/bot-logs`, LINE `/card`, 기기 페어링 `/pair`, 메모리 `/dreaming`, 전화 제어 `/phone`, Talk `/voice`와 같은 채널/Plugin 소유 명령은 해당 채널/Plugin 페이지와 [슬래시 명령](/ko/tools/slash-commands)에 문서화되어 있습니다.
|
||||
- 텍스트 명령은 앞에 `/`가 붙은 **독립형** 메시지여야 합니다.
|
||||
- `native: "auto"`는 Discord/Telegram의 네이티브 명령을 켜고 Slack은 꺼진 상태로 둡니다.
|
||||
- `nativeSkills: "auto"`는 Discord/Telegram의 네이티브 Skills 명령을 켜고 Slack은 꺼진 상태로 둡니다.
|
||||
- 채널별 재정의: `channels.discord.commands.native`(bool 또는 `"auto"`). Discord의 경우 `false`는 시작 중 네이티브 명령 등록 및 정리를 건너뜁니다.
|
||||
- 이 블록은 명령 표면을 구성합니다. 현재 내장 및 번들 명령 카탈로그는 [슬래시 명령](/ko/tools/slash-commands)을 참조하세요.
|
||||
- 이 페이지는 전체 명령 카탈로그가 아니라 **구성 키 참조**입니다. QQ Bot `/bot-ping` `/bot-help` `/bot-logs`, LINE `/card`, 기기 페어링 `/pair`, 메모리 `/dreaming`, 전화 제어 `/phone`, Talk `/voice`처럼 채널/Plugin이 소유한 명령은 해당 채널/Plugin 페이지와 [슬래시 명령](/ko/tools/slash-commands)에 문서화되어 있습니다.
|
||||
- 텍스트 명령은 선행 `/`가 있는 **독립형** 메시지여야 합니다.
|
||||
- `native: "auto"`는 Discord/Telegram에서 네이티브 명령을 켜고 Slack은 꺼진 상태로 둡니다.
|
||||
- `nativeSkills: "auto"`는 Discord/Telegram에서 네이티브 Skills 명령을 켜고 Slack은 꺼진 상태로 둡니다.
|
||||
- 채널별로 재정의하려면 `channels.discord.commands.native`(불리언 또는 `"auto"`)를 사용하세요. Discord의 경우 `false`는 시작 중 네이티브 명령 등록과 정리를 건너뜁니다.
|
||||
- `channels.<provider>.commands.nativeSkills`로 채널별 네이티브 Skills 등록을 재정의합니다.
|
||||
- `channels.telegram.customCommands`는 추가 Telegram 봇 메뉴 항목을 추가합니다.
|
||||
- `bash: true`는 호스트 셸에 대해 `! <cmd>`를 활성화합니다. `tools.elevated.enabled`와 발신자가 `tools.elevated.allowFrom.<channel>`에 있어야 합니다.
|
||||
- `config: true`는 `/config`를 활성화합니다(`openclaw.json` 읽기/쓰기). Gateway `chat.send` 클라이언트의 경우 지속적 `/config set|unset` 쓰기에는 `operator.admin`도 필요합니다. 읽기 전용 `/config show`는 일반 쓰기 범위 operator 클라이언트에서도 계속 사용할 수 있습니다.
|
||||
- `mcp: true`는 `mcp.servers` 아래의 OpenClaw 관리 MCP 서버 설정에 대해 `/mcp`를 활성화합니다.
|
||||
- `plugins: true`는 Plugin 검색, 설치, 활성화/비활성화 제어를 위해 `/plugins`를 활성화합니다.
|
||||
- `channels.<provider>.configWrites`는 채널별 설정 변경을 제어합니다(기본값: true).
|
||||
- `bash: true`는 호스트 셸에 대해 `! <cmd>`를 활성화합니다. `tools.elevated.enabled`가 필요하며 발신자가 `tools.elevated.allowFrom.<channel>`에 있어야 합니다.
|
||||
- `config: true`는 `/config`(`openclaw.json` 읽기/쓰기)를 활성화합니다. Gateway `chat.send` 클라이언트의 경우, 영구 `/config set|unset` 쓰기에는 `operator.admin`도 필요합니다. 읽기 전용 `/config show`는 일반 쓰기 범위 operator 클라이언트에서도 계속 사용할 수 있습니다.
|
||||
- `mcp: true`는 `mcp.servers` 아래의 OpenClaw 관리 MCP 서버 구성에 대해 `/mcp`를 활성화합니다.
|
||||
- `plugins: true`는 Plugin 검색, 설치, 활성화/비활성화 제어를 위한 `/plugins`를 활성화합니다.
|
||||
- `channels.<provider>.configWrites`는 채널별 구성 변경을 제어합니다(기본값: true).
|
||||
- 다중 계정 채널의 경우 `channels.<provider>.accounts.<id>.configWrites`도 해당 계정을 대상으로 하는 쓰기를 제어합니다(예: `/allowlist --config --account <id>` 또는 `/config set channels.<provider>.accounts.<id>...`).
|
||||
- `restart: false`는 `/restart`와 Gateway 재시작 도구 동작을 비활성화합니다. 기본값: `true`.
|
||||
- `ownerAllowFrom`은 소유자 전용 명령/도구에 대한 명시적 소유자 허용 목록입니다. `allowFrom`과는 별개입니다.
|
||||
- `ownerAllowFrom`은 소유자 전용 명령/도구를 위한 명시적 소유자 허용 목록입니다. `allowFrom`과 별개입니다.
|
||||
- `ownerDisplay: "hash"`는 시스템 프롬프트에서 소유자 ID를 해시합니다. 해싱을 제어하려면 `ownerDisplaySecret`을 설정하세요.
|
||||
- `allowFrom`은 제공자별입니다. 설정된 경우 이것이 **유일한** 권한 부여 소스입니다(채널 허용 목록/페어링 및 `useAccessGroups`는 무시됨).
|
||||
- `useAccessGroups: false`는 `allowFrom`이 설정되지 않은 경우 명령이 액세스 그룹 정책을 우회하도록 허용합니다.
|
||||
- `allowFrom`은 제공자별입니다. 설정하면 이것이 **유일한** 인증 소스가 됩니다(채널 허용 목록/페어링 및 `useAccessGroups`는 무시됨).
|
||||
- `useAccessGroups: false`는 `allowFrom`이 설정되지 않은 경우 명령이 액세스 그룹 정책을 우회할 수 있게 합니다.
|
||||
- 명령 문서 맵:
|
||||
- 기본 제공 + 번들 카탈로그: [슬래시 명령](/ko/tools/slash-commands)
|
||||
- 내장 및 번들 카탈로그: [슬래시 명령](/ko/tools/slash-commands)
|
||||
- 채널별 명령 표면: [채널](/ko/channels)
|
||||
- QQ Bot 명령: [QQ Bot](/ko/channels/qqbot)
|
||||
- 페어링 명령: [페어링](/ko/channels/pairing)
|
||||
@ -917,6 +913,6 @@ Gateway는 파일이 저장된 후 `messages` config를 핫 리로드합니다.
|
||||
|
||||
## 관련 항목
|
||||
|
||||
- [설정 참조](/ko/gateway/configuration-reference) — 최상위 키
|
||||
- [설정 — 에이전트](/ko/gateway/config-agents)
|
||||
- [구성 참조](/ko/gateway/configuration-reference) — 최상위 키
|
||||
- [구성 — 에이전트](/ko/gateway/config-agents)
|
||||
- [채널 개요](/ko/channels)
|
||||
|
||||
@ -1,24 +1,24 @@
|
||||
---
|
||||
read_when:
|
||||
- OpenClaw 구성 방법 배우기
|
||||
- 구성 예시 찾기
|
||||
- OpenClaw 처음 설정하기
|
||||
summary: 일반적인 OpenClaw 설정을 위한 스키마에 정확히 맞는 구성 예제
|
||||
- OpenClaw 구성 방법 알아보기
|
||||
- 설정 예시 찾기
|
||||
- 처음으로 OpenClaw 설정하기
|
||||
summary: 일반적인 OpenClaw 설정을 위한 스키마와 일치하는 구성 예제
|
||||
title: 구성 예시
|
||||
x-i18n:
|
||||
generated_at: "2026-04-30T06:29:46Z"
|
||||
generated_at: "2026-05-04T02:24:09Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 8bc1f8877bc635d6e3aafd911852d61e71fa08de9144751209542fd67c70f0ba
|
||||
source_hash: 60c8c2d731f8dce93c4d14657041d72043bc36e3d71ab6cb13c02993ba90dbe3
|
||||
source_path: gateway/configuration-examples.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
아래 예시는 현재 구성 스키마와 일치합니다. 전체 참고 자료와 필드별 참고 사항은 [구성](/ko/gateway/configuration)을 참조하세요.
|
||||
아래 예시는 현재 구성 스키마와 일치합니다. 전체 참조와 필드별 참고 사항은 [구성](/ko/gateway/configuration)을 참조하세요.
|
||||
|
||||
## 빠른 시작
|
||||
|
||||
### 절대 최소 구성
|
||||
### 최소 필수 구성
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -256,6 +256,7 @@ x-i18n:
|
||||
skills: ["github", "weather"], // inherited by agents that omit list[].skills
|
||||
thinkingDefault: "low",
|
||||
verboseDefault: "off",
|
||||
toolProgressDetail: "explain",
|
||||
reasoningDefault: "off",
|
||||
elevatedDefault: "on",
|
||||
blockStreamingDefault: "off",
|
||||
@ -472,7 +473,7 @@ x-i18n:
|
||||
|
||||
## 일반적인 패턴
|
||||
|
||||
### 하나의 재정의를 포함한 공유 Skills 기준선
|
||||
### 하나의 재정의가 있는 공유 Skills 기준선
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -489,11 +490,11 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
- `agents.defaults.skills`는 공유 기준선입니다.
|
||||
- `agents.list[].skills`는 한 에이전트에 대해 해당 기준선을 대체합니다.
|
||||
- 에이전트가 어떤 skills도 보지 않아야 하면 `skills: []`를 사용하세요.
|
||||
- `agents.defaults.skills`는 공유 기준값입니다.
|
||||
- `agents.list[].skills`는 한 에이전트에 대해 해당 기준값을 대체합니다.
|
||||
- 에이전트가 어떤 Skills도 보지 않아야 할 때는 `skills: []`를 사용하세요.
|
||||
|
||||
### 다중 플랫폼 설정
|
||||
### 멀티 플랫폼 설정
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -516,9 +517,9 @@ x-i18n:
|
||||
|
||||
### 신뢰할 수 있는 Node 네트워크 자동 승인
|
||||
|
||||
네트워크 경로를 제어하는 경우가 아니라면 기기 페어링은 수동으로 유지하세요. 전용
|
||||
랩 또는 tailnet 서브넷의 경우, 정확한 CIDR 또는 IP로 최초 Node 기기 자동 승인에
|
||||
동의할 수 있습니다.
|
||||
네트워크 경로를 제어하지 않는 한 기기 페어링은 수동으로 유지하세요. 전용
|
||||
랩이나 tailnet 서브넷의 경우, 정확한 CIDR 또는 IP를 사용해 최초 Node 기기
|
||||
자동 승인을 선택적으로 활성화할 수 있습니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -532,13 +533,13 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
설정하지 않으면 이 기능은 계속 꺼져 있습니다. 요청된 범위가 없는 새로운 `role: node`
|
||||
페어링에만 적용됩니다. 운영자/브라우저 클라이언트와 역할, 범위, 메타데이터 또는
|
||||
공개 키 업그레이드는 여전히 수동 승인이 필요합니다.
|
||||
설정하지 않으면 이 기능은 꺼진 상태로 유지됩니다. 요청된 범위가 없는
|
||||
새 `role: node` 페어링에만 적용됩니다. 운영자/브라우저 클라이언트와 역할,
|
||||
범위, 메타데이터 또는 공개 키 업그레이드는 여전히 수동 승인이 필요합니다.
|
||||
|
||||
### 보안 DM 모드(공유 받은편지함 / 다중 사용자 DM)
|
||||
### 보안 DM 모드(공유 받은 편지함 / 다중 사용자 DM)
|
||||
|
||||
두 명 이상이 봇에 DM을 보낼 수 있는 경우(`allowFrom`에 여러 항목, 여러 사람에 대한 페어링 승인, 또는 `dmPolicy: "open"`), **보안 DM 모드**를 활성화하여 서로 다른 발신자의 DM이 기본적으로 하나의 컨텍스트를 공유하지 않도록 하세요.
|
||||
두 명 이상이 봇에 DM을 보낼 수 있는 경우(`allowFrom`에 여러 항목이 있거나, 여러 사람에 대한 페어링 승인 또는 `dmPolicy: "open"`), **보안 DM 모드**를 활성화하여 서로 다른 발신자의 DM이 기본적으로 하나의 컨텍스트를 공유하지 않도록 하세요.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -562,10 +563,10 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
Discord/Slack/Google Chat/Microsoft Teams/Mattermost/IRC의 경우, 발신자 권한 부여는 기본적으로 ID 우선입니다.
|
||||
해당 위험을 명시적으로 수용하는 경우에만 각 채널의 `dangerouslyAllowNameMatching: true`로 직접 변경 가능한 이름/이메일/닉네임 매칭을 활성화하세요.
|
||||
Discord/Slack/Google Chat/Microsoft Teams/Mattermost/IRC의 경우, 발신자 승인은 기본적으로 ID 우선입니다.
|
||||
해당 위험을 명시적으로 수락하는 경우에만 각 채널의 `dangerouslyAllowNameMatching: true`로 직접 변경 가능한 이름/이메일/닉네임 매칭을 활성화하세요.
|
||||
|
||||
### Anthropic API 키 + MiniMax 대체 모델
|
||||
### Anthropic API 키 + MiniMax 대체 수단
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -599,7 +600,7 @@ Discord/Slack/Google Chat/Microsoft Teams/Mattermost/IRC의 경우, 발신자
|
||||
}
|
||||
```
|
||||
|
||||
### 업무용 봇(제한된 접근)
|
||||
### 업무용 봇(제한된 액세스)
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -658,12 +659,12 @@ Discord/Slack/Google Chat/Microsoft Teams/Mattermost/IRC의 경우, 발신자
|
||||
|
||||
## 팁
|
||||
|
||||
- `dmPolicy: "open"`을 설정하는 경우, 일치하는 `allowFrom` 목록에는 `"*"`가 포함되어야 합니다.
|
||||
- `dmPolicy: "open"`을 설정하면, 일치하는 `allowFrom` 목록에 `"*"`가 포함되어야 합니다.
|
||||
- 제공자 ID는 서로 다릅니다(전화번호, 사용자 ID, 채널 ID). 형식을 확인하려면 제공자 문서를 사용하세요.
|
||||
- 나중에 추가할 수 있는 선택적 섹션: `web`, `browser`, `ui`, `discovery`, `canvasHost`, `talk`, `signal`, `imessage`.
|
||||
- 더 자세한 설정 참고 사항은 [제공자](/ko/providers)와 [문제 해결](/ko/gateway/troubleshooting)을 참조하세요.
|
||||
- 나중에 추가할 수 있는 선택 섹션: `web`, `browser`, `ui`, `discovery`, `canvasHost`, `talk`, `signal`, `imessage`.
|
||||
- 더 자세한 설정 참고 사항은 [제공자](/ko/providers) 및 [문제 해결](/ko/gateway/troubleshooting)을 참조하세요.
|
||||
|
||||
## 관련 문서
|
||||
## 관련 항목
|
||||
|
||||
- [구성 참조](/ko/gateway/configuration-reference)
|
||||
- [구성](/ko/gateway/configuration)
|
||||
|
||||
@ -1,27 +1,27 @@
|
||||
---
|
||||
read_when:
|
||||
- OpenClaw 모델 사용량, 메시지 흐름 또는 세션 메트릭을 OpenTelemetry 수집기로 보내려는 경우
|
||||
- Grafana, Datadog, Honeycomb, New Relic, Tempo 또는 다른 OTLP 백엔드에 트레이스, 메트릭 또는 로그를 연결하는 경우
|
||||
- 대시보드나 알림을 구축하려면 정확한 지표 이름, 스팬 이름 또는 속성 구조가 필요합니다.
|
||||
- OpenClaw 모델 사용량, 메시지 흐름 또는 세션 메트릭을 OpenTelemetry 컬렉터로 보내려는 경우
|
||||
- 트레이스, 메트릭 또는 로그를 Grafana, Datadog, Honeycomb, New Relic, Tempo 또는 다른 OTLP 백엔드에 연동하는 경우
|
||||
- 대시보드나 알림을 구축하려면 정확한 메트릭 이름, 스팬 이름 또는 속성 형태가 필요합니다
|
||||
summary: diagnostics-otel Plugin(OTLP/HTTP)을 통해 OpenClaw 진단 정보를 모든 OpenTelemetry 수집기로 내보내기
|
||||
title: OpenTelemetry 내보내기
|
||||
x-i18n:
|
||||
generated_at: "2026-05-03T21:32:39Z"
|
||||
generated_at: "2026-05-04T02:24:06Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: c8091aa633a3e10593681f94913a858587a5dc69d9947e0c0d4132f6e897b00b
|
||||
source_hash: d0b5be99b29fe5f13132b03cfeaf3ce978ee16f29e307aa76769bc414b5ca35f
|
||||
source_path: gateway/opentelemetry.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
OpenClaw는 공식 `diagnostics-otel` Plugin을 통해 **OTLP/HTTP (protobuf)**로 진단 정보를 내보냅니다. OTLP/HTTP를 수락하는 모든 collector 또는 backend는 코드 변경 없이 작동합니다. 로컬 파일 로그와 읽는 방법은 [Logging](/ko/logging)을 참조하세요.
|
||||
OpenClaw는 공식 `diagnostics-otel` Plugin을 통해 **OTLP/HTTP (protobuf)**로 진단 정보를 내보냅니다. OTLP/HTTP를 수락하는 모든 컬렉터 또는 백엔드는 코드 변경 없이 작동합니다. 로컬 파일 로그와 읽는 방법은 [로깅](/ko/logging)을 참조하세요.
|
||||
|
||||
## 함께 작동하는 방식
|
||||
## 전체 구성 방식
|
||||
|
||||
- **진단 이벤트**는 모델 실행, 메시지 흐름, 세션, 큐, exec에 대해 Gateway와 번들 Plugin이 내보내는 구조화된 in-process 레코드입니다.
|
||||
- **`diagnostics-otel` Plugin**은 이러한 이벤트를 구독하고 OTLP/HTTP를 통해 OpenTelemetry **metrics**, **traces**, **logs**로 내보냅니다.
|
||||
- **Provider 호출**은 provider 전송 계층이 사용자 지정 헤더를 수락할 때 OpenClaw의 신뢰된 모델 호출 span context에서 W3C `traceparent` 헤더를 받습니다. Plugin에서 내보낸 trace context는 전파되지 않습니다.
|
||||
- Exporter는 진단 surface와 Plugin이 모두 활성화된 경우에만 연결되므로 in-process 비용은 기본적으로 거의 0에 가깝게 유지됩니다.
|
||||
- **진단 이벤트**는 모델 실행, 메시지 흐름, 세션, 큐, exec를 위해 Gateway와 번들 Plugin에서 내보내는 구조화된 인프로세스 레코드입니다.
|
||||
- **`diagnostics-otel` Plugin**은 이러한 이벤트를 구독하고 OTLP/HTTP를 통해 OpenTelemetry **메트릭**, **트레이스**, **로그**로 내보냅니다.
|
||||
- **Provider 호출**은 provider 전송이 사용자 지정 헤더를 허용할 때 OpenClaw의 신뢰된 모델 호출 span 컨텍스트에서 W3C `traceparent` 헤더를 받습니다. Plugin에서 내보낸 트레이스 컨텍스트는 전파되지 않습니다.
|
||||
- exporter는 진단 surface와 Plugin이 모두 활성화된 경우에만 연결되므로, 기본적으로 인프로세스 비용은 거의 0에 가깝게 유지됩니다.
|
||||
|
||||
## 빠른 시작
|
||||
|
||||
@ -56,7 +56,7 @@ openclaw plugins install clawhub:@openclaw/diagnostics-otel
|
||||
}
|
||||
```
|
||||
|
||||
CLI에서 Plugin을 활성화할 수도 있습니다.
|
||||
CLI에서도 Plugin을 활성화할 수 있습니다.
|
||||
|
||||
```bash
|
||||
openclaw plugins enable diagnostics-otel
|
||||
@ -66,15 +66,15 @@ openclaw plugins enable diagnostics-otel
|
||||
`protocol`은 현재 `http/protobuf`만 지원합니다. `grpc`는 무시됩니다.
|
||||
</Note>
|
||||
|
||||
## 내보내는 signal
|
||||
## 내보내는 신호
|
||||
|
||||
| Signal | 포함되는 내용 |
|
||||
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| **Metrics** | 토큰 사용량, 비용, 실행 기간, 메시지 흐름, 큐 lane, 세션 상태, exec, 메모리 압력에 대한 counter와 histogram. |
|
||||
| **Traces** | 모델 사용, 모델 호출, harness lifecycle, 도구 실행, exec, Webhook/메시지 처리, context assembly, 도구 loop에 대한 span. |
|
||||
| **Logs** | `diagnostics.otel.logs`가 활성화되면 OTLP를 통해 내보내는 구조화된 `logging.file` 레코드. |
|
||||
| 신호 | 포함되는 내용 |
|
||||
| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **메트릭** | 토큰 사용량, 비용, 실행 기간, 메시지 흐름, 큐 lane, 세션 상태, exec, 메모리 압박에 대한 카운터와 히스토그램. |
|
||||
| **트레이스** | 모델 사용량, 모델 호출, harness 수명 주기, 도구 실행, exec, Webhook/메시지 처리, 컨텍스트 조립, 도구 루프에 대한 span. |
|
||||
| **로그** | `diagnostics.otel.logs`가 활성화된 경우 OTLP를 통해 내보내는 구조화된 `logging.file` 레코드. |
|
||||
|
||||
`traces`, `metrics`, `logs`를 각각 독립적으로 전환할 수 있습니다. `diagnostics.otel.enabled`가 true이면 세 가지 모두 기본적으로 켜집니다.
|
||||
`traces`, `metrics`, `logs`를 독립적으로 전환할 수 있습니다. `diagnostics.otel.enabled`가 true이면 세 가지 모두 기본적으로 켜집니다.
|
||||
|
||||
## 구성 참조
|
||||
|
||||
@ -111,103 +111,103 @@ openclaw plugins enable diagnostics-otel
|
||||
|
||||
### 환경 변수
|
||||
|
||||
| 변수 | 목적 |
|
||||
| ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `OTEL_EXPORTER_OTLP_ENDPOINT` | `diagnostics.otel.endpoint`를 재정의합니다. 값에 이미 `/v1/traces`, `/v1/metrics`, `/v1/logs`가 포함되어 있으면 그대로 사용됩니다. |
|
||||
| `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` / `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` / `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` | 일치하는 `diagnostics.otel.*Endpoint` 구성 키가 설정되지 않았을 때 사용하는 signal별 endpoint 재정의입니다. Signal별 구성은 signal별 env보다 우선하고, signal별 env는 공유 endpoint보다 우선합니다. |
|
||||
| `OTEL_SERVICE_NAME` | `diagnostics.otel.serviceName`을 재정의합니다. |
|
||||
| `OTEL_EXPORTER_OTLP_PROTOCOL` | wire protocol을 재정의합니다. 현재는 `http/protobuf`만 적용됩니다. |
|
||||
| `OTEL_SEMCONV_STABILITY_OPT_IN` | legacy `gen_ai.system` 대신 최신 실험적 GenAI span attribute(`gen_ai.provider.name`)를 내보내려면 `gen_ai_latest_experimental`로 설정합니다. GenAI metrics는 관계없이 항상 bounded, low-cardinality semantic attribute를 사용합니다. |
|
||||
| `OPENCLAW_OTEL_PRELOADED` | 다른 preload 또는 host process가 이미 전역 OpenTelemetry SDK를 등록한 경우 `1`로 설정합니다. 그러면 Plugin은 자체 NodeSDK lifecycle을 건너뛰지만, diagnostic listener를 연결하고 `traces`/`metrics`/`logs`를 계속 준수합니다. |
|
||||
| 변수 | 목적 |
|
||||
| ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `OTEL_EXPORTER_OTLP_ENDPOINT` | `diagnostics.otel.endpoint`를 재정의합니다. 값에 이미 `/v1/traces`, `/v1/metrics`, `/v1/logs`가 포함되어 있으면 그대로 사용됩니다. |
|
||||
| `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` / `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` / `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` | 일치하는 `diagnostics.otel.*Endpoint` 구성 키가 설정되지 않았을 때 사용되는 신호별 엔드포인트 재정의입니다. 신호별 구성은 신호별 env보다 우선하고, 신호별 env는 공유 엔드포인트보다 우선합니다. |
|
||||
| `OTEL_SERVICE_NAME` | `diagnostics.otel.serviceName`을 재정의합니다. |
|
||||
| `OTEL_EXPORTER_OTLP_PROTOCOL` | wire protocol을 재정의합니다. 현재는 `http/protobuf`만 적용됩니다. |
|
||||
| `OTEL_SEMCONV_STABILITY_OPT_IN` | 레거시 `gen_ai.system` 대신 최신 실험적 GenAI span 속성(`gen_ai.provider.name`)을 내보내려면 `gen_ai_latest_experimental`로 설정합니다. GenAI 메트릭은 항상 범위가 제한된 낮은 카디널리티의 semantic 속성을 사용합니다. |
|
||||
| `OPENCLAW_OTEL_PRELOADED` | 다른 preload 또는 호스트 프로세스가 이미 전역 OpenTelemetry SDK를 등록한 경우 `1`로 설정합니다. 그러면 Plugin은 자체 NodeSDK 수명 주기를 건너뛰지만 진단 리스너를 계속 연결하고 `traces`/`metrics`/`logs`를 준수합니다. |
|
||||
|
||||
## 개인정보 보호 및 content capture
|
||||
## 개인정보 보호 및 콘텐츠 캡처
|
||||
|
||||
원시 모델/도구 content는 기본적으로 내보내지 **않습니다**. Span은 bounded identifier(channel, provider, model, error category, hash-only request id)를 포함하며 prompt text, response text, tool input, tool output 또는 session key를 절대 포함하지 않습니다.
|
||||
원시 모델/도구 콘텐츠는 기본적으로 내보내지 **않습니다**. span은 범위가 제한된 식별자(channel, provider, model, error category, hash-only request ids)를 포함하며, prompt text, response text, tool inputs, tool outputs 또는 session keys를 포함하지 않습니다.
|
||||
|
||||
Outbound 모델 요청에는 W3C `traceparent` 헤더가 포함될 수 있습니다. 이 헤더는 활성 모델 호출에 대한 OpenClaw 소유 진단 trace context에서만 생성됩니다. 기존 caller-supplied `traceparent` 헤더는 대체되므로 Plugin 또는 사용자 지정 provider option이 cross-service trace ancestry를 spoof할 수 없습니다.
|
||||
아웃바운드 모델 요청에는 W3C `traceparent` 헤더가 포함될 수 있습니다. 이 헤더는 활성 모델 호출에 대한 OpenClaw 소유 진단 트레이스 컨텍스트에서만 생성됩니다. 기존 호출자 제공 `traceparent` 헤더는 교체되므로 Plugin 또는 사용자 지정 provider 옵션이 cross-service trace ancestry를 스푸핑할 수 없습니다.
|
||||
|
||||
Collector와 retention policy가 prompt, response, tool 또는 system-prompt text에 대해 승인된 경우에만 `diagnostics.otel.captureContent.*`를 `true`로 설정하세요. 각 subkey는 독립적으로 opt-in됩니다.
|
||||
컬렉터와 보존 정책이 prompt, response, tool 또는 system-prompt 텍스트에 대해 승인된 경우에만 `diagnostics.otel.captureContent.*`를 `true`로 설정하세요. 각 하위 키는 독립적으로 opt-in됩니다.
|
||||
|
||||
- `inputMessages` — 사용자 prompt content.
|
||||
- `outputMessages` — 모델 response content.
|
||||
- `toolInputs` — 도구 argument payload.
|
||||
- `toolOutputs` — 도구 result payload.
|
||||
- `inputMessages` — 사용자 prompt 콘텐츠.
|
||||
- `outputMessages` — 모델 response 콘텐츠.
|
||||
- `toolInputs` — 도구 인자 payload.
|
||||
- `toolOutputs` — 도구 결과 payload.
|
||||
- `systemPrompt` — 조립된 system/developer prompt.
|
||||
|
||||
Subkey가 하나라도 활성화되면, 모델과 도구 span은 해당 클래스에 대해서만 bounded, redacted `openclaw.content.*` attribute를 받습니다.
|
||||
하위 키가 활성화되면 모델 및 도구 span은 해당 클래스에 대해서만 범위가 제한되고 redaction된 `openclaw.content.*` 속성을 받습니다.
|
||||
|
||||
## 샘플링 및 flush
|
||||
|
||||
- **Traces:** `diagnostics.otel.sampleRate`(root-span만, `0.0`은 모두 drop, `1.0`은 모두 유지).
|
||||
- **Metrics:** `diagnostics.otel.flushIntervalMs`(최소 `1000`).
|
||||
- **Logs:** OTLP logs는 `logging.level`(file log level)을 따릅니다. Console formatting이 아니라 diagnostic log-record redaction path를 사용합니다. High-volume 설치에서는 local sampling보다 OTLP collector sampling/filtering을 선호해야 합니다.
|
||||
- **File-log correlation:** JSONL file logs는 log call이 유효한 diagnostic trace context를 포함할 때 top-level `traceId`, `spanId`, `parentSpanId`, `traceFlags`를 포함하므로 log processor가 local log line을 exported span과 결합할 수 있습니다.
|
||||
- **Request correlation:** Gateway HTTP request와 WebSocket frame은 internal request trace scope를 생성합니다. 해당 scope 안의 logs와 diagnostic event는 기본적으로 request trace를 상속하며, agent run 및 model-call span은 자식으로 생성되어 provider `traceparent` 헤더가 같은 trace에 유지됩니다.
|
||||
- **트레이스:** `diagnostics.otel.sampleRate`(root-span만 해당, `0.0`은 모두 드롭, `1.0`은 모두 유지).
|
||||
- **메트릭:** `diagnostics.otel.flushIntervalMs`(최소 `1000`).
|
||||
- **로그:** OTLP 로그는 `logging.level`(파일 로그 수준)을 따릅니다. 콘솔 포맷팅이 아니라 진단 로그 레코드 redaction 경로를 사용합니다. 대용량 설치에서는 로컬 샘플링보다 OTLP collector 샘플링/필터링을 선호해야 합니다.
|
||||
- **파일 로그 상관관계:** JSONL 파일 로그는 로그 호출에 유효한 진단 트레이스 컨텍스트가 포함되어 있을 때 최상위 `traceId`, `spanId`, `parentSpanId`, `traceFlags`를 포함하므로, 로그 프로세서가 로컬 로그 라인을 내보낸 span과 결합할 수 있습니다.
|
||||
- **요청 상관관계:** Gateway HTTP 요청과 WebSocket 프레임은 내부 요청 트레이스 scope를 생성합니다. 해당 scope 안의 로그와 진단 이벤트는 기본적으로 요청 트레이스를 상속하고, 에이전트 실행 및 모델 호출 span은 자식으로 생성되므로 provider `traceparent` 헤더가 같은 트레이스에 유지됩니다.
|
||||
|
||||
## 내보내는 metrics
|
||||
## 내보내는 메트릭
|
||||
|
||||
### 모델 사용량
|
||||
|
||||
- `openclaw.tokens` (counter, attrs: `openclaw.token`, `openclaw.channel`, `openclaw.provider`, `openclaw.model`, `openclaw.agent`)
|
||||
- `openclaw.cost.usd` (counter, attrs: `openclaw.channel`, `openclaw.provider`, `openclaw.model`)
|
||||
- `openclaw.run.duration_ms` (histogram, attrs: `openclaw.channel`, `openclaw.provider`, `openclaw.model`)
|
||||
- `openclaw.context.tokens` (histogram, attrs: `openclaw.context`, `openclaw.channel`, `openclaw.provider`, `openclaw.model`)
|
||||
- `gen_ai.client.token.usage` (histogram, GenAI semantic-conventions metric, attrs: `gen_ai.token.type` = `input`/`output`, `gen_ai.provider.name`, `gen_ai.operation.name`, `gen_ai.request.model`)
|
||||
- `gen_ai.client.operation.duration` (histogram, 초, GenAI semantic-conventions metric, attrs: `gen_ai.provider.name`, `gen_ai.operation.name`, `gen_ai.request.model`, optional `error.type`)
|
||||
- `openclaw.model_call.duration_ms` (histogram, attrs: `openclaw.provider`, `openclaw.model`, `openclaw.api`, `openclaw.transport`, classified error의 경우 `openclaw.errorCategory` 및 `openclaw.failureKind` 추가)
|
||||
- `openclaw.model_call.request_bytes` (histogram, 최종 모델 request payload의 UTF-8 byte size; raw payload content 없음)
|
||||
- `openclaw.model_call.response_bytes` (histogram, streamed 모델 response event의 UTF-8 byte size; raw response content 없음)
|
||||
- `openclaw.model_call.time_to_first_byte_ms` (histogram, 첫 번째 streamed response event 전까지 경과한 시간)
|
||||
- `openclaw.tokens`(카운터, attrs: `openclaw.token`, `openclaw.channel`, `openclaw.provider`, `openclaw.model`, `openclaw.agent`)
|
||||
- `openclaw.cost.usd`(카운터, attrs: `openclaw.channel`, `openclaw.provider`, `openclaw.model`)
|
||||
- `openclaw.run.duration_ms`(히스토그램, attrs: `openclaw.channel`, `openclaw.provider`, `openclaw.model`)
|
||||
- `openclaw.context.tokens`(히스토그램, attrs: `openclaw.context`, `openclaw.channel`, `openclaw.provider`, `openclaw.model`)
|
||||
- `gen_ai.client.token.usage`(히스토그램, GenAI semantic-conventions 메트릭, attrs: `gen_ai.token.type` = `input`/`output`, `gen_ai.provider.name`, `gen_ai.operation.name`, `gen_ai.request.model`)
|
||||
- `gen_ai.client.operation.duration`(히스토그램, 초, GenAI semantic-conventions 메트릭, attrs: `gen_ai.provider.name`, `gen_ai.operation.name`, `gen_ai.request.model`, 선택적 `error.type`)
|
||||
- `openclaw.model_call.duration_ms`(히스토그램, attrs: `openclaw.provider`, `openclaw.model`, `openclaw.api`, `openclaw.transport`, 그리고 분류된 오류의 경우 `openclaw.errorCategory` 및 `openclaw.failureKind`)
|
||||
- `openclaw.model_call.request_bytes`(히스토그램, 최종 모델 요청 payload의 UTF-8 바이트 크기; 원시 payload 콘텐츠 없음)
|
||||
- `openclaw.model_call.response_bytes`(히스토그램, 스트리밍된 모델 response 이벤트의 UTF-8 바이트 크기; 원시 response 콘텐츠 없음)
|
||||
- `openclaw.model_call.time_to_first_byte_ms`(히스토그램, 첫 번째 스트리밍 response 이벤트 전까지 경과 시간)
|
||||
|
||||
### 메시지 흐름
|
||||
|
||||
- `openclaw.webhook.received` (counter, attrs: `openclaw.channel`, `openclaw.webhook`)
|
||||
- `openclaw.webhook.error` (counter, attrs: `openclaw.channel`, `openclaw.webhook`)
|
||||
- `openclaw.webhook.duration_ms` (histogram, attrs: `openclaw.channel`, `openclaw.webhook`)
|
||||
- `openclaw.message.queued` (counter, attrs: `openclaw.channel`, `openclaw.source`)
|
||||
- `openclaw.message.processed` (counter, attrs: `openclaw.channel`, `openclaw.outcome`)
|
||||
- `openclaw.message.duration_ms` (histogram, attrs: `openclaw.channel`, `openclaw.outcome`)
|
||||
- `openclaw.message.delivery.started` (counter, attrs: `openclaw.channel`, `openclaw.delivery.kind`)
|
||||
- `openclaw.message.delivery.duration_ms` (histogram, attrs: `openclaw.channel`, `openclaw.delivery.kind`, `openclaw.outcome`, `openclaw.errorCategory`)
|
||||
- `openclaw.webhook.received`(카운터, attrs: `openclaw.channel`, `openclaw.webhook`)
|
||||
- `openclaw.webhook.error`(카운터, attrs: `openclaw.channel`, `openclaw.webhook`)
|
||||
- `openclaw.webhook.duration_ms`(히스토그램, attrs: `openclaw.channel`, `openclaw.webhook`)
|
||||
- `openclaw.message.queued`(카운터, attrs: `openclaw.channel`, `openclaw.source`)
|
||||
- `openclaw.message.processed`(카운터, attrs: `openclaw.channel`, `openclaw.outcome`)
|
||||
- `openclaw.message.duration_ms`(히스토그램, attrs: `openclaw.channel`, `openclaw.outcome`)
|
||||
- `openclaw.message.delivery.started`(카운터, attrs: `openclaw.channel`, `openclaw.delivery.kind`)
|
||||
- `openclaw.message.delivery.duration_ms`(히스토그램, attrs: `openclaw.channel`, `openclaw.delivery.kind`, `openclaw.outcome`, `openclaw.errorCategory`)
|
||||
|
||||
### 큐 및 세션
|
||||
|
||||
- `openclaw.queue.lane.enqueue` (counter, attrs: `openclaw.lane`)
|
||||
- `openclaw.queue.lane.dequeue` (counter, attrs: `openclaw.lane`)
|
||||
- `openclaw.queue.depth` (histogram, attrs: `openclaw.lane` 또는 `openclaw.channel=heartbeat`)
|
||||
- `openclaw.queue.wait_ms` (histogram, attrs: `openclaw.lane`)
|
||||
- `openclaw.session.state` (counter, attrs: `openclaw.state`, `openclaw.reason`)
|
||||
- `openclaw.session.stuck` (counter, attrs: `openclaw.state`; active work가 없는 stale session bookkeeping에 대해서만 내보냄)
|
||||
- `openclaw.session.stuck_age_ms` (histogram, attrs: `openclaw.state`; active work가 없는 stale session bookkeeping에 대해서만 내보냄)
|
||||
- `openclaw.run.attempt` (counter, attrs: `openclaw.attempt`)
|
||||
- `openclaw.queue.lane.enqueue`(카운터, attrs: `openclaw.lane`)
|
||||
- `openclaw.queue.lane.dequeue`(카운터, attrs: `openclaw.lane`)
|
||||
- `openclaw.queue.depth`(히스토그램, attrs: `openclaw.lane` 또는 `openclaw.channel=heartbeat`)
|
||||
- `openclaw.queue.wait_ms`(히스토그램, attrs: `openclaw.lane`)
|
||||
- `openclaw.session.state`(카운터, attrs: `openclaw.state`, `openclaw.reason`)
|
||||
- `openclaw.session.stuck`(카운터, attrs: `openclaw.state`; 활성 작업이 없는 오래된 세션 bookkeeping에만 내보냄)
|
||||
- `openclaw.session.stuck_age_ms`(히스토그램, attrs: `openclaw.state`; 활성 작업이 없는 오래된 세션 bookkeeping에만 내보냄)
|
||||
- `openclaw.run.attempt`(카운터, attrs: `openclaw.attempt`)
|
||||
|
||||
### 세션 liveness telemetry
|
||||
### 세션 liveness 텔레메트리
|
||||
|
||||
`diagnostics.stuckSessionWarnMs`는 session liveness diagnostics를 위한 no-progress age threshold입니다. `processing` 세션은 OpenClaw가 reply, tool, status, block 또는 ACP runtime progress를 관찰하는 동안에는 이 threshold 방향으로 age가 증가하지 않습니다. Typing keepalive는 progress로 계산되지 않으므로 silent model 또는 harness도 계속 감지될 수 있습니다.
|
||||
`diagnostics.stuckSessionWarnMs`는 세션 liveness 진단의 진행 없음 age 임계값입니다. `processing` 세션은 OpenClaw가 reply, tool, status, block 또는 ACP runtime progress를 관찰하는 동안에는 이 임계값에 가까워지지 않습니다. Typing keepalive는 progress로 계산되지 않으므로, silent 모델 또는 harness도 계속 감지될 수 있습니다.
|
||||
|
||||
OpenClaw는 계속 관찰할 수 있는 work에 따라 session을 분류합니다:
|
||||
OpenClaw는 계속 관찰할 수 있는 작업에 따라 세션을 분류합니다:
|
||||
|
||||
- `session.long_running`: 활성 임베디드 작업, 모델 호출 또는 도구 호출이
|
||||
아직 진행 중입니다.
|
||||
- `session.stalled`: 활성 작업은 있지만, 활성 실행이 최근 진행 상황을
|
||||
보고하지 않았습니다. 중단된 임베디드 실행은 처음에는 관찰 전용으로 유지되고,
|
||||
그다음 진행 상황이 없는 상태가 최소 10분 및 `diagnostics.stuckSessionWarnMs`의 5배 동안 지속되면
|
||||
abort-drain되어 해당 레인 뒤에 대기 중인 턴이 재개될 수 있습니다.
|
||||
- `session.stuck`: 활성 작업이 없는 오래된 세션 장부 상태입니다. 영향을 받은
|
||||
세션 레인을 즉시 해제합니다.
|
||||
- `session.stalled`: 활성 작업이 있지만, 활성 실행이 최근 진행 상황을
|
||||
보고하지 않았습니다. 중단된 임베디드 실행은 처음에는 관찰 전용 상태로
|
||||
유지되며, 이후 최소 10분 및 진행 없음 상태의 `diagnostics.stuckSessionWarnMs`
|
||||
5배가 지난 뒤 중단-드레인되어 해당 레인 뒤에 대기 중인 턴이 재개될 수 있습니다.
|
||||
- `session.stuck`: 활성 작업이 없는 오래된 세션 장부 상태입니다. 이는
|
||||
영향을 받은 세션 레인을 즉시 해제합니다.
|
||||
|
||||
`session.stuck`만 `openclaw.session.stuck` 카운터,
|
||||
`openclaw.session.stuck_age_ms` 히스토그램 및 `openclaw.session.stuck`
|
||||
스팬을 내보냅니다. 반복되는 `session.stuck` 진단은 세션이 변경되지 않는 동안
|
||||
백오프하므로, 대시보드는 모든 Heartbeat 틱이 아니라 지속적인 증가에 대해
|
||||
알림을 설정해야 합니다. 구성 노브와 기본값은
|
||||
`openclaw.session.stuck_age_ms` 히스토그램, `openclaw.session.stuck`
|
||||
스팬을 내보냅니다. 반복되는 `session.stuck` 진단은 세션이 변경되지 않은
|
||||
동안 백오프하므로, 대시보드는 모든 Heartbeat 틱이 아니라 지속적인 증가에
|
||||
대해 경고해야 합니다. 구성 노브와 기본값은
|
||||
[구성 참조](/ko/gateway/configuration-reference#diagnostics)를 참조하세요.
|
||||
|
||||
### 하네스 수명 주기
|
||||
|
||||
- `openclaw.harness.duration_ms` (히스토그램, 속성: `openclaw.harness.id`, `openclaw.harness.plugin`, `openclaw.outcome`, 오류 시 `openclaw.harness.phase`)
|
||||
|
||||
### Exec
|
||||
### 실행
|
||||
|
||||
- `openclaw.exec.duration_ms` (히스토그램, 속성: `openclaw.exec.target`, `openclaw.exec.mode`, `openclaw.outcome`, `openclaw.failureKind`)
|
||||
|
||||
@ -219,21 +219,21 @@ OpenClaw는 계속 관찰할 수 있는 work에 따라 session을 분류합니
|
||||
- `openclaw.tool.loop.iterations` (카운터, 속성: `openclaw.toolName`, `openclaw.outcome`)
|
||||
- `openclaw.tool.loop.duration_ms` (히스토그램, 속성: `openclaw.toolName`, `openclaw.outcome`)
|
||||
|
||||
## 내보낸 스팬
|
||||
## 내보내는 스팬
|
||||
|
||||
- `openclaw.model.usage`
|
||||
- `openclaw.channel`, `openclaw.provider`, `openclaw.model`
|
||||
- `openclaw.tokens.*` (input/output/cache_read/cache_write/total)
|
||||
- 기본적으로 `gen_ai.system`, 또는 최신 GenAI 시맨틱 규칙을 선택한 경우 `gen_ai.provider.name`
|
||||
- 기본적으로 `gen_ai.system`, 또는 최신 GenAI 의미 규칙을 선택한 경우 `gen_ai.provider.name`
|
||||
- `gen_ai.request.model`, `gen_ai.operation.name`, `gen_ai.usage.*`
|
||||
- `openclaw.run`
|
||||
- `openclaw.outcome`, `openclaw.channel`, `openclaw.provider`, `openclaw.model`, `openclaw.errorCategory`
|
||||
- `openclaw.model.call`
|
||||
- 기본적으로 `gen_ai.system`, 또는 최신 GenAI 시맨틱 규칙을 선택한 경우 `gen_ai.provider.name`
|
||||
- 기본적으로 `gen_ai.system`, 또는 최신 GenAI 의미 규칙을 선택한 경우 `gen_ai.provider.name`
|
||||
- `gen_ai.request.model`, `gen_ai.operation.name`, `openclaw.provider`, `openclaw.model`, `openclaw.api`, `openclaw.transport`
|
||||
- 오류 시 `openclaw.errorCategory` 및 선택적 `openclaw.failureKind`
|
||||
- `openclaw.model_call.request_bytes`, `openclaw.model_call.response_bytes`, `openclaw.model_call.time_to_first_byte_ms`
|
||||
- `openclaw.provider.request_id_hash` (업스트림 제공자 요청 ID의 제한된 SHA 기반 해시; 원시 ID는 내보내지 않음)
|
||||
- `openclaw.provider.request_id_hash` (업스트림 제공자 요청 id의 제한된 SHA 기반 해시; 원시 id는 내보내지 않음)
|
||||
- `openclaw.harness.run`
|
||||
- `openclaw.harness.id`, `openclaw.harness.plugin`, `openclaw.outcome`, `openclaw.provider`, `openclaw.model`, `openclaw.channel`
|
||||
- 완료 시: `openclaw.harness.result_classification`, `openclaw.harness.yield_detected`, `openclaw.harness.items.started`, `openclaw.harness.items.completed`, `openclaw.harness.items.active`
|
||||
@ -243,37 +243,36 @@ OpenClaw는 계속 관찰할 수 있는 work에 따라 session을 분류합니
|
||||
- `openclaw.exec`
|
||||
- `openclaw.exec.target`, `openclaw.exec.mode`, `openclaw.outcome`, `openclaw.failureKind`, `openclaw.exec.command_length`, `openclaw.exec.exit_code`, `openclaw.exec.timed_out`
|
||||
- `openclaw.webhook.processed`
|
||||
- `openclaw.channel`, `openclaw.webhook`, `openclaw.chatId`
|
||||
- `openclaw.channel`, `openclaw.webhook`
|
||||
- `openclaw.webhook.error`
|
||||
- `openclaw.channel`, `openclaw.webhook`, `openclaw.chatId`, `openclaw.error`
|
||||
- `openclaw.channel`, `openclaw.webhook`, `openclaw.error`
|
||||
- `openclaw.message.processed`
|
||||
- `openclaw.channel`, `openclaw.outcome`, `openclaw.chatId`, `openclaw.messageId`, `openclaw.reason`
|
||||
- `openclaw.channel`, `openclaw.outcome`, `openclaw.reason`
|
||||
- `openclaw.message.delivery`
|
||||
- `openclaw.channel`, `openclaw.delivery.kind`, `openclaw.outcome`, `openclaw.errorCategory`, `openclaw.delivery.result_count`
|
||||
- `openclaw.session.stuck`
|
||||
- `openclaw.state`, `openclaw.ageMs`, `openclaw.queueDepth`
|
||||
- `openclaw.context.assembled`
|
||||
- `openclaw.prompt.size`, `openclaw.history.size`, `openclaw.context.tokens`, `openclaw.errorCategory` (프롬프트, 기록, 응답 또는 세션 키 콘텐츠 없음)
|
||||
- `openclaw.prompt.size`, `openclaw.history.size`, `openclaw.context.tokens`, `openclaw.errorCategory` (프롬프트, 기록, 응답 또는 세션 키 내용 없음)
|
||||
- `openclaw.tool.loop`
|
||||
- `openclaw.toolName`, `openclaw.outcome`, `openclaw.iterations`, `openclaw.errorCategory` (루프 메시지, 매개변수 또는 도구 출력 없음)
|
||||
- `openclaw.memory.pressure`
|
||||
- `openclaw.memory.level`, `openclaw.memory.heap_used_bytes`, `openclaw.memory.rss_bytes`
|
||||
|
||||
콘텐츠 캡처가 명시적으로 활성화된 경우, 모델 및 도구 스팬에는 선택한 특정
|
||||
콘텐츠 클래스에 대한 제한되고 수정된 `openclaw.content.*` 속성도
|
||||
포함될 수 있습니다.
|
||||
콘텐츠 캡처를 명시적으로 활성화하면, 모델 및 도구 스팬은 선택한 특정
|
||||
콘텐츠 클래스에 대해 제한되고 수정된 `openclaw.content.*` 속성도 포함할 수 있습니다.
|
||||
|
||||
## 진단 이벤트 카탈로그
|
||||
|
||||
아래 이벤트는 위의 메트릭과 스팬을 뒷받침합니다. Plugin은 OTLP 내보내기 없이도
|
||||
아래 이벤트는 위의 메트릭과 스팬을 뒷받침합니다. Plugin도 OTLP 내보내기 없이
|
||||
이 이벤트를 직접 구독할 수 있습니다.
|
||||
|
||||
**모델 사용량**
|
||||
|
||||
- `model.usage` — 토큰, 비용, 기간, 컨텍스트, 제공자/모델/채널,
|
||||
세션 ID. `usage`는 비용 및 텔레메트리를 위한 제공자/턴 회계입니다.
|
||||
`context.used`는 현재 프롬프트/컨텍스트 스냅샷이며, 캐시된 입력 또는 도구 루프 호출이
|
||||
포함된 경우 제공자 `usage.total`보다 낮을 수 있습니다.
|
||||
세션 id. `usage`는 비용 및 텔레메트리를 위한 제공자/턴 회계이며,
|
||||
`context.used`는 현재 프롬프트/컨텍스트 스냅샷입니다. 캐시된 입력이나
|
||||
도구 루프 호출이 포함된 경우 제공자 `usage.total`보다 낮을 수 있습니다.
|
||||
|
||||
**메시지 흐름**
|
||||
|
||||
@ -292,19 +291,18 @@ OpenClaw는 계속 관찰할 수 있는 work에 따라 session을 분류합니
|
||||
|
||||
- `harness.run.started` / `harness.run.completed` / `harness.run.error` —
|
||||
에이전트 하네스의 실행별 수명 주기입니다. `harnessId`, 선택적
|
||||
`pluginId`, 제공자/모델/채널 및 실행 ID를 포함합니다. 완료 시
|
||||
`pluginId`, 제공자/모델/채널, 실행 id를 포함합니다. 완료 시
|
||||
`durationMs`, `outcome`, 선택적 `resultClassification`, `yieldDetected`,
|
||||
및 `itemLifecycle` 개수가 추가됩니다. 오류 시 `phase`
|
||||
그리고 `itemLifecycle` 카운트가 추가됩니다. 오류 시 `phase`
|
||||
(`prepare`/`start`/`send`/`resolve`/`cleanup`), `errorCategory`, 그리고
|
||||
선택적 `cleanupFailed`가 추가됩니다.
|
||||
|
||||
**Exec**
|
||||
**실행**
|
||||
|
||||
- `exec.process.completed` — 터미널 결과, 기간, 대상, 모드, 종료
|
||||
코드 및 실패 종류입니다. 명령 텍스트와 작업 디렉터리는
|
||||
포함되지 않습니다.
|
||||
코드, 실패 종류입니다. 명령 텍스트와 작업 디렉터리는 포함되지 않습니다.
|
||||
|
||||
## 내보내기 도구 없이 사용
|
||||
## 내보내기 도구 없이
|
||||
|
||||
`diagnostics-otel`을 실행하지 않고도 진단 이벤트를 Plugin 또는 사용자 지정 싱크에서
|
||||
사용할 수 있게 유지할 수 있습니다.
|
||||
@ -315,8 +313,8 @@ OpenClaw는 계속 관찰할 수 있는 work에 따라 session을 분류합니
|
||||
}
|
||||
```
|
||||
|
||||
`logging.level`을 높이지 않고 대상 지정 디버그 출력을 사용하려면 진단
|
||||
플래그를 사용하세요. 플래그는 대소문자를 구분하지 않으며 와일드카드를 지원합니다(예: `telegram.*` 또는
|
||||
`logging.level`을 올리지 않고 대상 디버그 출력을 사용하려면 진단 플래그를
|
||||
사용하세요. 플래그는 대소문자를 구분하지 않으며 와일드카드를 지원합니다(예: `telegram.*` 또는
|
||||
`*`).
|
||||
|
||||
```json5
|
||||
@ -325,7 +323,7 @@ OpenClaw는 계속 관찰할 수 있는 work에 따라 session을 분류합니
|
||||
}
|
||||
```
|
||||
|
||||
또는 일회성 env 재정의로 사용할 수 있습니다.
|
||||
또는 일회성 env 재정의로:
|
||||
|
||||
```bash
|
||||
OPENCLAW_DIAGNOSTICS=telegram.http,telegram.payload openclaw gateway
|
||||
@ -348,8 +346,8 @@ OPENCLAW_DIAGNOSTICS=telegram.http,telegram.payload openclaw gateway
|
||||
|
||||
## 관련 항목
|
||||
|
||||
- [로깅](/ko/logging) — 파일 로그, 콘솔 출력, CLI tailing 및 Control UI 로그 탭
|
||||
- [Gateway 로깅 내부 구조](/ko/gateway/logging) — WS 로그 스타일, 하위 시스템 접두사 및 콘솔 캡처
|
||||
- [진단 플래그](/ko/diagnostics/flags) — 대상 지정 디버그 로그 플래그
|
||||
- [로깅](/ko/logging) — 파일 로그, 콘솔 출력, CLI tailing, Control UI 로그 탭
|
||||
- [Gateway 로깅 내부 구조](/ko/gateway/logging) — WS 로그 스타일, 하위 시스템 접두사, 콘솔 캡처
|
||||
- [진단 플래그](/ko/diagnostics/flags) — 대상 디버그 로그 플래그
|
||||
- [진단 내보내기](/ko/gateway/diagnostics) — 운영자 지원 번들 도구(OTEL 내보내기와 별도)
|
||||
- [구성 참조](/ko/gateway/configuration-reference#diagnostics) — 전체 `diagnostics.*` 필드 참조
|
||||
|
||||
@ -1,33 +1,33 @@
|
||||
---
|
||||
read_when:
|
||||
- 누락된 운영자 스코프 오류 디버깅
|
||||
- 장치 또는 Node 페어링 승인 검토
|
||||
- 누락된 운영자 범위 오류 디버깅
|
||||
- 기기 또는 Node 페어링 승인 검토
|
||||
- Gateway RPC 메서드 추가 또는 분류
|
||||
summary: Gateway 클라이언트를 위한 운영자 역할, 범위 및 승인 시점 검사
|
||||
summary: Gateway 클라이언트의 운영자 역할, 범위 및 승인 시점 검사
|
||||
title: 운영자 범위
|
||||
x-i18n:
|
||||
generated_at: "2026-05-03T06:17:07Z"
|
||||
generated_at: "2026-05-04T02:24:11Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 48f59f96b41333af9124ad4083ac5442eedb2d6cebdfff74e3ba256f06d36add
|
||||
source_hash: f05d6bdbf9bdad2aef1c9664bb7ebb4b6241334b8aefac7993104e9977e40450
|
||||
source_path: gateway/operator-scopes.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
Operator 범위는 Gateway 클라이언트가 인증 후 수행할 수 있는 작업을 정의합니다.
|
||||
이는 신뢰할 수 있는 단일 Gateway 운영자 도메인 내부의 제어 플레인 보호 장치이며,
|
||||
적대적인 멀티 테넌트 격리가 아닙니다. 사람, 팀 또는 머신 간의 강력한 분리가
|
||||
필요하다면 별도의 OS 사용자 또는 호스트에서 별도의 Gateway를 실행하세요.
|
||||
Operator 범위는 Gateway 클라이언트가 인증된 뒤 수행할 수 있는 작업을 정의합니다.
|
||||
이는 신뢰할 수 있는 하나의 Gateway 운영자 도메인 내부의 제어 플레인 가드레일이며,
|
||||
적대적 멀티테넌트 격리가 아닙니다. 사람, 팀, 머신 간에 강력한 분리가 필요하다면
|
||||
별도의 OS 사용자 또는 호스트에서 별도의 Gateway를 실행하세요.
|
||||
|
||||
관련: [보안](/ko/gateway/security), [Gateway 프로토콜](/ko/gateway/protocol),
|
||||
[Gateway 페어링](/ko/gateway/pairing), [디바이스 CLI](/ko/cli/devices).
|
||||
관련 항목: [보안](/ko/gateway/security), [Gateway 프로토콜](/ko/gateway/protocol),
|
||||
[Gateway 페어링](/ko/gateway/pairing), [기기 CLI](/ko/cli/devices).
|
||||
|
||||
## 역할
|
||||
|
||||
Gateway WebSocket 클라이언트는 하나의 역할로 연결합니다.
|
||||
|
||||
- `operator`: CLI, Control UI, 자동화, 신뢰할 수 있는 헬퍼 프로세스와 같은 제어 플레인 클라이언트.
|
||||
- `node`: `node.invoke`를 통해 명령을 노출하는 macOS, iOS, Android 또는 헤드리스 노드와 같은 기능 호스트.
|
||||
- `operator`: CLI, Control UI, 자동화, 신뢰할 수 있는 헬퍼 프로세스 같은 제어 플레인 클라이언트입니다.
|
||||
- `node`: macOS, iOS, Android 또는 `node.invoke`를 통해 명령을 노출하는 헤드리스 노드 같은 기능 호스트입니다.
|
||||
|
||||
Operator RPC 메서드에는 `operator` 역할이 필요합니다. Node에서 시작된 메서드에는
|
||||
`node` 역할이 필요합니다.
|
||||
@ -36,71 +36,76 @@ Operator RPC 메서드에는 `operator` 역할이 필요합니다. Node에서
|
||||
|
||||
| 범위 | 의미 |
|
||||
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `operator.read` | 읽기 전용 상태, 목록, 카탈로그, 로그, 세션 읽기 및 기타 변경하지 않는 제어 플레인 호출. |
|
||||
| `operator.write` | 메시지 전송, 도구 호출, 대화/음성 설정 업데이트, 노드 명령 릴레이와 같은 일반적인 변경 operator 작업. `operator.read`도 충족합니다. |
|
||||
| `operator.admin` | 관리용 제어 플레인 접근. 모든 `operator.*` 범위를 충족합니다. 구성 변경, 업데이트, 네이티브 훅, 민감한 예약 네임스페이스, 고위험 승인에 필요합니다. |
|
||||
| `operator.pairing` | 페어링 레코드 또는 디바이스 토큰의 나열, 승인, 거부, 제거, 회전, 폐기를 포함한 디바이스 및 노드 페어링 관리. |
|
||||
| `operator.approvals` | 실행 및 Plugin 승인 API. |
|
||||
| `operator.talk.secrets` | 비밀이 포함된 Talk 구성 읽기. |
|
||||
| `operator.read` | 읽기 전용 상태, 목록, 카탈로그, 로그, 세션 읽기, 그 밖의 변경을 일으키지 않는 제어 플레인 호출입니다. |
|
||||
| `operator.write` | 메시지 전송, 도구 호출, 말하기/음성 설정 업데이트, 노드 명령 릴레이 같은 일반적인 변경성 운영자 작업입니다. `operator.read`도 충족합니다. |
|
||||
| `operator.admin` | 관리용 제어 플레인 접근입니다. 모든 `operator.*` 범위를 충족합니다. 구성 변경, 업데이트, 네이티브 훅, 민감한 예약 네임스페이스, 고위험 승인에 필요합니다. |
|
||||
| `operator.pairing` | 페어링 기록 또는 기기 토큰의 나열, 승인, 거부, 제거, 회전, 폐기를 포함한 기기 및 노드 페어링 관리입니다. |
|
||||
| `operator.approvals` | 실행 및 Plugin 승인 API입니다. |
|
||||
| `operator.talk.secrets` | 비밀을 포함해 Talk 구성을 읽습니다. |
|
||||
|
||||
알 수 없는 향후 `operator.*` 범위는 호출자가 `operator.admin`을 가지고 있지 않은 한
|
||||
알 수 없는 미래의 `operator.*` 범위는 호출자에게 `operator.admin`이 없는 한
|
||||
정확히 일치해야 합니다.
|
||||
|
||||
## 메서드 범위는 첫 번째 관문일 뿐입니다
|
||||
## 메서드 범위는 첫 번째 게이트일 뿐입니다
|
||||
|
||||
각 Gateway RPC에는 최소 권한 메서드 범위가 있습니다. 해당 메서드 범위는
|
||||
요청이 핸들러에 도달할 수 있는지를 결정합니다. 그런 다음 일부 핸들러는 승인되거나
|
||||
요청이 핸들러에 도달할 수 있는지를 결정합니다. 일부 핸들러는 그다음 승인되거나
|
||||
변경되는 구체적인 대상에 따라 더 엄격한 승인 시점 검사를 적용합니다.
|
||||
|
||||
예:
|
||||
|
||||
- `device.pair.approve`는 `operator.pairing`으로 도달할 수 있지만, operator 디바이스를 승인할 때는 호출자가 이미 보유한 범위만 발급하거나 유지할 수 있습니다.
|
||||
- `node.pair.approve`는 `operator.pairing`으로 도달할 수 있으며, 이후 보류 중인 노드 명령 목록에서 추가 승인 범위를 파생합니다.
|
||||
- `chat.send`는 일반적으로 쓰기 범위 메서드이지만, 영구 `/config set` 및 `/config unset`은 명령 수준에서 `operator.admin`이 필요합니다.
|
||||
- `device.pair.approve`는 `operator.pairing`으로 도달할 수 있지만, 운영자 기기 승인은
|
||||
호출자가 이미 보유한 범위만 발급하거나 보존할 수 있습니다.
|
||||
- `node.pair.approve`는 `operator.pairing`으로 도달할 수 있으며, 그런 다음 대기 중인 노드 명령 목록에서
|
||||
추가 승인 범위를 파생합니다.
|
||||
- `chat.send`는 일반적으로 쓰기 범위 메서드이지만, 영구 `/config set` 및
|
||||
`/config unset`은 명령 수준에서 `operator.admin`이 필요합니다.
|
||||
|
||||
이를 통해 낮은 범위의 operator가 모든 페어링 승인을 관리자 전용으로 만들지 않고도
|
||||
낮은 위험의 페어링 작업을 수행할 수 있습니다.
|
||||
이를 통해 낮은 범위의 운영자가 모든 페어링 승인을 관리자 전용으로 만들지 않고도
|
||||
저위험 페어링 작업을 수행할 수 있습니다.
|
||||
|
||||
## 디바이스 페어링 승인
|
||||
## 기기 페어링 승인
|
||||
|
||||
디바이스 페어링 레코드는 승인된 역할과 범위의 지속적인 원본입니다.
|
||||
이미 페어링된 디바이스는 더 넓은 접근 권한을 조용히 얻지 않습니다. 더 넓은 역할 또는
|
||||
더 넓은 범위를 요청하는 재연결은 새로운 보류 중 업그레이드 요청을 생성합니다.
|
||||
기기 페어링 기록은 승인된 역할과 범위의 지속적 소스입니다.
|
||||
이미 페어링된 기기는 조용히 더 넓은 접근 권한을 얻지 않습니다. 더 넓은 역할이나
|
||||
더 넓은 범위를 요청하는 재연결은 새로운 대기 중인 업그레이드 요청을 생성합니다.
|
||||
|
||||
디바이스 요청을 승인할 때:
|
||||
기기 요청을 승인할 때:
|
||||
|
||||
- operator 역할이 없는 요청은 operator 토큰 범위 승인이 필요하지 않습니다.
|
||||
- `operator.read`, `operator.write`, `operator.approvals`, `operator.pairing` 또는 `operator.talk.secrets` 요청은 호출자가 해당 범위 또는 `operator.admin`을 보유해야 합니다.
|
||||
- 운영자 역할이 없는 요청은 운영자 토큰 범위 승인이 필요하지 않습니다.
|
||||
- `operator.read`, `operator.write`, `operator.approvals`,
|
||||
`operator.pairing` 또는 `operator.talk.secrets` 요청은 호출자가
|
||||
해당 범위 또는 `operator.admin`을 보유해야 합니다.
|
||||
- `operator.admin` 요청에는 `operator.admin`이 필요합니다.
|
||||
- 명시적 범위가 없는 복구 요청은 기존 operator 토큰 범위를 상속할 수 있습니다. 해당 기존 토큰이 관리자 범위인 경우에도 승인은 여전히 `operator.admin`이 필요합니다.
|
||||
- 명시적 범위가 없는 복구 요청은 기존 운영자 토큰 범위를 상속할 수 있습니다.
|
||||
해당 기존 토큰이 관리자 범위라면 승인에는 여전히 `operator.admin`이 필요합니다.
|
||||
|
||||
페어링된 디바이스 토큰 세션의 경우, 호출자가 `operator.admin`도 가지고 있지 않다면
|
||||
관리는 자기 범위로 제한됩니다. 관리자가 아닌 호출자는 자신의 디바이스 항목만 회전,
|
||||
폐기 또는 제거할 수 있습니다.
|
||||
페어링된 기기 토큰 세션의 경우, 호출자에게 `operator.admin`도 있지 않는 한
|
||||
관리는 자기 범위로 제한됩니다. 관리자가 아닌 호출자는 자신의 페어링 항목만 볼 수 있고,
|
||||
자신의 대기 중인 요청만 승인 또는 거부할 수 있으며, 자신의 기기 항목만 회전, 폐기 또는
|
||||
제거할 수 있습니다.
|
||||
|
||||
## 노드 페어링 승인
|
||||
## Node 페어링 승인
|
||||
|
||||
레거시 `node.pair.*`는 별도의 Gateway 소유 노드 페어링 저장소를 사용합니다. WS 노드는
|
||||
`role: node`와 함께 디바이스 페어링을 사용하지만, 동일한 승인 수준 용어가
|
||||
적용됩니다.
|
||||
`role: node`로 기기 페어링을 사용하지만, 동일한 승인 수준 어휘가 적용됩니다.
|
||||
|
||||
`node.pair.approve`는 보류 중인 요청 명령 목록을 사용해 필요한 추가 범위를 파생합니다.
|
||||
`node.pair.approve`는 대기 중인 요청 명령 목록을 사용해 추가로 필요한
|
||||
범위를 파생합니다.
|
||||
|
||||
- 명령이 없는 요청: `operator.pairing`
|
||||
- 실행이 아닌 노드 명령: `operator.pairing` + `operator.write`
|
||||
- `system.run`, `system.run.prepare` 또는 `system.which`:
|
||||
`operator.pairing` + `operator.admin`
|
||||
|
||||
노드 페어링은 ID와 신뢰를 설정합니다. 이는 노드 자체의 `system.run` 실행 승인 정책을
|
||||
대체하지 않습니다.
|
||||
Node 페어링은 신원과 신뢰를 수립합니다. 이는 노드 자체의
|
||||
`system.run` 실행 승인 정책을 대체하지 않습니다.
|
||||
|
||||
## 공유 비밀 인증
|
||||
|
||||
공유 Gateway 토큰/비밀번호 인증은 해당 Gateway에 대한 신뢰할 수 있는 operator 접근으로
|
||||
간주됩니다. OpenAI 호환 HTTP 표면과 `/tools/invoke`는 호출자가 더 좁은 선언 범위를
|
||||
보내더라도 공유 비밀 전달자 인증에 대해 일반적인 전체 operator 기본 범위 집합을
|
||||
복원합니다.
|
||||
공유 Gateway 토큰/비밀번호 인증은 해당 Gateway에 대해 신뢰할 수 있는 운영자 접근으로
|
||||
취급됩니다. OpenAI 호환 HTTP 표면과 `/tools/invoke`는 호출자가 더 좁은 선언 범위를
|
||||
전송하더라도 공유 비밀 bearer 인증에 대해 일반적인 전체 운영자 기본 범위 세트를 복원합니다.
|
||||
|
||||
신뢰할 수 있는 프록시 인증 또는 비공개 인그레스 `none`과 같은 ID 포함 모드는
|
||||
명시적으로 선언된 범위를 여전히 따를 수 있습니다. 실제 신뢰 경계 분리에는 별도의
|
||||
Gateway를 사용하세요.
|
||||
신뢰할 수 있는 프록시 인증 또는 프라이빗 인그레스 `none` 같은 신원 포함 모드는
|
||||
명시적으로 선언된 범위를 계속 존중할 수 있습니다. 실제 신뢰 경계 분리에는 별도의 Gateway를 사용하세요.
|
||||
|
||||
@ -1,29 +1,36 @@
|
||||
---
|
||||
read_when:
|
||||
- 새 OpenClaw Plugin을 만들려고 합니다
|
||||
- 새 OpenClaw Plugin을 만들고 싶습니다
|
||||
- Plugin 개발을 위한 빠른 시작 가이드가 필요합니다
|
||||
- OpenClaw에 새로운 채널, 제공자, 도구 또는 기타 기능을 추가하고 있습니다
|
||||
- OpenClaw에 새 채널, 제공자, 도구 또는 기타 기능을 추가하고 있습니다
|
||||
sidebarTitle: Getting Started
|
||||
summary: 몇 분 만에 첫 OpenClaw Plugin 만들기
|
||||
title: Plugin 빌드하기
|
||||
title: Plugin 만들기
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T20:57:11Z"
|
||||
generated_at: "2026-05-04T02:24:21Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: b42170b40094f89a63b1497c08ec31e397931dd536bd6faeeb8bc3c123ae45d1
|
||||
source_hash: 3e6c55c551629da54b3f150ce6299694186fe4434cfd7978a2d43d175d33a5d9
|
||||
source_path: plugins/building-plugins.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
Plugin은 OpenClaw에 채널, 모델 제공자, 음성, 실시간 전사, 실시간 음성, 미디어 이해, 이미지 생성, 동영상 생성, 웹 가져오기, 웹 검색, 에이전트 도구 또는 이들의 조합 같은 새로운 기능을 추가합니다.
|
||||
Plugin은 OpenClaw에 새로운 기능을 확장합니다: 채널, 모델 제공자,
|
||||
음성, 실시간 전사, 실시간 음성, 미디어 이해, 이미지
|
||||
생성, 비디오 생성, 웹 가져오기, 웹 검색, 에이전트 도구 또는 그
|
||||
조합입니다.
|
||||
|
||||
Plugin을 OpenClaw 저장소에 추가할 필요는 없습니다. [ClawHub](/ko/tools/clawhub)에 게시하면 사용자는 `openclaw plugins install clawhub:<package-name>`로 설치합니다. 출시 전환 기간에는 bare 패키지 명세도 여전히 npm에서 설치됩니다.
|
||||
Plugin을 OpenClaw 저장소에 추가할 필요는 없습니다. [ClawHub](/ko/tools/clawhub)에
|
||||
게시하면 사용자가 `openclaw plugins install clawhub:<package-name>`로 설치합니다.
|
||||
Bare 패키지 명세는 출시 전환 기간 동안 계속 npm에서 설치됩니다.
|
||||
|
||||
## 사전 요구 사항
|
||||
|
||||
- Node >= 22 및 패키지 관리자(npm 또는 pnpm)
|
||||
- TypeScript(ESM)에 대한 이해
|
||||
- 저장소 내부 Plugin의 경우: 저장소를 클론하고 `pnpm install` 완료. 소스 체크아웃 Plugin 개발은 pnpm 전용입니다. OpenClaw가 `extensions/*` workspace 패키지에서 번들 Plugin을 로드하기 때문입니다.
|
||||
- 저장소 내 Plugin의 경우: 저장소를 클론하고 `pnpm install`을 완료해야 합니다. 소스
|
||||
체크아웃 Plugin 개발은 pnpm 전용입니다. OpenClaw가 번들된
|
||||
Plugin을 `extensions/*` 워크스페이스 패키지에서 로드하기 때문입니다.
|
||||
|
||||
## 어떤 종류의 Plugin인가요?
|
||||
|
||||
@ -35,15 +42,19 @@ Plugin을 OpenClaw 저장소에 추가할 필요는 없습니다. [ClawHub](/ko/
|
||||
모델 제공자(LLM, 프록시 또는 사용자 지정 엔드포인트)를 추가합니다.
|
||||
</Card>
|
||||
<Card title="Tool / hook plugin" icon="wrench" href="/ko/plugins/hooks">
|
||||
에이전트 도구, 이벤트 훅 또는 서비스를 등록합니다 — 아래를 계속 읽으세요.
|
||||
에이전트 도구, 이벤트 훅 또는 서비스를 등록합니다 — 아래에서 계속합니다.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
온보딩/설정이 실행될 때 설치되어 있다고 보장할 수 없는 채널 Plugin의 경우 `openclaw/plugin-sdk/channel-setup`의 `createOptionalChannelSetupSurface(...)`를 사용하세요. 이 함수는 설치 요구 사항을 알리고, Plugin이 설치될 때까지 실제 설정 쓰기를 닫힌 상태로 실패시키는 설정 어댑터 + 마법사 쌍을 생성합니다.
|
||||
온보딩/설정 실행 시 설치되어 있음이 보장되지 않는 채널 Plugin의 경우,
|
||||
`openclaw/plugin-sdk/channel-setup`의 `createOptionalChannelSetupSurface(...)`를
|
||||
사용하세요. 이 함수는 설치 요구 사항을 알리고 Plugin이 설치될 때까지 실제 구성 쓰기에서
|
||||
닫힌 상태로 실패하는 설정 어댑터 + 마법사 쌍을 생성합니다.
|
||||
|
||||
## 빠른 시작: 도구 Plugin
|
||||
|
||||
이 안내에서는 에이전트 도구를 등록하는 최소 Plugin을 만듭니다. 채널 및 제공자 Plugin에는 위에 링크된 전용 가이드가 있습니다.
|
||||
이 안내서는 에이전트 도구를 등록하는 최소 Plugin을 만듭니다. 채널
|
||||
및 제공자 Plugin에는 위에 연결된 전용 가이드가 있습니다.
|
||||
|
||||
<Steps>
|
||||
<Step title="Create the package and manifest">
|
||||
@ -86,7 +97,12 @@ Plugin을 OpenClaw 저장소에 추가할 필요는 없습니다. [ClawHub](/ko/
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
모든 Plugin에는 설정이 없더라도 manifest가 필요합니다. 런타임에 등록되는 도구는 `contracts.tools`에 나열해야 OpenClaw가 모든 Plugin 런타임을 로드하지 않고도 소유 Plugin을 찾을 수 있습니다. Plugin은 `activation.onStartup`도 의도적으로 선언해야 합니다. 이 예시는 값을 `true`로 설정합니다. 전체 스키마는 [Manifest](/ko/plugins/manifest)를 참고하세요. 정식 ClawHub 게시 스니펫은 `docs/snippets/plugin-publish/`에 있습니다.
|
||||
모든 Plugin에는 구성이 없더라도 매니페스트가 필요합니다. 런타임에 등록되는 도구는
|
||||
`contracts.tools`에 나열되어야 하므로 OpenClaw가 모든 Plugin 런타임을 로드하지 않고도
|
||||
소유 Plugin을 찾을 수 있습니다. 또한 Plugin은
|
||||
`activation.onStartup`을 의도적으로 선언해야 합니다. 이 예시는 이를 `true`로 설정합니다. 전체 스키마는
|
||||
[매니페스트](/ko/plugins/manifest)를 참조하세요. 정식 ClawHub
|
||||
게시 스니펫은 `docs/snippets/plugin-publish/`에 있습니다.
|
||||
|
||||
</Step>
|
||||
|
||||
@ -114,13 +130,15 @@ Plugin을 OpenClaw 저장소에 추가할 필요는 없습니다. [ClawHub](/ko/
|
||||
});
|
||||
```
|
||||
|
||||
`definePluginEntry`는 채널이 아닌 Plugin용입니다. 채널에는 `defineChannelPluginEntry`를 사용하세요 — [Channel Plugins](/ko/plugins/sdk-channel-plugins)를 참고하세요. 전체 진입점 옵션은 [Entry Points](/ko/plugins/sdk-entrypoints)를 참고하세요.
|
||||
`definePluginEntry`는 채널이 아닌 Plugin용입니다. 채널의 경우
|
||||
`defineChannelPluginEntry`를 사용하세요 — [채널 Plugin](/ko/plugins/sdk-channel-plugins)을 참조하세요.
|
||||
전체 엔트리 포인트 옵션은 [엔트리 포인트](/ko/plugins/sdk-entrypoints)를 참조하세요.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Test and publish">
|
||||
|
||||
**외부 Plugin:** ClawHub로 검증하고 게시한 뒤 설치합니다.
|
||||
**외부 Plugin:** ClawHub로 검증하고 게시한 다음 설치합니다.
|
||||
|
||||
```bash
|
||||
clawhub package publish your-org/your-plugin --dry-run
|
||||
@ -128,9 +146,10 @@ Plugin을 OpenClaw 저장소에 추가할 필요는 없습니다. [ClawHub](/ko/
|
||||
openclaw plugins install clawhub:@myorg/openclaw-my-plugin
|
||||
```
|
||||
|
||||
`@myorg/openclaw-my-plugin` 같은 bare 패키지 명세는 출시 전환 기간에 npm에서 설치됩니다. ClawHub 해석을 원할 때는 `clawhub:`를 사용하세요.
|
||||
`@myorg/openclaw-my-plugin` 같은 Bare 패키지 명세는
|
||||
출시 전환 기간 동안 npm에서 설치됩니다. ClawHub 해석을 원할 때는 `clawhub:`를 사용하세요.
|
||||
|
||||
**저장소 내부 Plugin:** 번들 Plugin workspace 트리 아래에 배치하면 자동으로 발견됩니다.
|
||||
**저장소 내 Plugin:** 번들된 Plugin 워크스페이스 트리 아래에 배치하면 자동으로 발견됩니다.
|
||||
|
||||
```bash
|
||||
pnpm test -- <bundled-plugin-root>/my-plugin/
|
||||
@ -141,57 +160,67 @@ Plugin을 OpenClaw 저장소에 추가할 필요는 없습니다. [ClawHub](/ko/
|
||||
|
||||
## Plugin 기능
|
||||
|
||||
단일 Plugin은 `api` 객체를 통해 원하는 수의 기능을 등록할 수 있습니다.
|
||||
하나의 Plugin은 `api` 객체를 통해 원하는 수의 기능을 등록할 수 있습니다.
|
||||
|
||||
| 기능 | 등록 메서드 | 상세 가이드 |
|
||||
| ---------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------- |
|
||||
| 텍스트 추론(LLM) | `api.registerProvider(...)` | [Provider Plugins](/ko/plugins/sdk-provider-plugins) |
|
||||
| CLI 추론 백엔드 | `api.registerCliBackend(...)` | [CLI Backends](/ko/gateway/cli-backends) |
|
||||
| 채널 / 메시징 | `api.registerChannel(...)` | [Channel Plugins](/ko/plugins/sdk-channel-plugins) |
|
||||
| 음성(TTS/STT) | `api.registerSpeechProvider(...)` | [Provider Plugins](/ko/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) |
|
||||
| 실시간 전사 | `api.registerRealtimeTranscriptionProvider(...)` | [Provider Plugins](/ko/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) |
|
||||
| 실시간 음성 | `api.registerRealtimeVoiceProvider(...)` | [Provider Plugins](/ko/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) |
|
||||
| 미디어 이해 | `api.registerMediaUnderstandingProvider(...)` | [Provider Plugins](/ko/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) |
|
||||
| 이미지 생성 | `api.registerImageGenerationProvider(...)` | [Provider Plugins](/ko/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) |
|
||||
| 음악 생성 | `api.registerMusicGenerationProvider(...)` | [Provider Plugins](/ko/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) |
|
||||
| 동영상 생성 | `api.registerVideoGenerationProvider(...)` | [Provider Plugins](/ko/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) |
|
||||
| 웹 가져오기 | `api.registerWebFetchProvider(...)` | [Provider Plugins](/ko/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) |
|
||||
| 웹 검색 | `api.registerWebSearchProvider(...)` | [Provider Plugins](/ko/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) |
|
||||
| 도구 결과 middleware | `api.registerAgentToolResultMiddleware(...)` | [SDK Overview](/ko/plugins/sdk-overview#registration-api) |
|
||||
| 텍스트 추론(LLM) | `api.registerProvider(...)` | [제공자 Plugin](/ko/plugins/sdk-provider-plugins) |
|
||||
| CLI 추론 백엔드 | `api.registerCliBackend(...)` | [CLI 백엔드](/ko/gateway/cli-backends) |
|
||||
| 채널 / 메시징 | `api.registerChannel(...)` | [채널 Plugin](/ko/plugins/sdk-channel-plugins) |
|
||||
| 음성(TTS/STT) | `api.registerSpeechProvider(...)` | [제공자 Plugin](/ko/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) |
|
||||
| 실시간 전사 | `api.registerRealtimeTranscriptionProvider(...)` | [제공자 Plugin](/ko/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) |
|
||||
| 실시간 음성 | `api.registerRealtimeVoiceProvider(...)` | [제공자 Plugin](/ko/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) |
|
||||
| 미디어 이해 | `api.registerMediaUnderstandingProvider(...)` | [제공자 Plugin](/ko/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) |
|
||||
| 이미지 생성 | `api.registerImageGenerationProvider(...)` | [제공자 Plugin](/ko/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) |
|
||||
| 음악 생성 | `api.registerMusicGenerationProvider(...)` | [제공자 Plugin](/ko/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) |
|
||||
| 비디오 생성 | `api.registerVideoGenerationProvider(...)` | [제공자 Plugin](/ko/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) |
|
||||
| 웹 가져오기 | `api.registerWebFetchProvider(...)` | [제공자 Plugin](/ko/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) |
|
||||
| 웹 검색 | `api.registerWebSearchProvider(...)` | [제공자 Plugin](/ko/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) |
|
||||
| 도구 결과 미들웨어 | `api.registerAgentToolResultMiddleware(...)` | [SDK 개요](/ko/plugins/sdk-overview#registration-api) |
|
||||
| 에이전트 도구 | `api.registerTool(...)` | 아래 |
|
||||
| 사용자 지정 명령 | `api.registerCommand(...)` | [Entry Points](/ko/plugins/sdk-entrypoints) |
|
||||
| Plugin 훅 | `api.on(...)` | [Plugin hooks](/ko/plugins/hooks) |
|
||||
| 내부 이벤트 훅 | `api.registerHook(...)` | [Entry Points](/ko/plugins/sdk-entrypoints) |
|
||||
| HTTP 경로 | `api.registerHttpRoute(...)` | [Internals](/ko/plugins/architecture-internals#gateway-http-routes) |
|
||||
| CLI 하위 명령 | `api.registerCli(...)` | [Entry Points](/ko/plugins/sdk-entrypoints) |
|
||||
| 사용자 지정 명령 | `api.registerCommand(...)` | [엔트리 포인트](/ko/plugins/sdk-entrypoints) |
|
||||
| Plugin 훅 | `api.on(...)` | [Plugin 훅](/ko/plugins/hooks) |
|
||||
| 내부 이벤트 훅 | `api.registerHook(...)` | [엔트리 포인트](/ko/plugins/sdk-entrypoints) |
|
||||
| HTTP 라우트 | `api.registerHttpRoute(...)` | [내부 구조](/ko/plugins/architecture-internals#gateway-http-routes) |
|
||||
| CLI 하위 명령 | `api.registerCli(...)` | [엔트리 포인트](/ko/plugins/sdk-entrypoints) |
|
||||
|
||||
전체 등록 API는 [SDK Overview](/ko/plugins/sdk-overview#registration-api)를 참고하세요.
|
||||
전체 등록 API는 [SDK 개요](/ko/plugins/sdk-overview#registration-api)를 참조하세요.
|
||||
|
||||
번들 Plugin은 모델이 출력을 보기 전에 비동기 도구 결과 재작성이 필요할 때 `api.registerAgentToolResultMiddleware(...)`를 사용할 수 있습니다. 대상 런타임을 `contracts.agentToolResultMiddleware`에 선언하세요. 예: `["pi", "codex"]`. 이는 신뢰되는 번들 Plugin 연결점입니다. OpenClaw가 이 기능에 대한 명시적 신뢰 정책을 확장하기 전까지 외부 Plugin은 일반 OpenClaw Plugin 훅을 선호해야 합니다.
|
||||
번들된 Plugin은 모델이 출력을 보기 전에 비동기 도구 결과 재작성이
|
||||
필요할 때 `api.registerAgentToolResultMiddleware(...)`를 사용할 수 있습니다. 예를 들어
|
||||
`["pi", "codex"]`처럼 대상 런타임을 `contracts.agentToolResultMiddleware`에 선언하세요.
|
||||
이는 신뢰할 수 있는 번들 Plugin seam입니다. 외부
|
||||
Plugin은 OpenClaw가 이 기능에 대한 명시적 신뢰 정책을 확장하기 전까지는 일반 OpenClaw Plugin 훅을 선호해야 합니다.
|
||||
|
||||
Plugin이 사용자 지정 Gateway RPC 메서드를 등록한다면 Plugin별 접두사에 유지하세요. 핵심 관리자 네임스페이스(`config.*`, `exec.approvals.*`, `wizard.*`, `update.*`)는 예약된 상태로 유지되며, Plugin이 더 좁은 범위를 요청하더라도 항상 `operator.admin`으로 해석됩니다.
|
||||
Plugin이 사용자 지정 Gateway RPC 메서드를 등록하는 경우,
|
||||
Plugin 전용 접두사에 유지하세요. 핵심 관리자 네임스페이스(`config.*`,
|
||||
`exec.approvals.*`, `wizard.*`, `update.*`)는 예약 상태로 유지되며, Plugin이 더 좁은 범위를 요청하더라도
|
||||
항상 `operator.admin`으로 해석됩니다.
|
||||
|
||||
기억해야 할 훅 가드 의미 체계:
|
||||
기억해야 할 훅 가드 의미론:
|
||||
|
||||
- `before_tool_call`: `{ block: true }`는 종단 상태이며 더 낮은 우선순위의 핸들러를 중지합니다.
|
||||
- `before_tool_call`: `{ block: true }`는 종료 상태이며 더 낮은 우선순위 핸들러를 중지합니다.
|
||||
- `before_tool_call`: `{ block: false }`는 결정 없음으로 처리됩니다.
|
||||
- `before_tool_call`: `{ requireApproval: true }`는 에이전트 실행을 일시 중지하고 exec 승인 오버레이, Telegram 버튼, Discord 상호작용 또는 모든 채널의 `/approve` 명령을 통해 사용자에게 승인을 요청합니다.
|
||||
- `before_install`: `{ block: true }`는 종단 상태이며 더 낮은 우선순위의 핸들러를 중지합니다.
|
||||
- `before_install`: `{ block: true }`는 종료 상태이며 더 낮은 우선순위 핸들러를 중지합니다.
|
||||
- `before_install`: `{ block: false }`는 결정 없음으로 처리됩니다.
|
||||
- `message_sending`: `{ cancel: true }`는 종단 상태이며 더 낮은 우선순위의 핸들러를 중지합니다.
|
||||
- `message_sending`: `{ cancel: true }`는 종료 상태이며 더 낮은 우선순위 핸들러를 중지합니다.
|
||||
- `message_sending`: `{ cancel: false }`는 결정 없음으로 처리됩니다.
|
||||
- `message_received`: 인바운드 스레드/주제 라우팅이 필요할 때는 타입이 지정된 `threadId` 필드를 선호하세요. 채널별 추가 정보에는 `metadata`를 유지하세요.
|
||||
- `message_sending`: 채널별 metadata 키보다 타입이 지정된 `replyToId` / `threadId` 라우팅 필드를 선호하세요.
|
||||
- `message_received`: 인바운드 스레드/토픽 라우팅이 필요할 때는 타입이 지정된 `threadId` 필드를 선호하세요. `metadata`는 채널별 추가 정보용으로 유지하세요.
|
||||
- `message_sending`: 채널별 메타데이터 키보다 타입이 지정된 `replyToId` / `threadId` 라우팅 필드를 선호하세요.
|
||||
|
||||
`/approve` 명령은 제한된 fallback으로 exec 승인과 Plugin 승인을 모두 처리합니다. exec 승인 ID를 찾을 수 없으면 OpenClaw는 같은 ID로 Plugin 승인을 다시 시도합니다. Plugin 승인 전달은 설정의 `approvals.plugin`을 통해 독립적으로 구성할 수 있습니다.
|
||||
`/approve` 명령은 제한된 폴백으로 exec 승인과 Plugin 승인을 모두 처리합니다. exec 승인 id를 찾을 수 없으면 OpenClaw가 동일한 id로 Plugin 승인을 다시 시도합니다. Plugin 승인 전달은 구성의 `approvals.plugin`을 통해 독립적으로 설정할 수 있습니다.
|
||||
|
||||
사용자 지정 승인 배관에서 동일한 제한된 fallback 사례를 감지해야 한다면 승인 만료 문자열을 수동으로 매칭하는 대신 `openclaw/plugin-sdk/error-runtime`의 `isApprovalNotFoundError`를 선호하세요.
|
||||
사용자 지정 승인 배관에서 동일한 제한된 폴백 사례를 감지해야 한다면,
|
||||
승인 만료 문자열을 수동으로 매칭하는 대신 `openclaw/plugin-sdk/error-runtime`의 `isApprovalNotFoundError`를
|
||||
선호하세요.
|
||||
|
||||
예시와 훅 참조는 [Plugin hooks](/ko/plugins/hooks)를 참고하세요.
|
||||
예시와 훅 참조는 [Plugin 훅](/ko/plugins/hooks)을 참조하세요.
|
||||
|
||||
## 에이전트 도구 등록
|
||||
|
||||
도구는 LLM이 호출할 수 있는 타입 지정 함수입니다. 필수(항상 사용 가능) 또는 선택 사항(사용자 opt-in)일 수 있습니다.
|
||||
도구는 LLM이 호출할 수 있는 타입 지정 함수입니다. 도구는 필수(항상
|
||||
사용 가능) 또는 선택 사항(사용자 옵트인)일 수 있습니다.
|
||||
|
||||
```typescript
|
||||
register(api) {
|
||||
@ -220,19 +249,30 @@ register(api) {
|
||||
}
|
||||
```
|
||||
|
||||
`api.registerTool(...)`로 등록된 모든 도구는 Plugin manifest에도 선언해야 합니다.
|
||||
`api.registerTool(...)`로 등록된 모든 도구는 Plugin 매니페스트에도 선언되어야 합니다.
|
||||
|
||||
```json
|
||||
{
|
||||
"contracts": {
|
||||
"tools": ["my_tool", "workflow_tool"]
|
||||
},
|
||||
"toolMetadata": {
|
||||
"workflow_tool": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
OpenClaw는 등록된 도구에서 검증된 descriptor를 캡처하고 캐시하므로 Plugin은 manifest에 `description` 또는 스키마 데이터를 중복하지 않습니다. manifest contract는 소유권과 발견만 선언합니다. 실행은 여전히 실제 등록된 도구 구현을 호출합니다.
|
||||
OpenClaw는 등록된 도구에서 검증된 디스크립터를 캡처하고 캐시하므로,
|
||||
Plugin은 매니페스트에서 `description` 또는 스키마 데이터를 중복하지 않습니다.
|
||||
매니페스트 계약은 소유권과 검색만 선언하며, 실행은 여전히
|
||||
실시간으로 등록된 도구 구현을 호출합니다.
|
||||
OpenClaw가 도구가 명시적으로 허용 목록에 추가될 때까지 해당
|
||||
Plugin 런타임을 로드하지 않을 수 있도록, `api.registerTool(..., { optional: true })`로
|
||||
등록된 도구에는 `toolMetadata.<tool>.optional: true`를 설정하세요.
|
||||
|
||||
사용자는 설정에서 선택적 도구를 활성화합니다.
|
||||
사용자는 구성에서 선택적 도구를 활성화합니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -240,7 +280,7 @@ OpenClaw는 등록된 도구에서 검증된 descriptor를 캡처하고 캐시
|
||||
}
|
||||
```
|
||||
|
||||
- 도구 이름은 코어 도구와 충돌하면 안 됩니다(충돌하는 항목은 건너뜀)
|
||||
- 도구 이름은 코어 도구와 충돌해서는 안 됩니다(충돌은 건너뜁니다)
|
||||
- 누락된 `parameters`를 포함해 등록 객체 형식이 잘못된 도구는 에이전트 실행을 중단하는 대신 건너뛰고 Plugin 진단에 보고됩니다
|
||||
- 부작용이나 추가 바이너리 요구 사항이 있는 도구에는 `optional: true`를 사용하세요
|
||||
- 사용자는 Plugin ID를 `tools.allow`에 추가하여 Plugin의 모든 도구를 활성화할 수 있습니다
|
||||
@ -298,56 +338,56 @@ import { ... } from "openclaw/plugin-sdk";
|
||||
|
||||
전체 하위 경로 참조는 [SDK 개요](/ko/plugins/sdk-overview)를 참조하세요.
|
||||
|
||||
Plugin 내부에서는 내부 가져오기에 로컬 배럴 파일(`api.ts`, `runtime-api.ts`)을 사용하세요. 자체 Plugin을 SDK 경로를 통해 가져오면 안 됩니다.
|
||||
Plugin 내부에서는 내부 가져오기에 로컬 배럴 파일(`api.ts`, `runtime-api.ts`)을 사용하세요. SDK 경로를 통해 자기 Plugin을 가져오면 안 됩니다.
|
||||
|
||||
Provider Plugin의 경우 seam이 정말 범용이 아니라면 제공자별 헬퍼를 해당 패키지 루트 배럴에 유지하세요. 현재 번들 예시는 다음과 같습니다.
|
||||
Provider Plugin의 경우, seam이 정말로 일반적인 경우가 아니라면 제공자별 헬퍼를 해당 패키지 루트 배럴에 유지하세요. 현재 번들 예시는 다음과 같습니다.
|
||||
|
||||
- Anthropic: Claude 스트림 래퍼와 `service_tier` / 베타 헬퍼
|
||||
- Anthropic: Claude 스트림 래퍼 및 `service_tier` / 베타 헬퍼
|
||||
- OpenAI: 제공자 빌더, 기본 모델 헬퍼, 실시간 제공자
|
||||
- OpenRouter: 제공자 빌더와 온보딩/구성 헬퍼
|
||||
|
||||
헬퍼가 하나의 번들 제공자 패키지 안에서만 유용하다면 `openclaw/plugin-sdk/*`로 승격하지 말고 해당 패키지 루트 seam에 유지하세요.
|
||||
헬퍼가 하나의 번들 제공자 패키지 내부에서만 유용하다면 `openclaw/plugin-sdk/*`로 승격하지 말고 해당 패키지 루트 seam에 유지하세요.
|
||||
|
||||
일부 생성된 `openclaw/plugin-sdk/<bundled-id>` 헬퍼 seam은 추적된 소유자 사용이 있는 경우 번들 Plugin 유지보수를 위해 여전히 존재합니다. 이를 새 타사 Plugin의 기본 패턴이 아니라 예약된 표면으로 취급하세요.
|
||||
일부 생성된 `openclaw/plugin-sdk/<bundled-id>` 헬퍼 seam은 추적된 소유자 사용이 있는 경우 번들 Plugin 유지보수를 위해 여전히 존재합니다. 이를 새 서드 파티 Plugin의 기본 패턴이 아니라 예약된 표면으로 취급하세요.
|
||||
|
||||
## 제출 전 체크리스트
|
||||
|
||||
<Check>**package.json**에 올바른 `openclaw` 메타데이터가 있음</Check>
|
||||
<Check>**openclaw.plugin.json** 매니페스트가 있고 유효함</Check>
|
||||
<Check>진입점이 `defineChannelPluginEntry` 또는 `definePluginEntry`를 사용함</Check>
|
||||
<Check>모든 가져오기가 집중된 `plugin-sdk/<subpath>` 경로를 사용함</Check>
|
||||
<Check>내부 가져오기는 SDK 자체 가져오기가 아니라 로컬 모듈을 사용함</Check>
|
||||
<Check>테스트 통과(`pnpm test -- <bundled-plugin-root>/my-plugin/`)</Check>
|
||||
<Check>`pnpm check` 통과(리포지토리 내 Plugin)</Check>
|
||||
<Check>**package.json**에 올바른 `openclaw` 메타데이터가 있습니다</Check>
|
||||
<Check>**openclaw.plugin.json** 매니페스트가 존재하고 유효합니다</Check>
|
||||
<Check>엔트리 포인트가 `defineChannelPluginEntry` 또는 `definePluginEntry`를 사용합니다</Check>
|
||||
<Check>모든 가져오기가 집중된 `plugin-sdk/<subpath>` 경로를 사용합니다</Check>
|
||||
<Check>내부 가져오기가 SDK 자기 가져오기가 아니라 로컬 모듈을 사용합니다</Check>
|
||||
<Check>테스트가 통과합니다(`pnpm test -- <bundled-plugin-root>/my-plugin/`)</Check>
|
||||
<Check>`pnpm check`가 통과합니다(저장소 내 Plugin)</Check>
|
||||
|
||||
## 베타 릴리스 테스트
|
||||
|
||||
1. [openclaw/openclaw](https://github.com/openclaw/openclaw/releases)의 GitHub 릴리스 태그를 확인하고 `Watch` > `Releases`를 통해 구독하세요. 베타 태그는 `v2026.3.N-beta.1`과 같은 형태입니다. 릴리스 공지를 받기 위해 공식 OpenClaw X 계정 [@openclaw](https://x.com/openclaw)의 알림을 켤 수도 있습니다.
|
||||
2. 베타 태그가 나타나는 즉시 해당 태그에 대해 Plugin을 테스트하세요. 안정 릴리스 전 창구는 일반적으로 몇 시간에 불과합니다.
|
||||
3. 테스트 후 `plugin-forum` Discord 채널의 Plugin 스레드에 `all good` 또는 깨진 내용을 게시하세요. 아직 스레드가 없다면 하나를 만드세요.
|
||||
1. [openclaw/openclaw](https://github.com/openclaw/openclaw/releases)의 GitHub 릴리스 태그를 확인하고 `Watch` > `Releases`로 구독하세요. 베타 태그는 `v2026.3.N-beta.1` 형식입니다. 릴리스 발표를 위해 공식 OpenClaw X 계정 [@openclaw](https://x.com/openclaw)의 알림을 켤 수도 있습니다.
|
||||
2. 베타 태그가 나타나는 즉시 해당 태그에 대해 Plugin을 테스트하세요. 안정 버전 전의 기간은 보통 몇 시간뿐입니다.
|
||||
3. 테스트 후 `plugin-forum` Discord 채널의 Plugin 스레드에 `all good` 또는 깨진 내용을 게시하세요. 아직 스레드가 없다면 새로 만드세요.
|
||||
4. 문제가 발생하면 `Beta blocker: <plugin-name> - <summary>` 제목의 이슈를 열거나 업데이트하고 `beta-blocker` 라벨을 적용하세요. 스레드에 이슈 링크를 넣으세요.
|
||||
5. `main`에 `fix(<plugin-id>): beta blocker - <summary>` 제목의 PR을 열고 PR과 Discord 스레드 양쪽에 이슈를 링크하세요. 기여자는 PR에 라벨을 붙일 수 없으므로 제목이 유지관리자와 자동화를 위한 PR 측 신호입니다. PR이 있는 차단 문제는 병합되며, PR이 없는 차단 문제는 그대로 배포될 수도 있습니다. 유지관리자는 베타 테스트 중에 이 스레드를 확인합니다.
|
||||
6. 침묵은 정상 신호입니다. 창구를 놓치면 수정 사항은 다음 주기에 반영될 가능성이 높습니다.
|
||||
5. `main`에 대해 `fix(<plugin-id>): beta blocker - <summary>` 제목의 PR을 열고 PR과 Discord 스레드 모두에 이슈를 링크하세요. 기여자는 PR에 라벨을 붙일 수 없으므로 제목이 유지관리자와 자동화를 위한 PR 측 신호입니다. PR이 있는 차단 이슈는 병합되고, PR이 없는 차단 이슈는 그대로 배포될 수 있습니다. 유지관리자는 베타 테스트 중 이 스레드를 확인합니다.
|
||||
6. 침묵은 정상이라는 뜻입니다. 이 기간을 놓치면 수정 사항은 다음 주기에 반영될 가능성이 높습니다.
|
||||
|
||||
## 다음 단계
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Channel Plugin" icon="messages-square" href="/ko/plugins/sdk-channel-plugins">
|
||||
메시징 채널 Plugin 빌드
|
||||
<Card title="Channel Plugins" icon="messages-square" href="/ko/plugins/sdk-channel-plugins">
|
||||
메시징 채널 Plugin 빌드하기
|
||||
</Card>
|
||||
<Card title="Provider Plugin" icon="cpu" href="/ko/plugins/sdk-provider-plugins">
|
||||
모델 제공자 Plugin 빌드
|
||||
<Card title="Provider Plugins" icon="cpu" href="/ko/plugins/sdk-provider-plugins">
|
||||
모델 제공자 Plugin 빌드하기
|
||||
</Card>
|
||||
<Card title="SDK 개요" icon="book-open" href="/ko/plugins/sdk-overview">
|
||||
<Card title="SDK Overview" icon="book-open" href="/ko/plugins/sdk-overview">
|
||||
가져오기 맵 및 등록 API 참조
|
||||
</Card>
|
||||
<Card title="런타임 헬퍼" icon="settings" href="/ko/plugins/sdk-runtime">
|
||||
api.runtime을 통한 TTS, 검색, 하위 에이전트
|
||||
<Card title="Runtime Helpers" icon="settings" href="/ko/plugins/sdk-runtime">
|
||||
api.runtime을 통한 TTS, 검색, 서브에이전트
|
||||
</Card>
|
||||
<Card title="테스트" icon="test-tubes" href="/ko/plugins/sdk-testing">
|
||||
<Card title="Testing" icon="test-tubes" href="/ko/plugins/sdk-testing">
|
||||
테스트 유틸리티 및 패턴
|
||||
</Card>
|
||||
<Card title="Plugin 매니페스트" icon="file-json" href="/ko/plugins/manifest">
|
||||
<Card title="Plugin Manifest" icon="file-json" href="/ko/plugins/manifest">
|
||||
전체 매니페스트 스키마 참조
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@ -357,5 +397,5 @@ Provider Plugin의 경우 seam이 정말 범용이 아니라면 제공자별 헬
|
||||
- [Plugin 아키텍처](/ko/plugins/architecture) — 내부 아키텍처 심층 분석
|
||||
- [SDK 개요](/ko/plugins/sdk-overview) — Plugin SDK 참조
|
||||
- [매니페스트](/ko/plugins/manifest) — Plugin 매니페스트 형식
|
||||
- [Channel Plugin](/ko/plugins/sdk-channel-plugins) — 채널 Plugin 빌드
|
||||
- [Provider Plugin](/ko/plugins/sdk-provider-plugins) — 제공자 Plugin 빌드
|
||||
- [Channel Plugins](/ko/plugins/sdk-channel-plugins) — 채널 Plugin 빌드
|
||||
- [Provider Plugins](/ko/plugins/sdk-provider-plugins) — 제공자 Plugin 빌드
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,30 +1,31 @@
|
||||
---
|
||||
read_when:
|
||||
- 단순한 MEMORY.md 메모를 넘어서는 지속적인 지식이 필요합니다
|
||||
- 단순한 MEMORY.md 메모를 넘어 지속적으로 유지되는 지식이 필요합니다
|
||||
- 번들로 제공되는 memory-wiki Plugin을 구성하고 있습니다
|
||||
- wiki_search, wiki_get 또는 브리지 모드를 이해하고 싶은 경우
|
||||
summary: 'memory-wiki: 출처 정보, 주장, 대시보드, 브리지 모드를 포함한 컴파일된 지식 저장소'
|
||||
- wiki_search, wiki_get 또는 브리지 모드를 이해하고 싶습니다
|
||||
summary: '메모리 위키: 출처 정보, 클레임, 대시보드, 브리지 모드를 포함하는 컴파일된 지식 저장소'
|
||||
title: 메모리 위키
|
||||
x-i18n:
|
||||
generated_at: "2026-04-30T06:42:42Z"
|
||||
generated_at: "2026-05-04T02:24:56Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 744d569f8b0c9b668ea54dc057f808544359eaae87d5557de2e6acd1b31acd89
|
||||
source_hash: b070177b7c1217e9102bc57680b4009265e3584ede7ad6dc3ba7b6393260fefe
|
||||
source_path: plugins/memory-wiki.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
`memory-wiki`는 지속성 메모리를 컴파일된 지식 저장소로 바꾸는 번들 제공 Plugin입니다.
|
||||
`memory-wiki`는 지속 메모리를 컴파일된
|
||||
지식 저장소로 바꾸는 번들 Plugin입니다.
|
||||
|
||||
이는 Active Memory Plugin을 **대체하지 않습니다**. Active Memory Plugin은 여전히
|
||||
회상, 승격, 색인화, Dreaming을 담당합니다. `memory-wiki`는 그 옆에 위치하며
|
||||
지속성 지식을 결정론적 페이지, 구조화된 주장, 출처, 대시보드, 기계 판독 가능한 다이제스트를 갖춘 탐색 가능한 위키로 컴파일합니다.
|
||||
이는 Active Memory Plugin을 **대체하지 않습니다**. Active Memory Plugin은 계속
|
||||
회상, 승격, 색인, Dreaming을 담당합니다. `memory-wiki`는 그 옆에서
|
||||
지속 지식을 결정적 페이지, 구조화된 주장, 출처, 대시보드, 기계가 읽을 수 있는 다이제스트를 갖춘 탐색 가능한 위키로 컴파일합니다.
|
||||
|
||||
메모리가 Markdown 파일 더미가 아니라 유지 관리되는 지식 계층처럼 동작하기를 원할 때 사용하세요.
|
||||
메모리가 Markdown 파일 더미에 가깝기보다 관리되는 지식 계층처럼 동작하기를 원할 때 사용하세요.
|
||||
|
||||
## 추가되는 기능
|
||||
|
||||
- 결정론적 페이지 레이아웃을 갖춘 전용 위키 저장소
|
||||
- 결정적 페이지 레이아웃을 갖춘 전용 위키 저장소
|
||||
- 단순한 산문이 아닌 구조화된 주장 및 증거 메타데이터
|
||||
- 페이지 수준의 출처, 신뢰도, 모순, 열린 질문
|
||||
- 에이전트/런타임 소비자를 위한 컴파일된 다이제스트
|
||||
@ -34,45 +35,45 @@ x-i18n:
|
||||
|
||||
## 메모리와 맞물리는 방식
|
||||
|
||||
분리는 다음과 같이 생각하면 됩니다.
|
||||
분리를 다음과 같이 생각하세요.
|
||||
|
||||
| 계층 | 담당 |
|
||||
| ------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
|
||||
| Active Memory Plugin (`memory-core`, QMD, Honcho 등) | 회상, 의미 검색, 승격, Dreaming, 메모리 런타임 |
|
||||
| `memory-wiki` | 컴파일된 위키 페이지, 출처가 풍부한 종합, 대시보드, 위키 특화 검색/가져오기/적용 |
|
||||
| Active Memory Plugin(`memory-core`, QMD, Honcho 등) | 회상, 의미 검색, 승격, Dreaming, 메모리 런타임 |
|
||||
| `memory-wiki` | 컴파일된 위키 페이지, 출처가 풍부한 합성, 대시보드, 위키 전용 검색/가져오기/적용 |
|
||||
|
||||
Active Memory Plugin이 공유 회상 아티팩트를 노출하면, OpenClaw는
|
||||
`memory_search corpus=all`로 두 계층을 한 번에 검색할 수 있습니다.
|
||||
|
||||
위키 특화 순위 지정, 출처, 직접 페이지 접근이 필요할 때는 대신
|
||||
위키 네이티브 도구를 사용하세요.
|
||||
위키 전용 랭킹, 출처, 직접 페이지 접근이 필요할 때는
|
||||
대신 위키 네이티브 도구를 사용하세요.
|
||||
|
||||
## 권장 하이브리드 패턴
|
||||
|
||||
로컬 우선 설정에 대한 강력한 기본값은 다음과 같습니다.
|
||||
로컬 우선 설정의 강력한 기본값은 다음과 같습니다.
|
||||
|
||||
- 회상과 광범위한 의미 검색을 위한 Active Memory 백엔드로 QMD 사용
|
||||
- 지속성 종합 지식 페이지를 위한 `bridge` 모드의 `memory-wiki`
|
||||
- 회상 및 광범위한 의미 검색을 위한 Active Memory 백엔드로 QMD 사용
|
||||
- 지속 합성 지식 페이지를 위한 `bridge` 모드의 `memory-wiki`
|
||||
|
||||
이 분리는 각 계층이 초점을 유지하므로 잘 작동합니다.
|
||||
이 분리는 각 계층이 집중할 수 있기 때문에 잘 작동합니다.
|
||||
|
||||
- QMD는 원시 노트, 세션 내보내기, 추가 컬렉션을 검색 가능하게 유지합니다
|
||||
- `memory-wiki`는 안정적인 엔티티, 주장, 대시보드, 소스 페이지를 컴파일합니다
|
||||
- `memory-wiki`는 안정적인 엔터티, 주장, 대시보드, 소스 페이지를 컴파일합니다
|
||||
|
||||
실용적인 규칙:
|
||||
|
||||
- 메모리 전반에 걸친 하나의 넓은 회상 패스를 원하면 `memory_search`를 사용하세요
|
||||
- 출처 인식 위키 결과를 원하면 `wiki_search`와 `wiki_get`을 사용하세요
|
||||
- 공유 검색이 두 계층 모두를 포괄하길 원하면 `memory_search corpus=all`을 사용하세요
|
||||
- 메모리 전반에 걸친 하나의 광범위한 회상 패스가 필요하면 `memory_search`를 사용하세요
|
||||
- 출처를 인식하는 위키 결과가 필요하면 `wiki_search`와 `wiki_get`을 사용하세요
|
||||
- 공유 검색이 두 계층을 모두 포괄해야 하면 `memory_search corpus=all`을 사용하세요
|
||||
|
||||
브리지 모드가 내보낸 아티팩트 0개를 보고하면, Active Memory Plugin이
|
||||
아직 공개 브리지 입력을 노출하지 않는 상태입니다. 먼저 `openclaw wiki doctor`를 실행한 다음,
|
||||
브리지 모드가 내보낸 아티팩트가 0개라고 보고하면, Active Memory Plugin이
|
||||
아직 공개 브리지 입력을 노출하고 있지 않은 것입니다. 먼저 `openclaw wiki doctor`를 실행한 다음,
|
||||
Active Memory Plugin이 공개 아티팩트를 지원하는지 확인하세요.
|
||||
|
||||
브리지 모드가 활성화되어 있고 `bridge.readMemoryArtifacts`가 활성화되어 있으면,
|
||||
브리지 모드가 활성화되어 있고 `bridge.readMemoryArtifacts`가 활성화된 경우,
|
||||
`openclaw wiki status`, `openclaw wiki doctor`, `openclaw wiki bridge
|
||||
import`는 실행 중인 Gateway를 통해 읽습니다. 이렇게 하면 CLI 브리지 검사가
|
||||
런타임 메모리 Plugin 컨텍스트와 정렬됩니다. 브리지가 비활성화되었거나 아티팩트 읽기가
|
||||
런타임 메모리 Plugin 컨텍스트와 정렬됩니다. 브리지가 비활성화되어 있거나 아티팩트 읽기가
|
||||
꺼져 있으면, 해당 명령은 로컬/오프라인 동작을 유지합니다.
|
||||
|
||||
## 저장소 모드
|
||||
@ -83,16 +84,17 @@ import`는 실행 중인 Gateway를 통해 읽습니다. 이렇게 하면 CLI
|
||||
|
||||
자체 저장소, 자체 소스, `memory-core`에 대한 의존성 없음.
|
||||
|
||||
위키를 자체적으로 선별된 지식 저장소로 만들고 싶을 때 사용하세요.
|
||||
위키가 자체 큐레이션된 지식 저장소가 되기를 원할 때 사용하세요.
|
||||
|
||||
### `bridge`
|
||||
|
||||
공개 Plugin SDK 경계를 통해 Active Memory Plugin에서 공개 메모리 아티팩트와 메모리 이벤트를 읽습니다.
|
||||
공개 Plugin SDK 이음새를 통해 Active Memory Plugin에서
|
||||
공개 메모리 아티팩트와 메모리 이벤트를 읽습니다.
|
||||
|
||||
비공개 Plugin 내부 구현에 접근하지 않고 메모리 Plugin의
|
||||
내보낸 아티팩트를 컴파일하고 구성하려는 경우 사용하세요.
|
||||
비공개 Plugin 내부에 접근하지 않고 메모리 Plugin의
|
||||
내보낸 아티팩트를 컴파일하고 정리하려는 경우 사용하세요.
|
||||
|
||||
브리지 모드는 다음을 색인화할 수 있습니다.
|
||||
브리지 모드는 다음을 색인할 수 있습니다.
|
||||
|
||||
- 내보낸 메모리 아티팩트
|
||||
- Dream 보고서
|
||||
@ -102,10 +104,11 @@ import`는 실행 중인 Gateway를 통해 읽습니다. 이렇게 하면 CLI
|
||||
|
||||
### `unsafe-local`
|
||||
|
||||
로컬 비공개 경로를 위한 명시적인 동일 머신 탈출구입니다.
|
||||
로컬 비공개 경로를 위한 명시적인 동일 머신 탈출구.
|
||||
|
||||
이 모드는 의도적으로 실험적이며 이식 가능하지 않습니다. 신뢰 경계를 이해하고
|
||||
브리지 모드가 제공할 수 없는 로컬 파일시스템 접근이 특별히 필요한 경우에만 사용하세요.
|
||||
이 모드는 의도적으로 실험적이며 이식성이 없습니다. 신뢰 경계를
|
||||
이해하고 브리지 모드가 제공할 수 없는 로컬 파일 시스템 접근이
|
||||
구체적으로 필요할 때만 사용하세요.
|
||||
|
||||
## 저장소 레이아웃
|
||||
|
||||
@ -131,15 +134,15 @@ Plugin은 다음과 같이 저장소를 초기화합니다.
|
||||
|
||||
주요 페이지 그룹은 다음과 같습니다.
|
||||
|
||||
- 가져온 원자료와 브리지 기반 페이지를 위한 `sources/`
|
||||
- 지속성 있는 사물, 사람, 시스템, 프로젝트, 객체를 위한 `entities/`
|
||||
- 가져온 원자료 및 브리지 기반 페이지를 위한 `sources/`
|
||||
- 지속적인 사물, 사람, 시스템, 프로젝트, 객체를 위한 `entities/`
|
||||
- 아이디어, 추상화, 패턴, 정책을 위한 `concepts/`
|
||||
- 컴파일된 요약과 유지 관리되는 롤업을 위한 `syntheses/`
|
||||
- 컴파일된 요약 및 관리되는 롤업을 위한 `syntheses/`
|
||||
- 생성된 대시보드를 위한 `reports/`
|
||||
|
||||
## 구조화된 주장과 증거
|
||||
|
||||
페이지는 자유 형식 텍스트뿐 아니라 구조화된 `claims` frontmatter를 포함할 수 있습니다.
|
||||
페이지는 자유 형식 텍스트뿐 아니라 구조화된 `claims` frontmatter를 가질 수 있습니다.
|
||||
|
||||
각 주장은 다음을 포함할 수 있습니다.
|
||||
|
||||
@ -162,31 +165,29 @@ Plugin은 다음과 같이 저장소를 초기화합니다.
|
||||
- `note`
|
||||
- `updatedAt`
|
||||
|
||||
이것이 위키가 수동적인 노트 덤프가 아니라 신념 계층처럼 동작하게 만드는 요소입니다.
|
||||
주장은 추적, 점수화, 반박, 소스 기반 해결이 가능합니다.
|
||||
이것이 위키를 수동적인 노트 덤프보다 믿음 계층에 더 가깝게 작동하게 만드는 요소입니다. 주장은 추적, 점수화, 이의 제기, 소스로의 해결이 가능합니다.
|
||||
|
||||
## 에이전트용 엔티티 메타데이터
|
||||
## 에이전트 대상 엔터티 메타데이터
|
||||
|
||||
엔티티 페이지는 에이전트 사용을 위한 라우팅 메타데이터도 포함할 수 있습니다. 이는 일반적인
|
||||
엔터티 페이지는 에이전트 사용을 위한 라우팅 메타데이터도 가질 수 있습니다. 이는 일반적인
|
||||
frontmatter이므로 사람, 팀, 시스템, 프로젝트 또는 다른 모든
|
||||
엔티티 유형에 사용할 수 있습니다.
|
||||
엔터티 유형에 사용할 수 있습니다.
|
||||
|
||||
일반적인 필드는 다음과 같습니다.
|
||||
|
||||
- `entityType`: 예: `person`, `team`, `system`, `project`
|
||||
- `entityType`: 예: `person`, `team`, `system`, 또는 `project`
|
||||
- `canonicalId`: 별칭과 가져오기 전반에서 사용되는 안정적인 식별 키
|
||||
- `aliases`: 같은 페이지로 해석되어야 하는 이름, 핸들, 레이블
|
||||
- `privacyTier`: `public`, `local-private`, `sensitive`, `confirm-before-use`
|
||||
- `bestUsedFor` / `notEnoughFor`: 압축된 라우팅 힌트
|
||||
- `lastRefreshedAt`: 페이지 편집 시간과 분리된 소스 새로 고침 타임스탬프
|
||||
- `aliases`: 같은 페이지로 확인되어야 하는 이름, 핸들 또는 레이블
|
||||
- `privacyTier`: `public`, `local-private`, `sensitive`, 또는 `confirm-before-use`
|
||||
- `bestUsedFor` / `notEnoughFor`: 간결한 라우팅 힌트
|
||||
- `lastRefreshedAt`: 페이지 편집 시간과 별개인 소스 새로고침 타임스탬프
|
||||
- `personCard`: 핸들, 소셜,
|
||||
이메일, 시간대, 레인, 요청 대상, 요청을 피할 대상, 신뢰도, 개인정보 등급을 포함하는 선택적 인물별 라우팅 카드
|
||||
이메일, 시간대, 레인, 요청 대상, 요청을 피할 대상, 신뢰도, 개인정보 등급을 포함하는 선택적 사람별 라우팅 카드
|
||||
- `relationships`: 대상, 종류, 가중치,
|
||||
신뢰도, 증거 종류, 개인정보 등급, 노트가 포함된 관련 페이지로의 형식화된 엣지
|
||||
신뢰도, 증거 종류, 개인정보 등급, 노트가 포함된 관련 페이지로의 유형화된 엣지
|
||||
|
||||
인물 위키의 경우 에이전트는 일반적으로
|
||||
`reports/person-agent-directory.md`에서 시작한 다음, 연락처 세부 정보나 추론된 사실을 사용하기 전에
|
||||
`wiki_get`으로 해당 인물 페이지를 열어야 합니다.
|
||||
사람 위키의 경우, 에이전트는 일반적으로
|
||||
`reports/person-agent-directory.md`에서 시작한 다음 연락처 세부 정보나 추론된 사실을 사용하기 전에 `wiki_get`으로 사람 페이지를 열어야 합니다.
|
||||
|
||||
예:
|
||||
|
||||
@ -238,8 +239,8 @@ claims:
|
||||
|
||||
## 컴파일 파이프라인
|
||||
|
||||
컴파일 단계는 위키 페이지를 읽고, 요약을 정규화하며, 안정적인
|
||||
기계 대상 아티팩트를 다음 위치에 생성합니다.
|
||||
컴파일 단계는 위키 페이지를 읽고, 요약을 정규화하며, 다음 위치 아래에 안정적인
|
||||
기계 대상 아티팩트를 내보냅니다.
|
||||
|
||||
- `.openclaw-wiki/cache/agent-digest.json`
|
||||
- `.openclaw-wiki/cache/claims.jsonl`
|
||||
@ -249,14 +250,15 @@ claims:
|
||||
|
||||
컴파일된 출력은 다음에도 사용됩니다.
|
||||
|
||||
- 검색/가져오기 흐름을 위한 1차 위키 색인화
|
||||
- 주장 ID에서 소유 페이지로의 역조회
|
||||
- 압축된 프롬프트 보충 자료
|
||||
- 검색/가져오기 흐름을 위한 1차 위키 색인
|
||||
- claim-id에서 소유 페이지로의 조회
|
||||
- 간결한 프롬프트 보충 자료
|
||||
- 보고서/대시보드 생성
|
||||
|
||||
## 대시보드와 상태 보고서
|
||||
|
||||
`render.createDashboards`가 활성화되면 컴파일은 `reports/` 아래의 대시보드를 유지 관리합니다.
|
||||
`render.createDashboards`가 활성화되면 컴파일이
|
||||
`reports/` 아래의 대시보드를 유지합니다.
|
||||
|
||||
기본 제공 보고서는 다음과 같습니다.
|
||||
|
||||
@ -273,15 +275,15 @@ claims:
|
||||
이 보고서는 다음과 같은 항목을 추적합니다.
|
||||
|
||||
- 모순 노트 클러스터
|
||||
- 경쟁 주장 클러스터
|
||||
- 구조화된 증거가 없는 주장
|
||||
- 낮은 신뢰도의 페이지와 주장
|
||||
- 경쟁하는 주장 클러스터
|
||||
- 구조화된 증거가 누락된 주장
|
||||
- 신뢰도가 낮은 페이지와 주장
|
||||
- 오래되었거나 알 수 없는 최신성
|
||||
- 미해결 질문이 있는 페이지
|
||||
- 인물/엔티티 라우팅 카드
|
||||
- 해결되지 않은 질문이 있는 페이지
|
||||
- 사람/엔터티 라우팅 카드
|
||||
- 구조화된 관계 엣지
|
||||
- 증거 클래스 커버리지
|
||||
- 사용 전 검토가 필요한 비공개 개인정보 등급
|
||||
- 증거 클래스 범위
|
||||
- 사용 전에 검토가 필요한 비공개 개인정보 등급
|
||||
|
||||
## 검색과 조회
|
||||
|
||||
@ -290,7 +292,7 @@ claims:
|
||||
- `shared`: 사용 가능한 경우 공유 메모리 검색 흐름 사용
|
||||
- `local`: 위키를 로컬에서 검색
|
||||
|
||||
세 가지 말뭉치도 지원합니다.
|
||||
또한 세 가지 코퍼스를 지원합니다.
|
||||
|
||||
- `wiki`
|
||||
- `memory`
|
||||
@ -299,33 +301,33 @@ claims:
|
||||
중요한 동작:
|
||||
|
||||
- `wiki_search`와 `wiki_get`은 가능한 경우 컴파일된 다이제스트를 1차 패스로 사용합니다
|
||||
- 주장 ID는 소유 페이지로 역해석될 수 있습니다
|
||||
- 논쟁 중/오래됨/최신 주장이 순위 지정에 영향을 줍니다
|
||||
- 출처 레이블은 결과에 유지될 수 있습니다
|
||||
- 검색 모드는 인물 조회, 질문 라우팅, 소스
|
||||
증거, 원시 주장에 대해 순위 지정 편향을 줄 수 있습니다
|
||||
- claim id는 소유 페이지로 다시 확인될 수 있습니다
|
||||
- 이의 제기된/오래된/최신 주장이 랭킹에 영향을 줍니다
|
||||
- 출처 레이블이 결과에 유지될 수 있습니다
|
||||
- 검색 모드는 사람 조회, 질문 라우팅, 소스
|
||||
증거 또는 원시 주장에 대해 랭킹을 편향할 수 있습니다
|
||||
|
||||
실용적인 규칙:
|
||||
|
||||
- 하나의 넓은 회상 패스에는 `memory_search corpus=all`을 사용하세요
|
||||
- 위키 특화 순위 지정,
|
||||
출처, 페이지 수준 신념 구조가 중요할 때는 `wiki_search` + `wiki_get`을 사용하세요
|
||||
- 하나의 광범위한 회상 패스에는 `memory_search corpus=all`을 사용하세요
|
||||
- 위키 전용 랭킹,
|
||||
출처 또는 페이지 수준의 믿음 구조가 중요할 때는 `wiki_search` + `wiki_get`을 사용하세요
|
||||
|
||||
검색 모드:
|
||||
|
||||
- `auto`: 균형 잡힌 기본값
|
||||
- `find-person`: 인물형 엔티티, 별칭, 핸들, 소셜,
|
||||
정식 ID를 강화합니다
|
||||
- `find-person`: 사람 같은 엔터티, 별칭, 핸들, 소셜,
|
||||
표준 ID를 강화합니다
|
||||
- `route-question`: 에이전트 카드, 요청 대상 힌트, 가장 적합한 용도 힌트,
|
||||
관계 컨텍스트를 강화합니다
|
||||
- `source-evidence`: 소스 페이지와 구조화된 증거 메타데이터를 강화합니다
|
||||
- `raw-claim`: 일치하는 구조화된 주장을 강화하고 결과에 주장/증거
|
||||
메타데이터를 반환합니다
|
||||
|
||||
결과가 구조화된 주장과 일치하면, `wiki_search`는
|
||||
세부 페이로드에서 `matchedClaimId`, `matchedClaimStatus`, `matchedClaimConfidence`,
|
||||
`evidenceKinds`, `evidenceSourceIds`를 반환할 수 있습니다. 텍스트 출력에는
|
||||
사용 가능한 경우 압축된 `Claim:` 및 `Evidence:` 줄도 포함됩니다.
|
||||
결과가 구조화된 주장과 일치하면 `wiki_search`는
|
||||
세부 정보 페이로드에 `matchedClaimId`, `matchedClaimStatus`, `matchedClaimConfidence`,
|
||||
`evidenceKinds`, `evidenceSourceIds`를 반환할 수 있습니다. 텍스트 출력도
|
||||
사용 가능한 경우 간결한 `Claim:` 및 `Evidence:` 줄을 포함합니다.
|
||||
|
||||
## 에이전트 도구
|
||||
|
||||
@ -340,35 +342,36 @@ Plugin은 다음 도구를 등록합니다.
|
||||
각 도구의 역할:
|
||||
|
||||
- `wiki_status`: 현재 저장소 모드, 상태, Obsidian CLI 사용 가능 여부
|
||||
- `wiki_search`: 위키 페이지와, 구성된 경우, 공유 메모리 말뭉치를 검색합니다.
|
||||
인물 조회, 질문 라우팅, 소스 증거, 원시
|
||||
주장 심층 조회를 위한 `mode`를 받습니다
|
||||
- `wiki_get`: id/path로 위키 페이지를 읽거나 공유 메모리 말뭉치로 폴백합니다
|
||||
- `wiki_apply`: 자유 형식 페이지 수술 없이 제한된 종합/메타데이터 변경을 수행합니다
|
||||
- `wiki_search`: 위키 페이지와, 구성된 경우 공유 메모리 코퍼스를 검색합니다.
|
||||
사람 조회, 질문 라우팅, 소스 증거 또는 원시
|
||||
주장 드릴다운을 위한 `mode`를 받습니다
|
||||
- `wiki_get`: id/path로 위키 페이지를 읽거나 공유 메모리 코퍼스로 폴백합니다
|
||||
- `wiki_apply`: 자유 형식 페이지 수술 없이 좁은 범위의 합성/메타데이터 변경
|
||||
- `wiki_lint`: 구조 검사, 출처 공백, 모순, 열린 질문
|
||||
|
||||
Plugin은 비독점 메모리 말뭉치 보충 자료도 등록하므로, Active Memory
|
||||
Plugin이 말뭉치 선택을 지원할 때 공유 `memory_search`와 `memory_get`이 위키에 접근할 수 있습니다.
|
||||
Plugin은 비독점 메모리 코퍼스 보충 자료도 등록하므로, Active Memory
|
||||
Plugin이 코퍼스 선택을 지원할 때 공유
|
||||
`memory_search`와 `memory_get`이 위키에 접근할 수 있습니다.
|
||||
|
||||
## 프롬프트와 컨텍스트 동작
|
||||
|
||||
`context.includeCompiledDigestPrompt`가 활성화되면 메모리 프롬프트 섹션은
|
||||
`agent-digest.json`의 압축된 컴파일 스냅샷을 덧붙입니다.
|
||||
`context.includeCompiledDigestPrompt`가 활성화되면, 메모리 프롬프트 섹션은
|
||||
`agent-digest.json`에서 가져온 간결한 컴파일된 스냅샷을 덧붙입니다.
|
||||
|
||||
이 스냅샷은 의도적으로 작고 신호가 높습니다.
|
||||
해당 스냅샷은 의도적으로 작고 신호가 높습니다.
|
||||
|
||||
- 최상위 페이지만
|
||||
- 최상위 주장만
|
||||
- 상위 페이지만
|
||||
- 상위 주장만
|
||||
- 모순 수
|
||||
- 질문 수
|
||||
- 신뢰도/최신성 한정자
|
||||
|
||||
이는 프롬프트 형상을 변경하며, 메모리 보충 자료를 명시적으로 소비하는 컨텍스트
|
||||
엔진이나 레거시 프롬프트 조립에 주로 유용하므로 옵트인입니다.
|
||||
이는 프롬프트 형태를 바꾸며, 주로 메모리 보충 자료를 명시적으로 소비하는 컨텍스트
|
||||
엔진이나 레거시 프롬프트 조립에 유용하기 때문에 선택 사항입니다.
|
||||
|
||||
## 구성
|
||||
|
||||
`plugins.entries.memory-wiki.config` 아래에 구성을 넣으세요:
|
||||
구성은 `plugins.entries.memory-wiki.config` 아래에 넣으세요:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -425,21 +428,24 @@ Plugin이 말뭉치 선택을 지원할 때 공유 `memory_search`와 `memory_ge
|
||||
- `vaultMode`: `isolated`, `bridge`, `unsafe-local`
|
||||
- `vault.renderMode`: `native` 또는 `obsidian`
|
||||
- `bridge.readMemoryArtifacts`: Active Memory Plugin 공개 아티팩트 가져오기
|
||||
- `bridge.followMemoryEvents`: 브리지 모드에서 이벤트 로그 포함
|
||||
- `bridge.followMemoryEvents`: 브리지 모드에 이벤트 로그 포함
|
||||
- `search.backend`: `shared` 또는 `local`
|
||||
- `search.corpus`: `wiki`, `memory`, 또는 `all`
|
||||
- `search.corpus`: `wiki`, `memory` 또는 `all`
|
||||
- `context.includeCompiledDigestPrompt`: 메모리 프롬프트 섹션에 압축된 다이제스트 스냅샷 추가
|
||||
- `render.createBacklinks`: 결정론적 관련 블록 생성
|
||||
- `render.createBacklinks`: 결정적 관련 블록 생성
|
||||
- `render.createDashboards`: 대시보드 페이지 생성
|
||||
|
||||
### 예: QMD + 브리지 모드
|
||||
### 예시: QMD + 브리지 모드
|
||||
|
||||
회상을 위해 QMD를 사용하고 유지 관리되는 지식 레이어로 `memory-wiki`를 사용하려는 경우 사용하세요:
|
||||
회상을 위해 QMD를 사용하고 유지 관리되는 지식 계층을 위해 `memory-wiki`를 사용하려면 이것을 사용하세요.
|
||||
|
||||
```json5
|
||||
{
|
||||
memory: {
|
||||
backend: "qmd",
|
||||
},
|
||||
plugins: {
|
||||
entries: {
|
||||
"memory-wiki": {
|
||||
enabled: true,
|
||||
config: {
|
||||
@ -466,15 +472,15 @@ Plugin이 말뭉치 선택을 지원할 때 공유 `memory_search`와 `memory_ge
|
||||
}
|
||||
```
|
||||
|
||||
이렇게 하면 다음이 유지됩니다:
|
||||
이렇게 하면 다음이 유지됩니다.
|
||||
|
||||
- QMD가 Active Memory 회상을 담당
|
||||
- Active Memory 회상은 QMD가 담당
|
||||
- `memory-wiki`는 컴파일된 페이지와 대시보드에 집중
|
||||
- 컴파일된 다이제스트 프롬프트를 의도적으로 활성화하기 전까지 프롬프트 형태는 변경되지 않음
|
||||
- 컴파일된 다이제스트 프롬프트를 의도적으로 활성화할 때까지 프롬프트 형태는 변경되지 않음
|
||||
|
||||
## CLI
|
||||
|
||||
`memory-wiki`는 최상위 CLI 표면도 제공합니다:
|
||||
`memory-wiki`는 최상위 CLI 표면도 노출합니다.
|
||||
|
||||
```bash
|
||||
openclaw wiki status
|
||||
@ -494,27 +500,27 @@ openclaw wiki obsidian status
|
||||
|
||||
## Obsidian 지원
|
||||
|
||||
`vault.renderMode`가 `obsidian`이면 Plugin은 Obsidian 친화적인 Markdown을 작성하고 선택적으로 공식 `obsidian` CLI를 사용할 수 있습니다.
|
||||
`vault.renderMode`가 `obsidian`이면 Plugin은 Obsidian 친화적인 Markdown을 작성하고, 선택적으로 공식 `obsidian` CLI를 사용할 수 있습니다.
|
||||
|
||||
지원되는 워크플로에는 다음이 포함됩니다:
|
||||
지원되는 워크플로는 다음과 같습니다.
|
||||
|
||||
- 상태 확인
|
||||
- 상태 조사
|
||||
- vault 검색
|
||||
- 페이지 열기
|
||||
- Obsidian 명령 호출
|
||||
- 일일 노트로 이동
|
||||
- 데일리 노트로 이동
|
||||
|
||||
이는 선택 사항입니다. 위키는 Obsidian 없이도 네이티브 모드에서 계속 작동합니다.
|
||||
이는 선택 사항입니다. 위키는 Obsidian 없이 네이티브 모드에서도 계속 작동합니다.
|
||||
|
||||
## 권장 워크플로
|
||||
|
||||
1. 회상/승격/Dreaming을 위해 Active Memory Plugin을 유지하세요.
|
||||
1. 회상/승격/Dreaming에는 Active Memory Plugin을 유지하세요.
|
||||
2. `memory-wiki`를 활성화하세요.
|
||||
3. 브리지 모드를 명시적으로 원하지 않는 한 `isolated` 모드로 시작하세요.
|
||||
4. 출처가 중요할 때 `wiki_search` / `wiki_get`을 사용하세요.
|
||||
4. 출처가 중요할 때는 `wiki_search` / `wiki_get`을 사용하세요.
|
||||
5. 좁은 범위의 종합 또는 메타데이터 업데이트에는 `wiki_apply`를 사용하세요.
|
||||
6. 의미 있는 변경 후에는 `wiki_lint`를 실행하세요.
|
||||
7. 오래된 항목/모순 가시성이 필요하면 대시보드를 켜세요.
|
||||
7. 오래된 내용/모순 가시성이 필요하면 대시보드를 켜세요.
|
||||
|
||||
## 관련 문서
|
||||
|
||||
|
||||
@ -1,21 +1,21 @@
|
||||
---
|
||||
read_when:
|
||||
- 여러 대규모 언어 모델에 사용할 단일 API 키가 필요합니다
|
||||
- 여러 LLM에 사용할 단일 API 키가 필요합니다
|
||||
- OpenClaw에서 OpenRouter를 통해 모델을 실행하려는 경우
|
||||
- 이미지 생성을 위해 OpenRouter를 사용하려고 합니다
|
||||
- 동영상 생성을 위해 OpenRouter를 사용하려고 합니다
|
||||
summary: OpenClaw에서 여러 모델에 액세스하려면 OpenRouter의 통합 API를 사용하세요
|
||||
- 이미지 생성에 OpenRouter를 사용하려는 경우
|
||||
- 동영상 생성에 OpenRouter를 사용하려는 경우
|
||||
summary: OpenRouter의 통합 API를 사용해 OpenClaw에서 여러 모델에 액세스하세요
|
||||
title: OpenRouter
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T21:12:10Z"
|
||||
generated_at: "2026-05-04T02:25:01Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: e98b8b540265b6d11681390c02cb68312f33625bf223823a2dbca17e877c0422
|
||||
source_hash: f6b7299408aa0de7530e2248c7fa5dae8c09095e2d20a0e9d12a64cab83966fc
|
||||
source_path: providers/openrouter.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
OpenRouter는 단일 엔드포인트와 API 키 뒤에서 여러 모델로 요청을 라우팅하는 **통합 API**를 제공합니다. OpenAI 호환 방식이므로, 대부분의 OpenAI SDK는 기본 URL만 바꾸면 작동합니다.
|
||||
OpenRouter는 단일 엔드포인트와 API 키 뒤에서 여러 모델로 요청을 라우팅하는 **통합 API**를 제공합니다. OpenAI와 호환되므로 대부분의 OpenAI SDK는 기본 URL만 전환하면 작동합니다.
|
||||
|
||||
## 시작하기
|
||||
|
||||
@ -57,7 +57,7 @@ OpenRouter는 단일 엔드포인트와 API 키 뒤에서 여러 모델로 요
|
||||
모델 참조는 `openrouter/<provider>/<model>` 패턴을 따릅니다. 사용 가능한 제공자와 모델의 전체 목록은 [/concepts/model-providers](/ko/concepts/model-providers)를 참조하세요.
|
||||
</Note>
|
||||
|
||||
번들된 대체 예시:
|
||||
번들된 폴백 예시:
|
||||
|
||||
| 모델 참조 | 참고 |
|
||||
| --------------------------------- | ---------------------------- |
|
||||
@ -66,7 +66,7 @@ OpenRouter는 단일 엔드포인트와 API 키 뒤에서 여러 모델로 요
|
||||
|
||||
## 이미지 생성
|
||||
|
||||
OpenRouter는 `image_generate` 도구의 백엔드로도 사용할 수 있습니다. `agents.defaults.imageGenerationModel` 아래에 OpenRouter 이미지 모델을 사용하세요.
|
||||
OpenRouter는 `image_generate` 도구의 백엔드로도 사용할 수 있습니다. `agents.defaults.imageGenerationModel` 아래에서 OpenRouter 이미지 모델을 사용하세요.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -82,11 +82,11 @@ OpenRouter는 `image_generate` 도구의 백엔드로도 사용할 수 있습니
|
||||
}
|
||||
```
|
||||
|
||||
OpenClaw는 이미지 요청을 `modalities: ["image", "text"]`와 함께 OpenRouter의 채팅 완성 이미지 API로 보냅니다. Gemini 이미지 모델은 지원되는 `aspectRatio` 및 `resolution` 힌트를 OpenRouter의 `image_config`를 통해 받습니다. 더 느린 OpenRouter 이미지 모델에는 `agents.defaults.imageGenerationModel.timeoutMs`를 사용하세요. `image_generate` 도구의 호출별 `timeoutMs` 매개변수는 여전히 우선합니다.
|
||||
OpenClaw는 `modalities: ["image", "text"]`를 사용하여 OpenRouter의 채팅 완성 이미지 API로 이미지 요청을 보냅니다. Gemini 이미지 모델은 OpenRouter의 `image_config`를 통해 지원되는 `aspectRatio` 및 `resolution` 힌트를 받습니다. 더 느린 OpenRouter 이미지 모델에는 `agents.defaults.imageGenerationModel.timeoutMs`를 사용하세요. `image_generate` 도구의 호출별 `timeoutMs` 매개변수가 여전히 우선합니다.
|
||||
|
||||
## 동영상 생성
|
||||
|
||||
OpenRouter는 비동기 `/videos` API를 통해 `video_generate` 도구의 백엔드로도 사용할 수 있습니다. `agents.defaults.videoGenerationModel` 아래에 OpenRouter 동영상 모델을 사용하세요.
|
||||
OpenRouter는 비동기 `/videos` API를 통해 `video_generate` 도구의 백엔드로도 사용할 수 있습니다. `agents.defaults.videoGenerationModel` 아래에서 OpenRouter 동영상 모델을 사용하세요.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -101,7 +101,7 @@ OpenRouter는 비동기 `/videos` API를 통해 `video_generate` 도구의 백
|
||||
}
|
||||
```
|
||||
|
||||
OpenClaw는 텍스트-동영상 및 이미지-동영상 작업을 OpenRouter에 제출하고, 반환된 `polling_url`을 폴링한 뒤 완료된 동영상을 OpenRouter의 `unsigned_urls` 또는 문서화된 작업 콘텐츠 엔드포인트에서 다운로드합니다. 참조 이미지는 기본적으로 첫 번째/마지막 프레임 이미지로 전송되며, `reference_image` 태그가 지정된 이미지는 OpenRouter 입력 참조로 전송됩니다. 번들된 `google/veo-3.1-fast` 기본값은 현재 지원되는 4/6/8초 길이, `720P`/`1080P` 해상도, `16:9`/`9:16` 종횡비를 알립니다. 업스트림 동영상 생성 API가 현재 텍스트와 이미지 참조를 허용하기 때문에 동영상-동영상은 OpenRouter에 등록되어 있지 않습니다.
|
||||
OpenClaw는 텍스트-동영상 및 이미지-동영상 작업을 OpenRouter에 제출하고, 반환된 `polling_url`을 폴링하며, 완료된 동영상을 OpenRouter의 `unsigned_urls` 또는 문서화된 작업 콘텐츠 엔드포인트에서 다운로드합니다. 참조 이미지는 기본적으로 첫 프레임/마지막 프레임 이미지로 전송됩니다. `reference_image` 태그가 지정된 이미지는 OpenRouter 입력 참조로 전송됩니다. 번들된 `google/veo-3.1-fast` 기본값은 현재 지원되는 4/6/8초 길이, `720P`/`1080P` 해상도, `16:9`/`9:16` 종횡비를 알립니다. 업스트림 동영상 생성 API가 현재 텍스트와 이미지 참조를 허용하므로 동영상-동영상은 OpenRouter에 등록되지 않습니다.
|
||||
|
||||
## 텍스트 음성 변환
|
||||
|
||||
@ -131,47 +131,73 @@ OpenRouter는 OpenAI 호환 `/audio/speech` 엔드포인트를 통해 TTS 제공
|
||||
|
||||
OpenRouter는 내부적으로 API 키와 함께 Bearer 토큰을 사용합니다.
|
||||
|
||||
실제 OpenRouter 요청(`https://openrouter.ai/api/v1`)에서는 OpenClaw가 OpenRouter의 문서화된 앱 귀속 헤더도 추가합니다.
|
||||
실제 OpenRouter 요청(`https://openrouter.ai/api/v1`)에서 OpenClaw는 OpenRouter의 문서화된 앱 기여도 헤더도 추가합니다.
|
||||
|
||||
| 헤더 | 값 |
|
||||
| ------------------------- | --------------------- |
|
||||
| `HTTP-Referer` | `https://openclaw.ai` |
|
||||
| `X-OpenRouter-Title` | `OpenClaw` |
|
||||
| `X-OpenRouter-Categories` | `cli-agent` |
|
||||
| 헤더 | 값 |
|
||||
| ------------------------- | ------------------------------------------------------------------------------------------------------ |
|
||||
| `HTTP-Referer` | `https://openclaw.ai` |
|
||||
| `X-OpenRouter-Title` | `OpenClaw` |
|
||||
| `X-OpenRouter-Categories` | `cli-agent,cloud-agent,programming-app,creative-writing,writing-assistant,general-chat,personal-agent` |
|
||||
|
||||
<Warning>
|
||||
OpenRouter 제공자를 다른 프록시나 기본 URL로 다시 지정하면, OpenClaw는 해당 OpenRouter 전용 헤더나 Anthropic 캐시 마커를 삽입하지 **않습니다**.
|
||||
OpenRouter 제공자를 다른 프록시 또는 기본 URL로 다시 지정하면 OpenClaw는 해당 OpenRouter 전용 헤더나 Anthropic 캐시 마커를 삽입하지 **않습니다**.
|
||||
</Warning>
|
||||
|
||||
## 고급 설정
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="응답 캐싱">
|
||||
OpenRouter 응답 캐싱은 선택 사항입니다. 모델 매개변수를 사용하여 OpenRouter 모델별로 활성화하세요.
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
models: {
|
||||
"openrouter/auto": {
|
||||
params: {
|
||||
responseCache: true,
|
||||
responseCacheTtlSeconds: 300,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
OpenClaw는 `X-OpenRouter-Cache: true`를 보내고, 설정된 경우 `X-OpenRouter-Cache-TTL`을 보냅니다. `responseCacheClear: true`는 현재 요청에 대해 새로 고침을 강제하고 대체 응답을 저장합니다. Snake_case 별칭(`response_cache`, `response_cache_ttl_seconds`, `response_cache_clear`)도 허용됩니다.
|
||||
|
||||
이는 제공자 프롬프트 캐싱 및 OpenRouter의 Anthropic `cache_control` 마커와는 별개입니다. 사용자 지정 프록시 기본 URL이 아니라 검증된 `openrouter.ai` 경로에만 적용됩니다.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Anthropic 캐시 마커">
|
||||
검증된 OpenRouter 라우트에서는 Anthropic 모델 참조가 시스템/개발자 프롬프트 블록에서 더 나은 프롬프트 캐시 재사용을 위해 OpenClaw가 사용하는 OpenRouter 전용 Anthropic `cache_control` 마커를 유지합니다.
|
||||
검증된 OpenRouter 경로에서 Anthropic 모델 참조는 OpenClaw가 시스템/개발자 프롬프트 블록에서 더 나은 프롬프트 캐시 재사용을 위해 사용하는 OpenRouter 전용 Anthropic `cache_control` 마커를 유지합니다.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Anthropic 추론 프리필">
|
||||
검증된 OpenRouter 라우트에서는 추론이 활성화된 Anthropic 모델 참조가 요청이 OpenRouter에 도달하기 전에 뒤쪽의 assistant 프리필 턴을 제거하여, 추론 대화가 사용자 턴으로 끝나야 한다는 Anthropic 요구 사항과 일치시킵니다.
|
||||
검증된 OpenRouter 경로에서 추론이 활성화된 Anthropic 모델 참조는 요청이 OpenRouter에 도달하기 전에 뒤따르는 어시스턴트 프리필 턴을 제거하여, 추론 대화가 사용자 턴으로 끝나야 한다는 Anthropic의 요구 사항과 일치시킵니다.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="사고 / 추론 삽입">
|
||||
지원되는 비-`auto` 라우트에서는 OpenClaw가 선택된 사고 수준을 OpenRouter 프록시 추론 페이로드로 매핑합니다. 지원되지 않는 모델 힌트와 `openrouter/auto`는 해당 추론 삽입을 건너뜁니다. Hunter Alpha도 오래된 설정 모델 참조에 대해 프록시 추론을 건너뜁니다. OpenRouter가 해당 폐기된 라우트의 추론 필드에 최종 답변 텍스트를 반환할 수 있기 때문입니다.
|
||||
지원되는 비-`auto` 경로에서 OpenClaw는 선택한 사고 수준을 OpenRouter 프록시 추론 페이로드에 매핑합니다. 지원되지 않는 모델 힌트와 `openrouter/auto`는 해당 추론 삽입을 건너뜁니다. Hunter Alpha도 오래된 설정 모델 참조에 대해서는 프록시 추론을 건너뜁니다. OpenRouter가 해당 은퇴한 경로의 추론 필드에 최종 답변 텍스트를 반환할 수 있기 때문입니다.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="DeepSeek V4 추론 재생">
|
||||
검증된 OpenRouter 라우트에서는 `openrouter/deepseek/deepseek-v4-flash` 및 `openrouter/deepseek/deepseek-v4-pro`가 재생된 assistant 턴에서 누락된 `reasoning_content`를 채워 사고/도구 대화가 DeepSeek V4의 필수 후속 형태를 유지하도록 합니다.
|
||||
검증된 OpenRouter 경로에서 `openrouter/deepseek/deepseek-v4-flash`와 `openrouter/deepseek/deepseek-v4-pro`는 재생된 어시스턴트 턴에서 누락된 `reasoning_content`를 채워 사고/도구 대화가 DeepSeek V4의 필수 후속 형태를 유지하도록 합니다.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="OpenAI 전용 요청 구성">
|
||||
OpenRouter는 여전히 프록시 스타일의 OpenAI 호환 경로를 거치므로, `serviceTier`, Responses `store`, OpenAI 추론 호환 페이로드, 프롬프트 캐시 힌트 같은 네이티브 OpenAI 전용 요청 구성은 전달되지 않습니다.
|
||||
OpenRouter는 여전히 프록시 스타일의 OpenAI 호환 경로를 거치므로 `serviceTier`, Responses `store`, OpenAI 추론 호환 페이로드, 프롬프트 캐시 힌트와 같은 네이티브 OpenAI 전용 요청 구성은 전달되지 않습니다.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Gemini 기반 라우트">
|
||||
Gemini 기반 OpenRouter 참조는 프록시-Gemini 경로에 남습니다. OpenClaw는 거기에서 Gemini 사고 서명 정리를 유지하지만, 네이티브 Gemini 재생 검증이나 부트스트랩 재작성은 활성화하지 않습니다.
|
||||
<Accordion title="Gemini 기반 경로">
|
||||
Gemini 기반 OpenRouter 참조는 프록시-Gemini 경로에 유지됩니다. OpenClaw는 그곳에서 Gemini 사고 서명 정리를 유지하지만, 네이티브 Gemini 재생 검증이나 부트스트랩 재작성은 활성화하지 않습니다.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="제공자 라우팅 메타데이터">
|
||||
모델 매개변수 아래에 OpenRouter 제공자 라우팅을 전달하면, OpenClaw는 공유 스트림 래퍼가 실행되기 전에 이를 OpenRouter 라우팅 메타데이터로 전달합니다.
|
||||
모델 매개변수 아래에 OpenRouter 제공자 라우팅을 전달하면 OpenClaw는 공유 스트림 래퍼가 실행되기 전에 이를 OpenRouter 라우팅 메타데이터로 전달합니다.
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
@ -182,6 +208,6 @@ OpenRouter 제공자를 다른 프록시나 기본 URL로 다시 지정하면, O
|
||||
제공자, 모델 참조, 장애 조치 동작 선택.
|
||||
</Card>
|
||||
<Card title="설정 참조" href="/ko/gateway/configuration-reference" icon="gear">
|
||||
에이전트, 모델, 제공자에 대한 전체 설정 참조.
|
||||
에이전트, 모델, 제공자의 전체 설정 참조.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@ -2,39 +2,39 @@
|
||||
read_when:
|
||||
- SSRF 및 DNS 리바인딩 공격에 대한 심층 방어가 필요합니다
|
||||
- OpenClaw 런타임 트래픽을 위한 외부 포워드 프록시 구성
|
||||
summary: OpenClaw 런타임 HTTP 및 WebSocket 트래픽을 운영자 관리 필터링 프록시를 통해 라우팅하는 방법
|
||||
summary: 운영자가 관리하는 필터링 프록시를 통해 OpenClaw 런타임 HTTP 및 WebSocket 트래픽을 라우팅하는 방법
|
||||
title: 네트워크 프록시
|
||||
x-i18n:
|
||||
generated_at: "2026-05-01T06:27:11Z"
|
||||
generated_at: "2026-05-04T02:25:18Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 9207d349e4410e38631ae7665be19b536e4a4128a4e80dd095e802804dfd66a3
|
||||
source_hash: cd5594324e8c6b7da51d903e98fda0feacb8970e0b15d980f7a249d6641461c9
|
||||
source_path: security/network-proxy.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
# 네트워크 프록시
|
||||
|
||||
OpenClaw는 런타임 HTTP 및 WebSocket 트래픽을 운영자가 관리하는 포워드 프록시를 통해 라우팅할 수 있습니다. 이는 중앙 집중식 송신 제어, 더 강력한 SSRF 보호, 더 나은 네트워크 감사 가능성을 원하는 배포를 위한 선택적 심층 방어입니다.
|
||||
OpenClaw는 런타임 HTTP 및 WebSocket 트래픽을 운영자가 관리하는 포워드 프록시를 통해 라우팅할 수 있습니다. 이는 중앙 집중식 이그레스 제어, 더 강력한 SSRF 보호, 더 나은 네트워크 감사 가능성을 원하는 배포를 위한 선택적 심층 방어입니다.
|
||||
|
||||
OpenClaw는 프록시를 제공하거나, 다운로드하거나, 시작하거나, 구성하거나, 인증하지 않습니다. 환경에 맞는 프록시 기술을 직접 실행하면, OpenClaw는 일반적인 프로세스 로컬 HTTP 및 WebSocket 클라이언트를 해당 프록시를 통해 라우팅합니다.
|
||||
OpenClaw는 프록시를 제공하거나, 다운로드하거나, 시작하거나, 구성하거나, 인증하지 않습니다. 사용자의 환경에 맞는 프록시 기술을 직접 실행하면, OpenClaw는 일반적인 프로세스 로컬 HTTP 및 WebSocket 클라이언트를 그 프록시를 통해 라우팅합니다.
|
||||
|
||||
## 프록시를 사용하는 이유
|
||||
## 왜 프록시를 사용하나요?
|
||||
|
||||
프록시는 운영자에게 송신 HTTP 및 WebSocket 트래픽을 위한 단일 네트워크 제어 지점을 제공합니다. 이는 SSRF 강화 외에도 유용할 수 있습니다.
|
||||
프록시는 운영자에게 아웃바운드 HTTP 및 WebSocket 트래픽에 대한 단일 네트워크 제어 지점을 제공합니다. 이는 SSRF 강화 이외의 상황에서도 유용할 수 있습니다.
|
||||
|
||||
- 중앙 정책: 모든 애플리케이션 HTTP 호출 지점이 네트워크 규칙을 올바르게 적용하도록 의존하는 대신 하나의 송신 정책을 유지합니다.
|
||||
- 연결 시점 검사: DNS 해석 후, 프록시가 업스트림 연결을 열기 직전에 대상을 평가합니다.
|
||||
- DNS 리바인딩 방어: 애플리케이션 수준 DNS 검사와 실제 송신 연결 사이의 간격을 줄입니다.
|
||||
- 더 넓은 JavaScript 적용 범위: 일반 `fetch`, `node:http`, `node:https`, WebSocket, axios, got, node-fetch 및 유사한 클라이언트를 동일한 경로로 라우팅합니다.
|
||||
- 감사 가능성: 송신 경계에서 허용 및 거부된 대상을 기록합니다.
|
||||
- 운영 제어: OpenClaw를 다시 빌드하지 않고 대상 규칙, 네트워크 세분화, 속도 제한 또는 송신 허용 목록을 적용합니다.
|
||||
- 중앙 정책: 모든 애플리케이션 HTTP 호출 지점이 네트워크 규칙을 올바르게 처리하도록 의존하는 대신 하나의 이그레스 정책을 유지합니다.
|
||||
- 연결 시점 검사: DNS 확인 후, 프록시가 업스트림 연결을 열기 직전에 대상을 평가합니다.
|
||||
- DNS 리바인딩 방어: 애플리케이션 수준 DNS 검사와 실제 아웃바운드 연결 사이의 간격을 줄입니다.
|
||||
- 더 넓은 JavaScript 적용 범위: 일반적인 `fetch`, `node:http`, `node:https`, WebSocket, axios, got, node-fetch 및 유사 클라이언트를 같은 경로로 라우팅합니다.
|
||||
- 감사 가능성: 이그레스 경계에서 허용 및 거부된 대상을 기록합니다.
|
||||
- 운영 제어: OpenClaw를 다시 빌드하지 않고 대상 규칙, 네트워크 세분화, 속도 제한 또는 아웃바운드 허용 목록을 적용합니다.
|
||||
|
||||
프록시 라우팅은 일반 HTTP 및 WebSocket 송신을 위한 프로세스 수준 가드레일입니다. 운영자가 지원되는 JavaScript HTTP 클라이언트를 자체 필터링 프록시를 통해 라우팅하는 실패 시 차단 경로를 제공하지만, OS 수준 네트워크 샌드박스는 아니며 OpenClaw가 프록시의 대상 정책을 인증하게 만들지도 않습니다.
|
||||
프록시 라우팅은 일반 HTTP 및 WebSocket 이그레스에 대한 프로세스 수준 가드레일입니다. 운영자가 지원되는 JavaScript HTTP 클라이언트를 자체 필터링 프록시를 통해 라우팅할 수 있는 실패 시 차단 경로를 제공하지만, 이는 OS 수준 네트워크 샌드박스가 아니며 OpenClaw가 프록시의 대상 정책을 인증한다는 의미도 아닙니다.
|
||||
|
||||
## OpenClaw가 트래픽을 라우팅하는 방식
|
||||
|
||||
`proxy.enabled=true`이고 프록시 URL이 구성된 경우, `openclaw gateway run`, `openclaw node run`, `openclaw agent --local` 같은 보호된 런타임 프로세스는 일반 HTTP 및 WebSocket 송신을 구성된 프록시를 통해 라우팅합니다.
|
||||
`proxy.enabled=true`이고 프록시 URL이 구성되어 있으면, `openclaw gateway run`, `openclaw node run`, `openclaw agent --local` 같은 보호된 런타임 프로세스는 일반 HTTP 및 WebSocket 이그레스를 구성된 프록시를 통해 라우팅합니다.
|
||||
|
||||
```text
|
||||
OpenClaw process
|
||||
@ -43,27 +43,27 @@ OpenClaw process
|
||||
WebSocket clients -> operator-managed filtering proxy -> public internet
|
||||
```
|
||||
|
||||
공개 계약은 이를 구현하는 데 사용되는 내부 Node 훅이 아니라 라우팅 동작입니다. OpenClaw Gateway 제어 평면 WebSocket 클라이언트는 Gateway URL이 `localhost` 또는 `127.0.0.1`이나 `[::1]` 같은 리터럴 loopback IP를 사용할 때 local loopback Gateway RPC 트래픽에 대해 좁은 직접 경로를 사용합니다. 이 제어 평면 경로는 운영자 프록시가 loopback 대상을 차단하더라도 loopback Gateway에 도달할 수 있어야 합니다. 일반 런타임 HTTP 및 WebSocket 요청은 계속 구성된 프록시를 사용합니다.
|
||||
공개 계약은 이를 구현하는 데 사용되는 내부 Node 훅이 아니라 라우팅 동작입니다. OpenClaw Gateway 제어 평면 WebSocket 클라이언트는 Gateway URL이 `localhost` 또는 `127.0.0.1`이나 `[::1]` 같은 리터럴 루프백 IP를 사용할 때 local loopback Gateway RPC 트래픽에 대해 좁은 직접 경로를 사용합니다. 이 제어 평면 경로는 운영자 프록시가 루프백 대상을 차단하더라도 루프백 Gateway에 도달할 수 있어야 합니다. 일반 런타임 HTTP 및 WebSocket 요청은 계속 구성된 프록시를 사용합니다.
|
||||
|
||||
내부적으로 OpenClaw는 이 기능을 위해 두 가지 프로세스 수준 라우팅 훅을 사용합니다.
|
||||
내부적으로 OpenClaw는 이 기능에 두 가지 프로세스 수준 라우팅 훅을 사용합니다.
|
||||
|
||||
- Undici 디스패처 라우팅은 `fetch`, undici 기반 클라이언트, 자체 undici 디스패처를 제공하는 전송을 처리합니다.
|
||||
- `global-agent` 라우팅은 `http.request`, `https.request`, `http.get`, `https.get` 위에 계층화된 많은 라이브러리를 포함해 Node 코어 `node:http` 및 `node:https` 호출자를 처리합니다. 관리형 프록시 모드는 명시적인 Node HTTP 에이전트가 실수로 운영자 프록시를 우회하지 않도록 해당 전역 에이전트를 강제합니다.
|
||||
- Undici 디스패처 라우팅은 `fetch`, undici 기반 클라이언트, 자체 undici 디스패처를 제공하는 전송 계층을 처리합니다.
|
||||
- `global-agent` 라우팅은 `http.request`, `https.request`, `http.get`, `https.get` 위에 구성된 많은 라이브러리를 포함하여 Node 코어 `node:http` 및 `node:https` 호출자를 처리합니다. 관리형 프록시 모드는 명시적 Node HTTP 에이전트가 실수로 운영자 프록시를 우회하지 않도록 해당 전역 에이전트를 강제합니다.
|
||||
|
||||
일부 plugins는 프로세스 수준 라우팅이 있더라도 명시적인 프록시 배선이 필요한 사용자 지정 전송을 소유합니다. 예를 들어 Telegram의 Bot API 전송은 자체 HTTP/1 undici 디스패처를 사용하므로 해당 소유자별 전송 경로에서 프로세스 프록시 환경과 관리형 `OPENCLAW_PROXY_URL` 대체값을 따릅니다.
|
||||
일부 Plugin은 프로세스 수준 라우팅이 존재하더라도 명시적 프록시 연결이 필요한 사용자 지정 전송 계층을 소유합니다. 예를 들어 Telegram의 Bot API 전송 계층은 자체 HTTP/1 undici 디스패처를 사용하므로, 해당 소유자별 전송 경로에서 프로세스 프록시 환경과 관리형 `OPENCLAW_PROXY_URL` 폴백을 따릅니다.
|
||||
|
||||
프록시 URL 자체는 `http://`를 사용해야 합니다. HTTPS 대상은 여전히 HTTP `CONNECT`를 통해 프록시에서 지원됩니다. 이는 OpenClaw가 `http://127.0.0.1:3128` 같은 일반 HTTP 포워드 프록시 리스너를 기대한다는 뜻일 뿐입니다.
|
||||
|
||||
프록시가 활성화되어 있는 동안 OpenClaw는 `no_proxy`, `NO_PROXY`, `GLOBAL_AGENT_NO_PROXY`를 지웁니다. 이러한 우회 목록은 대상 기반이므로, 여기에 `localhost` 또는 `127.0.0.1`을 남겨 두면 고위험 SSRF 대상이 필터링 프록시를 건너뛸 수 있습니다.
|
||||
프록시가 활성화된 동안 OpenClaw는 `no_proxy`, `NO_PROXY`, `GLOBAL_AGENT_NO_PROXY`를 지웁니다. 이러한 우회 목록은 대상 기반이므로, 거기에 `localhost` 또는 `127.0.0.1`이 남아 있으면 고위험 SSRF 대상이 필터링 프록시를 건너뛸 수 있습니다.
|
||||
|
||||
종료 시 OpenClaw는 이전 프록시 환경을 복원하고 캐시된 프로세스 라우팅 상태를 재설정합니다.
|
||||
|
||||
## 관련 프록시 용어
|
||||
|
||||
- `proxy.enabled` / `proxy.proxyUrl`: OpenClaw 런타임 송신을 위한 송신 포워드 프록시 라우팅입니다. 이 페이지는 해당 기능을 문서화합니다.
|
||||
- `gateway.auth.mode: "trusted-proxy"`: Gateway 액세스를 위한 인바운드 ID 인식 리버스 프록시 인증입니다. [신뢰할 수 있는 프록시 인증](/ko/gateway/trusted-proxy-auth)을 참조하세요.
|
||||
- `proxy.enabled` / `proxy.proxyUrl`: OpenClaw 런타임 이그레스를 위한 아웃바운드 포워드 프록시 라우팅입니다. 이 페이지는 해당 기능을 문서화합니다.
|
||||
- `gateway.auth.mode: "trusted-proxy"`: Gateway 접근을 위한 인바운드 ID 인식 리버스 프록시 인증입니다. [신뢰할 수 있는 프록시 인증](/ko/gateway/trusted-proxy-auth)을 참조하세요.
|
||||
- `openclaw proxy`: 개발 및 지원을 위한 로컬 디버그 프록시와 캡처 검사기입니다. [openclaw proxy](/ko/cli/proxy)를 참조하세요.
|
||||
- 채널 또는 제공자별 프록시 설정: 특정 전송을 위한 소유자별 재정의입니다. 목표가 런타임 전체의 중앙 송신 제어라면 관리형 네트워크 프록시를 선호하세요.
|
||||
- 채널 또는 공급자별 프록시 설정: 특정 전송 계층에 대한 소유자별 오버라이드입니다. 목표가 런타임 전반의 중앙 이그레스 제어라면 관리형 네트워크 프록시를 선호하세요.
|
||||
|
||||
## 구성
|
||||
|
||||
@ -81,9 +81,9 @@ OPENCLAW_PROXY_URL=http://127.0.0.1:3128 openclaw gateway run
|
||||
|
||||
`proxy.proxyUrl`은 `OPENCLAW_PROXY_URL`보다 우선합니다.
|
||||
|
||||
`enabled=true`이지만 유효한 프록시 URL이 구성되지 않은 경우, 보호된 명령은 직접 네트워크 액세스로 대체되는 대신 시작에 실패합니다.
|
||||
`enabled=true`이지만 유효한 프록시 URL이 구성되어 있지 않으면, 보호된 명령은 직접 네트워크 접근으로 폴백하는 대신 시작에 실패합니다.
|
||||
|
||||
`openclaw gateway start`로 시작되는 관리형 Gateway 서비스의 경우 URL을 구성에 저장하는 것을 권장합니다.
|
||||
`openclaw gateway start`로 시작되는 관리형 Gateway 서비스의 경우 URL을 구성에 저장하는 방식을 선호하세요.
|
||||
|
||||
```bash
|
||||
openclaw config set proxy.enabled true
|
||||
@ -92,9 +92,9 @@ openclaw gateway install --force
|
||||
openclaw gateway start
|
||||
```
|
||||
|
||||
환경 대체값은 포그라운드 실행에 가장 적합합니다. 설치된 서비스와 함께 사용하는 경우 `OPENCLAW_PROXY_URL`을 `$OPENCLAW_STATE_DIR/.env` 또는 `~/.openclaw/.env` 같은 서비스의 지속 환경에 넣은 다음, launchd, systemd 또는 Scheduled Tasks가 해당 값으로 Gateway를 시작하도록 서비스를 다시 설치하세요.
|
||||
환경 폴백은 포그라운드 실행에 가장 적합합니다. 설치된 서비스에서 이를 사용하는 경우, `OPENCLAW_PROXY_URL`을 `$OPENCLAW_STATE_DIR/.env` 또는 `~/.openclaw/.env` 같은 서비스의 지속 환경에 넣은 다음 서비스를 다시 설치하여 launchd, systemd 또는 Scheduled Tasks가 해당 값으로 Gateway를 시작하도록 하세요.
|
||||
|
||||
`openclaw --container ...` 명령의 경우, OpenClaw는 `OPENCLAW_PROXY_URL`이 설정되어 있으면 컨테이너 대상 하위 CLI로 이를 전달합니다. URL은 컨테이너 내부에서 도달할 수 있어야 합니다. `127.0.0.1`은 호스트가 아니라 컨테이너 자체를 가리킵니다. 명시적으로 해당 안전 검사를 재정의하지 않는 한, OpenClaw는 컨테이너 대상 명령에서 loopback 프록시 URL을 거부합니다.
|
||||
`openclaw --container ...` 명령의 경우, OpenClaw는 설정된 `OPENCLAW_PROXY_URL`을 컨테이너 대상 하위 CLI로 전달합니다. URL은 컨테이너 내부에서 도달 가능해야 합니다. `127.0.0.1`은 호스트가 아니라 컨테이너 자체를 가리킵니다. OpenClaw는 사용자가 해당 안전 검사를 명시적으로 오버라이드하지 않는 한 컨테이너 대상 명령에 대한 루프백 프록시 URL을 거부합니다.
|
||||
|
||||
## 프록시 요구 사항
|
||||
|
||||
@ -102,41 +102,41 @@ openclaw gateway start
|
||||
|
||||
프록시를 다음과 같이 구성하세요.
|
||||
|
||||
- loopback 또는 비공개 신뢰 인터페이스에만 바인딩합니다.
|
||||
- OpenClaw 프로세스, 호스트, 컨테이너 또는 서비스 계정만 사용할 수 있도록 액세스를 제한합니다.
|
||||
- 대상을 자체적으로 해석하고 DNS 해석 후 대상 IP를 차단합니다.
|
||||
- 루프백 또는 신뢰할 수 있는 비공개 인터페이스에만 바인딩합니다.
|
||||
- OpenClaw 프로세스, 호스트, 컨테이너 또는 서비스 계정만 사용할 수 있도록 접근을 제한합니다.
|
||||
- 대상을 자체적으로 확인하고 DNS 확인 후 대상 IP를 차단합니다.
|
||||
- 일반 HTTP 요청과 HTTPS `CONNECT` 터널 모두에 대해 연결 시점에 정책을 적용합니다.
|
||||
- loopback, 비공개, 링크 로컬, 메타데이터, 멀티캐스트, 예약 또는 문서화 범위에 대한 대상 기반 우회를 거부합니다.
|
||||
- DNS 해석 경로를 완전히 신뢰하지 않는 한 호스트 이름 허용 목록을 피합니다.
|
||||
- 요청 본문, 인증 헤더, 쿠키 또는 기타 비밀을 기록하지 않고 대상, 결정, 상태, 이유를 기록합니다.
|
||||
- 프록시 정책을 버전 관리에 두고 보안에 민감한 구성처럼 변경 사항을 검토합니다.
|
||||
- 루프백, 비공개, 링크 로컬, 메타데이터, 멀티캐스트, 예약 또는 문서화 범위에 대한 대상 기반 우회를 거부합니다.
|
||||
- DNS 확인 경로를 완전히 신뢰하지 않는 한 호스트 이름 허용 목록을 피합니다.
|
||||
- 요청 본문, 인증 헤더, 쿠키 또는 기타 비밀을 기록하지 않고 대상, 결정, 상태 및 이유를 기록합니다.
|
||||
- 프록시 정책을 버전 관리하에 두고 보안에 민감한 구성처럼 변경 사항을 검토합니다.
|
||||
|
||||
## 권장 차단 대상
|
||||
|
||||
모든 포워드 프록시, 방화벽 또는 송신 정책의 시작점으로 이 거부 목록을 사용하세요.
|
||||
이 거부 목록을 모든 포워드 프록시, 방화벽 또는 이그레스 정책의 시작점으로 사용하세요.
|
||||
|
||||
OpenClaw 애플리케이션 수준 분류기 로직은 `src/infra/net/ssrf.ts` 및 `src/shared/net/ip.ts`에 있습니다. 관련 패리티 훅은 `BLOCKED_HOSTNAMES`, `BLOCKED_IPV4_SPECIAL_USE_RANGES`, `BLOCKED_IPV6_SPECIAL_USE_RANGES`, `RFC2544_BENCHMARK_PREFIX`, 그리고 NAT64, 6to4, Teredo, ISATAP, IPv4 매핑 형식에 대한 내장 IPv4 센티널 처리입니다. 이러한 파일은 외부 프록시 정책을 유지 관리할 때 유용한 참조이지만, OpenClaw는 해당 규칙을 사용자의 프록시에 자동으로 내보내거나 적용하지 않습니다.
|
||||
OpenClaw 애플리케이션 수준 분류기 로직은 `src/infra/net/ssrf.ts` 및 `src/shared/net/ip.ts`에 있습니다. 관련 패리티 훅은 `BLOCKED_HOSTNAMES`, `BLOCKED_IPV4_SPECIAL_USE_RANGES`, `BLOCKED_IPV6_SPECIAL_USE_RANGES`, `RFC2544_BENCHMARK_PREFIX`, 그리고 NAT64, 6to4, Teredo, ISATAP 및 IPv4 매핑 형식에 대한 내장 IPv4 센티널 처리입니다. 이러한 파일은 외부 프록시 정책을 유지 관리할 때 유용한 참고 자료이지만, OpenClaw가 해당 규칙을 사용자의 프록시에 자동으로 내보내거나 적용하지는 않습니다.
|
||||
|
||||
| 범위 또는 호스트 | 차단 이유 |
|
||||
| 범위 또는 호스트 | 차단 이유 |
|
||||
| ------------------------------------------------------------------------------------ | ---------------------------------------------------- |
|
||||
| `127.0.0.0/8`, `localhost`, `localhost.localdomain` | IPv4 loopback |
|
||||
| `::1/128` | IPv6 loopback |
|
||||
| `127.0.0.0/8`, `localhost`, `localhost.localdomain` | IPv4 루프백 |
|
||||
| `::1/128` | IPv6 루프백 |
|
||||
| `0.0.0.0/8`, `::/128` | 지정되지 않은 주소 및 이 네트워크 주소 |
|
||||
| `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16` | RFC1918 비공개 네트워크 |
|
||||
| `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16` | RFC1918 비공개 네트워크 |
|
||||
| `169.254.0.0/16`, `fe80::/10` | 링크 로컬 주소 및 일반적인 클라우드 메타데이터 경로 |
|
||||
| `169.254.169.254`, `metadata.google.internal` | 클라우드 메타데이터 서비스 |
|
||||
| `100.64.0.0/10` | 통신사급 NAT 공유 주소 공간 |
|
||||
| `100.64.0.0/10` | 캐리어급 NAT 공유 주소 공간 |
|
||||
| `198.18.0.0/15`, `2001:2::/48` | 벤치마킹 범위 |
|
||||
| `192.0.0.0/24`, `192.0.2.0/24`, `198.51.100.0/24`, `203.0.113.0/24`, `2001:db8::/32` | 특수 용도 및 문서화 범위 |
|
||||
| `224.0.0.0/4`, `ff00::/8` | 멀티캐스트 |
|
||||
| `240.0.0.0/4` | 예약된 IPv4 |
|
||||
| `fc00::/7`, `fec0::/10` | IPv6 로컬/비공개 범위 |
|
||||
| `100::/64`, `2001:20::/28` | IPv6 폐기 및 ORCHIDv2 범위 |
|
||||
| `64:ff9b::/96`, `64:ff9b:1::/48` | 내장 IPv4가 있는 NAT64 접두사 |
|
||||
| `2002::/16`, `2001::/32` | 내장 IPv4가 있는 6to4 및 Teredo |
|
||||
| `64:ff9b::/96`, `64:ff9b:1::/48` | 내장 IPv4가 포함된 NAT64 접두사 |
|
||||
| `2002::/16`, `2001::/32` | 내장 IPv4가 포함된 6to4 및 Teredo |
|
||||
| `::/96`, `::ffff:0:0/96` | IPv4 호환 및 IPv4 매핑 IPv6 |
|
||||
|
||||
클라우드 제공자 또는 네트워크 플랫폼이 추가 메타데이터 호스트나 예약 범위를 문서화하는 경우, 그것들도 추가하세요.
|
||||
클라우드 공급자 또는 네트워크 플랫폼이 추가 메타데이터 호스트나 예약 범위를 문서화한 경우, 그것들도 추가하세요.
|
||||
|
||||
## 검증
|
||||
|
||||
@ -146,9 +146,9 @@ OpenClaw를 실행하는 동일한 호스트, 컨테이너 또는 서비스 계
|
||||
openclaw proxy validate --proxy-url http://127.0.0.1:3128
|
||||
```
|
||||
|
||||
기본적으로 사용자 지정 대상이 제공되지 않으면 명령은 `https://example.com/`이 성공하는지 확인하고, 프록시가 도달해서는 안 되는 임시 loopback 카나리아를 시작합니다. 기본 거부 검사는 프록시가 2xx가 아닌 거부 응답을 반환하거나 전송 실패로 카나리아를 차단하면 통과합니다. 성공 응답이 카나리아에 도달하면 실패합니다. 프록시가 활성화 및 구성되어 있지 않으면 검증은 구성 문제를 보고합니다. 구성을 변경하기 전 일회성 사전 점검에는 `--proxy-url`을 사용하세요. 배포별 기대치를 테스트하려면 `--allowed-url` 및 `--denied-url`을 사용하세요. 사용자 지정 거부 대상은 실패 시 차단 방식입니다. 어떤 HTTP 응답이든 대상이 프록시를 통해 도달 가능했다는 의미이며, OpenClaw가 프록시가 도달 가능한 원본을 차단했음을 증명할 수 없으므로 모든 전송 오류는 결론 불가로 보고됩니다. 검증 실패 시 명령은 코드 1로 종료됩니다.
|
||||
기본적으로 사용자 지정 대상이 제공되지 않으면, 명령은 `https://example.com/`이 성공하는지 확인하고 프록시가 도달해서는 안 되는 임시 루프백 카나리를 시작합니다. 기본 거부 검사는 프록시가 2xx가 아닌 거부 응답을 반환하거나 전송 실패로 카나리를 차단하면 통과합니다. 성공 응답이 카나리에 도달하면 실패합니다. 프록시가 활성화되고 구성되어 있지 않으면 검증은 구성 문제를 보고합니다. 구성을 변경하기 전 일회성 사전 점검에는 `--proxy-url`을 사용하세요. 배포별 기대 사항을 테스트하려면 `--allowed-url` 및 `--denied-url`을 사용하세요. 사용자 지정 거부 대상은 실패 시 차단됩니다. 어떤 HTTP 응답이든 대상이 프록시를 통해 도달 가능했다는 의미이며, 어떤 전송 오류든 OpenClaw가 프록시가 도달 가능한 원본을 차단했음을 증명할 수 없기 때문에 결론 불가로 보고됩니다. 검증 실패 시 명령은 코드 1로 종료됩니다.
|
||||
|
||||
자동화에는 `--json`을 사용하세요. JSON 출력에는 전체 결과, 유효한 프록시 구성 소스, 구성 오류, 각 대상 검사가 포함됩니다. 프록시 URL 자격 증명은 텍스트 및 JSON 출력에서 수정 처리됩니다.
|
||||
자동화에는 `--json`을 사용하세요. JSON 출력에는 전체 결과, 유효한 프록시 구성 소스, 구성 오류 및 각 대상 검사가 포함됩니다. 프록시 URL 자격 증명은 텍스트 및 JSON 출력에서 수정 처리됩니다.
|
||||
|
||||
```json
|
||||
{
|
||||
@ -170,7 +170,7 @@ openclaw proxy validate --proxy-url http://127.0.0.1:3128
|
||||
}
|
||||
```
|
||||
|
||||
`curl`로 수동 검증할 수도 있습니다:
|
||||
`curl`로 수동 검증할 수도 있습니다.
|
||||
|
||||
```bash
|
||||
curl -x http://127.0.0.1:3128 https://example.com/
|
||||
@ -178,9 +178,9 @@ curl -x http://127.0.0.1:3128 http://127.0.0.1/
|
||||
curl -x http://127.0.0.1:3128 http://169.254.169.254/
|
||||
```
|
||||
|
||||
공개 요청은 성공해야 합니다. 루프백 및 메타데이터 요청은 프록시에 의해 차단되어야 합니다. `openclaw proxy validate`의 경우 기본 제공 루프백 카나리아는 프록시 거부와 도달 가능한 원본을 구분할 수 있습니다. 사용자 지정 `--denied-url` 검사는 해당 카나리아가 없으므로, 프록시가 배포별 거부 신호를 노출하고 이를 별도로 검증할 수 있는 경우가 아니라면 HTTP 응답과 모호한 전송 실패를 모두 검증 실패로 간주하세요.
|
||||
공개 요청은 성공해야 합니다. 루프백 및 메타데이터 요청은 프록시에 의해 차단되어야 합니다. `openclaw proxy validate`의 경우, 내장 루프백 카나리아는 프록시 거부와 도달 가능한 원본을 구분할 수 있습니다. 사용자 지정 `--denied-url` 검사에는 해당 카나리아가 없으므로, 프록시가 별도로 검증할 수 있는 배포별 거부 신호를 노출하지 않는 한 HTTP 응답과 모호한 전송 실패를 모두 검증 실패로 처리하세요.
|
||||
|
||||
그런 다음 OpenClaw 프록시 라우팅을 활성화하세요:
|
||||
그런 다음 OpenClaw 프록시 라우팅을 활성화합니다.
|
||||
|
||||
```bash
|
||||
openclaw config set proxy.enabled true
|
||||
@ -188,7 +188,7 @@ openclaw config set proxy.proxyUrl http://127.0.0.1:3128
|
||||
openclaw gateway run
|
||||
```
|
||||
|
||||
또는 다음을 설정하세요:
|
||||
또는 다음을 설정합니다.
|
||||
|
||||
```yaml
|
||||
proxy:
|
||||
@ -199,8 +199,9 @@ proxy:
|
||||
## 제한 사항
|
||||
|
||||
- 프록시는 프로세스 로컬 JavaScript HTTP 및 WebSocket 클라이언트에 대한 적용 범위를 개선하지만, OS 수준 네트워크 샌드박스는 아닙니다.
|
||||
- Raw `net`, `tls`, `http2` 소켓, 네이티브 애드온, 자식 프로세스는 프록시 환경 변수를 상속하고 준수하지 않는 한 Node 수준 프록시 라우팅을 우회할 수 있습니다.
|
||||
- 사용자 로컬 WebUI와 로컬 모델 서버는 필요한 경우 운영자 프록시 정책의 허용 목록에 추가해야 합니다. OpenClaw는 이를 위한 일반적인 로컬 네트워크 우회를 노출하지 않습니다.
|
||||
- Gateway 제어 플레인 프록시 우회는 의도적으로 `localhost`와 리터럴 루프백 IP URL로 제한됩니다. 로컬 직접 Gateway 제어 플레인 연결에는 `ws://127.0.0.1:18789`, `ws://[::1]:18789` 또는 `ws://localhost:18789`를 사용하세요. 다른 호스트 이름은 일반적인 호스트 이름 기반 트래픽처럼 라우팅됩니다.
|
||||
- OpenClaw는 프록시 정책을 검사, 테스트 또는 인증하지 않습니다.
|
||||
- 원시 `net`, `tls`, `http2` 소켓, 네이티브 애드온, 자식 프로세스는 프록시 환경 변수를 상속하고 준수하지 않는 한 Node 수준 프록시 라우팅을 우회할 수 있습니다.
|
||||
- IRC는 운영자가 관리하는 전달 프록시 라우팅 외부의 원시 TCP/TLS 채널입니다. 모든 송신 트래픽이 해당 전달 프록시를 거쳐야 하는 배포에서는 직접 IRC 송신이 명시적으로 승인되지 않는 한 `channels.irc.enabled=false`를 설정하세요.
|
||||
- 사용자 로컬 WebUI와 로컬 모델 서버는 필요할 때 운영자 프록시 정책의 허용 목록에 추가해야 합니다. OpenClaw는 이를 위한 일반적인 로컬 네트워크 우회를 노출하지 않습니다.
|
||||
- Gateway 제어 평면 프록시 우회는 의도적으로 `localhost`와 리터럴 루프백 IP URL로 제한됩니다. 로컬 직접 Gateway 제어 평면 연결에는 `ws://127.0.0.1:18789`, `ws://[::1]:18789` 또는 `ws://localhost:18789`를 사용하세요. 다른 호스트 이름은 일반적인 호스트 이름 기반 트래픽처럼 라우팅됩니다.
|
||||
- OpenClaw는 프록시 정책을 검사하거나 테스트하거나 인증하지 않습니다.
|
||||
- 프록시 정책 변경은 보안에 민감한 운영 변경으로 취급하세요.
|
||||
|
||||
@ -1,27 +1,25 @@
|
||||
---
|
||||
read_when:
|
||||
- 워크플로 내부에 JSON 전용 LLM 단계를 두고 싶습니다
|
||||
- 자동화를 위해 스키마로 검증된 LLM 출력이 필요합니다
|
||||
summary: 워크플로용 JSON 전용 LLM 작업 (선택적 Plugin 도구)
|
||||
- 워크플로 내에서 JSON 전용 LLM 단계를 사용하려는 경우
|
||||
- 자동화를 위해 스키마 검증된 LLM 출력이 필요합니다
|
||||
summary: 워크플로용 JSON 전용 LLM 작업(선택적 Plugin 도구)
|
||||
title: LLM 작업
|
||||
x-i18n:
|
||||
generated_at: "2026-04-24T06:40:40Z"
|
||||
model: gpt-5.4
|
||||
generated_at: "2026-05-04T02:25:20Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 613aefd1bac5b9675821a118c11130c8bfaefb1673d0266f14ff4e91b47fed8b
|
||||
source_hash: 9cdc5d4feef17fb6d6d90d819d4c92d26a4ec43e4f5364c6acbaad1934a89269
|
||||
source_path: tools/llm-task.md
|
||||
workflow: 15
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
`llm-task`는 JSON 전용 LLM 작업을 실행하고
|
||||
구조화된 출력을 반환하는 **선택적 Plugin 도구**입니다(JSON Schema에 대한 선택적 검증 포함).
|
||||
`llm-task`는 JSON 전용 LLM 작업을 실행하고 구조화된 출력(선택적으로 JSON Schema에 대해 검증됨)을 반환하는 **선택적 Plugin 도구**입니다.
|
||||
|
||||
이 도구는 Lobster 같은 워크플로 엔진에 적합합니다. 각 워크플로마다 커스텀 OpenClaw 코드를 작성하지 않고도
|
||||
단일 LLM 단계를 추가할 수 있습니다.
|
||||
Lobster와 같은 워크플로 엔진에 적합합니다. 각 워크플로마다 사용자 지정 OpenClaw 코드를 작성하지 않고도 단일 LLM 단계를 추가할 수 있습니다.
|
||||
|
||||
## Plugin 활성화
|
||||
|
||||
1. Plugin을 활성화합니다:
|
||||
1. Plugin을 활성화합니다.
|
||||
|
||||
```json
|
||||
{
|
||||
@ -33,22 +31,19 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
2. 도구를 allowlist에 추가합니다 (`optional: true`로 등록됨):
|
||||
2. 선택적 도구를 허용합니다.
|
||||
|
||||
```json
|
||||
{
|
||||
"agents": {
|
||||
"list": [
|
||||
{
|
||||
"id": "main",
|
||||
"tools": { "allow": ["llm-task"] }
|
||||
}
|
||||
]
|
||||
"tools": {
|
||||
"alsoAllow": ["llm-task"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 구성 (선택 사항)
|
||||
제한적 허용 목록 모드를 사용하려는 경우에만 `tools.allow`를 사용하세요.
|
||||
|
||||
## 구성(선택 사항)
|
||||
|
||||
```json
|
||||
{
|
||||
@ -70,30 +65,28 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
`allowedModels`는 `provider/model` 문자열의 allowlist입니다. 설정되면
|
||||
목록 밖의 모든 요청은 거부됩니다.
|
||||
`allowedModels`는 `provider/model` 문자열의 허용 목록입니다. 설정하면 목록 밖의 모든 요청이 거부됩니다.
|
||||
|
||||
## 도구 매개변수
|
||||
|
||||
- `prompt` (string, 필수)
|
||||
- `input` (any, 선택 사항)
|
||||
- `schema` (object, 선택 사항 JSON Schema)
|
||||
- `provider` (string, 선택 사항)
|
||||
- `model` (string, 선택 사항)
|
||||
- `thinking` (string, 선택 사항)
|
||||
- `authProfileId` (string, 선택 사항)
|
||||
- `temperature` (number, 선택 사항)
|
||||
- `maxTokens` (number, 선택 사항)
|
||||
- `timeoutMs` (number, 선택 사항)
|
||||
- `prompt`(문자열, 필수)
|
||||
- `input`(모든 값, 선택 사항)
|
||||
- `schema`(객체, 선택적 JSON Schema)
|
||||
- `provider`(문자열, 선택 사항)
|
||||
- `model`(문자열, 선택 사항)
|
||||
- `thinking`(문자열, 선택 사항)
|
||||
- `authProfileId`(문자열, 선택 사항)
|
||||
- `temperature`(숫자, 선택 사항)
|
||||
- `maxTokens`(숫자, 선택 사항)
|
||||
- `timeoutMs`(숫자, 선택 사항)
|
||||
|
||||
`thinking`은 `low` 또는 `medium` 같은 표준 OpenClaw 추론 프리셋을 받습니다.
|
||||
`thinking`은 `low` 또는 `medium` 같은 표준 OpenClaw 추론 프리셋을 허용합니다.
|
||||
|
||||
## 출력
|
||||
|
||||
파싱된 JSON을 포함하는 `details.json`을 반환하며(`schema`가 제공되면
|
||||
이에 대해 검증도 수행함).
|
||||
파싱된 JSON이 포함된 `details.json`을 반환합니다(`schema`가 제공된 경우 이에 대해 검증함).
|
||||
|
||||
## 예시: Lobster 워크플로 단계
|
||||
## 예: Lobster 워크플로 단계
|
||||
|
||||
```lobster
|
||||
openclaw.invoke --tool llm-task --action json --args-json '{
|
||||
@ -117,13 +110,13 @@ openclaw.invoke --tool llm-task --action json --args-json '{
|
||||
|
||||
## 안전 참고 사항
|
||||
|
||||
- 이 도구는 **JSON 전용**이며 모델이 JSON만 출력하도록 지시합니다(코드 펜스 없음, 설명 없음).
|
||||
- 이 실행에서는 어떤 도구도 모델에 노출되지 않습니다.
|
||||
- `schema`로 검증하지 않는 한 출력은 신뢰할 수 없는 것으로 취급하세요.
|
||||
- 부작용이 있는 단계(send, post, exec) 앞에는 승인을 두세요.
|
||||
- 이 도구는 **JSON 전용**이며 모델에 JSON만 출력하도록 지시합니다(코드 펜스나 설명 없음).
|
||||
- 이 실행에서는 모델에 어떤 도구도 노출되지 않습니다.
|
||||
- `schema`로 검증하지 않는 한 출력을 신뢰할 수 없는 것으로 취급하세요.
|
||||
- 부작용이 있는 단계(전송, 게시, 실행) 앞에는 승인을 배치하세요.
|
||||
|
||||
## 관련
|
||||
## 관련 항목
|
||||
|
||||
- [추론 수준](/ko/tools/thinking)
|
||||
- [사고 수준](/ko/tools/thinking)
|
||||
- [하위 에이전트](/ko/tools/subagents)
|
||||
- [슬래시 명령](/ko/tools/slash-commands)
|
||||
|
||||
@ -5,48 +5,48 @@ read_when:
|
||||
summary: 재개 가능한 승인 게이트를 갖춘 OpenClaw용 타입 지정 워크플로 런타임.
|
||||
title: 바닷가재
|
||||
x-i18n:
|
||||
generated_at: "2026-04-30T06:54:39Z"
|
||||
generated_at: "2026-05-04T02:25:29Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 1700bcfdbcf4558cb908935834e9059221d0d26ad78ed6f9e2158f7e0b83edbd
|
||||
source_hash: 67f5145b11f2d6e07e9d78a44a389ae5f236c85ec8c287ab0f217a18b622ece0
|
||||
source_path: tools/lobster.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
Lobster는 OpenClaw가 명시적 승인 체크포인트가 있는 단일 결정적 작업으로 다단계 도구 시퀀스를 실행할 수 있게 해주는 워크플로 셸입니다.
|
||||
Lobster는 OpenClaw가 여러 단계의 도구 시퀀스를 명시적 승인 체크포인트가 있는 하나의 결정적 작업으로 실행할 수 있게 해 주는 워크플로 셸입니다.
|
||||
|
||||
Lobster는 분리된 백그라운드 작업 위에 있는 작성 계층입니다. 개별 작업 위의 흐름 오케스트레이션은 [작업 흐름](/ko/automation/taskflow)(`openclaw tasks flow`)을 참고하세요. 작업 활동 원장은 [`openclaw tasks`](/ko/automation/tasks)를 참고하세요.
|
||||
Lobster는 분리된 백그라운드 작업 위의 작성 계층입니다. 개별 작업 위의 플로 오케스트레이션은 [Task Flow](/ko/automation/taskflow)(`openclaw tasks flow`)를 참조하세요. 작업 활동 원장은 [`openclaw tasks`](/ko/automation/tasks)를 참조하세요.
|
||||
|
||||
## 훅
|
||||
|
||||
어시스턴트는 자기 자신을 관리하는 도구를 만들 수 있습니다. 워크플로를 요청하면 30분 뒤 하나의 호출로 실행되는 CLI와 파이프라인을 갖게 됩니다. Lobster는 빠진 조각입니다. 결정적 파이프라인, 명시적 승인, 재개 가능한 상태를 제공합니다.
|
||||
어시스턴트는 자신을 관리하는 도구를 빌드할 수 있습니다. 워크플로를 요청하면 30분 뒤에는 한 번의 호출로 실행되는 CLI와 파이프라인을 갖게 됩니다. Lobster는 빠진 조각입니다. 결정적 파이프라인, 명시적 승인, 재개 가능한 상태를 제공합니다.
|
||||
|
||||
## 이유
|
||||
|
||||
오늘날 복잡한 워크플로에는 많은 왕복 도구 호출이 필요합니다. 각 호출에는 토큰 비용이 들고, LLM이 모든 단계를 오케스트레이션해야 합니다. Lobster는 그 오케스트레이션을 타입이 지정된 런타임으로 옮깁니다.
|
||||
오늘날 복잡한 워크플로에는 여러 번의 왕복 도구 호출이 필요합니다. 각 호출은 토큰을 소비하고, LLM은 모든 단계를 오케스트레이션해야 합니다. Lobster는 이 오케스트레이션을 타입이 지정된 런타임으로 옮깁니다.
|
||||
|
||||
- **많은 호출 대신 하나의 호출**: OpenClaw는 하나의 Lobster 도구 호출을 실행하고 구조화된 결과를 받습니다.
|
||||
- **승인 내장**: 부작용(이메일 보내기, 댓글 게시)은 명시적으로 승인될 때까지 워크플로를 중단합니다.
|
||||
- **여러 번 대신 한 번의 호출**: OpenClaw는 Lobster 도구 호출 하나를 실행하고 구조화된 결과를 얻습니다.
|
||||
- **내장된 승인**: 부작용(이메일 보내기, 댓글 게시)은 명시적으로 승인될 때까지 워크플로를 중단합니다.
|
||||
- **재개 가능**: 중단된 워크플로는 토큰을 반환합니다. 승인하고 모든 것을 다시 실행하지 않고 재개할 수 있습니다.
|
||||
|
||||
## 일반 프로그램 대신 DSL을 사용하는 이유는 무엇인가요?
|
||||
## 일반 프로그램 대신 DSL을 쓰는 이유는 무엇인가요?
|
||||
|
||||
Lobster는 의도적으로 작게 설계되었습니다. 목표는 "새 언어"가 아니라, 일급 승인과 재개 토큰을 갖춘 예측 가능하고 AI 친화적인 파이프라인 명세입니다.
|
||||
Lobster는 의도적으로 작습니다. 목표는 "새 언어"가 아니라, 일급 승인과 재개 토큰을 갖춘 예측 가능하고 AI 친화적인 파이프라인 명세입니다.
|
||||
|
||||
- **승인/재개가 내장됨**: 일반 프로그램도 사람에게 프롬프트를 표시할 수는 있지만, 직접 런타임을 만들지 않고는 영속 토큰으로 _일시 중지하고 재개_할 수 없습니다.
|
||||
- **결정성 + 감사 가능성**: 파이프라인은 데이터이므로 로그 기록, diff, 재생, 검토가 쉽습니다.
|
||||
- **승인/재개가 내장됨**: 일반 프로그램은 사람에게 프롬프트를 표시할 수 있지만, 직접 런타임을 만들지 않는 한 내구성 있는 토큰으로 _일시 중지하고 재개_할 수는 없습니다.
|
||||
- **결정성 + 감사 가능성**: 파이프라인은 데이터이므로 로깅, diff, 재실행, 검토가 쉽습니다.
|
||||
- **AI를 위한 제한된 표면**: 작은 문법 + JSON 파이핑은 “창의적인” 코드 경로를 줄이고 검증을 현실적으로 만듭니다.
|
||||
- **안전 정책 내장**: 시간 제한, 출력 한도, 샌드박스 검사, 허용 목록은 각 스크립트가 아니라 런타임이 강제합니다.
|
||||
- **여전히 프로그래밍 가능**: 각 단계는 어떤 CLI나 스크립트든 호출할 수 있습니다. JS/TS를 원하면 코드에서 `.lobster` 파일을 생성하세요.
|
||||
- **내장된 안전 정책**: 타임아웃, 출력 한도, 샌드박스 검사, 허용 목록은 각 스크립트가 아니라 런타임이 강제합니다.
|
||||
- **여전히 프로그래밍 가능**: 각 단계는 임의의 CLI 또는 스크립트를 호출할 수 있습니다. JS/TS를 원한다면 코드에서 `.lobster` 파일을 생성하세요.
|
||||
|
||||
## 작동 방식
|
||||
|
||||
OpenClaw는 임베디드 러너를 사용해 Lobster 워크플로를 **프로세스 내부에서** 실행합니다. 외부 CLI 서브프로세스는 생성되지 않습니다. 워크플로 엔진은 Gateway 프로세스 내부에서 실행되고 JSON 엔벌로프를 직접 반환합니다.
|
||||
파이프라인이 승인을 위해 일시 중지되면, 나중에 계속할 수 있도록 도구가 `resumeToken`을 반환합니다.
|
||||
OpenClaw는 내장 러너를 사용해 Lobster 워크플로를 **프로세스 내부**에서 실행합니다. 외부 CLI 하위 프로세스는 생성되지 않습니다. 워크플로 엔진은 gateway 프로세스 안에서 실행되고 JSON 봉투를 직접 반환합니다.
|
||||
파이프라인이 승인을 위해 일시 중지되면, 도구는 나중에 계속할 수 있도록 `resumeToken`을 반환합니다.
|
||||
|
||||
## 패턴: 작은 CLI + JSON 파이프 + 승인
|
||||
|
||||
JSON을 말하는 작은 명령을 만든 다음, 하나의 Lobster 호출로 연결하세요. (아래 예시 명령 이름은 직접 사용하는 이름으로 바꾸세요.)
|
||||
JSON을 주고받는 작은 명령을 만든 다음, 하나의 Lobster 호출로 연결하세요. (아래 예시 명령 이름은 원하는 것으로 바꾸세요.)
|
||||
|
||||
```bash
|
||||
inbox list --json
|
||||
@ -62,7 +62,7 @@ inbox apply --json
|
||||
}
|
||||
```
|
||||
|
||||
파이프라인이 승인을 요청하면 토큰으로 재개합니다.
|
||||
파이프라인이 승인을 요청하면 토큰으로 재개하세요.
|
||||
|
||||
```json
|
||||
{
|
||||
@ -84,10 +84,10 @@ gog.gmail.search --query 'newer_than:1d' \
|
||||
## JSON 전용 LLM 단계(llm-task)
|
||||
|
||||
**구조화된 LLM 단계**가 필요한 워크플로의 경우 선택 사항인
|
||||
`llm-task` Plugin 도구를 활성화하고 Lobster에서 호출하세요. 이렇게 하면 모델로 분류/요약/초안을 작성할 수 있으면서도 워크플로를
|
||||
`llm-task` Plugin 도구를 활성화하고 Lobster에서 호출하세요. 이렇게 하면 모델로 분류/요약/초안을 만들 수 있으면서도 워크플로를
|
||||
결정적으로 유지할 수 있습니다.
|
||||
|
||||
도구 활성화:
|
||||
도구를 활성화하세요.
|
||||
|
||||
```json
|
||||
{
|
||||
@ -100,14 +100,14 @@ gog.gmail.search --query 'newer_than:1d' \
|
||||
"list": [
|
||||
{
|
||||
"id": "main",
|
||||
"tools": { "allow": ["llm-task"] }
|
||||
"tools": { "alsoAllow": ["llm-task"] }
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
파이프라인에서 사용:
|
||||
파이프라인에서 사용하세요.
|
||||
|
||||
```lobster
|
||||
openclaw.invoke --tool llm-task --action json --args-json '{
|
||||
@ -126,7 +126,7 @@ openclaw.invoke --tool llm-task --action json --args-json '{
|
||||
}'
|
||||
```
|
||||
|
||||
자세한 내용과 구성 옵션은 [LLM 작업](/ko/tools/llm-task)을 참고하세요.
|
||||
자세한 내용과 구성 옵션은 [LLM Task](/ko/tools/llm-task)를 참조하세요.
|
||||
|
||||
## 워크플로 파일(.lobster)
|
||||
|
||||
@ -155,20 +155,20 @@ steps:
|
||||
|
||||
참고:
|
||||
|
||||
- `stdin: $step.stdout` 및 `stdin: $step.json`은 이전 단계의 출력을 전달합니다.
|
||||
- `stdin: $step.stdout`와 `stdin: $step.json`은 이전 단계의 출력을 전달합니다.
|
||||
- `condition`(또는 `when`)은 `$step.approved`를 기준으로 단계를 게이트할 수 있습니다.
|
||||
|
||||
## Lobster 설치
|
||||
|
||||
번들된 Lobster 워크플로는 프로세스 내부에서 실행되며 별도의 `lobster` 바이너리가 필요하지 않습니다. 임베디드 러너는 Lobster Plugin과 함께 제공됩니다.
|
||||
번들된 Lobster 워크플로는 프로세스 내부에서 실행되며, 별도의 `lobster` 바이너리가 필요하지 않습니다. 내장 러너는 Lobster Plugin과 함께 제공됩니다.
|
||||
|
||||
개발 또는 외부 파이프라인을 위해 독립 실행형 Lobster CLI가 필요한 경우 [Lobster 저장소](https://github.com/openclaw/lobster)에서 설치하고 `lobster`가 `PATH`에 있는지 확인하세요.
|
||||
개발 또는 외부 파이프라인을 위해 독립 실행형 Lobster CLI가 필요하다면 [Lobster 저장소](https://github.com/openclaw/lobster)에서 설치하고 `lobster`가 `PATH`에 있는지 확인하세요.
|
||||
|
||||
## 도구 활성화
|
||||
|
||||
Lobster는 **선택 사항** Plugin 도구입니다(기본적으로 활성화되지 않음).
|
||||
|
||||
권장(추가 방식, 안전함):
|
||||
권장 방식(추가형, 안전함):
|
||||
|
||||
```json
|
||||
{
|
||||
@ -195,10 +195,10 @@ Lobster는 **선택 사항** Plugin 도구입니다(기본적으로 활성화되
|
||||
}
|
||||
```
|
||||
|
||||
제한적인 허용 목록 모드에서 실행하려는 경우가 아니라면 `tools.allow: ["lobster"]` 사용을 피하세요.
|
||||
제한적인 허용 목록 모드로 실행하려는 경우가 아니라면 `tools.allow: ["lobster"]` 사용을 피하세요.
|
||||
|
||||
<Note>
|
||||
허용 목록은 선택 사항 Plugin에 대해 옵트인 방식입니다. 허용 목록에 `lobster` 같은 Plugin 도구만 이름으로 지정하면 OpenClaw는 핵심 도구를 계속 활성화해 둡니다. 핵심 도구를 제한하려면 허용 목록에 원하는 핵심 도구나 그룹도 포함하세요.
|
||||
허용 목록은 선택 사항 Plugin에 대해 옵트인 방식입니다. `alsoAllow`는 일반 코어 도구 세트를 보존하면서 이름이 지정된 선택 사항 Plugin 도구만 활성화합니다. 코어 도구를 제한하려면 원하는 코어 도구 또는 그룹과 함께 `tools.allow`를 사용하세요.
|
||||
</Note>
|
||||
|
||||
## 예: 이메일 분류
|
||||
@ -226,7 +226,7 @@ Lobster 사용:
|
||||
}
|
||||
```
|
||||
|
||||
JSON 엔벌로프를 반환합니다(일부 생략):
|
||||
JSON 봉투를 반환합니다(일부 생략).
|
||||
|
||||
```json
|
||||
{
|
||||
@ -270,7 +270,7 @@ JSON 엔벌로프를 반환합니다(일부 생략):
|
||||
}
|
||||
```
|
||||
|
||||
인수를 사용해 워크플로 파일 실행:
|
||||
인수와 함께 워크플로 파일을 실행합니다.
|
||||
|
||||
```json
|
||||
{
|
||||
@ -294,47 +294,47 @@ JSON 엔벌로프를 반환합니다(일부 생략):
|
||||
|
||||
### 선택 입력
|
||||
|
||||
- `cwd`: 파이프라인의 상대 작업 디렉터리(Gateway 작업 디렉터리 안에 머물러야 함).
|
||||
- `timeoutMs`: 이 기간을 초과하면 워크플로를 중단합니다(기본값: 20000).
|
||||
- `cwd`: 파이프라인의 상대 작업 디렉터리(gateway 작업 디렉터리 안에 있어야 함).
|
||||
- `timeoutMs`: 이 시간을 초과하면 워크플로를 중단합니다(기본값: 20000).
|
||||
- `maxStdoutBytes`: 출력이 이 크기를 초과하면 워크플로를 중단합니다(기본값: 512000).
|
||||
- `argsJson`: `lobster run --args-json`에 전달되는 JSON 문자열(워크플로 파일에만 해당).
|
||||
- `argsJson`: `lobster run --args-json`에 전달되는 JSON 문자열(워크플로 파일 전용).
|
||||
|
||||
## 출력 엔벌로프
|
||||
## 출력 봉투
|
||||
|
||||
Lobster는 세 가지 상태 중 하나가 포함된 JSON 엔벌로프를 반환합니다.
|
||||
Lobster는 세 가지 상태 중 하나가 포함된 JSON 봉투를 반환합니다.
|
||||
|
||||
- `ok` → 성공적으로 완료됨
|
||||
- `needs_approval` → 일시 중지됨. 재개하려면 `requiresApproval.resumeToken`이 필요함
|
||||
- `cancelled` → 명시적으로 거부되었거나 취소됨
|
||||
|
||||
도구는 `content`(예쁘게 출력된 JSON)와 `details`(원시 객체) 모두에 엔벌로프를 노출합니다.
|
||||
도구는 `content`(보기 좋게 정렬된 JSON)와 `details`(원시 객체) 양쪽에 봉투를 표시합니다.
|
||||
|
||||
## 승인
|
||||
|
||||
`requiresApproval`이 있으면 프롬프트를 검토하고 결정하세요.
|
||||
|
||||
- `approve: true` → 재개하고 부작용 계속 진행
|
||||
- `approve: false` → 취소하고 워크플로 종료
|
||||
- `approve: true` → 재개하고 부작용을 계속 진행
|
||||
- `approve: false` → 취소하고 워크플로 마무리
|
||||
|
||||
사용자 지정 jq/heredoc 접착 코드 없이 승인 요청에 JSON 미리보기를 첨부하려면 `approve --preview-from-stdin --limit N`을 사용하세요. 재개 토큰은 이제 간결합니다. Lobster는 워크플로 재개 상태를 상태 디렉터리에 저장하고 작은 토큰 키를 돌려줍니다.
|
||||
사용자 지정 jq/heredoc 연결 코드 없이 승인 요청에 JSON 미리보기를 첨부하려면 `approve --preview-from-stdin --limit N`을 사용하세요. 이제 재개 토큰은 작습니다. Lobster는 워크플로 재개 상태를 자체 상태 디렉터리에 저장하고 작은 토큰 키를 반환합니다.
|
||||
|
||||
## OpenProse
|
||||
|
||||
OpenProse는 Lobster와 잘 어울립니다. `/prose`를 사용해 다중 에이전트 준비를 오케스트레이션한 다음, 결정적 승인을 위해 Lobster 파이프라인을 실행하세요. Prose 프로그램에 Lobster가 필요하면 `tools.subagents.tools`를 통해 하위 에이전트에 `lobster` 도구를 허용하세요. [OpenProse](/ko/prose)를 참고하세요.
|
||||
OpenProse는 Lobster와 잘 어울립니다. `/prose`를 사용해 다중 에이전트 준비를 오케스트레이션한 다음, 결정적 승인을 위해 Lobster 파이프라인을 실행하세요. Prose 프로그램에 Lobster가 필요하면 `tools.subagents.tools`를 통해 하위 에이전트에 `lobster` 도구를 허용하세요. [OpenProse](/ko/prose)를 참조하세요.
|
||||
|
||||
## 안전
|
||||
## 안전성
|
||||
|
||||
- **로컬 프로세스 내부 전용** — 워크플로는 Gateway 프로세스 내부에서 실행됩니다. Plugin 자체에서는 네트워크 호출을 하지 않습니다.
|
||||
- **비밀 없음** — Lobster는 OAuth를 관리하지 않습니다. 이를 처리하는 OpenClaw 도구를 호출합니다.
|
||||
- **로컬 프로세스 내부 전용** — 워크플로는 gateway 프로세스 안에서 실행되며, Plugin 자체는 네트워크 호출을 하지 않습니다.
|
||||
- **비밀 없음** — Lobster는 OAuth를 관리하지 않습니다. OAuth를 관리하는 OpenClaw 도구를 호출합니다.
|
||||
- **샌드박스 인식** — 도구 컨텍스트가 샌드박스 처리된 경우 비활성화됩니다.
|
||||
- **강화됨** — 임베디드 러너가 시간 제한과 출력 한도를 강제합니다.
|
||||
- **강화됨** — 내장 러너가 타임아웃과 출력 한도를 강제합니다.
|
||||
|
||||
## 문제 해결
|
||||
|
||||
- **`lobster timed out`** → `timeoutMs`를 늘리거나 긴 파이프라인을 분할하세요.
|
||||
- **`lobster output exceeded maxStdoutBytes`** → `maxStdoutBytes`를 올리거나 출력 크기를 줄이세요.
|
||||
- **`lobster output exceeded maxStdoutBytes`** → `maxStdoutBytes`를 높이거나 출력 크기를 줄이세요.
|
||||
- **`lobster returned invalid JSON`** → 파이프라인이 도구 모드에서 실행되고 JSON만 출력하는지 확인하세요.
|
||||
- **`lobster failed`** → 임베디드 러너 오류 세부 정보는 Gateway 로그를 확인하세요.
|
||||
- **`lobster failed`** → 내장 러너 오류 세부 정보는 gateway 로그를 확인하세요.
|
||||
|
||||
## 더 알아보기
|
||||
|
||||
@ -343,12 +343,12 @@ OpenProse는 Lobster와 잘 어울립니다. `/prose`를 사용해 다중 에이
|
||||
|
||||
## 사례 연구: 커뮤니티 워크플로
|
||||
|
||||
공개 예시 하나: 세 개의 Markdown 볼트(개인, 파트너, 공유)를 관리하는 “세컨드 브레인” CLI + Lobster 파이프라인입니다. CLI는 통계, 받은 편지함 목록, 오래된 항목 스캔을 위한 JSON을 내보내고, Lobster는 이 명령을 `weekly-review`, `inbox-triage`, `memory-consolidation`, `shared-task-sync` 같은 워크플로로 연결하며 각 워크플로에는 승인 게이트가 있습니다. AI는 사용 가능할 때 판단(분류)을 처리하고, 그렇지 않을 때는 결정적 규칙으로 대체합니다.
|
||||
공개 예시 하나: 세 개의 Markdown vault(개인, 파트너, 공유)를 관리하는 “세컨드 브레인” CLI + Lobster 파이프라인입니다. CLI는 통계, 받은 편지함 목록, 오래된 항목 스캔을 JSON으로 내보냅니다. Lobster는 해당 명령을 `weekly-review`, `inbox-triage`, `memory-consolidation`, `shared-task-sync` 같은 워크플로로 연결하며, 각각 승인 게이트를 갖습니다. AI는 사용 가능한 경우 판단(분류)을 처리하고, 그렇지 않은 경우 결정적 규칙으로 대체합니다.
|
||||
|
||||
- 스레드: [https://x.com/plattenschieber/status/2014508656335770033](https://x.com/plattenschieber/status/2014508656335770033)
|
||||
- 저장소: [https://github.com/bloomedai/brain-cli](https://github.com/bloomedai/brain-cli)
|
||||
|
||||
## 관련 항목
|
||||
## 관련
|
||||
|
||||
- [자동화 및 작업](/ko/automation) — Lobster 워크플로 예약
|
||||
- [자동화 개요](/ko/automation) — 모든 자동화 메커니즘
|
||||
|
||||
@ -3,40 +3,40 @@ read_when:
|
||||
- 채팅 명령 사용 또는 구성
|
||||
- 명령 라우팅 또는 권한 디버깅
|
||||
sidebarTitle: Slash commands
|
||||
summary: '슬래시 명령어: 텍스트와 네이티브, 설정 및 지원되는 명령어'
|
||||
summary: '슬래시 명령: 텍스트와 네이티브, 설정, 지원되는 명령'
|
||||
title: 슬래시 명령어
|
||||
x-i18n:
|
||||
generated_at: "2026-05-03T21:39:07Z"
|
||||
generated_at: "2026-05-04T02:25:52Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 9fbdd76ccd43159cabfbc3f15f7bddd2a7ada07fcd6eea2e169d2d88df18f28c
|
||||
source_hash: 49eb41674c8d0a01dbd28a2df783eb9aba3dde18d8425951a266cede825e9a84
|
||||
source_path: tools/slash-commands.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
Commands는 Gateway에서 처리됩니다. 대부분의 명령은 `/`로 시작하는 **독립형** 메시지로 보내야 합니다. 호스트 전용 bash 채팅 명령은 `! <cmd>`를 사용합니다(`/bash <cmd>`는 별칭).
|
||||
명령은 Gateway가 처리합니다. 대부분의 명령은 `/`로 시작하는 **독립형** 메시지로 보내야 합니다. 호스트 전용 bash 채팅 명령은 `! <cmd>`를 사용합니다(`/bash <cmd>`는 별칭).
|
||||
|
||||
대화 또는 스레드가 ACP 세션에 바인딩되면 일반 후속 텍스트는 해당 ACP 하네스로 라우팅됩니다. Gateway 관리 명령은 계속 로컬에 남습니다. `/acp ...`는 항상 OpenClaw ACP 명령 핸들러에 도달하며, 해당 표면에서 명령 처리가 활성화되어 있으면 `/status`와 `/unfocus`도 로컬에 남습니다.
|
||||
대화나 스레드가 ACP 세션에 바인딩되어 있으면 일반 후속 텍스트는 해당 ACP 하네스로 라우팅됩니다. Gateway 관리 명령은 여전히 로컬에 남습니다. `/acp ...`는 항상 OpenClaw ACP 명령 핸들러에 도달하며, `/status`와 `/unfocus`는 해당 표면에서 명령 처리가 활성화되어 있을 때마다 로컬에 남습니다.
|
||||
|
||||
관련된 시스템은 두 가지입니다.
|
||||
관련 시스템은 두 가지입니다.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="명령">
|
||||
<Accordion title="Commands">
|
||||
독립형 `/...` 메시지입니다.
|
||||
</Accordion>
|
||||
<Accordion title="지시문">
|
||||
<Accordion title="Directives">
|
||||
`/think`, `/fast`, `/verbose`, `/trace`, `/reasoning`, `/elevated`, `/exec`, `/model`, `/queue`.
|
||||
|
||||
- 지시문은 모델이 메시지를 보기 전에 메시지에서 제거됩니다.
|
||||
- 일반 채팅 메시지(지시문만 있는 메시지가 아님)에서는 "인라인 힌트"로 처리되며 세션 설정을 지속하지 **않습니다**.
|
||||
- 지시문만 있는 메시지(메시지에 지시문만 포함됨)에서는 세션에 지속되며 확인 응답을 보냅니다.
|
||||
- 지시문은 **승인된 발신자**에게만 적용됩니다. `commands.allowFrom`이 설정되어 있으면 이것이 사용되는 유일한 허용 목록입니다. 그렇지 않으면 권한 부여는 채널 허용 목록/페어링과 `commands.useAccessGroups`에서 나옵니다. 승인되지 않은 발신자의 지시문은 일반 텍스트로 처리됩니다.
|
||||
- 일반 채팅 메시지(지시문만 있는 메시지가 아님)에서는 "인라인 힌트"로 처리되며 세션 설정으로 유지되지 **않습니다**.
|
||||
- 지시문만 있는 메시지(메시지에 지시문만 포함됨)에서는 세션에 유지되고 확인 응답을 보냅니다.
|
||||
- 지시문은 **승인된 발신자**에게만 적용됩니다. `commands.allowFrom`이 설정되어 있으면 이것만 허용 목록으로 사용됩니다. 그렇지 않으면 채널 허용 목록/페어링과 `commands.useAccessGroups`에서 권한 부여가 결정됩니다. 승인되지 않은 발신자의 지시문은 일반 텍스트로 처리됩니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="인라인 단축 명령">
|
||||
<Accordion title="Inline shortcuts">
|
||||
허용 목록에 있거나 승인된 발신자만: `/help`, `/commands`, `/status`, `/whoami` (`/id`).
|
||||
|
||||
즉시 실행되고, 모델이 메시지를 보기 전에 제거되며, 남은 텍스트는 일반 흐름을 계속 거칩니다.
|
||||
즉시 실행되고, 모델이 메시지를 보기 전에 제거되며, 남은 텍스트는 일반 흐름을 계속 통과합니다.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
@ -69,20 +69,20 @@ Commands는 Gateway에서 처리됩니다. 대부분의 명령은 `/`로 시작
|
||||
```
|
||||
|
||||
<ParamField path="commands.text" type="boolean" default="true">
|
||||
채팅 메시지에서 `/...` 파싱을 활성화합니다. 네이티브 명령이 없는 표면(WhatsApp/WebChat/Signal/iMessage/Google Chat/Microsoft Teams)에서는 이 값을 `false`로 설정하더라도 텍스트 명령이 계속 작동합니다.
|
||||
채팅 메시지에서 `/...` 파싱을 활성화합니다. 네이티브 명령이 없는 표면(WhatsApp/WebChat/Signal/iMessage/Google Chat/Microsoft Teams)에서는 이 값을 `false`로 설정해도 텍스트 명령이 계속 작동합니다.
|
||||
</ParamField>
|
||||
<ParamField path="commands.native" type='boolean | "auto"' default='"auto"'>
|
||||
네이티브 명령을 등록합니다. Auto: Discord/Telegram에서는 켜짐, Slack에서는 꺼짐(슬래시 명령을 추가할 때까지), 네이티브 지원이 없는 제공자에서는 무시됩니다. 제공자별로 재정의하려면 `channels.discord.commands.native`, `channels.telegram.commands.native` 또는 `channels.slack.commands.native`를 설정하세요(bool 또는 `"auto"`). Discord에서 `false`는 시작 중 슬래시 명령 등록 및 정리를 건너뜁니다. 이전에 등록된 명령은 Discord 앱에서 제거할 때까지 계속 표시될 수 있습니다. Slack 명령은 Slack 앱에서 관리되며 자동으로 제거되지 않습니다.
|
||||
네이티브 명령을 등록합니다. 자동: Discord/Telegram에서는 켜짐, Slack에서는 꺼짐(슬래시 명령을 추가할 때까지), 네이티브 지원이 없는 공급자에서는 무시됩니다. 공급자별로 재정의하려면 `channels.discord.commands.native`, `channels.telegram.commands.native` 또는 `channels.slack.commands.native`를 설정하세요(bool 또는 `"auto"`). Discord에서 `false`는 시작 중 슬래시 명령 등록과 정리를 건너뜁니다. 이전에 등록된 명령은 Discord 앱에서 제거할 때까지 계속 표시될 수 있습니다. Slack 명령은 Slack 앱에서 관리되며 자동으로 제거되지 않습니다.
|
||||
</ParamField>
|
||||
Discord에서 네이티브 명령 사양에는 `descriptionLocalizations`가 포함될 수 있으며, OpenClaw는 이를 Discord `description_localizations`로 게시하고 조정 비교에 포함합니다.
|
||||
Discord에서 네이티브 명령 사양은 `descriptionLocalizations`를 포함할 수 있으며, OpenClaw는 이를 Discord `description_localizations`로 게시하고 조정 비교에 포함합니다.
|
||||
<ParamField path="commands.nativeSkills" type='boolean | "auto"' default='"auto"'>
|
||||
지원되는 경우 **skill** 명령을 네이티브로 등록합니다. Auto: Discord/Telegram에서는 켜짐, Slack에서는 꺼짐(Slack은 skill마다 슬래시 명령을 만들어야 함). 제공자별로 재정의하려면 `channels.discord.commands.nativeSkills`, `channels.telegram.commands.nativeSkills` 또는 `channels.slack.commands.nativeSkills`를 설정하세요(bool 또는 `"auto"`).
|
||||
지원되는 경우 **skill** 명령을 네이티브로 등록합니다. 자동: Discord/Telegram에서는 켜짐, Slack에서는 꺼짐(Slack은 Skill마다 슬래시 명령 생성이 필요함). 공급자별로 재정의하려면 `channels.discord.commands.nativeSkills`, `channels.telegram.commands.nativeSkills` 또는 `channels.slack.commands.nativeSkills`를 설정하세요(bool 또는 `"auto"`).
|
||||
</ParamField>
|
||||
<ParamField path="commands.bash" type="boolean" default="false">
|
||||
`! <cmd>`로 호스트 셸 명령을 실행할 수 있게 합니다(`/bash <cmd>`는 별칭이며, `tools.elevated` 허용 목록이 필요합니다).
|
||||
호스트 셸 명령을 실행하도록 `! <cmd>`를 활성화합니다(`/bash <cmd>`는 별칭이며, `tools.elevated` 허용 목록이 필요함).
|
||||
</ParamField>
|
||||
<ParamField path="commands.bashForegroundMs" type="number" default="2000">
|
||||
bash가 백그라운드 모드로 전환하기 전에 대기하는 시간을 제어합니다(`0`은 즉시 백그라운드로 전환).
|
||||
bash가 백그라운드 모드로 전환하기 전에 기다리는 시간을 제어합니다(`0`은 즉시 백그라운드로 전환).
|
||||
</ParamField>
|
||||
<ParamField path="commands.config" type="boolean" default="false">
|
||||
`/config`를 활성화합니다(`openclaw.json` 읽기/쓰기).
|
||||
@ -91,75 +91,76 @@ Discord에서 네이티브 명령 사양에는 `descriptionLocalizations`가 포
|
||||
`/mcp`를 활성화합니다(`mcp.servers` 아래의 OpenClaw 관리 MCP 구성 읽기/쓰기).
|
||||
</ParamField>
|
||||
<ParamField path="commands.plugins" type="boolean" default="false">
|
||||
`/plugins`를 활성화합니다(Plugin 탐색/상태 및 설치 + 활성화/비활성화 제어).
|
||||
`/plugins`를 활성화합니다(Plugin 검색/상태와 설치 및 활성화/비활성화 제어).
|
||||
</ParamField>
|
||||
<ParamField path="commands.debug" type="boolean" default="false">
|
||||
`/debug`를 활성화합니다(런타임 전용 재정의).
|
||||
</ParamField>
|
||||
<ParamField path="commands.restart" type="boolean" default="true">
|
||||
`/restart`와 gateway 재시작 도구 작업을 활성화합니다.
|
||||
`/restart`와 Gateway 재시작 도구 작업을 활성화합니다.
|
||||
</ParamField>
|
||||
<ParamField path="commands.ownerAllowFrom" type="string[]">
|
||||
소유자 전용 명령/도구 표면에 대한 명시적 소유자 허용 목록을 설정합니다. 이는 위험한 작업을 승인하고 `/diagnostics`, `/export-trajectory`, `/config` 같은 명령을 실행할 수 있는 인간 운영자 계정입니다. `commands.allowFrom` 및 DM 페어링 접근 권한과는 별개입니다.
|
||||
소유자 전용 명령/도구 표면에 대한 명시적 소유자 허용 목록을 설정합니다. 이는 위험한 작업을 승인하고 `/diagnostics`, `/export-trajectory`, `/config` 같은 명령을 실행할 수 있는 사람 운영자 계정입니다. `commands.allowFrom` 및 DM 페어링 액세스와는 별개입니다.
|
||||
</ParamField>
|
||||
<ParamField path="channels.<channel>.commands.enforceOwnerForCommands" type="boolean" default="false">
|
||||
채널별: 소유자 전용 명령을 해당 표면에서 실행하려면 **소유자 ID**가 필요하도록 합니다. `true`이면 발신자는 확인된 소유자 후보(예: `commands.ownerAllowFrom` 항목 또는 제공자 네이티브 소유자 메타데이터)와 일치하거나, 내부 메시지 채널에서 내부 `operator.admin` 범위를 보유해야 합니다. 채널 `allowFrom`의 와일드카드 항목 또는 비어 있거나 확인되지 않은 소유자 후보 목록만으로는 충분하지 **않습니다**. 소유자 전용 명령은 해당 채널에서 폐쇄적으로 실패합니다. 소유자 전용 명령을 `ownerAllowFrom`과 표준 명령 허용 목록만으로 제한하려면 이 설정을 꺼 두세요.
|
||||
채널별: 소유자 전용 명령이 해당 표면에서 실행되려면 **소유자 신원**을 요구합니다. `true`이면 발신자는 해석된 소유자 후보(예: `commands.ownerAllowFrom` 항목 또는 공급자 네이티브 소유자 메타데이터)와 일치하거나 내부 메시지 채널에서 내부 `operator.admin` 범위를 보유해야 합니다. 채널 `allowFrom`의 와일드카드 항목이나 비어 있거나 해석되지 않은 소유자 후보 목록만으로는 충분하지 **않습니다**. 소유자 전용 명령은 해당 채널에서 실패로 닫힙니다. 소유자 전용 명령을 `ownerAllowFrom`과 표준 명령 허용 목록으로만 게이트하려면 이 옵션을 꺼 두세요.
|
||||
</ParamField>
|
||||
<ParamField path="commands.ownerDisplay" type='"raw" | "hash"'>
|
||||
시스템 프롬프트에서 소유자 ID가 표시되는 방식을 제어합니다.
|
||||
</ParamField>
|
||||
<ParamField path="commands.ownerDisplaySecret" type="string">
|
||||
`commands.ownerDisplay="hash"`일 때 사용되는 HMAC 시크릿을 선택적으로 설정합니다.
|
||||
선택적으로 `commands.ownerDisplay="hash"`일 때 사용되는 HMAC 시크릿을 설정합니다.
|
||||
</ParamField>
|
||||
<ParamField path="commands.allowFrom" type="object">
|
||||
명령 권한 부여를 위한 제공자별 허용 목록입니다. 구성되면 명령과 지시문에 대한 유일한 권한 부여 소스가 됩니다(채널 허용 목록/페어링 및 `commands.useAccessGroups`는 무시됨). 전역 기본값에는 `"*"`를 사용하세요. 제공자별 키가 이를 재정의합니다.
|
||||
명령 권한 부여를 위한 공급자별 허용 목록입니다. 구성되면 명령과 지시문에 대한 유일한 권한 부여 소스가 됩니다(채널 허용 목록/페어링 및 `commands.useAccessGroups`는 무시됨). 전역 기본값에는 `"*"`를 사용하세요. 공급자별 키가 이를 재정의합니다.
|
||||
</ParamField>
|
||||
<ParamField path="commands.useAccessGroups" type="boolean" default="true">
|
||||
`commands.allowFrom`이 설정되지 않은 경우 명령에 대한 허용 목록/정책을 강제합니다.
|
||||
`commands.allowFrom`이 설정되지 않은 경우 명령에 대한 허용 목록/정책을 적용합니다.
|
||||
</ParamField>
|
||||
|
||||
## 명령 목록
|
||||
|
||||
현재 단일 진실 공급원:
|
||||
현재 단일 진실 소스:
|
||||
|
||||
- 코어 내장 명령은 `src/auto-reply/commands-registry.shared.ts`에서 나옵니다.
|
||||
- 생성된 dock 명령은 `src/auto-reply/commands-registry.data.ts`에서 나옵니다.
|
||||
- Plugin 명령은 Plugin `registerCommand()` 호출에서 나옵니다.
|
||||
- Gateway에서의 실제 가용성은 여전히 구성 플래그, 채널 표면, 설치/활성화된 Plugin에 따라 달라집니다.
|
||||
- 핵심 내장 명령은 `src/auto-reply/commands-registry.shared.ts`에서 옵니다.
|
||||
- 생성된 dock 명령은 `src/auto-reply/commands-registry.data.ts`에서 옵니다.
|
||||
- Plugin 명령은 Plugin `registerCommand()` 호출에서 옵니다.
|
||||
- Gateway에서의 실제 사용 가능 여부는 여전히 구성 플래그, 채널 표면, 설치/활성화된 Plugin에 따라 달라집니다.
|
||||
|
||||
### 코어 내장 명령
|
||||
### 핵심 내장 명령
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="세션 및 실행">
|
||||
<Accordion title="Sessions and runs">
|
||||
- `/new [model]`은 새 세션을 시작합니다. `/reset`은 재설정 별칭입니다.
|
||||
- Control UI는 입력된 `/new`를 가로채 새 대시보드 세션을 만들고 전환합니다. 입력된 `/reset`은 여전히 Gateway의 인플레이스 재설정을 실행합니다.
|
||||
- `/reset soft [message]`는 현재 트랜스크립트를 유지하고, 재사용된 CLI 백엔드 세션 ID를 삭제하며, 시작/시스템 프롬프트 로딩을 제자리에서 다시 실행합니다.
|
||||
- Control UI는 입력된 `/new`를 가로채 새 대시보드 세션을 만들고 전환합니다. 입력된 `/reset`은 여전히 Gateway의 제자리 재설정을 실행합니다.
|
||||
- `/reset soft [message]`는 현재 transcript를 유지하고, 재사용된 CLI 백엔드 세션 ID를 삭제하며, 시작/시스템 프롬프트 로딩을 제자리에서 다시 실행합니다.
|
||||
- `/compact [instructions]`는 세션 컨텍스트를 압축합니다. [Compaction](/ko/concepts/compaction)을 참조하세요.
|
||||
- `/stop`은 현재 실행을 중단합니다.
|
||||
- `/session idle <duration|off>` 및 `/session max-age <duration|off>`는 스레드 바인딩 만료를 관리합니다.
|
||||
- `/export-session [path]`는 현재 세션을 HTML로 내보냅니다. 별칭: `/export`.
|
||||
- `/export-trajectory [path]`는 exec 승인을 요청한 다음, 현재 세션에 대한 JSONL [trajectory 번들](/ko/tools/trajectory)을 내보냅니다. 하나의 OpenClaw 세션에 대한 프롬프트, 도구, 트랜스크립트 타임라인이 필요할 때 사용하세요. 그룹 채팅에서는 승인 프롬프트와 내보내기 결과가 소유자에게 비공개로 전송됩니다. 별칭: `/trajectory`.
|
||||
- `/export-trajectory [path]`는 exec 승인을 요청한 다음 현재 세션의 JSONL [trajectory bundle](/ko/tools/trajectory)을 내보냅니다. OpenClaw 세션 하나에 대한 프롬프트, 도구, transcript 타임라인이 필요할 때 사용하세요. 그룹 채팅에서는 승인 프롬프트와 내보내기 결과가 소유자에게 비공개로 전송됩니다. 별칭: `/trajectory`.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="모델 및 실행 제어">
|
||||
- `/think <level>`은 thinking 수준을 설정합니다. 옵션은 활성 모델의 제공자 프로필에서 오며, 일반적인 수준은 `off`, `minimal`, `low`, `medium`, `high`입니다. `xhigh`, `adaptive`, `max` 같은 사용자 지정 수준 또는 이진 `on`은 지원되는 경우에만 사용할 수 있습니다. 별칭: `/thinking`, `/t`.
|
||||
- `/verbose on|off|full`은 상세 출력을 전환합니다. 별칭: `/v`.
|
||||
<Accordion title="Model and run controls">
|
||||
- `/think <level>`은 사고 수준을 설정합니다. 옵션은 활성 모델의 공급자 프로필에서 오며, 일반적인 수준은 `off`, `minimal`, `low`, `medium`, `high`이고, `xhigh`, `adaptive`, `max` 같은 사용자 지정 수준이나 이진 `on`은 지원되는 곳에서만 사용할 수 있습니다. 별칭: `/thinking`, `/t`.
|
||||
- `/verbose on|off|full`은 자세한 출력을 전환합니다. 별칭: `/v`.
|
||||
- `/trace on|off`는 현재 세션의 Plugin 추적 출력을 전환합니다.
|
||||
- `/fast [status|on|off]`는 빠른 모드를 표시하거나 설정합니다.
|
||||
- `/reasoning [on|off|stream]`은 reasoning 가시성을 전환합니다. 별칭: `/reason`.
|
||||
- `/reasoning [on|off|stream]`은 추론 표시 여부를 전환합니다. 별칭: `/reason`.
|
||||
- `/elevated [on|off|ask|full]`은 elevated 모드를 전환합니다. 별칭: `/elev`.
|
||||
- `/exec host=<auto|sandbox|gateway|node> security=<deny|allowlist|full> ask=<off|on-miss|always> node=<id>`는 exec 기본값을 표시하거나 설정합니다.
|
||||
- `/model [name|#|status]`는 모델을 표시하거나 설정합니다.
|
||||
- `/models [provider] [page] [limit=<n>|size=<n>|all]`는 구성되었거나 인증 사용 가능한 제공자, 또는 특정 제공자의 모델을 나열합니다. 해당 제공자의 전체 카탈로그를 탐색하려면 `all`을 추가하세요.
|
||||
- `/queue <mode>`는 queue 동작(`steer`, 레거시 `queue`, `followup`, `collect`, `steer-backlog`, `interrupt`)과 `debounce:0.5s cap:25 drop:summarize` 같은 옵션을 관리합니다. `/queue default` 또는 `/queue reset`은 세션 재정의를 지웁니다. [명령 queue](/ko/concepts/queue) 및 [Steering queue](/ko/concepts/queue-steering)를 참조하세요.
|
||||
- `/models [provider] [page] [limit=<n>|size=<n>|all]`은 구성되었거나 인증 사용 가능한 공급자 또는 특정 공급자의 모델을 나열합니다. 해당 공급자의 전체 카탈로그를 탐색하려면 `all`을 추가하세요.
|
||||
- `/queue <mode>`는 큐 동작(`steer`, 기존 `queue`, `followup`, `collect`, `steer-backlog`, `interrupt`)과 `debounce:0.5s cap:25 drop:summarize` 같은 옵션을 관리합니다. `/queue default` 또는 `/queue reset`은 세션 재정의를 지웁니다. [Command queue](/ko/concepts/queue) 및 [Steering queue](/ko/concepts/queue-steering)를 참조하세요.
|
||||
- `/steer <message>`는 `/queue` 모드와 독립적으로 현재 세션의 활성 실행에 지침을 주입합니다. 세션이 유휴 상태일 때 새 실행을 시작하지 않습니다. 별칭: `/tell`. [Steer](/ko/tools/steer)를 참조하세요.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="탐색 및 상태">
|
||||
<Accordion title="Discovery and status">
|
||||
- `/help`는 짧은 도움말 요약을 표시합니다.
|
||||
- `/commands`는 생성된 명령 카탈로그를 표시합니다.
|
||||
- `/tools [compact|verbose]`는 현재 에이전트가 지금 사용할 수 있는 항목을 표시합니다.
|
||||
- `/status`는 가능한 경우 `Execution`/`Runtime` 레이블 및 제공자 사용량/할당량을 포함한 실행/런타임 상태를 표시합니다.
|
||||
- `/diagnostics [note]`는 Gateway 버그와 Codex 하네스 실행을 위한 소유자 전용 지원 보고서 흐름입니다. `openclaw gateway diagnostics export --json`을 실행하기 전에 매번 명시적 exec 승인을 요청합니다. allow-all 규칙으로 진단을 승인하지 마세요. 승인 후에는 로컬 번들 경로, 매니페스트 요약, 개인정보 보호 참고 사항, 관련 세션 ID가 포함된 붙여넣기 가능한 보고서를 보냅니다. 그룹 채팅에서는 승인 프롬프트와 보고서가 소유자에게 비공개로 전송됩니다. 활성 세션이 OpenAI Codex 하네스를 사용하는 경우 동일한 승인으로 관련 Codex 피드백도 OpenAI 서버로 전송되며, 완료된 응답에는 OpenClaw 세션 ID, Codex 스레드 ID, `codex resume <thread-id>` 명령이 나열됩니다. [Diagnostics Export](/ko/gateway/diagnostics)를 참조하세요.
|
||||
- `/status`는 사용 가능한 경우 `Execution`/`Runtime` 레이블과 공급자 사용량/할당량을 포함한 실행/런타임 상태를 표시합니다.
|
||||
- `/diagnostics [note]`는 Gateway 버그와 Codex 하네스 실행을 위한 소유자 전용 지원 보고서 흐름입니다. `openclaw gateway diagnostics export --json`을 실행하기 전에 매번 명시적 exec 승인을 요청합니다. allow-all 규칙으로 diagnostics를 승인하지 마세요. 승인 후에는 로컬 번들 경로, 매니페스트 요약, 개인정보 보호 참고 사항, 관련 세션 ID가 포함된 붙여넣기 가능한 보고서를 전송합니다. 그룹 채팅에서는 승인 프롬프트와 보고서가 소유자에게 비공개로 전송됩니다. 활성 세션이 OpenAI Codex 하네스를 사용하는 경우 동일한 승인으로 관련 Codex 피드백도 OpenAI 서버에 전송되며, 완료된 응답에는 OpenClaw 세션 ID, Codex 스레드 ID, `codex resume <thread-id>` 명령이 나열됩니다. [Diagnostics Export](/ko/gateway/diagnostics)를 참조하세요.
|
||||
- `/crestodian <request>`는 소유자 DM에서 Crestodian 설정 및 복구 헬퍼를 실행합니다.
|
||||
- `/tasks`는 현재 세션의 활성/최근 백그라운드 작업을 나열합니다.
|
||||
- `/context [list|detail|json]`는 컨텍스트가 조립되는 방식을 설명합니다.
|
||||
@ -167,34 +168,34 @@ Discord에서 네이티브 명령 사양에는 `descriptionLocalizations`가 포
|
||||
- `/usage off|tokens|full|cost`는 응답별 사용량 푸터를 제어하거나 로컬 비용 요약을 출력합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Skills, 허용 목록, 승인">
|
||||
- `/skill <name> [input]`은 이름으로 skill을 실행합니다.
|
||||
- `/allowlist [list|add|remove] ...`는 허용 목록 항목을 관리합니다. 텍스트 전용.
|
||||
<Accordion title="Skills, allowlists, approvals">
|
||||
- `/skill <name> [input]`은 이름으로 Skill을 실행합니다.
|
||||
- `/allowlist [list|add|remove] ...`는 허용 목록 항목을 관리합니다. 텍스트 전용입니다.
|
||||
- `/approve <id> <decision>`은 exec 승인 프롬프트를 해결합니다.
|
||||
- `/btw <question>`은 이후 세션 컨텍스트를 변경하지 않고 부가 질문을 합니다. 별칭: `/side`. [BTW](/ko/tools/btw)를 참조하세요.
|
||||
- `/btw <question>`은 향후 세션 컨텍스트를 변경하지 않고 부가 질문을 합니다. 별칭: `/side`. [BTW](/ko/tools/btw)를 참조하세요.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="하위 에이전트와 ACP">
|
||||
- `/subagents list|kill|log|info|send|steer|spawn`는 현재 세션의 하위 에이전트 실행을 관리합니다.
|
||||
- `/acp spawn|cancel|steer|close|sessions|status|set-mode|set|cwd|permissions|timeout|model|reset-options|doctor|install|help`는 ACP 세션과 런타임 옵션을 관리합니다.
|
||||
- `/focus <target>`는 현재 Discord 스레드 또는 Telegram 토픽/대화를 세션 대상으로 바인딩합니다.
|
||||
- `/focus <target>`는 현재 Discord 스레드 또는 Telegram 주제/대화를 세션 대상으로 바인딩합니다.
|
||||
- `/unfocus`는 현재 바인딩을 제거합니다.
|
||||
- `/agents`는 현재 세션에 스레드로 바인딩된 에이전트를 나열합니다.
|
||||
- `/kill <id|#|all>`는 실행 중인 하위 에이전트 하나 또는 전체를 중단합니다.
|
||||
- `/steer <id|#> <message>`는 실행 중인 하위 에이전트에 조정 지시를 보냅니다. 별칭: `/tell`.
|
||||
- `/agents`는 현재 세션의 스레드 바인딩 에이전트를 나열합니다.
|
||||
- `/kill <id|#|all>`는 실행 중인 하위 에이전트 하나 또는 모두를 중단합니다.
|
||||
- `/subagents steer <id|#> <message>`는 실행 중인 하위 에이전트에 조종 메시지를 보냅니다. [조종](/ko/tools/steer)을 참고하세요.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="소유자 전용 쓰기와 관리">
|
||||
<Accordion title="소유자 전용 쓰기 및 관리자">
|
||||
- `/config show|get|set|unset`는 `openclaw.json`을 읽거나 씁니다. 소유자 전용입니다. `commands.config: true`가 필요합니다.
|
||||
- `/mcp show|get|set|unset`는 `mcp.servers` 아래의 OpenClaw 관리 MCP 서버 구성을 읽거나 씁니다. 소유자 전용입니다. `commands.mcp: true`가 필요합니다.
|
||||
- `/plugins list|inspect|show|get|install|enable|disable`는 Plugin 상태를 검사하거나 변경합니다. `/plugin`은 별칭입니다. 쓰기는 소유자 전용입니다. `commands.plugins: true`가 필요합니다.
|
||||
- `/plugins list|inspect|show|get|install|enable|disable`는 plugin 상태를 검사하거나 변경합니다. `/plugin`은 별칭입니다. 쓰기는 소유자 전용입니다. `commands.plugins: true`가 필요합니다.
|
||||
- `/debug show|set|unset|reset`는 런타임 전용 구성 재정의를 관리합니다. 소유자 전용입니다. `commands.debug: true`가 필요합니다.
|
||||
- `/restart`는 활성화된 경우 OpenClaw를 다시 시작합니다. 기본값: 활성화됨. 비활성화하려면 `commands.restart: false`를 설정합니다.
|
||||
- `/restart`는 활성화된 경우 OpenClaw를 다시 시작합니다. 기본값: 활성화됨. 비활성화하려면 `commands.restart: false`를 설정하세요.
|
||||
- `/send on|off|inherit`는 전송 정책을 설정합니다. 소유자 전용입니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="음성, TTS, 채널 제어">
|
||||
- `/tts on|off|status|chat|latest|provider|limit|summary|audio|help`는 TTS를 제어합니다. [TTS](/ko/tools/tts)를 참조하세요.
|
||||
- `/tts on|off|status|chat|latest|provider|limit|summary|audio|help`는 TTS를 제어합니다. [TTS](/ko/tools/tts)를 참고하세요.
|
||||
- `/activation mention|always`는 그룹 활성화 모드를 설정합니다.
|
||||
- `/bash <command>`는 호스트 셸 명령을 실행합니다. 텍스트 전용입니다. 별칭: `! <command>`. `commands.bash: true`와 `tools.elevated` 허용 목록이 필요합니다.
|
||||
- `!poll [sessionId]`는 백그라운드 bash 작업을 확인합니다.
|
||||
@ -203,34 +204,34 @@ Discord에서 네이티브 명령 사양에는 `descriptionLocalizations`가 포
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
### 생성된 dock 명령
|
||||
### 생성된 도킹 명령
|
||||
|
||||
dock 명령은 현재 세션의 응답 경로를 연결된 다른
|
||||
채널로 전환합니다. 설정, 예시, 문제 해결은 [채널 도킹](/ko/concepts/channel-docking)을 참조하세요.
|
||||
도킹 명령은 현재 세션의 응답 경로를 연결된 다른
|
||||
채널로 전환합니다. 설정, 예시, 문제 해결은 [채널 도킹](/ko/concepts/channel-docking)을 참고하세요.
|
||||
|
||||
dock 명령은 네이티브 명령을 지원하는 채널 plugins에서 생성됩니다. 현재 번들 세트:
|
||||
도킹 명령은 네이티브 명령을 지원하는 채널 plugins에서 생성됩니다. 현재 번들 세트:
|
||||
|
||||
- `/dock-discord` (별칭: `/dock_discord`)
|
||||
- `/dock-mattermost` (별칭: `/dock_mattermost`)
|
||||
- `/dock-slack` (별칭: `/dock_slack`)
|
||||
- `/dock-telegram` (별칭: `/dock_telegram`)
|
||||
- `/dock-discord`(별칭: `/dock_discord`)
|
||||
- `/dock-mattermost`(별칭: `/dock_mattermost`)
|
||||
- `/dock-slack`(별칭: `/dock_slack`)
|
||||
- `/dock-telegram`(별칭: `/dock_telegram`)
|
||||
|
||||
직접 채팅에서 dock 명령을 사용해 현재 세션의 응답 경로를 연결된 다른 채널로 전환합니다. 에이전트는 같은 세션 컨텍스트를 유지하지만, 해당 세션의 향후 응답은 선택한 채널 피어로 전달됩니다.
|
||||
직접 채팅에서 도킹 명령을 사용해 현재 세션의 응답 경로를 연결된 다른 채널로 전환하세요. 에이전트는 동일한 세션 컨텍스트를 유지하지만, 해당 세션의 이후 응답은 선택한 채널 피어로 전달됩니다.
|
||||
|
||||
dock 명령에는 `session.identityLinks`가 필요합니다. 소스 발신자와 대상 피어는 같은 ID 그룹에 있어야 합니다. 예: `["telegram:123", "discord:456"]`. ID가 `123`인 Telegram 사용자가 `/dock_discord`를 보내면 OpenClaw는 활성 세션에 `lastChannel: "discord"`와 `lastTo: "456"`을 저장합니다. 발신자가 Discord 피어에 연결되어 있지 않으면, 명령은 일반 채팅으로 넘어가지 않고 설정 힌트로 응답합니다.
|
||||
도킹 명령에는 `session.identityLinks`가 필요합니다. 소스 발신자와 대상 피어는 같은 ID 그룹에 있어야 합니다. 예: `["telegram:123", "discord:456"]`. ID가 `123`인 Telegram 사용자가 `/dock_discord`를 보내면 OpenClaw는 활성 세션에 `lastChannel: "discord"`와 `lastTo: "456"`을 저장합니다. 발신자가 Discord 피어에 연결되어 있지 않으면, 명령은 일반 채팅으로 넘어가지 않고 설정 힌트로 응답합니다.
|
||||
|
||||
도킹은 활성 세션 경로만 변경합니다. 채널 계정을 만들거나, 액세스 권한을 부여하거나, 채널 허용 목록을 우회하거나, 대화 기록을 다른 세션으로 옮기지 않습니다. 경로를 다시 전환하려면 `/dock-telegram`, `/dock-slack`, `/dock-mattermost` 또는 다른 생성된 dock 명령을 사용하세요.
|
||||
도킹은 활성 세션 경로만 변경합니다. 채널 계정을 만들거나, 접근 권한을 부여하거나, 채널 허용 목록을 우회하거나, 대화 기록을 다른 세션으로 이동하지 않습니다. 경로를 다시 전환하려면 `/dock-telegram`, `/dock-slack`, `/dock-mattermost` 또는 생성된 다른 도킹 명령을 사용하세요.
|
||||
|
||||
### 번들 Plugin 명령
|
||||
### 번들 plugin 명령
|
||||
|
||||
번들 plugins는 더 많은 슬래시 명령을 추가할 수 있습니다. 이 저장소의 현재 번들 명령:
|
||||
|
||||
- `/dreaming [on|off|status|help]`는 메모리 dreaming을 전환합니다. [Dreaming](/ko/concepts/dreaming)을 참조하세요.
|
||||
- `/pair [qr|status|pending|approve|cleanup|notify]`는 기기 페어링/설정 흐름을 관리합니다. [페어링](/ko/channels/pairing)을 참조하세요.
|
||||
- `/phone status|arm <camera|screen|writes|all> [duration]|disarm`는 고위험 전화 Node 명령을 일시적으로 활성화합니다.
|
||||
- `/voice status|list [limit]|set <voiceId|name>`는 Talk 음성 구성을 관리합니다. Discord에서는 네이티브 명령 이름이 `/talkvoice`입니다.
|
||||
- `/card ...`는 LINE 리치 카드 프리셋을 보냅니다. [LINE](/ko/channels/line)을 참조하세요.
|
||||
- `/codex status|models|threads|resume|compact|review|diagnostics|account|mcp|skills`는 번들 Codex 앱 서버 하네스를 검사하고 제어합니다. [Codex 하네스](/ko/plugins/codex-harness)를 참조하세요.
|
||||
- `/dreaming [on|off|status|help]`는 메모리 Dreaming을 켜거나 끕니다. [Dreaming](/ko/concepts/dreaming)을 참고하세요.
|
||||
- `/pair [qr|status|pending|approve|cleanup|notify]`는 디바이스 페어링/설정 흐름을 관리합니다. [페어링](/ko/channels/pairing)을 참고하세요.
|
||||
- `/phone status|arm <camera|screen|writes|all> [duration]|disarm`는 고위험 전화 노드 명령을 일시적으로 무장합니다.
|
||||
- `/voice status|list [limit]|set <voiceId|name>`는 Talk 음성 구성을 관리합니다. Discord에서 네이티브 명령 이름은 `/talkvoice`입니다.
|
||||
- `/card ...`는 LINE 리치 카드 프리셋을 보냅니다. [LINE](/ko/channels/line)을 참고하세요.
|
||||
- `/codex status|models|threads|resume|compact|review|diagnostics|account|mcp|skills`는 번들 Codex 앱 서버 하네스를 검사하고 제어합니다. [Codex 하네스](/ko/plugins/codex-harness)를 참고하세요.
|
||||
- QQBot 전용 명령:
|
||||
- `/bot-ping`
|
||||
- `/bot-version`
|
||||
@ -240,65 +241,65 @@ dock 명령에는 `session.identityLinks`가 필요합니다. 소스 발신자
|
||||
|
||||
### 동적 skill 명령
|
||||
|
||||
사용자가 호출할 수 있는 skills도 슬래시 명령으로 노출됩니다.
|
||||
사용자 호출 가능 skills도 슬래시 명령으로 노출됩니다.
|
||||
|
||||
- `/skill <name> [input]`는 일반 진입점으로 항상 작동합니다.
|
||||
- `/skill <name> [input]`은 일반 진입점으로 항상 작동합니다.
|
||||
- skill/plugin이 등록한 경우 skills는 `/prose` 같은 직접 명령으로도 나타날 수 있습니다.
|
||||
- 네이티브 skill 명령 등록은 `commands.nativeSkills`와 `channels.<provider>.commands.nativeSkills`로 제어됩니다.
|
||||
- 명령 사양은 Discord를 포함해 지역화된 설명을 지원하는 네이티브 표면에 `descriptionLocalizations`를 제공할 수 있습니다.
|
||||
- 네이티브 skill 명령 등록은 `commands.nativeSkills` 및 `channels.<provider>.commands.nativeSkills`로 제어됩니다.
|
||||
- 명령 사양은 Discord를 포함해 현지화된 설명을 지원하는 네이티브 표면에 `descriptionLocalizations`를 제공할 수 있습니다.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="인수 및 파서 참고 사항">
|
||||
- 명령은 명령과 인수 사이에 선택적으로 `:`를 허용합니다(예: `/think: high`, `/send: on`, `/help:`).
|
||||
- `/new <model>`은 모델 별칭, `provider/model` 또는 provider 이름을 허용합니다(퍼지 매칭). 일치 항목이 없으면 텍스트를 메시지 본문으로 처리합니다.
|
||||
- 전체 provider 사용량 분석은 `openclaw status --usage`를 사용하세요.
|
||||
- `/allowlist add|remove`에는 `commands.config=true`가 필요하며 채널 `configWrites`를 따릅니다.
|
||||
- 다중 계정 채널에서는 구성을 대상으로 하는 `/allowlist --account <id>`와 `/config set channels.<provider>.accounts.<id>...`도 대상 계정의 `configWrites`를 따릅니다.
|
||||
- `/usage`는 응답별 사용량 푸터를 제어합니다. `/usage cost`는 OpenClaw 세션 로그에서 로컬 비용 요약을 출력합니다.
|
||||
- `/restart`는 기본적으로 활성화되어 있습니다. 비활성화하려면 `commands.restart: false`를 설정합니다.
|
||||
- `/plugins install <spec>`는 `openclaw plugins install`과 같은 Plugin 사양을 허용합니다: 로컬 경로/아카이브, npm 패키지, `git:<repo>` 또는 `clawhub:<pkg>`. 그런 다음 Plugin 소스 모듈이 변경되었으므로 Gateway 재시작을 요청합니다.
|
||||
- `/plugins enable|disable`는 Plugin 구성을 업데이트하고 새 에이전트 턴에 대해 Gateway Plugin 다시 로드를 트리거합니다.
|
||||
- `/new <model>`은 모델 별칭, `provider/model` 또는 제공자 이름(퍼지 매치)을 허용합니다. 일치 항목이 없으면 텍스트를 메시지 본문으로 처리합니다.
|
||||
- 전체 제공자 사용량 분석은 `openclaw status --usage`를 사용하세요.
|
||||
- `/allowlist add|remove`는 `commands.config=true`가 필요하며 채널 `configWrites`를 준수합니다.
|
||||
- 다중 계정 채널에서는 구성 대상 `/allowlist --account <id>` 및 `/config set channels.<provider>.accounts.<id>...`도 대상 계정의 `configWrites`를 준수합니다.
|
||||
- `/usage`는 응답별 사용량 푸터를 제어합니다. `/usage cost`는 OpenClaw 세션 로그의 로컬 비용 요약을 출력합니다.
|
||||
- `/restart`는 기본적으로 활성화되어 있습니다. 비활성화하려면 `commands.restart: false`를 설정하세요.
|
||||
- `/plugins install <spec>`는 `openclaw plugins install`과 동일한 plugin 사양을 허용합니다. 로컬 경로/아카이브, npm 패키지, `git:<repo>` 또는 `clawhub:<pkg>`를 허용하며, plugin 소스 모듈이 변경되었기 때문에 Gateway 재시작을 요청합니다.
|
||||
- `/plugins enable|disable`는 plugin 구성을 업데이트하고 새 에이전트 턴을 위해 Gateway plugin 재로드를 트리거합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="채널별 동작">
|
||||
- Discord 전용 네이티브 명령: `/vc join|leave|status`는 음성 채널을 제어합니다(텍스트로 사용할 수 없음). `join`에는 길드와 선택된 음성/스테이지 채널이 필요합니다. `channels.discord.voice`와 네이티브 명령이 필요합니다.
|
||||
- Discord 전용 네이티브 명령: `/vc join|leave|status`는 음성 채널을 제어합니다(텍스트로는 사용할 수 없음). `join`에는 길드와 선택된 음성/스테이지 채널이 필요합니다. `channels.discord.voice`와 네이티브 명령이 필요합니다.
|
||||
- Discord 스레드 바인딩 명령(`/focus`, `/unfocus`, `/agents`, `/session idle`, `/session max-age`)에는 유효한 스레드 바인딩이 활성화되어 있어야 합니다(`session.threadBindings.enabled` 및/또는 `channels.discord.threadBindings.enabled`).
|
||||
- ACP 명령 참조 및 런타임 동작: [ACP 에이전트](/ko/tools/acp-agents).
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="상세 / 추적 / 빠른 모드 / reasoning 안전">
|
||||
- `/verbose`는 디버깅과 추가 가시성을 위한 것입니다. 일반 사용에서는 **꺼진 상태**로 유지하세요.
|
||||
- `/trace`는 `/verbose`보다 범위가 좁습니다. Plugin 소유의 trace/debug 줄만 드러내고 일반 verbose 도구 잡담은 꺼진 상태로 유지합니다.
|
||||
- `/fast on|off`는 세션 재정의를 영구 저장합니다. 이를 지우고 구성 기본값으로 되돌리려면 Sessions UI의 `inherit` 옵션을 사용하세요.
|
||||
- `/fast`는 provider별로 다릅니다. OpenAI/OpenAI Codex는 네이티브 Responses 엔드포인트에서 이를 `service_tier=priority`로 매핑하는 반면, `api.anthropic.com`으로 전송되는 OAuth 인증 트래픽을 포함한 직접 공개 Anthropic 요청은 이를 `service_tier=auto` 또는 `standard_only`로 매핑합니다. [OpenAI](/ko/providers/openai)와 [Anthropic](/ko/providers/anthropic)을 참조하세요.
|
||||
<Accordion title="상세 / 추적 / 빠른 모드 / 추론 안전">
|
||||
- `/verbose`는 디버깅과 추가 가시성을 위한 것입니다. 일반 사용에서는 **끄기**로 유지하세요.
|
||||
- `/trace`는 `/verbose`보다 범위가 좁습니다. plugin 소유 추적/디버그 줄만 표시하고 일반 상세 도구 잡담은 끕니다.
|
||||
- `/fast on|off`는 세션 재정의를 유지합니다. 이를 지우고 구성 기본값으로 돌아가려면 세션 UI의 `inherit` 옵션을 사용하세요.
|
||||
- `/fast`는 제공자별로 동작합니다. OpenAI/OpenAI Codex는 네이티브 Responses 엔드포인트에서 이를 `service_tier=priority`로 매핑하지만, `api.anthropic.com`으로 전송되는 OAuth 인증 트래픽을 포함한 직접 공개 Anthropic 요청은 이를 `service_tier=auto` 또는 `standard_only`로 매핑합니다. [OpenAI](/ko/providers/openai) 및 [Anthropic](/ko/providers/anthropic)을 참고하세요.
|
||||
- 도구 실패 요약은 관련이 있을 때 계속 표시되지만, 자세한 실패 텍스트는 `/verbose`가 `on` 또는 `full`일 때만 포함됩니다.
|
||||
- `/reasoning`, `/verbose`, `/trace`는 그룹 환경에서 위험합니다. 노출하려는 의도가 없었던 내부 reasoning, 도구 출력 또는 Plugin 진단을 드러낼 수 있습니다. 특히 그룹 채팅에서는 꺼진 상태로 두는 것이 좋습니다.
|
||||
- `/reasoning`, `/verbose`, `/trace`는 그룹 환경에서 위험합니다. 노출하려 하지 않았던 내부 추론, 도구 출력 또는 plugin 진단이 드러날 수 있습니다. 특히 그룹 채팅에서는 꺼진 상태로 두는 것을 권장합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="모델 전환">
|
||||
- `/model`은 새 세션 모델을 즉시 영구 저장합니다.
|
||||
- `/model`은 새 세션 모델을 즉시 유지합니다.
|
||||
- 에이전트가 유휴 상태이면 다음 실행에서 바로 사용합니다.
|
||||
- 실행이 이미 활성 상태이면 OpenClaw는 라이브 전환을 보류 중으로 표시하고, 깔끔한 재시도 지점에서만 새 모델로 다시 시작합니다.
|
||||
- 도구 활동 또는 응답 출력이 이미 시작된 경우, 보류 중인 전환은 이후 재시도 기회 또는 다음 사용자 턴까지 대기열에 남아 있을 수 있습니다.
|
||||
- 도구 활동이나 응답 출력이 이미 시작된 경우, 보류 중인 전환은 이후 재시도 기회 또는 다음 사용자 턴까지 대기열에 남을 수 있습니다.
|
||||
- 로컬 TUI에서 `/crestodian [request]`는 일반 에이전트 TUI에서 Crestodian으로 돌아갑니다. 이는 메시지 채널 구조 모드와 별개이며 원격 구성 권한을 부여하지 않습니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="빠른 경로와 인라인 단축 명령">
|
||||
<Accordion title="빠른 경로 및 인라인 바로가기">
|
||||
- **빠른 경로:** 허용 목록에 있는 발신자의 명령 전용 메시지는 즉시 처리됩니다(대기열 + 모델 우회).
|
||||
- **그룹 멘션 게이팅:** 허용 목록에 있는 발신자의 명령 전용 메시지는 멘션 요구 사항을 우회합니다.
|
||||
- **인라인 단축 명령(허용 목록에 있는 발신자만):** 특정 명령은 일반 메시지 안에 포함되어도 작동하며, 모델이 나머지 텍스트를 보기 전에 제거됩니다.
|
||||
- 예: `hey /status`는 상태 응답을 트리거하고, 남은 텍스트는 일반 흐름을 계속 따릅니다.
|
||||
- 현재: `/help`, `/commands`, `/status`, `/whoami` (`/id`).
|
||||
- **인라인 바로가기(허용 목록 발신자 전용):** 특정 명령은 일반 메시지에 포함되어 있어도 작동하며, 모델이 남은 텍스트를 보기 전에 제거됩니다.
|
||||
- 예: `hey /status`는 상태 응답을 트리거하고, 남은 텍스트는 일반 흐름을 계속 통과합니다.
|
||||
- 현재: `/help`, `/commands`, `/status`, `/whoami`(`/id`).
|
||||
- 권한이 없는 명령 전용 메시지는 조용히 무시되며, 인라인 `/...` 토큰은 일반 텍스트로 처리됩니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Skill 명령과 네이티브 인수">
|
||||
<Accordion title="Skill 명령 및 네이티브 인수">
|
||||
- **Skill 명령:** `user-invocable` skills는 슬래시 명령으로 노출됩니다. 이름은 `a-z0-9_`로 정리됩니다(최대 32자). 충돌 시 숫자 접미사가 붙습니다(예: `_2`).
|
||||
- `/skill <name> [input]`는 이름으로 skill을 실행합니다(네이티브 명령 제한 때문에 skill별 명령을 만들 수 없을 때 유용함).
|
||||
- `/skill <name> [input]`은 이름으로 skill을 실행합니다(네이티브 명령 제한으로 skill별 명령을 만들 수 없을 때 유용).
|
||||
- 기본적으로 skill 명령은 일반 요청으로 모델에 전달됩니다.
|
||||
- Skills는 선택적으로 `command-dispatch: tool`을 선언해 명령을 도구로 직접 라우팅할 수 있습니다(결정적, 모델 없음).
|
||||
- 예: `/prose` (OpenProse Plugin) — [OpenProse](/ko/prose)를 참조하세요.
|
||||
- **네이티브 명령 인수:** Discord는 동적 옵션에 자동 완성을 사용합니다(필수 인수를 생략하면 버튼 메뉴 사용). Telegram과 Slack은 명령이 선택지를 지원하고 인수를 생략하면 버튼 메뉴를 표시합니다. 동적 선택지는 대상 세션 모델을 기준으로 해석되므로, `/think` 수준 같은 모델별 옵션은 해당 세션의 `/model` 재정의를 따릅니다.
|
||||
- 예: `/prose`(OpenProse plugin) — [OpenProse](/ko/prose)를 참고하세요.
|
||||
- **네이티브 명령 인수:** Discord는 동적 옵션에 자동 완성을 사용합니다(필수 인수를 생략하면 버튼 메뉴 사용). Telegram과 Slack은 명령이 선택지를 지원하고 인수를 생략하면 버튼 메뉴를 표시합니다. 동적 선택지는 대상 세션 모델을 기준으로 확인되므로, `/think` 수준 같은 모델별 옵션은 해당 세션의 `/model` 재정의를 따릅니다.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
@ -309,25 +310,25 @@ dock 명령에는 `session.identityLinks`가 필요합니다. 소스 발신자
|
||||
|
||||
- 기본 `/tools`는 간결하며 빠른 훑어보기에 최적화되어 있습니다.
|
||||
- `/tools verbose`는 짧은 설명을 추가합니다.
|
||||
- 인수를 지원하는 네이티브 명령 표면은 `compact|verbose`와 같은 모드 전환을 노출합니다.
|
||||
- 인수를 지원하는 네이티브 명령 표면은 `compact|verbose`와 동일한 모드 전환을 노출합니다.
|
||||
- 결과는 세션 범위이므로 에이전트, 채널, 스레드, 발신자 권한 또는 모델을 변경하면 출력이 달라질 수 있습니다.
|
||||
- `/tools`에는 핵심 도구, 연결된 Plugin 도구, 채널 소유 도구를 포함해 런타임에서 실제로 도달 가능한 도구가 포함됩니다.
|
||||
- `/tools`에는 핵심 도구, 연결된 plugin 도구, 채널 소유 도구를 포함해 런타임에서 실제로 접근 가능한 도구가 포함됩니다.
|
||||
|
||||
프로필 및 재정의 편집의 경우 `/tools`를 정적 카탈로그로 취급하지 말고 Control UI Tools 패널이나 구성/카탈로그 표면을 사용하세요.
|
||||
프로필 및 재정의 편집에는 `/tools`를 정적 카탈로그로 취급하지 말고 Control UI 도구 패널 또는 구성/카탈로그 표면을 사용하세요.
|
||||
|
||||
## 사용 표면(어디에 무엇이 표시되는가)
|
||||
|
||||
- **제공자 사용량/할당량**(예: "Claude 80% left")은 사용량 추적이 활성화된 경우 현재 모델 제공자의 `/status`에 표시됩니다. OpenClaw는 제공자 윈도우를 `% left`로 정규화합니다. MiniMax의 경우 남은 비율만 제공하는 필드는 표시 전에 반전되며, `model_remains` 응답은 채팅 모델 항목과 모델 태그가 붙은 플랜 레이블을 우선합니다.
|
||||
- **토큰/캐시 줄**은 라이브 세션 스냅샷이 희소한 경우 `/status`에서 최신 트랜스크립트 사용량 항목으로 대체될 수 있습니다. 기존의 0이 아닌 라이브 값이 여전히 우선하며, 저장된 합계가 없거나 더 작은 경우 트랜스크립트 대체는 활성 런타임 모델 레이블과 더 큰 프롬프트 중심 합계도 복구할 수 있습니다.
|
||||
- **실행 vs 런타임:** `/status`는 유효한 샌드박스 경로를 `Execution`으로, 실제로 세션을 실행하는 주체를 `Runtime`으로 보고합니다: `OpenClaw Pi Default`, `OpenAI Codex`, CLI 백엔드 또는 ACP 백엔드.
|
||||
- **응답별 토큰/비용**은 `/usage off|tokens|full`로 제어됩니다(일반 응답에 추가됨).
|
||||
- **제공자 사용량/할당량**(예: "Claude 80% 남음")은 사용량 추적이 활성화된 경우 현재 모델 제공자의 `/status`에 표시됩니다. OpenClaw는 제공자 기간을 `% left`로 정규화합니다. MiniMax의 경우 남은 비율만 있는 필드는 표시 전에 반전되며, `model_remains` 응답은 채팅 모델 항목과 모델 태그가 붙은 플랜 레이블을 우선합니다.
|
||||
- **토큰/캐시 줄**은 라이브 세션 스냅샷이 부족할 때 `/status`에서 최신 transcript 사용량 항목으로 폴백할 수 있습니다. 기존의 0이 아닌 라이브 값이 여전히 우선하며, transcript 폴백은 저장된 합계가 없거나 더 작을 때 활성 런타임 모델 레이블과 더 큰 프롬프트 중심 합계도 복구할 수 있습니다.
|
||||
- **실행 vs 런타임:** `/status`는 유효한 샌드박스 경로를 `Execution`으로 보고하고, 실제로 세션을 실행하는 주체를 `Runtime`으로 보고합니다: `OpenClaw Pi Default`, `OpenAI Codex`, CLI 백엔드 또는 ACP 백엔드.
|
||||
- **응답별 토큰/비용**은 `/usage off|tokens|full`로 제어됩니다(일반 답변에 추가됨).
|
||||
- `/model status`는 사용량이 아니라 **모델/인증/엔드포인트**에 관한 것입니다.
|
||||
|
||||
## 모델 선택(`/model`)
|
||||
|
||||
`/model`은 지시문으로 구현됩니다.
|
||||
|
||||
예:
|
||||
예시:
|
||||
|
||||
```
|
||||
/model
|
||||
@ -340,16 +341,16 @@ dock 명령에는 `session.identityLinks`가 필요합니다. 소스 발신자
|
||||
|
||||
참고:
|
||||
|
||||
- `/model`과 `/model list`는 간결한 번호가 매겨진 선택기(모델 계열 + 사용 가능한 제공자)를 표시합니다.
|
||||
- Discord에서는 `/model`과 `/models`가 제공자 및 모델 드롭다운과 Submit 단계가 포함된 대화형 선택기를 엽니다.
|
||||
- `/model <#>`는 해당 선택기에서 선택합니다(가능한 경우 현재 제공자를 우선함).
|
||||
- `/model status`는 구성된 제공자 엔드포인트(`baseUrl`)와 API 모드(`api`)가 사용 가능할 때 이를 포함한 상세 보기를 표시합니다.
|
||||
- `/model`과 `/model list`는 간결한 번호 매기기 선택기(모델 패밀리 + 사용 가능한 제공자)를 표시합니다.
|
||||
- Discord에서는 `/model`과 `/models`가 제공자 및 모델 드롭다운과 제출 단계를 포함한 대화형 선택기를 엽니다.
|
||||
- `/model <#>`는 해당 선택기에서 선택합니다(가능하면 현재 제공자를 우선함).
|
||||
- `/model status`는 구성된 제공자 엔드포인트(`baseUrl`)와 API 모드(`api`)가 있으면 이를 포함한 상세 보기를 표시합니다.
|
||||
|
||||
## 디버그 재정의
|
||||
|
||||
`/debug`를 사용하면 **런타임 전용** 구성 재정의(메모리, 디스크 아님)를 설정할 수 있습니다. 소유자 전용입니다. 기본적으로 비활성화되어 있으며, `commands.debug: true`로 활성화합니다.
|
||||
|
||||
예:
|
||||
예시:
|
||||
|
||||
```
|
||||
/debug show
|
||||
@ -360,14 +361,14 @@ dock 명령에는 `session.identityLinks`가 필요합니다. 소스 발신자
|
||||
```
|
||||
|
||||
<Note>
|
||||
재정의는 새 구성 읽기에 즉시 적용되지만 `openclaw.json`에는 쓰지 않습니다. 모든 재정의를 지우고 디스크의 구성으로 돌아가려면 `/debug reset`을 사용하세요.
|
||||
재정의는 새 구성 읽기에 즉시 적용되지만, `openclaw.json`에는 쓰지 **않습니다**. 모든 재정의를 지우고 디스크의 구성으로 돌아가려면 `/debug reset`을 사용하세요.
|
||||
</Note>
|
||||
|
||||
## Plugin 추적 출력
|
||||
|
||||
`/trace`를 사용하면 전체 상세 모드를 켜지 않고도 **세션 범위 Plugin 추적/디버그 줄**을 전환할 수 있습니다.
|
||||
`/trace`를 사용하면 전체 verbose 모드를 켜지 않고도 **세션 범위 Plugin 추적/디버그 줄**을 토글할 수 있습니다.
|
||||
|
||||
예:
|
||||
예시:
|
||||
|
||||
```text
|
||||
/trace
|
||||
@ -377,18 +378,18 @@ dock 명령에는 `session.identityLinks`가 필요합니다. 소스 발신자
|
||||
|
||||
참고:
|
||||
|
||||
- 인수 없이 `/trace`를 사용하면 현재 세션 추적 상태를 표시합니다.
|
||||
- `/trace on`은 현재 세션에 대해 Plugin 추적 줄을 활성화합니다.
|
||||
- 인수 없이 `/trace`를 사용하면 현재 세션 추적 상태가 표시됩니다.
|
||||
- `/trace on`은 현재 세션에 Plugin 추적 줄을 활성화합니다.
|
||||
- `/trace off`는 이를 다시 비활성화합니다.
|
||||
- Plugin 추적 줄은 `/status`에 표시되거나 일반 어시스턴트 응답 이후 후속 진단 메시지로 나타날 수 있습니다.
|
||||
- Plugin 추적 줄은 `/status`에 나타날 수 있으며, 일반 assistant 답변 이후 후속 진단 메시지로도 나타날 수 있습니다.
|
||||
- `/trace`는 `/debug`를 대체하지 않습니다. `/debug`는 여전히 런타임 전용 구성 재정의를 관리합니다.
|
||||
- `/trace`는 `/verbose`를 대체하지 않습니다. 일반 상세 도구/상태 출력은 여전히 `/verbose`에 속합니다.
|
||||
- `/trace`는 `/verbose`를 대체하지 않습니다. 일반 verbose 도구/상태 출력은 여전히 `/verbose`에 속합니다.
|
||||
|
||||
## 구성 업데이트
|
||||
|
||||
`/config`는 디스크의 구성(`openclaw.json`)에 씁니다. 소유자 전용입니다. 기본적으로 비활성화되어 있으며, `commands.config: true`로 활성화합니다.
|
||||
|
||||
예:
|
||||
예시:
|
||||
|
||||
```
|
||||
/config show
|
||||
@ -404,9 +405,9 @@ dock 명령에는 `session.identityLinks`가 필요합니다. 소스 발신자
|
||||
|
||||
## MCP 업데이트
|
||||
|
||||
`/mcp`는 OpenClaw가 관리하는 MCP 서버 정의를 `mcp.servers` 아래에 씁니다. 소유자 전용입니다. 기본적으로 비활성화되어 있으며, `commands.mcp: true`로 활성화합니다.
|
||||
`/mcp`는 `mcp.servers` 아래의 OpenClaw 관리 MCP 서버 정의를 씁니다. 소유자 전용입니다. 기본적으로 비활성화되어 있으며, `commands.mcp: true`로 활성화합니다.
|
||||
|
||||
예:
|
||||
예시:
|
||||
|
||||
```text
|
||||
/mcp show
|
||||
@ -416,14 +417,14 @@ dock 명령에는 `session.identityLinks`가 필요합니다. 소스 발신자
|
||||
```
|
||||
|
||||
<Note>
|
||||
`/mcp`는 구성을 Pi 소유 프로젝트 설정이 아니라 OpenClaw 구성에 저장합니다. 런타임 어댑터가 실제로 실행 가능한 전송 방식을 결정합니다.
|
||||
`/mcp`는 Pi 소유 프로젝트 설정이 아니라 OpenClaw 구성에 구성을 저장합니다. 런타임 어댑터가 실제로 실행 가능한 전송 방식을 결정합니다.
|
||||
</Note>
|
||||
|
||||
## Plugin 업데이트
|
||||
|
||||
`/plugins`를 사용하면 운영자가 발견된 Plugin을 검사하고 구성에서 활성화를 전환할 수 있습니다. 읽기 전용 흐름은 `/plugin`을 별칭으로 사용할 수 있습니다. 기본적으로 비활성화되어 있으며, `commands.plugins: true`로 활성화합니다.
|
||||
`/plugins`를 사용하면 운영자가 발견된 Plugin을 검사하고 구성에서 활성화 여부를 토글할 수 있습니다. 읽기 전용 흐름에서는 `/plugin`을 별칭으로 사용할 수 있습니다. 기본적으로 비활성화되어 있으며, `commands.plugins: true`로 활성화합니다.
|
||||
|
||||
예:
|
||||
예시:
|
||||
|
||||
```text
|
||||
/plugins
|
||||
@ -434,10 +435,10 @@ dock 명령에는 `session.identityLinks`가 필요합니다. 소스 발신자
|
||||
```
|
||||
|
||||
<Note>
|
||||
- `/plugins list`와 `/plugins show`는 현재 워크스페이스와 디스크 구성에 대해 실제 Plugin 검색을 사용합니다.
|
||||
- `/plugins install`은 ClawHub, npm, git, 로컬 디렉터리, 아카이브에서 설치합니다.
|
||||
- `/plugins enable|disable`은 Plugin 구성만 업데이트합니다. Plugin을 설치하거나 제거하지는 않습니다.
|
||||
- 활성화 및 비활성화 변경은 새 에이전트 턴을 위해 Gateway Plugin 런타임 표면을 핫 리로드합니다. 설치는 Plugin 소스 모듈이 변경되었으므로 Gateway 재시작을 요청합니다.
|
||||
- `/plugins list`와 `/plugins show`는 현재 워크스페이스와 디스크의 구성을 기준으로 실제 Plugin 검색을 사용합니다.
|
||||
- `/plugins install`은 ClawHub, npm, git, 로컬 디렉터리 및 아카이브에서 설치합니다.
|
||||
- `/plugins enable|disable`은 Plugin 구성만 업데이트하며, Plugin을 설치하거나 제거하지 않습니다.
|
||||
- 활성화 및 비활성화 변경은 새 에이전트 턴에 대해 Gateway Plugin 런타임 표면을 핫 리로드합니다. 설치는 Plugin 소스 모듈이 변경되었기 때문에 Gateway 재시작을 요청합니다.
|
||||
|
||||
</Note>
|
||||
|
||||
@ -454,35 +455,35 @@ dock 명령에는 `session.identityLinks`가 필요합니다. 소스 발신자
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Slack 세부 사항">
|
||||
`channels.slack.slashCommand`는 단일 `/openclaw` 스타일 명령에 대해 여전히 지원됩니다. `commands.native`를 활성화하는 경우 내장 명령마다 Slack 슬래시 명령을 하나씩 만들어야 합니다(`/help`와 동일한 이름). Slack용 명령 인수 메뉴는 임시 Block Kit 버튼으로 전달됩니다.
|
||||
`channels.slack.slashCommand`는 단일 `/openclaw` 스타일 명령에 대해 여전히 지원됩니다. `commands.native`를 활성화하면 기본 제공 명령마다 Slack 슬래시 명령을 하나씩 만들어야 합니다(`/help`와 같은 이름). Slack용 명령 인수 메뉴는 임시 Block Kit 버튼으로 전달됩니다.
|
||||
|
||||
Slack 네이티브 예외: Slack이 `/status`를 예약하므로 `/status`가 아니라 `/agentstatus`를 등록하세요. 텍스트 `/status`는 Slack 메시지에서 여전히 작동합니다.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## BTW 부가 질문
|
||||
## BTW 보조 질문
|
||||
|
||||
`/btw`는 현재 세션에 관한 빠른 **부가 질문**입니다. `/side`는 별칭입니다.
|
||||
`/btw`는 현재 세션에 대한 빠른 **보조 질문**입니다. `/side`는 별칭입니다.
|
||||
|
||||
일반 채팅과 달리:
|
||||
|
||||
- 현재 세션을 배경 컨텍스트로 사용합니다.
|
||||
- 별도의 **도구 없는** 일회성 호출로 실행됩니다.
|
||||
- 이후 세션 컨텍스트를 변경하지 않습니다.
|
||||
- 트랜스크립트 기록에 쓰이지 않습니다.
|
||||
- 일반 어시스턴트 메시지가 아니라 라이브 부가 결과로 전달됩니다.
|
||||
- 향후 세션 컨텍스트를 변경하지 않습니다.
|
||||
- transcript 기록에 기록되지 않습니다.
|
||||
- 일반 assistant 메시지 대신 라이브 보조 결과로 전달됩니다.
|
||||
|
||||
이로 인해 `/btw`는 주 작업이 계속 진행되는 동안 임시 설명이 필요할 때 유용합니다.
|
||||
따라서 `/btw`는 메인 작업이 계속 진행되는 동안 임시 설명이 필요할 때 유용합니다.
|
||||
|
||||
예:
|
||||
예시:
|
||||
|
||||
```text
|
||||
/btw what are we doing right now?
|
||||
/side what changed while the main run continued?
|
||||
```
|
||||
|
||||
전체 동작과 클라이언트 UX 세부 사항은 [BTW 부가 질문](/ko/tools/btw)을 참조하세요.
|
||||
전체 동작과 클라이언트 UX 세부 정보는 [BTW 보조 질문](/ko/tools/btw)을 참조하세요.
|
||||
|
||||
## 관련 항목
|
||||
|
||||
|
||||
74
docs/ko/tools/steer.md
Normal file
74
docs/ko/tools/steer.md
Normal file
@ -0,0 +1,74 @@
|
||||
---
|
||||
read_when:
|
||||
- 에이전트가 이미 실행 중일 때 /steer 또는 /tell 사용
|
||||
- /steer와 /queue steer 비교
|
||||
- 현재 실행, 하위 에이전트 또는 ACP 세션 중 무엇을 조정할지 결정하기
|
||||
sidebarTitle: Steer
|
||||
summary: 대기열 모드를 변경하지 않고 활성 실행 제어하기
|
||||
title: 조정
|
||||
x-i18n:
|
||||
generated_at: "2026-05-04T02:26:00Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 71e1c80c0eea86d5c3c29513d3ed0675c04779fc9c6ee3b8a76c4bedaa264d22
|
||||
source_path: tools/steer.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
`/steer`는 이미 활성화된 실행에 지침을 보냅니다. 새 턴을 시작하기 위한 것이 아니라, "이 실행이 아직 작업 중일 때 조정"해야 하는 순간에 사용합니다.
|
||||
|
||||
## 현재 세션
|
||||
|
||||
최상위 `/steer`를 사용해 현재 세션의 활성 실행을 대상으로 지정합니다.
|
||||
|
||||
```text
|
||||
/steer prefer the smaller patch and keep the tests focused
|
||||
/tell summarize before making the next tool call
|
||||
```
|
||||
|
||||
동작:
|
||||
|
||||
- 현재 세션의 활성 실행만 대상으로 지정합니다.
|
||||
- 세션의 `/queue` 모드와 독립적으로 작동합니다.
|
||||
- 세션이 유휴 상태일 때 새 실행을 시작하지 않습니다.
|
||||
- 조정할 활성 실행이 없으면 경고로 응답합니다.
|
||||
- 활성 런타임의 조정 경로를 사용하므로, 모델은 다음에 지원되는 런타임 경계에서 지침을 확인합니다.
|
||||
|
||||
## steer와 queue 비교
|
||||
|
||||
`/queue steer`는 실행이 활성 상태일 때 일반 수신 메시지가 도착하면 해당 메시지가 어떻게 동작할지 변경합니다. `/steer <message>`는 저장된 `/queue` 설정과 관계없이, 다음에 지원되는 런타임 경계에서 해당 명령의 메시지를 활성 실행에 주입하려고 시도하는 명시적 명령입니다.
|
||||
|
||||
사용:
|
||||
|
||||
- 활성 실행을 지금 바로 안내하려면 `/steer <message>`를 사용합니다.
|
||||
- 앞으로 일반 메시지가 기본적으로 활성 실행을 조정하도록 하려면 `/queue steer`를 사용합니다.
|
||||
- 새 메시지가 활성 실행을 조정하는 대신 이후 턴을 기다려야 한다면 `/queue collect` 또는 `/queue followup`을 사용합니다.
|
||||
|
||||
큐 모드와 폴백 동작은 [명령 큐](/ko/concepts/queue) 및 [조정 큐](/ko/concepts/queue-steering)를 참조하세요.
|
||||
|
||||
## 하위 에이전트
|
||||
|
||||
대상이 하위 실행인 경우 `/subagents steer`를 사용합니다.
|
||||
|
||||
```text
|
||||
/subagents steer 2 focus only on the API surface
|
||||
```
|
||||
|
||||
최상위 `/steer`는 id나 목록 인덱스로 하위 에이전트를 선택하지 않습니다. 항상 현재 세션의 활성 실행을 대상으로 지정합니다. 하위 에이전트 id, 레이블, 제어 명령은 [하위 에이전트](/ko/tools/subagents)를 참조하세요.
|
||||
|
||||
## ACP 세션
|
||||
|
||||
대상이 ACP 하네스 세션인 경우 `/acp steer`를 사용합니다.
|
||||
|
||||
```text
|
||||
/acp steer --session agent:main:acp:codex tighten the repro
|
||||
```
|
||||
|
||||
ACP 세션 선택과 런타임 동작은 [ACP 에이전트](/ko/tools/acp-agents)를 참조하세요.
|
||||
|
||||
## 관련 항목
|
||||
|
||||
- [슬래시 명령](/ko/tools/slash-commands)
|
||||
- [명령 큐](/ko/concepts/queue)
|
||||
- [조정 큐](/ko/concepts/queue-steering)
|
||||
- [하위 에이전트](/ko/tools/subagents)
|
||||
@ -1,45 +1,45 @@
|
||||
---
|
||||
read_when:
|
||||
- 에이전트를 통해 백그라운드 또는 병렬 작업을 수행하려는 경우
|
||||
- 에이전트를 통해 백그라운드 작업이나 병렬 작업을 실행하려는 경우
|
||||
- sessions_spawn 또는 하위 에이전트 도구 정책을 변경하고 있습니다
|
||||
- 스레드에 바인딩된 하위 에이전트 세션을 구현하거나 문제를 해결하는 경우
|
||||
- 스레드에 바인딩된 서브에이전트 세션을 구현하거나 문제를 해결하는 중입니다
|
||||
sidebarTitle: Sub-agents
|
||||
summary: 결과를 요청자 채팅에 다시 알리는 격리된 백그라운드 에이전트 실행을 생성합니다
|
||||
summary: 결과를 요청자 채팅으로 다시 알리는 격리된 백그라운드 에이전트 실행을 생성합니다
|
||||
title: 하위 에이전트
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T21:17:07Z"
|
||||
generated_at: "2026-05-04T02:26:10Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 0e964df543bd19435daf94f2c85a34b9d32e07662405d2eac7635935f1e7bf64
|
||||
source_hash: d0df39e06b952def3eb0b296f36c7dc8c0b0a115785d865236a970c5d453fc37
|
||||
source_path: tools/subagents.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
하위 에이전트는 기존 에이전트 실행에서 생성되는 백그라운드 에이전트 실행입니다.
|
||||
자체 세션(`agent:<agentId>:subagent:<uuid>`)에서 실행되며,
|
||||
완료되면 그 결과를 요청자 채팅 채널에 **알립니다**. 각 하위 에이전트 실행은
|
||||
[백그라운드 작업](/ko/automation/tasks)으로 추적됩니다.
|
||||
각자의 세션(`agent:<agentId>:subagent:<uuid>`)에서 실행되며,
|
||||
완료되면 결과를 요청자 채팅 채널로 **알립니다**.
|
||||
각 하위 에이전트 실행은 [백그라운드 작업](/ko/automation/tasks)으로 추적됩니다.
|
||||
|
||||
주요 목표:
|
||||
|
||||
- 메인 실행을 차단하지 않고 "조사 / 긴 작업 / 느린 도구" 작업을 병렬화합니다.
|
||||
- 기본적으로 하위 에이전트를 격리 상태로 유지합니다(세션 분리 + 선택적 샌드박싱).
|
||||
- 도구 표면을 오용하기 어렵게 유지합니다. 하위 에이전트는 기본적으로 세션 도구를 받지 **않습니다**.
|
||||
- 오케스트레이터 패턴을 위해 구성 가능한 중첩 깊이를 지원합니다.
|
||||
- 기본 실행을 차단하지 않고 "조사 / 장기 작업 / 느린 도구" 작업을 병렬화합니다.
|
||||
- 기본적으로 하위 에이전트를 격리된 상태로 유지합니다(세션 분리 + 선택적 샌드박싱).
|
||||
- 도구 표면을 오용하기 어렵게 유지합니다. 하위 에이전트에는 기본적으로 세션 도구가 제공되지 **않습니다**.
|
||||
- 오케스트레이터 패턴을 위한 구성 가능한 중첩 깊이를 지원합니다.
|
||||
|
||||
<Note>
|
||||
**비용 참고:** 각 하위 에이전트는 기본적으로 자체 컨텍스트와 토큰 사용량을 가집니다.
|
||||
무겁거나 반복적인 작업에는 하위 에이전트에 더 저렴한 모델을 설정하고
|
||||
메인 에이전트는 더 높은 품질의 모델로 유지하세요. `agents.defaults.subagents.model`
|
||||
또는 에이전트별 재정의를 통해 구성합니다. 자식이 요청자의 현재 transcript를
|
||||
실제로 필요로 할 때는 해당 생성 한 번에 `context: "fork"`를 요청할 수 있습니다.
|
||||
thread-bound 하위 에이전트 세션은 현재 대화를 후속 thread로 분기하므로
|
||||
**비용 참고:** 기본적으로 각 하위 에이전트에는 자체 컨텍스트와 토큰 사용량이 있습니다.
|
||||
무겁거나 반복적인 작업의 경우 하위 에이전트에는 더 저렴한 모델을 설정하고
|
||||
기본 에이전트는 더 높은 품질의 모델로 유지하세요. `agents.defaults.subagents.model`
|
||||
또는 에이전트별 재정의를 통해 구성합니다. 자식이 요청자의 현재 transcript가
|
||||
실제로 필요한 경우, 에이전트는 해당 생성 한 번에 대해 `context: "fork"`를 요청할 수 있습니다.
|
||||
스레드 바인딩된 하위 에이전트 세션은 현재 대화를 후속 스레드로 분기하므로
|
||||
기본값이 `context: "fork"`입니다.
|
||||
</Note>
|
||||
|
||||
## 슬래시 명령
|
||||
|
||||
**현재 세션**의 하위 에이전트 실행을 검사하거나 제어하려면 `/subagents`를 사용합니다.
|
||||
**현재 세션**의 하위 에이전트 실행을 검사하거나 제어하려면 `/subagents`를 사용하세요.
|
||||
|
||||
```text
|
||||
/subagents list
|
||||
@ -51,15 +51,17 @@ x-i18n:
|
||||
/subagents spawn <agentId> <task> [--model <model>] [--thinking <level>]
|
||||
```
|
||||
|
||||
`/subagents info`는 실행 메타데이터(상태, 타임스탬프, 세션 id,
|
||||
transcript 경로, 정리)를 표시합니다. 제한된 안전 필터링 recall 보기는
|
||||
현재 요청자 세션의 활성 실행을 조종하려면 최상위 [`/steer <message>`](/ko/tools/steer)를 사용하세요. 대상이 자식 실행이면 `/subagents steer <id|#> <message>`를 사용하세요.
|
||||
|
||||
`/subagents info`는 실행 메타데이터(상태, 타임스탬프, 세션 ID,
|
||||
transcript 경로, 정리)를 표시합니다. 제한되고 안전 필터링된 회수 보기는
|
||||
`sessions_history`를 사용하고, 원시 전체 transcript가 필요할 때는 디스크의
|
||||
transcript 경로를 검사하세요.
|
||||
|
||||
### Thread 바인딩 제어
|
||||
### 스레드 바인딩 제어
|
||||
|
||||
이 명령은 영구 thread 바인딩을 지원하는 채널에서 작동합니다.
|
||||
아래의 [Thread 지원 채널](#thread-supporting-channels)을 참조하세요.
|
||||
이 명령은 영구 스레드 바인딩을 지원하는 채널에서 작동합니다.
|
||||
아래의 [스레드 지원 채널](#thread-supporting-channels)을 참조하세요.
|
||||
|
||||
```text
|
||||
/focus <subagent-label|session-key|session-id|session-label>
|
||||
@ -71,73 +73,72 @@ transcript 경로를 검사하세요.
|
||||
|
||||
### 생성 동작
|
||||
|
||||
`/subagents spawn`은 사용자 명령(내부 릴레이가 아님)으로 백그라운드 하위 에이전트를 시작하고,
|
||||
실행이 완료되면 최종 완료 업데이트 하나를 요청자 채팅으로 보냅니다.
|
||||
`/subagents spawn`은 내부 릴레이가 아닌 사용자 명령으로 백그라운드 하위 에이전트를 시작하고,
|
||||
실행이 끝나면 요청자 채팅으로 최종 완료 업데이트 하나를 보냅니다.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Non-blocking, push-based completion">
|
||||
- 생성 명령은 비차단입니다. 즉시 실행 id를 반환합니다.
|
||||
- 완료되면 하위 에이전트가 요약/결과 메시지를 요청자 채팅 채널로 알립니다.
|
||||
- 완료는 push 기반입니다. 생성한 뒤에는 완료를 기다리기 위해 `/subagents list`, `sessions_list`, 또는 `sessions_history`를 루프에서 polling하지 **마세요**. 디버깅이나 개입이 필요할 때만 상태를 확인하세요.
|
||||
- 완료 시 OpenClaw는 announce 정리 흐름이 계속되기 전에 해당 하위 에이전트 세션이 연 추적된 브라우저 탭/프로세스를 best-effort로 닫습니다.
|
||||
<Accordion title="비차단 푸시 기반 완료">
|
||||
- 생성 명령은 비차단 방식이며, 실행 ID를 즉시 반환합니다.
|
||||
- 완료 시 하위 에이전트는 요약/결과 메시지를 요청자 채팅 채널로 알립니다.
|
||||
- 완료는 푸시 기반입니다. 생성된 후에는 완료를 기다리기 위해 `/subagents list`, `sessions_list`, 또는 `sessions_history`를 루프에서 폴링하지 **마세요**. 디버깅이나 개입이 필요할 때만 온디맨드로 상태를 검사하세요.
|
||||
- 완료 시 OpenClaw는 알림 정리 흐름이 계속되기 전에 해당 하위 에이전트 세션이 연 추적된 브라우저 탭/프로세스를 최선 노력으로 닫습니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Manual-spawn delivery resilience">
|
||||
- OpenClaw는 안정적인 idempotency key로 직접 `agent` 전달을 먼저 시도합니다.
|
||||
- 직접 전달이 실패하면 queue routing으로 fallback합니다.
|
||||
- queue routing도 아직 사용할 수 없으면 최종 포기 전에 짧은 exponential backoff로 announce를 재시도합니다.
|
||||
- 완료 전달은 해석된 요청자 route를 유지합니다. 사용 가능한 경우 thread-bound 또는 conversation-bound 완료 route가 우선하며, 완료 origin이 채널만 제공하는 경우 OpenClaw는 요청자 세션의 해석된 route(`lastChannel` / `lastTo` / `lastAccountId`)에서 누락된 target/account를 채워 직접 전달이 계속 작동하게 합니다.
|
||||
<Accordion title="수동 생성 전달 복원력">
|
||||
- OpenClaw는 안정적인 멱등성 키로 직접 `agent` 전달을 먼저 시도합니다.
|
||||
- 직접 전달이 실패하면 큐 라우팅으로 폴백합니다.
|
||||
- 큐 라우팅도 여전히 사용할 수 없으면 최종 포기 전에 짧은 지수 백오프로 알림을 재시도합니다.
|
||||
- 완료 전달은 확인된 요청자 경로를 유지합니다. 스레드 바인딩 또는 대화 바인딩 완료 경로가 사용 가능하면 우선하며, 완료 출처가 채널만 제공하는 경우 OpenClaw는 요청자 세션의 확인된 경로(`lastChannel` / `lastTo` / `lastAccountId`)에서 누락된 대상/계정을 채워 직접 전달이 계속 작동하도록 합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Completion handoff metadata">
|
||||
요청자 세션으로의 완료 handoff는 런타임이 생성한 내부 컨텍스트(사용자가 작성한 텍스트가 아님)이며 다음을 포함합니다.
|
||||
<Accordion title="완료 인계 메타데이터">
|
||||
요청자 세션으로의 완료 인계는 런타임에서 생성한 내부 컨텍스트(사용자가 작성한 텍스트가 아님)이며 다음을 포함합니다.
|
||||
|
||||
- `Result` — 최신 visible `assistant` 응답 텍스트, 없으면 sanitize된 최신 tool/toolResult 텍스트입니다. terminal failed 실행은 캡처된 응답 텍스트를 재사용하지 않습니다.
|
||||
- `Result` — 최신 가시 `assistant` 응답 텍스트, 없으면 정리된 최신 도구/toolResult 텍스트입니다. 종료된 실패 실행은 캡처된 응답 텍스트를 재사용하지 않습니다.
|
||||
- `Status` — `completed successfully` / `failed` / `timed out` / `unknown`.
|
||||
- 압축된 런타임/토큰 통계.
|
||||
- 요청자 에이전트에게 원시 내부 메타데이터를 전달하지 말고 일반 assistant 음성으로 다시 작성하라는 전달 지시.
|
||||
- 간결한 런타임/토큰 통계.
|
||||
- 요청자 에이전트에게 원시 내부 메타데이터를 전달하지 말고 일반 assistant 음성으로 다시 쓰라고 지시하는 전달 지침.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Modes and ACP runtime">
|
||||
- `--model` 및 `--thinking`은 해당 특정 실행의 기본값을 재정의합니다.
|
||||
<Accordion title="모드 및 ACP 런타임">
|
||||
- `--model`과 `--thinking`은 해당 특정 실행의 기본값을 재정의합니다.
|
||||
- 완료 후 세부 정보와 출력을 검사하려면 `info`/`log`를 사용하세요.
|
||||
- `/subagents spawn`은 one-shot 모드(`mode: "run"`)입니다. 영구 thread-bound 세션에는 `thread: true` 및 `mode: "session"`으로 `sessions_spawn`을 사용하세요.
|
||||
- ACP harness 세션(Claude Code, Gemini CLI, OpenCode, 또는 명시적인 Codex ACP/acpx)의 경우, 도구가 해당 런타임을 광고할 때 `runtime: "acp"`로 `sessions_spawn`을 사용하세요. 완료 또는 에이전트 간 루프를 디버깅할 때는 [ACP delivery model](/ko/tools/acp-agents#delivery-model)을 참조하세요. `codex` Plugin이 활성화되어 있으면, 사용자가 ACP/acpx를 명시적으로 요청하지 않는 한 Codex 채팅/thread 제어는 ACP보다 `/codex ...`를 선호해야 합니다.
|
||||
- OpenClaw는 ACP가 활성화되고, 요청자가 샌드박스 상태가 아니며, `acpx` 같은 backend Plugin이 로드될 때까지 `runtime: "acp"`를 숨깁니다. `runtime: "acp"`는 외부 ACP harness id 또는 `runtime.type="acp"`인 `agents.list[]` 항목을 기대합니다. `agents_list`의 일반 OpenClaw 구성 에이전트에는 기본 하위 에이전트 런타임을 사용하세요.
|
||||
- `/subagents spawn`은 일회성 모드(`mode: "run"`)입니다. 영구 스레드 바인딩 세션의 경우 `thread: true` 및 `mode: "session"`과 함께 `sessions_spawn`을 사용하세요.
|
||||
- ACP 하네스 세션(Claude Code, Gemini CLI, OpenCode, 또는 명시적 Codex ACP/acpx)의 경우 도구가 해당 런타임을 알릴 때 `runtime: "acp"`와 함께 `sessions_spawn`을 사용하세요. 완료나 에이전트 간 루프를 디버깅할 때는 [ACP 전달 모델](/ko/tools/acp-agents#delivery-model)을 참조하세요. `codex` Plugin이 활성화된 경우, 사용자가 ACP/acpx를 명시적으로 요청하지 않는 한 Codex 채팅/스레드 제어는 ACP보다 `/codex ...`를 선호해야 합니다.
|
||||
- OpenClaw는 ACP가 활성화되고, 요청자가 샌드박스 처리되어 있지 않으며, `acpx` 같은 백엔드 Plugin이 로드될 때까지 `runtime: "acp"`를 숨깁니다. `runtime: "acp"`는 외부 ACP 하네스 ID 또는 `runtime.type="acp"`인 `agents.list[]` 항목을 기대합니다. `agents_list`의 일반 OpenClaw 구성 에이전트에는 기본 하위 에이전트 런타임을 사용하세요.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 컨텍스트 모드
|
||||
|
||||
Native 하위 에이전트는 호출자가 현재 transcript fork를 명시적으로 요청하지 않는 한 격리 상태로 시작합니다.
|
||||
네이티브 하위 에이전트는 호출자가 현재 transcript를 포크하도록 명시적으로 요청하지 않는 한 격리된 상태로 시작합니다.
|
||||
|
||||
| 모드 | 사용 시점 | 동작 |
|
||||
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
|
||||
| `isolated` | 새로운 조사, 독립적인 구현, 느린 도구 작업, 또는 작업 텍스트로 간략히 설명할 수 있는 모든 것 | 깨끗한 자식 transcript를 생성합니다. 이것이 기본값이며 토큰 사용량을 낮게 유지합니다. |
|
||||
| `isolated` | 새로운 조사, 독립 구현, 느린 도구 작업, 또는 작업 텍스트로 간략히 설명할 수 있는 모든 작업 | 깨끗한 자식 transcript를 만듭니다. 이것이 기본값이며 토큰 사용량을 낮게 유지합니다. |
|
||||
| `fork` | 현재 대화, 이전 도구 결과, 또는 요청자 transcript에 이미 있는 미묘한 지침에 의존하는 작업 | 자식이 시작되기 전에 요청자 transcript를 자식 세션으로 분기합니다. |
|
||||
|
||||
`fork`는 아껴서 사용하세요. 이는 컨텍스트에 민감한 위임을 위한 것이지,
|
||||
명확한 작업 프롬프트를 작성하는 것을 대체하지 않습니다.
|
||||
`fork`는 아껴서 사용하세요. 이는 컨텍스트에 민감한 위임을 위한 것이며,
|
||||
명확한 작업 프롬프트 작성의 대체물이 아닙니다.
|
||||
|
||||
## 도구: `sessions_spawn`
|
||||
|
||||
전역 `subagent` lane에서 `deliver: false`로 하위 에이전트 실행을 시작한 다음,
|
||||
announce 단계를 실행하고 announce 응답을 요청자 채팅 채널에 게시합니다.
|
||||
전역 `subagent` 레인에서 `deliver: false`로 하위 에이전트 실행을 시작한 다음,
|
||||
알림 단계를 실행하고 알림 응답을 요청자 채팅 채널에 게시합니다.
|
||||
|
||||
사용 가능 여부는 호출자의 effective tool policy에 따라 달라집니다. `coding` 및
|
||||
`full` profile은 기본적으로 `sessions_spawn`을 노출합니다. `messaging` profile은
|
||||
그렇지 않습니다. 작업을 위임해야 하는 에이전트에는
|
||||
`tools.alsoAllow: ["sessions_spawn", "sessions_yield", "subagents"]`를 추가하거나
|
||||
`tools.profile: "coding"`을 사용하세요. 채널/그룹, provider, sandbox, 에이전트별
|
||||
allow/deny policy는 profile 단계 이후에도 도구를 제거할 수 있습니다. 같은 세션에서
|
||||
`/tools`를 사용해 effective tool list를 확인하세요.
|
||||
사용 가능 여부는 호출자의 유효 도구 정책에 따라 달라집니다. `coding` 및
|
||||
`full` 프로필은 기본적으로 `sessions_spawn`을 노출합니다. `messaging` 프로필은
|
||||
그렇지 않습니다. 작업을 위임해야 하는 에이전트에는 `tools.alsoAllow: ["sessions_spawn", "sessions_yield",
|
||||
"subagents"]`를 추가하거나 `tools.profile: "coding"`을 사용하세요.
|
||||
채널/그룹, 제공자, 샌드박스, 에이전트별 허용/거부 정책은 프로필 단계 이후에도
|
||||
도구를 제거할 수 있습니다. 유효 도구 목록을 확인하려면 같은 세션에서 `/tools`를 사용하세요.
|
||||
|
||||
**기본값:**
|
||||
|
||||
- **모델:** `agents.defaults.subagents.model`(또는 에이전트별 `agents.list[].subagents.model`)을 설정하지 않는 한 호출자를 상속합니다. 명시적인 `sessions_spawn.model`이 여전히 우선합니다.
|
||||
- **Thinking:** `agents.defaults.subagents.thinking`(또는 에이전트별 `agents.list[].subagents.thinking`)을 설정하지 않는 한 호출자를 상속합니다. 명시적인 `sessions_spawn.thinking`이 여전히 우선합니다.
|
||||
- **실행 timeout:** `sessions_spawn.runTimeoutSeconds`가 생략되면, OpenClaw는 설정된 경우 `agents.defaults.subagents.runTimeoutSeconds`를 사용합니다. 그렇지 않으면 `0`(timeout 없음)으로 fallback합니다.
|
||||
- **모델:** `agents.defaults.subagents.model`(또는 에이전트별 `agents.list[].subagents.model`)을 설정하지 않으면 호출자를 상속합니다. 명시적 `sessions_spawn.model`이 여전히 우선합니다.
|
||||
- **Thinking:** `agents.defaults.subagents.thinking`(또는 에이전트별 `agents.list[].subagents.thinking`)을 설정하지 않으면 호출자를 상속합니다. 명시적 `sessions_spawn.thinking`이 여전히 우선합니다.
|
||||
- **실행 제한 시간:** `sessions_spawn.runTimeoutSeconds`가 생략되면 OpenClaw는 설정된 경우 `agents.defaults.subagents.runTimeoutSeconds`를 사용하고, 그렇지 않으면 `0`(제한 시간 없음)으로 폴백합니다.
|
||||
|
||||
### 도구 매개변수
|
||||
|
||||
@ -145,60 +146,61 @@ allow/deny policy는 profile 단계 이후에도 도구를 제거할 수 있습
|
||||
하위 에이전트의 작업 설명입니다.
|
||||
</ParamField>
|
||||
<ParamField path="label" type="string">
|
||||
선택적 사람이 읽기 쉬운 label입니다.
|
||||
선택적 사람이 읽을 수 있는 레이블입니다.
|
||||
</ParamField>
|
||||
<ParamField path="agentId" type="string">
|
||||
`subagents.allowAgents`에서 허용될 때 다른 에이전트 id 아래에 생성합니다.
|
||||
`subagents.allowAgents`에서 허용되는 경우 다른 에이전트 ID 아래에서 생성합니다.
|
||||
</ParamField>
|
||||
<ParamField path="runtime" type='"subagent" | "acp"' default="subagent">
|
||||
`acp`는 외부 ACP harness(`claude`, `droid`, `gemini`, `opencode`, 또는 명시적으로 요청된 Codex ACP/acpx)와 `runtime.type`이 `acp`인 `agents.list[]` 항목에만 사용합니다.
|
||||
`acp`는 외부 ACP 하네스(`claude`, `droid`, `gemini`, `opencode`, 또는 명시적으로 요청된 Codex ACP/acpx)와 `runtime.type`이 `acp`인 `agents.list[]` 항목에만 사용됩니다.
|
||||
</ParamField>
|
||||
<ParamField path="resumeSessionId" type="string">
|
||||
ACP 전용입니다. `runtime: "acp"`일 때 기존 ACP harness 세션을 재개합니다. native 하위 에이전트 생성에서는 무시됩니다.
|
||||
ACP 전용입니다. `runtime: "acp"`일 때 기존 ACP 하네스 세션을 재개하며, 네이티브 하위 에이전트 생성에서는 무시됩니다.
|
||||
</ParamField>
|
||||
<ParamField path="streamTo" type='"parent"'>
|
||||
ACP 전용입니다. `runtime: "acp"`일 때 ACP 실행 출력을 부모 세션으로 스트리밍합니다. native 하위 에이전트 생성에서는 생략하세요.
|
||||
ACP 전용입니다. `runtime: "acp"`일 때 ACP 실행 출력을 부모 세션으로 스트리밍합니다. 네이티브 하위 에이전트 생성에서는 생략하세요.
|
||||
</ParamField>
|
||||
<ParamField path="model" type="string">
|
||||
하위 에이전트 모델을 재정의합니다. 유효하지 않은 값은 건너뛰며, 하위 에이전트는 도구 결과의 경고와 함께 기본 모델에서 실행됩니다.
|
||||
하위 에이전트 모델을 재정의합니다. 유효하지 않은 값은 건너뛰며, 하위 에이전트는 도구 결과에 경고를 남기고 기본 모델로 실행됩니다.
|
||||
</ParamField>
|
||||
<ParamField path="thinking" type="string">
|
||||
하위 에이전트 실행의 thinking level을 재정의합니다.
|
||||
하위 에이전트 실행의 thinking 수준을 재정의합니다.
|
||||
</ParamField>
|
||||
<ParamField path="runTimeoutSeconds" type="number">
|
||||
설정된 경우 기본값은 `agents.defaults.subagents.runTimeoutSeconds`이며, 그렇지 않으면 `0`입니다. 설정하면 하위 에이전트 실행은 N초 후 중단됩니다.
|
||||
설정된 경우 기본값은 `agents.defaults.subagents.runTimeoutSeconds`이고, 그렇지 않으면 `0`입니다. 설정하면 하위 에이전트 실행은 N초 후 중단됩니다.
|
||||
</ParamField>
|
||||
<ParamField path="thread" type="boolean" default="false">
|
||||
`true`이면 이 하위 에이전트 세션에 대한 채널 thread 바인딩을 요청합니다.
|
||||
`true`이면 이 하위 에이전트 세션에 채널 스레드 바인딩을 요청합니다.
|
||||
</ParamField>
|
||||
<ParamField path="mode" type='"run" | "session"' default="run">
|
||||
`thread: true`이고 `mode`가 생략되면 기본값은 `session`이 됩니다. `mode: "session"`에는 `thread: true`가 필요합니다.
|
||||
</ParamField>
|
||||
<ParamField path="cleanup" type='"delete" | "keep"' default="keep">
|
||||
`"delete"`는 announce 직후 archive합니다(이름 변경을 통해 transcript는 계속 유지).
|
||||
`"delete"`는 알림 직후 아카이브합니다(이름 변경을 통해 transcript는 여전히 유지).
|
||||
</ParamField>
|
||||
<ParamField path="sandbox" type='"inherit" | "require"' default="inherit">
|
||||
`require`는 대상 자식 런타임이 sandboxed가 아니면 생성을 거부합니다.
|
||||
`require`는 대상 자식 런타임이 샌드박스 처리되어 있지 않으면 생성을 거부합니다.
|
||||
</ParamField>
|
||||
<ParamField path="context" type='"isolated" | "fork"' default="isolated">
|
||||
`fork`는 요청자의 현재 transcript를 자식 세션으로 분기합니다. native 하위 에이전트 전용입니다. thread-bound 생성은 기본값이 `fork`이고, non-thread 생성은 기본값이 `isolated`입니다.
|
||||
`fork`는 요청자의 현재 transcript를 자식 세션으로 분기합니다. 네이티브 하위 에이전트 전용입니다. 스레드 바인딩 생성은 기본값이 `fork`이고, 비스레드 생성은 기본값이 `isolated`입니다.
|
||||
</ParamField>
|
||||
|
||||
<Warning>
|
||||
`sessions_spawn`은 채널 전달 매개변수(`target`,
|
||||
`channel`, `to`, `threadId`, `replyTo`, `transport`)를 허용하지 **않습니다**. 전달에는 생성된 실행에서
|
||||
`message`/`sessions_send`를 사용하세요.
|
||||
`channel`, `to`, `threadId`, `replyTo`, `transport`)를 허용하지 **않습니다**.
|
||||
전달에는 생성된 실행에서 `message`/`sessions_send`를 사용하세요.
|
||||
</Warning>
|
||||
|
||||
## Thread-bound 세션
|
||||
## 스레드 바인딩 세션
|
||||
|
||||
채널에 thread 바인딩이 활성화되어 있으면 하위 에이전트가 thread에 계속 바인딩되어,
|
||||
해당 thread의 후속 사용자 메시지가 같은 하위 에이전트 세션으로 계속 routing될 수 있습니다.
|
||||
채널에 스레드 바인딩이 활성화되어 있으면, 하위 에이전트는 스레드에 바인딩된 상태로 유지되어
|
||||
해당 스레드의 후속 사용자 메시지가 같은 하위 에이전트 세션으로 계속 라우팅되도록 할 수 있습니다.
|
||||
|
||||
### Thread 지원 채널
|
||||
### 스레드 지원 채널
|
||||
|
||||
**Discord**는 현재 유일하게 지원되는 채널입니다. 영구 thread-bound 하위 에이전트 세션(`thread: true`가 포함된 `sessions_spawn`), 수동 thread 제어(`/focus`, `/unfocus`, `/agents`,
|
||||
`/session idle`, `/session max-age`), 그리고 adapter key
|
||||
**Discord**가 현재 유일하게 지원되는 채널입니다. 영구 스레드 바인딩 하위 에이전트 세션(`thread: true`와 함께 `sessions_spawn`),
|
||||
수동 스레드 제어(`/focus`, `/unfocus`, `/agents`,
|
||||
`/session idle`, `/session max-age`), 그리고 어댑터 키
|
||||
`channels.discord.threadBindings.enabled`,
|
||||
`channels.discord.threadBindings.idleHours`,
|
||||
`channels.discord.threadBindings.maxAgeHours`, 및
|
||||
@ -207,74 +209,78 @@ allow/deny policy는 profile 단계 이후에도 도구를 제거할 수 있습
|
||||
### 빠른 흐름
|
||||
|
||||
<Steps>
|
||||
<Step title="Spawn">
|
||||
`sessions_spawn`에 `thread: true`를 사용합니다(선택적으로 `mode: "session"`도 사용).
|
||||
<Step title="생성">
|
||||
`thread: true`(선택적으로 `mode: "session"` 포함)와 함께 `sessions_spawn`.
|
||||
</Step>
|
||||
<Step title="Bind">
|
||||
OpenClaw는 활성 채널에서 해당 세션 target에 thread를 생성하거나 바인딩합니다.
|
||||
<Step title="바인딩">
|
||||
OpenClaw는 활성 채널에서 해당 세션 대상에 스레드를 생성하거나 바인딩합니다.
|
||||
</Step>
|
||||
<Step title="Route follow-ups">
|
||||
해당 thread의 응답과 후속 메시지는 바인딩된 세션으로 routing됩니다.
|
||||
<Step title="후속 메시지 라우팅">
|
||||
해당 스레드의 답장과 후속 메시지는 바인딩된 세션으로 라우팅됩니다.
|
||||
</Step>
|
||||
<Step title="Inspect timeouts">
|
||||
`/session idle`을 사용해 inactivity auto-unfocus를 검사/업데이트하고
|
||||
`/session max-age`로 hard cap을 제어합니다.
|
||||
<Step title="제한 시간 검사">
|
||||
비활성 자동 unfocus를 검사/업데이트하려면 `/session idle`을 사용하고,
|
||||
하드 상한을 제어하려면 `/session max-age`를 사용하세요.
|
||||
</Step>
|
||||
<Step title="Detach">
|
||||
수동으로 분리하려면 `/unfocus`를 사용합니다.
|
||||
<Step title="분리">
|
||||
수동으로 분리하려면 `/unfocus`를 사용하세요.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
### 수동 제어
|
||||
|
||||
| 명령 | 효과 |
|
||||
| ------------------ | -------------------------------------------------------------------------- |
|
||||
| `/focus <target>` | 현재 스레드를 하위 에이전트/세션 대상에 바인딩합니다(또는 새로 만듭니다) |
|
||||
| `/unfocus` | 현재 바인딩된 스레드의 바인딩을 제거합니다 |
|
||||
| `/agents` | 활성 실행 및 바인딩 상태를 나열합니다(`thread:<id>` 또는 `unbound`) |
|
||||
| `/session idle` | 유휴 자동 포커스 해제를 검사/업데이트합니다(포커스된 바인딩 스레드만 해당) |
|
||||
| `/session max-age` | 하드 캡을 검사/업데이트합니다(포커스된 바인딩 스레드만 해당) |
|
||||
| 명령어 | 효과 |
|
||||
| ------------------ | --------------------------------------------------------------------- |
|
||||
| `/focus <target>` | 현재 스레드를 하위 에이전트/세션 대상에 바인딩하거나 새로 만듭니다 |
|
||||
| `/unfocus` | 현재 바인딩된 스레드의 바인딩을 제거합니다 |
|
||||
| `/agents` | 활성 실행과 바인딩 상태(`thread:<id>` 또는 `unbound`)를 나열합니다 |
|
||||
| `/session idle` | 유휴 자동 포커스 해제를 검사/업데이트합니다(포커스된 바인딩 스레드만) |
|
||||
| `/session max-age` | 하드 한도를 검사/업데이트합니다(포커스된 바인딩 스레드만) |
|
||||
|
||||
### 설정 스위치
|
||||
### 구성 스위치
|
||||
|
||||
- **전역 기본값:** `session.threadBindings.enabled`, `session.threadBindings.idleHours`, `session.threadBindings.maxAgeHours`.
|
||||
- **채널 재정의 및 생성 시 자동 바인딩 키**는 어댑터별로 다릅니다. 위의 [스레드를 지원하는 채널](#thread-supporting-channels)을 참조하세요.
|
||||
- **채널 재정의 및 생성 자동 바인딩 키**는 어댑터별로 다릅니다. 위의 [스레드 지원 채널](#thread-supporting-channels)을 참조하세요.
|
||||
|
||||
현재 어댑터 세부 정보는 [설정 참조](/ko/gateway/configuration-reference) 및
|
||||
[슬래시 명령](/ko/tools/slash-commands)을 참조하세요.
|
||||
현재 어댑터 세부 정보는 [구성 참조](/ko/gateway/configuration-reference) 및
|
||||
[슬래시 명령어](/ko/tools/slash-commands)를 참조하세요.
|
||||
|
||||
### 허용 목록
|
||||
|
||||
<ParamField path="agents.list[].subagents.allowAgents" type="string[]">
|
||||
명시적 `agentId`로 대상으로 지정할 수 있는 에이전트 ID 목록입니다(`["*"]`는 모두 허용). 기본값: 요청자 에이전트만. 목록을 설정했지만 요청자가 `agentId`로 자기 자신을 생성할 수 있게 하려면 요청자 ID를 목록에 포함하세요.
|
||||
명시적 `agentId`를 통해 대상으로 지정할 수 있는 에이전트 id 목록입니다(`["*"]`는 모두 허용). 기본값: 요청자 에이전트만. 목록을 설정하면서 요청자가 `agentId`로 자기 자신을 생성하도록 하려면, 목록에 요청자 id를 포함하세요.
|
||||
</ParamField>
|
||||
<ParamField path="agents.defaults.subagents.allowAgents" type="string[]">
|
||||
요청자 에이전트가 자체 `subagents.allowAgents`를 설정하지 않을 때 사용되는 기본 대상 에이전트 허용 목록입니다.
|
||||
</ParamField>
|
||||
<ParamField path="agents.defaults.subagents.requireAgentId" type="boolean" default="false">
|
||||
`agentId`를 생략한 `sessions_spawn` 호출을 차단합니다(명시적 프로필 선택을 강제). 에이전트별 재정의: `agents.list[].subagents.requireAgentId`.
|
||||
`agentId`를 생략한 `sessions_spawn` 호출을 차단합니다(명시적 프로필 선택 강제). 에이전트별 재정의: `agents.list[].subagents.requireAgentId`.
|
||||
</ParamField>
|
||||
|
||||
요청자 세션이 샌드박스 처리된 경우, `sessions_spawn`은 샌드박스 없이 실행될 대상을 거부합니다.
|
||||
요청자 세션이 샌드박스 처리된 경우, `sessions_spawn`은 샌드박스 없이 실행될
|
||||
대상을 거부합니다.
|
||||
|
||||
### 검색
|
||||
|
||||
`sessions_spawn`에 현재 허용된 에이전트 ID를 보려면 `agents_list`를 사용하세요. 응답에는 나열된 각 에이전트의 유효 모델과 내장 런타임 메타데이터가 포함되므로 호출자는 PI, Codex 앱 서버 및 기타 구성된 네이티브 런타임을 구분할 수 있습니다.
|
||||
`sessions_spawn`에 현재 허용된 에이전트 id를 보려면 `agents_list`를 사용하세요.
|
||||
응답에는 각 나열된 에이전트의 유효 모델과 포함된 런타임 메타데이터가 포함되므로
|
||||
호출자는 PI, Codex app-server 및 기타 구성된 네이티브 런타임을 구분할 수 있습니다.
|
||||
|
||||
### 자동 보관
|
||||
### 자동 아카이브
|
||||
|
||||
- 하위 에이전트 세션은 `agents.defaults.subagents.archiveAfterMinutes` 이후 자동으로 보관됩니다(기본값 `60`).
|
||||
- 보관은 `sessions.delete`를 사용하며 트랜스크립트 이름을 `*.deleted.<timestamp>`로 변경합니다(같은 폴더).
|
||||
- `cleanup: "delete"`는 알림 직후 즉시 보관합니다(그래도 이름 변경으로 트랜스크립트는 유지).
|
||||
- 자동 보관은 최선형입니다. Gateway가 다시 시작되면 대기 중인 타이머는 손실됩니다.
|
||||
- `runTimeoutSeconds`는 자동 보관하지 않습니다. 실행만 중지합니다. 세션은 자동 보관될 때까지 남아 있습니다.
|
||||
- 자동 보관은 깊이 1 및 깊이 2 세션에 동일하게 적용됩니다.
|
||||
- 브라우저 정리는 보관 정리와 별개입니다. 추적된 브라우저 탭/프로세스는 트랜스크립트/세션 레코드가 유지되더라도 실행이 끝나면 최선형으로 닫힙니다.
|
||||
- 하위 에이전트 세션은 `agents.defaults.subagents.archiveAfterMinutes` 이후 자동으로 아카이브됩니다(기본값 `60`).
|
||||
- 아카이브는 `sessions.delete`를 사용하고 트랜스크립트 이름을 `*.deleted.<timestamp>`로 바꿉니다(같은 폴더).
|
||||
- `cleanup: "delete"`는 알림 직후 아카이브합니다(그래도 이름 변경을 통해 트랜스크립트는 유지).
|
||||
- 자동 아카이브는 최선 노력 방식입니다. Gateway가 다시 시작되면 대기 중인 타이머는 손실됩니다.
|
||||
- `runTimeoutSeconds`는 자동 아카이브하지 않습니다. 실행만 중지합니다. 세션은 자동 아카이브될 때까지 유지됩니다.
|
||||
- 자동 아카이브는 깊이 1 및 깊이 2 세션에 동일하게 적용됩니다.
|
||||
- 브라우저 정리는 아카이브 정리와 별개입니다. 트랜스크립트/세션 레코드가 유지되더라도, 추적된 브라우저 탭/프로세스는 실행이 완료되면 최선 노력 방식으로 닫힙니다.
|
||||
|
||||
## 중첩 하위 에이전트
|
||||
## 중첩된 하위 에이전트
|
||||
|
||||
기본적으로 하위 에이전트는 자체 하위 에이전트를 생성할 수 없습니다
|
||||
(`maxSpawnDepth: 1`). 한 단계 중첩을 활성화하려면 `maxSpawnDepth: 2`를 설정하세요. 이는 **오케스트레이터 패턴**입니다: 메인 → 오케스트레이터 하위 에이전트 →
|
||||
(`maxSpawnDepth: 1`). 한 수준의 중첩을 활성화하려면 `maxSpawnDepth: 2`를 설정하세요.
|
||||
이는 **오케스트레이터 패턴**입니다: 메인 → 오케스트레이터 하위 에이전트 →
|
||||
작업자 하위-하위 에이전트.
|
||||
|
||||
```json5
|
||||
@ -294,130 +300,145 @@ allow/deny policy는 profile 단계 이후에도 도구를 제거할 수 있습
|
||||
|
||||
### 깊이 수준
|
||||
|
||||
| 깊이 | 세션 키 형태 | 역할 | 생성 가능 여부 |
|
||||
| ---- | --------------------------------------------- | ----------------------------------------------------- | ----------------------------- |
|
||||
| 0 | `agent:<id>:main` | 메인 에이전트 | 항상 가능 |
|
||||
| 1 | `agent:<id>:subagent:<uuid>` | 하위 에이전트(깊이 2가 허용되면 오케스트레이터) | `maxSpawnDepth >= 2`인 경우만 |
|
||||
| 2 | `agent:<id>:subagent:<uuid>:subagent:<uuid>` | 하위-하위 에이전트(리프 작업자) | 불가능 |
|
||||
| 깊이 | 세션 키 형태 | 역할 | 생성 가능 여부 |
|
||||
| ----- | -------------------------------------------- | --------------------------------------------- | ---------------------------- |
|
||||
| 0 | `agent:<id>:main` | 메인 에이전트 | 항상 |
|
||||
| 1 | `agent:<id>:subagent:<uuid>` | 하위 에이전트(깊이 2가 허용되면 오케스트레이터) | `maxSpawnDepth >= 2`인 경우에만 |
|
||||
| 2 | `agent:<id>:subagent:<uuid>:subagent:<uuid>` | 하위-하위 에이전트(리프 작업자) | 불가 |
|
||||
|
||||
### 알림 체인
|
||||
|
||||
결과는 체인을 따라 위로 전달됩니다:
|
||||
결과는 체인을 따라 위로 전달됩니다.
|
||||
|
||||
1. 깊이 2 작업자가 완료됨 → 부모(깊이 1 오케스트레이터)에게 알립니다.
|
||||
2. 깊이 1 오케스트레이터가 알림을 받고, 결과를 종합한 뒤 완료됨 → 메인에게 알립니다.
|
||||
3. 메인 에이전트가 알림을 받고 사용자에게 전달합니다.
|
||||
|
||||
각 수준은 직접 자식의 알림만 볼 수 있습니다.
|
||||
각 수준은 직접적인 자식의 알림만 봅니다.
|
||||
|
||||
<Note>
|
||||
**운영 지침:** `sessions_list`,
|
||||
`sessions_history`, `/subagents list`, 또는 `exec` sleep 명령을 중심으로 폴링 루프를 만들지 말고 자식 작업을 한 번 시작한 뒤 완료 이벤트를 기다리세요.
|
||||
`sessions_list` 및 `/subagents list`는 자식 세션 관계를 라이브 작업에 집중시킵니다. 라이브 자식은 연결된 상태로 남고, 종료된 자식은 짧은 최근 창 동안 표시되며, 오래된 저장소 전용 자식 링크는 최신성 창이 지나면 무시됩니다. 이렇게 하면 다시 시작 후 오래된 `spawnedBy` /
|
||||
`parentSessionKey` 메타데이터가 고스트 자식을 되살리는 일을 방지합니다. 이미 최종 답변을 보낸 뒤 자식 완료 이벤트가 도착하면 올바른 후속 응답은 정확한 무음 토큰
|
||||
`sessions_history`, `/subagents list` 또는 `exec` sleep 명령을 중심으로 폴링 루프를 만드는 대신, 자식 작업을 한 번 시작하고 완료
|
||||
이벤트를 기다리세요. `sessions_list`와 `/subagents list`는 자식 세션 관계를
|
||||
라이브 작업에 집중시킵니다. 라이브 자식은 연결된 상태로 유지되고, 종료된 자식은
|
||||
짧은 최근 창 동안 표시되며, 오래된 저장소 전용 자식 링크는 신선도 창 이후
|
||||
무시됩니다. 이렇게 하면 재시작 후 오래된 `spawnedBy` /
|
||||
`parentSessionKey` 메타데이터가 유령 자식을 되살리는 것을 방지합니다.
|
||||
이미 최종 답변을 보낸 뒤 자식 완료 이벤트가 도착하면, 올바른 후속 응답은 정확한 무음 토큰
|
||||
`NO_REPLY` / `no_reply`입니다.
|
||||
</Note>
|
||||
|
||||
### 깊이별 도구 정책
|
||||
|
||||
- 역할 및 제어 범위는 생성 시 세션 메타데이터에 기록됩니다. 이렇게 하면 평면화되었거나 복원된 세션 키가 실수로 오케스트레이터 권한을 다시 얻는 일을 막습니다.
|
||||
- **깊이 1(오케스트레이터, `maxSpawnDepth >= 2`일 때):** 자식을 관리할 수 있도록 `sessions_spawn`, `subagents`, `sessions_list`, `sessions_history`를 받습니다. 다른 세션/시스템 도구는 계속 거부됩니다.
|
||||
- **깊이 1(리프, `maxSpawnDepth == 1`일 때):** 세션 도구 없음(현재 기본 동작).
|
||||
- **깊이 2(리프 작업자):** 세션 도구 없음. 깊이 2에서는 `sessions_spawn`이 항상 거부됩니다. 더 이상 자식을 생성할 수 없습니다.
|
||||
- 역할과 제어 범위는 생성 시점에 세션 메타데이터에 기록됩니다. 이렇게 하면 평면화되었거나 복원된 세션 키가 실수로 오케스트레이터 권한을 되찾지 않습니다.
|
||||
- **깊이 1(오케스트레이터, `maxSpawnDepth >= 2`인 경우):** 자식을 관리할 수 있도록 `sessions_spawn`, `subagents`, `sessions_list`, `sessions_history`를 받습니다. 다른 세션/시스템 도구는 계속 거부됩니다.
|
||||
- **깊이 1(리프, `maxSpawnDepth == 1`인 경우):** 세션 도구 없음(현재 기본 동작).
|
||||
- **깊이 2(리프 작업자):** 세션 도구 없음. `sessions_spawn`은 깊이 2에서 항상 거부됩니다. 추가 자식을 생성할 수 없습니다.
|
||||
|
||||
### 에이전트별 생성 제한
|
||||
|
||||
각 에이전트 세션(모든 깊이)은 한 번에 최대 `maxChildrenPerAgent`
|
||||
개(기본값 `5`)의 활성 자식을 가질 수 있습니다. 이는 단일 오케스트레이터에서 무제한으로 팬아웃되는 일을 방지합니다.
|
||||
개의 활성 자식을 가질 수 있습니다(기본값 `5`). 이는 단일 오케스트레이터에서
|
||||
무제한 팬아웃이 발생하는 것을 방지합니다.
|
||||
|
||||
### 연쇄 중지
|
||||
|
||||
깊이 1 오케스트레이터를 중지하면 모든 깊이 2 자식도 자동으로 중지됩니다:
|
||||
깊이 1 오케스트레이터를 중지하면 모든 깊이 2 자식도 자동으로 중지됩니다.
|
||||
|
||||
- 메인 채팅의 `/stop`은 모든 깊이 1 에이전트를 중지하고 해당 깊이 2 자식까지 연쇄 중지합니다.
|
||||
- `/subagents kill <id>`는 특정 하위 에이전트를 중지하고 해당 자식까지 연쇄 중지합니다.
|
||||
- 메인 채팅의 `/stop`은 모든 깊이 1 에이전트를 중지하고 그 깊이 2 자식까지 연쇄 중지합니다.
|
||||
- `/subagents kill <id>`는 특정 하위 에이전트를 중지하고 그 자식까지 연쇄 중지합니다.
|
||||
- `/subagents kill all`은 요청자의 모든 하위 에이전트를 중지하고 연쇄 중지합니다.
|
||||
|
||||
## 인증
|
||||
|
||||
하위 에이전트 인증은 세션 유형이 아니라 **에이전트 ID**로 해석됩니다:
|
||||
하위 에이전트 인증은 세션 유형이 아니라 **에이전트 id**로 확인됩니다.
|
||||
|
||||
- 하위 에이전트 세션 키는 `agent:<agentId>:subagent:<uuid>`입니다.
|
||||
- 인증 저장소는 해당 에이전트의 `agentDir`에서 로드됩니다.
|
||||
- 메인 에이전트의 인증 프로필은 **대체값**으로 병합됩니다. 충돌 시 에이전트 프로필이 메인 프로필을 재정의합니다.
|
||||
- 메인 에이전트의 인증 프로필은 **fallback**으로 병합됩니다. 충돌 시 에이전트 프로필이 메인 프로필을 재정의합니다.
|
||||
|
||||
병합은 추가 방식이므로 메인 프로필은 항상 대체값으로 사용할 수 있습니다. 에이전트별로 완전히 격리된 인증은 아직 지원되지 않습니다.
|
||||
병합은 추가 방식이므로, 메인 프로필은 항상 fallback으로 사용할 수 있습니다.
|
||||
에이전트별 완전 격리 인증은 아직 지원되지 않습니다.
|
||||
|
||||
## 알림
|
||||
|
||||
하위 에이전트는 알림 단계를 통해 보고합니다:
|
||||
하위 에이전트는 알림 단계를 통해 보고합니다.
|
||||
|
||||
- 알림 단계는 요청자 세션이 아니라 하위 에이전트 세션 내부에서 실행됩니다.
|
||||
- 알림 단계는 요청자 세션이 아니라 하위 에이전트 세션 안에서 실행됩니다.
|
||||
- 하위 에이전트가 정확히 `ANNOUNCE_SKIP`으로 응답하면 아무것도 게시되지 않습니다.
|
||||
- 최신 어시스턴트 텍스트가 정확한 무음 토큰 `NO_REPLY` / `no_reply`인 경우, 이전에 표시된 진행 내용이 있더라도 알림 출력은 억제됩니다.
|
||||
- 최신 어시스턴트 텍스트가 정확한 무음 토큰 `NO_REPLY` / `no_reply`인 경우, 이전에 표시된 진행 상황이 있었더라도 알림 출력은 억제됩니다.
|
||||
|
||||
전달은 요청자 깊이에 따라 달라집니다:
|
||||
전달은 요청자 깊이에 따라 달라집니다.
|
||||
|
||||
- 최상위 요청자 세션은 외부 전달(`deliver=true`)과 함께 후속 `agent` 호출을 사용합니다.
|
||||
- 중첩 요청자 하위 에이전트 세션은 내부 후속 주입(`deliver=false`)을 받아 오케스트레이터가 세션 내에서 자식 결과를 종합할 수 있게 합니다.
|
||||
- 중첩 요청자 하위 에이전트 세션이 사라진 경우, OpenClaw는 사용 가능할 때 해당 세션의 요청자로 폴백합니다.
|
||||
- 최상위 요청자 세션은 외부 전달(`deliver=true`)이 포함된 후속 `agent` 호출을 사용합니다.
|
||||
- 중첩된 요청자 하위 에이전트 세션은 내부 후속 주입(`deliver=false`)을 받으므로 오케스트레이터가 세션 안에서 자식 결과를 종합할 수 있습니다.
|
||||
- 중첩된 요청자 하위 에이전트 세션이 사라진 경우, OpenClaw는 가능한 경우 해당 세션의 요청자로 fallback합니다.
|
||||
|
||||
최상위 요청자 세션의 경우, 완료 모드 직접 전달은 먼저 바인딩된 대화/스레드 경로와 훅 재정의를 해석한 다음, 요청자 세션에 저장된 경로에서 누락된 채널 대상 필드를 채웁니다. 이렇게 하면 완료 출처가 채널만 식별하더라도 올바른 채팅/토픽에 완료가 유지됩니다.
|
||||
최상위 요청자 세션의 경우, 완료 모드 직접 전달은 먼저 바인딩된 대화/스레드 경로와 훅 재정의를 해석한 뒤, 누락된 채널 대상 필드를 요청자 세션에 저장된 경로로 채웁니다.
|
||||
이를 통해 완료 출처가 채널만 식별하더라도 올바른 채팅/토픽에 완료가 유지됩니다.
|
||||
|
||||
중첩 완료 발견 항목을 만들 때 자식 완료 집계는 현재 요청자 실행으로 범위가 지정되어, 이전 실행의 오래된 자식 출력이 현재 알림으로 새어 들어가는 일을 방지합니다. 알림 응답은 채널 어댑터에서 사용 가능한 경우 스레드/토픽 라우팅을 보존합니다.
|
||||
중첩 완료 결과를 만들 때 자식 완료 집계는 현재 요청자 실행으로 범위가 제한되어,
|
||||
이전 실행의 오래된 자식 출력이 현재 알림으로 새어 들어가는 것을 방지합니다. 알림 응답은
|
||||
채널 어댑터에서 사용할 수 있을 때 스레드/토픽 라우팅을 보존합니다.
|
||||
|
||||
### 알림 컨텍스트
|
||||
|
||||
알림 컨텍스트는 안정적인 내부 이벤트 블록으로 정규화됩니다:
|
||||
알림 컨텍스트는 안정적인 내부 이벤트 블록으로 정규화됩니다.
|
||||
|
||||
| 필드 | 소스 |
|
||||
| ----------- | ---------------------------------------------------------------------------------------------------------------- |
|
||||
| 소스 | `subagent` 또는 `cron` |
|
||||
| 세션 ID | 자식 세션 키/ID |
|
||||
| 유형 | 알림 유형 + 작업 레이블 |
|
||||
| 상태 | 런타임 결과에서 파생됨(`success`, `error`, `timeout`, 또는 `unknown`) — 모델 텍스트에서 추론하지 **않음** |
|
||||
| 결과 내용 | 최신 표시 어시스턴트 텍스트, 없으면 정리된 최신 도구/toolResult 텍스트 |
|
||||
| 후속 조치 | 응답해야 하는 경우와 침묵을 유지해야 하는 경우를 설명하는 지침 |
|
||||
| 필드 | 소스 |
|
||||
| -------------- | ------------------------------------------------------------------------------------------------------------- |
|
||||
| 소스 | `subagent` 또는 `cron` |
|
||||
| 세션 id | 자식 세션 키/id |
|
||||
| 유형 | 알림 유형 + 작업 레이블 |
|
||||
| 상태 | 런타임 결과(`success`, `error`, `timeout` 또는 `unknown`)에서 파생됨 — 모델 텍스트에서 추론하지 **않음** |
|
||||
| 결과 콘텐츠 | 최신 표시 어시스턴트 텍스트, 없으면 정리된 최신 도구/toolResult 텍스트 |
|
||||
| 후속 조치 | 응답할 때와 조용히 있을 때를 설명하는 지침 |
|
||||
|
||||
터미널 실패 실행은 캡처된 응답 텍스트를 재생하지 않고 실패 상태를 보고합니다. 시간 초과 시 자식이 도구 호출까지만 진행했다면, 알림은 원시 도구 출력을 재생하는 대신 해당 기록을 짧은 부분 진행 요약으로 축약할 수 있습니다.
|
||||
종료된 실패 실행은 캡처된 응답 텍스트를 재생하지 않고 실패 상태를 보고합니다.
|
||||
타임아웃 시 자식이 도구 호출까지만 진행한 경우, 알림은 원시 도구 출력을 재생하는 대신
|
||||
해당 기록을 짧은 부분 진행 요약으로 축약할 수 있습니다.
|
||||
|
||||
### 통계 줄
|
||||
|
||||
알림 페이로드에는 끝에 통계 줄이 포함됩니다(래핑된 경우에도):
|
||||
알림 페이로드는 끝에 통계 줄을 포함합니다(래핑된 경우에도).
|
||||
|
||||
- 런타임(예: `runtime 5m12s`).
|
||||
- 토큰 사용량(입력/출력/총합).
|
||||
- 모델 가격이 구성된 경우 추정 비용(`models.providers.*.models[].cost`).
|
||||
- 메인 에이전트가 `sessions_history`를 통해 기록을 가져오거나 디스크의 파일을 검사할 수 있도록 `sessionKey`, `sessionId`, 트랜스크립트 경로.
|
||||
- 토큰 사용량(입력/출력/전체).
|
||||
- 모델 가격이 구성된 경우 예상 비용(`models.providers.*.models[].cost`).
|
||||
- 메인 에이전트가 `sessions_history`를 통해 기록을 가져오거나 디스크의 파일을 검사할 수 있도록 `sessionKey`, `sessionId` 및 트랜스크립트 경로.
|
||||
|
||||
내부 메타데이터는 오케스트레이션 전용입니다. 사용자 대상 응답은 일반적인 어시스턴트 어조로 다시 작성해야 합니다.
|
||||
내부 메타데이터는 오케스트레이션 전용입니다. 사용자 대상 응답은 일반 어시스턴트 목소리로 다시 작성해야 합니다.
|
||||
|
||||
### `sessions_history`를 선호하는 이유
|
||||
|
||||
`sessions_history`는 더 안전한 오케스트레이션 경로입니다:
|
||||
`sessions_history`는 더 안전한 오케스트레이션 경로입니다.
|
||||
|
||||
- 어시스턴트 리콜이 먼저 정규화됩니다. thinking 태그가 제거되고, `<relevant-memories>` / `<relevant_memories>` 스캐폴딩이 제거되며, 일반 텍스트 도구 호출 XML 페이로드 블록(`<tool_call>`, `<function_call>`, `<tool_calls>`, `<function_calls>`)이 깨끗하게 닫히지 않은 잘린 페이로드까지 포함해 제거됩니다. 강등된 도구 호출/결과 스캐폴딩 및 과거 컨텍스트 마커가 제거되고, 유출된 모델 제어 토큰(`<|assistant|>`, 기타 ASCII `<|...|>`, 전각 `<|...|>`)이 제거되며, 잘못된 MiniMax 도구 호출 XML이 제거됩니다.
|
||||
- 자격 증명/토큰처럼 보이는 텍스트가 수정됩니다.
|
||||
- 어시스턴트 회상이 먼저 정규화됩니다. 사고 태그가 제거되고, `<relevant-memories>` / `<relevant_memories>` 스캐폴딩이 제거되며, 일반 텍스트 도구 호출 XML 페이로드 블록(`<tool_call>`, `<function_call>`, `<tool_calls>`, `<function_calls>`)이 제거됩니다. 여기에는 깔끔하게 닫히지 않는 잘린 페이로드도 포함됩니다. 다운그레이드된 도구 호출/결과 스캐폴딩과 기록 컨텍스트 마커가 제거됩니다. 유출된 모델 제어 토큰(`<|assistant|>`, 기타 ASCII `<|...|>`, 전각 `<|...|>`)이 제거됩니다. 잘못된 MiniMax 도구 호출 XML이 제거됩니다.
|
||||
- 자격 증명/토큰처럼 보이는 텍스트는 마스킹됩니다.
|
||||
- 긴 블록은 잘릴 수 있습니다.
|
||||
- 매우 큰 기록은 오래된 행을 삭제하거나 크기가 초과된 행을 `[sessions_history omitted: message too large]`로 대체할 수 있습니다.
|
||||
- 바이트 단위로 완전한 트랜스크립트가 필요할 때는 디스크의 원시 트랜스크립트 검사가 대체 경로입니다.
|
||||
- 매우 큰 기록은 오래된 행을 삭제하거나 과도하게 큰 행을 `[sessions_history omitted: message too large]`로 대체할 수 있습니다.
|
||||
- 전체 바이트 단위 트랜스크립트가 필요할 때는 디스크의 원시 트랜스크립트 검사가 fallback입니다.
|
||||
|
||||
## 도구 정책
|
||||
|
||||
하위 에이전트는 먼저 부모 또는 대상 에이전트와 동일한 프로필 및 도구 정책 파이프라인을 사용합니다. 그 후 OpenClaw가 하위 에이전트 제한 계층을 적용합니다.
|
||||
하위 에이전트는 먼저 부모 또는 대상 에이전트와 동일한 프로필 및 도구 정책 파이프라인을 사용합니다.
|
||||
그 후 OpenClaw가 하위 에이전트 제한 계층을 적용합니다.
|
||||
|
||||
제한적인 `tools.profile`이 없으면 하위 에이전트는 **세션 도구와 시스템 도구를 제외한 모든 도구**를 받습니다:
|
||||
제한적인 `tools.profile`이 없으면, 하위 에이전트는 세션 도구와 시스템 도구를
|
||||
**제외한 모든 도구**를 받습니다.
|
||||
|
||||
- `sessions_list`
|
||||
- `sessions_history`
|
||||
- `sessions_send`
|
||||
- `sessions_spawn`
|
||||
|
||||
여기서도 `sessions_history`는 제한되고 정리된 리콜 뷰입니다. 원시 트랜스크립트 덤프가 아닙니다.
|
||||
여기서도 `sessions_history`는 제한되고 정리된 회상 뷰로 유지됩니다. 원시 트랜스크립트 덤프가 아닙니다.
|
||||
|
||||
`maxSpawnDepth >= 2`인 경우, 깊이 1 오케스트레이터 하위 에이전트는 자식을 관리할 수 있도록 추가로 `sessions_spawn`, `subagents`, `sessions_list`, `sessions_history`를 받습니다.
|
||||
`maxSpawnDepth >= 2`인 경우, 깊이 1 오케스트레이터 하위 에이전트는 자식을 관리할 수 있도록
|
||||
추가로 `sessions_spawn`, `subagents`, `sessions_list`,
|
||||
`sessions_history`를 받습니다.
|
||||
|
||||
### 설정을 통한 재정의
|
||||
### 구성을 통한 재정의
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -441,7 +462,7 @@ allow/deny policy는 profile 단계 이후에도 도구를 제거할 수 있습
|
||||
}
|
||||
```
|
||||
|
||||
`tools.subagents.tools.allow`는 최종 허용 전용 필터입니다. 이미 해석된 도구 집합을 좁힐 수는 있지만, `tools.profile`로 제거된 도구를 **다시 추가**할 수는 없습니다. 예를 들어 `tools.profile: "coding"`에는 `web_search`/`web_fetch`가 포함되지만 `browser` 도구는 포함되지 않습니다. `coding` 프로필 하위 에이전트가 브라우저 자동화를 사용하게 하려면 프로필 단계에서 browser를 추가하세요.
|
||||
`tools.subagents.tools.allow`는 최종 허용 전용 필터입니다. 이미 해석된 도구 세트를 좁힐 수는 있지만, `tools.profile`에서 제거된 도구를 **다시 추가할 수는 없습니다**. 예를 들어 `tools.profile: "coding"`에는 `web_search`/`web_fetch`가 포함되지만 `browser` 도구는 포함되지 않습니다. 코딩 프로필 하위 에이전트가 브라우저 자동화를 사용하게 하려면 프로필 단계에서 browser를 추가하세요.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -456,40 +477,40 @@ allow/deny policy는 profile 단계 이후에도 도구를 제거할 수 있습
|
||||
|
||||
## 동시성
|
||||
|
||||
하위 에이전트는 전용 인프로세스 큐 레인을 사용합니다.
|
||||
하위 에이전트는 전용 프로세스 내 큐 레인을 사용합니다.
|
||||
|
||||
- **레인 이름:** `subagent`
|
||||
- **동시성:** `agents.defaults.subagents.maxConcurrent`(기본값 `8`)
|
||||
|
||||
## 활성 상태 및 복구
|
||||
|
||||
OpenClaw는 `endedAt` 부재를 하위 에이전트가 아직 살아 있다는 영구적인 증거로 취급하지 않습니다. 오래된 실행 기간보다 오래된 종료되지 않은 실행은 `/subagents list`, 상태 요약, 하위 항목 완료 게이팅, 세션별 동시성 검사에서 활성/대기 중으로 계산되지 않습니다.
|
||||
OpenClaw는 `endedAt`이 없다는 사실을 하위 에이전트가 아직 살아 있다는 영구적인 증거로 간주하지 않습니다. 오래된 실행 창보다 오래된 종료되지 않은 실행은 `/subagents list`, 상태 요약, 하위 항목 완료 게이팅, 세션별 동시성 검사에서 활성/대기 중으로 계산되지 않습니다.
|
||||
|
||||
Gateway 재시작 후 오래되어 종료되지 않은 복원된 실행은 해당 자식 세션이 `abortedLastRun: true`로 표시되지 않은 한 정리됩니다. 이러한 재시작 중단 자식 세션은 하위 에이전트 고아 복구 흐름을 통해 계속 복구할 수 있으며, 이 흐름은 중단 표시를 지우기 전에 합성 재개 메시지를 보냅니다.
|
||||
Gateway 재시작 후 오래되어 종료되지 않은 복원 실행은 해당 자식 세션이 `abortedLastRun: true`로 표시되어 있지 않으면 정리됩니다. 이렇게 재시작으로 중단된 자식 세션은 하위 에이전트 고아 복구 흐름을 통해 계속 복구할 수 있으며, 이 흐름은 중단 표시를 지우기 전에 합성 재개 메시지를 보냅니다.
|
||||
|
||||
자동 재시작 복구는 자식 세션별로 제한됩니다. 같은 하위 에이전트 자식이 빠른 재고착 기간 안에 반복해서 고아 복구 대상으로 수락되면 OpenClaw는 해당 세션에 복구 tombstone을 유지하고 이후 재시작에서 자동 재개를 중지합니다. 작업 레코드를 조정하려면 `openclaw tasks maintenance --apply`를 실행하거나, tombstone 처리된 세션에서 오래된 중단 복구 플래그를 지우려면 `openclaw doctor --fix`를 실행하세요.
|
||||
자동 재시작 복구는 자식 세션별로 제한됩니다. 동일한 하위 에이전트 자식이 빠른 재고착 창 안에서 반복적으로 고아 복구 대상으로 수락되면 OpenClaw는 해당 세션에 복구 툼스톤을 저장하고 이후 재시작 시 자동 재개를 중지합니다. 작업 레코드를 조정하려면 `openclaw tasks maintenance --apply`를 실행하거나, 툼스톤 처리된 세션의 오래된 중단 복구 플래그를 지우려면 `openclaw doctor --fix`를 실행하세요.
|
||||
|
||||
<Note>
|
||||
하위 에이전트 생성이 Gateway `PAIRING_REQUIRED` / `scope-upgrade`로 실패하면 페어링 상태를 편집하기 전에 RPC 호출자를 확인하세요. 내부 `sessions_spawn` 조정은 직접 loopback 공유 토큰/비밀번호 인증을 통해 `client.id: "gateway-client"` 및 `client.mode: "backend"`로 연결해야 합니다. 이 경로는 CLI의 페어링된 기기 범위 기준선에 의존하지 않습니다. 원격 호출자, 명시적 `deviceIdentity`, 명시적 기기 토큰 경로, 브라우저/node 클라이언트는 범위 업그레이드에 여전히 일반 기기 승인이 필요합니다.
|
||||
하위 에이전트 생성이 Gateway `PAIRING_REQUIRED` / `scope-upgrade`로 실패하면 페어링 상태를 편집하기 전에 RPC 호출자를 확인하세요. 내부 `sessions_spawn` 조정은 직접 루프백 공유 토큰/비밀번호 인증을 통해 `client.id: "gateway-client"` 및 `client.mode: "backend"`로 연결해야 합니다. 이 경로는 CLI의 페어링된 기기 범위 기준선에 의존하지 않습니다. 원격 호출자, 명시적 `deviceIdentity`, 명시적 기기 토큰 경로, 브라우저/Node 클라이언트에는 범위 업그레이드를 위한 일반적인 기기 승인이 여전히 필요합니다.
|
||||
</Note>
|
||||
|
||||
## 중지
|
||||
|
||||
- 요청자 채팅에서 `/stop`을 보내면 요청자 세션이 중단되고, 그 세션에서 생성된 활성 하위 에이전트 실행이 모두 중지되며 중첩된 자식으로 연쇄 적용됩니다.
|
||||
- `/subagents kill <id>`는 특정 하위 에이전트를 중지하고 그 자식으로 연쇄 적용됩니다.
|
||||
- 요청자 채팅에서 `/stop`을 보내면 요청자 세션이 중단되고 여기서 생성된 활성 하위 에이전트 실행이 중지되며, 중첩된 자식에게도 전파됩니다.
|
||||
- `/subagents kill <id>`는 특정 하위 에이전트를 중지하고 그 자식에게도 전파합니다.
|
||||
|
||||
## 제한 사항
|
||||
|
||||
- 하위 에이전트 알림은 **최선 노력** 방식입니다. Gateway가 재시작되면 대기 중인 "announce back" 작업은 손실됩니다.
|
||||
- 하위 에이전트는 여전히 같은 Gateway 프로세스 리소스를 공유합니다. `maxConcurrent`를 안전밸브로 간주하세요.
|
||||
- `sessions_spawn`은 항상 비차단입니다. 즉시 `{ status: "accepted", runId, childSessionKey }`를 반환합니다.
|
||||
- 하위 에이전트 컨텍스트는 `AGENTS.md` + `TOOLS.md`만 주입합니다(`SOUL.md`, `IDENTITY.md`, `USER.md`, `HEARTBEAT.md`, `BOOTSTRAP.md`는 제외).
|
||||
- 최대 중첩 깊이는 5입니다(`maxSpawnDepth` 범위: 1-5). 대부분의 사용 사례에는 깊이 2를 권장합니다.
|
||||
- `maxChildrenPerAgent`는 세션당 활성 자식 수를 제한합니다(기본값 `5`, 범위 `1-20`).
|
||||
- 하위 에이전트 알림은 **최선 노력** 방식입니다. Gateway가 재시작되면 보류 중인 "announce back" 작업은 손실됩니다.
|
||||
- 하위 에이전트는 여전히 동일한 Gateway 프로세스 리소스를 공유하므로 `maxConcurrent`를 안전 밸브로 취급하세요.
|
||||
- `sessions_spawn`은 항상 비차단 방식입니다. 즉시 `{ status: "accepted", runId, childSessionKey }`를 반환합니다.
|
||||
- 하위 에이전트 컨텍스트는 `AGENTS.md` + `TOOLS.md`만 주입합니다(`SOUL.md`, `IDENTITY.md`, `USER.md`, `HEARTBEAT.md`, `BOOTSTRAP.md`는 없음).
|
||||
- 최대 중첩 깊이는 5입니다(`maxSpawnDepth` 범위: 1~5). 대부분의 사용 사례에는 깊이 2를 권장합니다.
|
||||
- `maxChildrenPerAgent`는 세션당 활성 자식 수를 제한합니다(기본값 `5`, 범위 `1~20`).
|
||||
|
||||
## 관련 항목
|
||||
|
||||
- [ACP 에이전트](/ko/tools/acp-agents)
|
||||
- [에이전트 보내기](/ko/tools/agent-send)
|
||||
- [에이전트 전송](/ko/tools/agent-send)
|
||||
- [백그라운드 작업](/ko/automation/tasks)
|
||||
- [멀티 에이전트 샌드박스 도구](/ko/tools/multi-agent-sandbox-tools)
|
||||
- [다중 에이전트 샌드박스 도구](/ko/tools/multi-agent-sandbox-tools)
|
||||
|
||||
@ -1,140 +1,143 @@
|
||||
---
|
||||
read_when:
|
||||
- thinking, fast-mode 또는 verbose 지시문 파싱이나 기본값 조정
|
||||
summary: /think, /fast, /verbose, /trace 및 추론 가시성을 위한 지시문 구문
|
||||
summary: /think, /fast, /verbose, /trace 및 추론 표시 여부를 위한 지시문 구문
|
||||
title: 사고 수준
|
||||
x-i18n:
|
||||
generated_at: "2026-04-30T16:30:59Z"
|
||||
generated_at: "2026-05-04T02:26:12Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: f9adf065e46cb64e4c2149b95ecd69ed887a17e2eff5a5569894defa3e7217b7
|
||||
source_hash: 6fa1b0a2b5f7b93a706488c3ad39dfe08c08eed0bdd30880eb4c07d730ee4d4f
|
||||
source_path: tools/thinking.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
## 수행 기능
|
||||
## 기능
|
||||
|
||||
- 모든 인바운드 본문의 인라인 지시문: `/t <level>`, `/think:<level>` 또는 `/thinking <level>`.
|
||||
- 모든 인바운드 본문의 인라인 지시어: `/t <level>`, `/think:<level>`, 또는 `/thinking <level>`.
|
||||
- 수준(별칭): `off | minimal | low | medium | high | xhigh | adaptive | max`
|
||||
- minimal → “think”
|
||||
- low → “think hard”
|
||||
- medium → “think harder”
|
||||
- high → “ultrathink”(최대 예산)
|
||||
- xhigh → “ultrathink+”(GPT-5.2+ 및 Codex 모델, 그리고 Anthropic Claude Opus 4.7 effort)
|
||||
- adaptive → 공급자가 관리하는 적응형 thinking(Anthropic/Bedrock의 Claude 4.6, Anthropic Claude Opus 4.7, Google Gemini 동적 thinking에서 지원)
|
||||
- max → 공급자 최대 reasoning(Anthropic Claude Opus 4.7; Ollama는 이를 자체 최상위 `think` effort로 매핑)
|
||||
- `x-high`, `x_high`, `extra-high`, `extra high`, `extra_high`는 `xhigh`로 매핑됩니다.
|
||||
- `highest`는 `high`로 매핑됩니다.
|
||||
- 공급자 참고 사항:
|
||||
- Thinking 메뉴와 선택기는 공급자 프로필 기반입니다. 공급자 Plugin은 선택된 모델의 정확한 수준 집합을 선언하며, binary `on` 같은 레이블도 포함합니다.
|
||||
- `adaptive`, `xhigh`, `max`는 이를 지원하는 공급자/모델 프로필에만 표시됩니다. 지원되지 않는 수준을 입력한 지시문은 해당 모델의 유효한 옵션과 함께 거부됩니다.
|
||||
- 기존에 저장된 지원되지 않는 수준은 공급자 프로필 순위에 따라 다시 매핑됩니다. `adaptive`는 비적응형 모델에서 `medium`으로 대체되고, `xhigh`와 `max`는 선택된 모델에서 지원되는 가장 큰 non-off 수준으로 대체됩니다.
|
||||
- Anthropic Claude 4.6 모델은 명시적 thinking 수준이 설정되지 않은 경우 기본값이 `adaptive`입니다.
|
||||
- Anthropic Claude Opus 4.7은 기본적으로 adaptive thinking을 사용하지 않습니다. 명시적으로 thinking 수준을 설정하지 않는 한 해당 API effort 기본값은 공급자 소유로 유지됩니다.
|
||||
- Anthropic Claude Opus 4.7은 `/think xhigh`를 adaptive thinking과 `output_config.effort: "xhigh"`로 매핑합니다. `/think`는 thinking 지시문이고 `xhigh`는 Opus 4.7 effort 설정이기 때문입니다.
|
||||
- Anthropic Claude Opus 4.7은 `/think max`도 노출하며, 동일한 공급자 소유 max effort 경로로 매핑됩니다.
|
||||
- DeepSeek V4 모델은 `/think xhigh|max`를 노출합니다. 둘 다 DeepSeek `reasoning_effort: "max"`로 매핑되며, 더 낮은 non-off 수준은 `high`로 매핑됩니다.
|
||||
- Ollama thinking 가능 모델은 `/think low|medium|high|max`를 노출합니다. Ollama의 네이티브 API가 `low`, `medium`, `high` effort 문자열을 허용하므로 `max`는 네이티브 `think: "high"`로 매핑됩니다.
|
||||
- OpenAI GPT 모델은 모델별 Responses API effort 지원을 통해 `/think`를 매핑합니다. `/think off`는 대상 모델이 지원하는 경우에만 `reasoning.effort: "none"`을 전송합니다. 그렇지 않으면 OpenClaw는 지원되지 않는 값을 보내는 대신 비활성화된 reasoning payload를 생략합니다.
|
||||
- 사용자 지정 OpenAI 호환 카탈로그 항목은 `models.providers.<provider>.models[].compat.supportedReasoningEfforts`에 `"xhigh"`를 포함하도록 설정하여 `/think xhigh`를 선택할 수 있습니다. 이는 아웃바운드 OpenAI reasoning effort payload를 매핑하는 것과 동일한 호환성 메타데이터를 사용하므로 메뉴, 세션 검증, 에이전트 CLI, `llm-task`가 전송 동작과 일치합니다.
|
||||
- 오래된 OpenRouter Hunter Alpha 참조가 구성되어 있으면, 해당 폐기된 경로가 reasoning 필드를 통해 최종 답변 텍스트를 반환할 수 있으므로 프록시 reasoning 주입을 건너뜁니다.
|
||||
- Google Gemini는 `/think adaptive`를 Gemini의 공급자 소유 동적 thinking으로 매핑합니다. Gemini 3 요청은 고정 `thinkingLevel`을 생략하고, Gemini 2.5 요청은 `thinkingBudget: -1`을 전송합니다. 고정 수준은 여전히 해당 모델 계열에 가장 가까운 Gemini `thinkingLevel` 또는 예산으로 매핑됩니다.
|
||||
- Anthropic 호환 스트리밍 경로의 MiniMax(`minimax/*`)는 모델 매개변수나 요청 매개변수에서 thinking을 명시적으로 설정하지 않는 한 기본값이 `thinking: { type: "disabled" }`입니다. 이렇게 하면 MiniMax의 비네이티브 Anthropic 스트림 형식에서 `reasoning_content` 델타가 노출되는 일을 방지합니다.
|
||||
- Z.AI(`zai/*`)는 binary thinking(`on`/`off`)만 지원합니다. `off`가 아닌 모든 수준은 `on`으로 처리됩니다(`low`로 매핑).
|
||||
- Moonshot(`moonshot/*`)은 `/think off`를 `thinking: { type: "disabled" }`로, `off`가 아닌 모든 수준을 `thinking: { type: "enabled" }`로 매핑합니다. thinking이 활성화되면 Moonshot은 `tool_choice` `auto|none`만 허용합니다. OpenClaw는 호환되지 않는 값을 `auto`로 정규화합니다.
|
||||
- high → “ultrathink” (최대 예산)
|
||||
- xhigh → “ultrathink+” (GPT-5.2+ 및 Codex 모델, 그리고 Anthropic Claude Opus 4.7 노력도)
|
||||
- adaptive → 제공자 관리형 적응형 사고(Anthropic/Bedrock의 Claude 4.6, Anthropic Claude Opus 4.7, Google Gemini 동적 사고에서 지원)
|
||||
- max → 제공자 최대 추론(Anthropic Claude Opus 4.7; Ollama는 이를 자체 최고 `think` 노력도에 매핑)
|
||||
- `x-high`, `x_high`, `extra-high`, `extra high`, `extra_high`는 `xhigh`에 매핑됩니다.
|
||||
- `highest`는 `high`에 매핑됩니다.
|
||||
- 제공자 참고 사항:
|
||||
- 사고 메뉴와 선택기는 제공자 프로필 기반입니다. 제공자 Plugin은 선택한 모델의 정확한 수준 집합을 선언하며, 여기에는 이진 `on` 같은 레이블도 포함됩니다.
|
||||
- `adaptive`, `xhigh`, `max`는 이를 지원하는 제공자/모델 프로필에만 표시됩니다. 지원되지 않는 수준에 대한 입력형 지시어는 해당 모델의 유효한 옵션과 함께 거부됩니다.
|
||||
- 기존에 저장된 지원되지 않는 수준은 제공자 프로필 순위에 따라 재매핑됩니다. 비적응형 모델에서는 `adaptive`가 `medium`으로 대체되고, `xhigh`와 `max`는 선택한 모델에서 지원되는 가장 큰 비-`off` 수준으로 대체됩니다.
|
||||
- Anthropic Claude 4.6 모델은 명시적 사고 수준이 설정되지 않은 경우 기본값이 `adaptive`입니다.
|
||||
- Anthropic Claude Opus 4.7은 기본적으로 적응형 사고를 사용하지 않습니다. 사고 수준을 명시적으로 설정하지 않는 한 해당 API 노력도 기본값은 제공자가 소유합니다.
|
||||
- Anthropic Claude Opus 4.7은 `/think xhigh`를 적응형 사고와 `output_config.effort: "xhigh"`로 매핑합니다. `/think`는 사고 지시어이고 `xhigh`는 Opus 4.7 노력도 설정이기 때문입니다.
|
||||
- Anthropic Claude Opus 4.7은 `/think max`도 노출하며, 이는 동일한 제공자 소유 최대 노력도 경로에 매핑됩니다.
|
||||
- DeepSeek V4 모델은 `/think xhigh|max`를 노출합니다. 둘 다 DeepSeek `reasoning_effort: "max"`에 매핑되고, 더 낮은 비-`off` 수준은 `high`에 매핑됩니다.
|
||||
- Ollama의 사고 가능 모델은 `/think low|medium|high|max`를 노출합니다. Ollama의 네이티브 API가 `low`, `medium`, `high` 노력도 문자열을 허용하므로 `max`는 네이티브 `think: "high"`에 매핑됩니다.
|
||||
- OpenAI GPT 모델은 모델별 Responses API 노력도 지원을 통해 `/think`를 매핑합니다. `/think off`는 대상 모델이 지원하는 경우에만 `reasoning.effort: "none"`을 전송합니다. 그렇지 않으면 OpenClaw는 지원되지 않는 값을 전송하는 대신 비활성화된 추론 페이로드를 생략합니다.
|
||||
- 사용자 지정 OpenAI 호환 카탈로그 항목은 `models.providers.<provider>.models[].compat.supportedReasoningEfforts`에 `"xhigh"`를 포함하도록 설정하여 `/think xhigh`를 선택적으로 지원할 수 있습니다. 이는 아웃바운드 OpenAI 추론 노력도 페이로드를 매핑하는 동일한 호환성 메타데이터를 사용하므로 메뉴, 세션 검증, 에이전트 CLI, `llm-task`가 전송 동작과 일치합니다.
|
||||
- 오래된 구성의 OpenRouter Hunter Alpha 참조는 프록시 추론 주입을 건너뜁니다. 해당 은퇴된 경로가 추론 필드를 통해 최종 답변 텍스트를 반환할 수 있기 때문입니다.
|
||||
- Google Gemini는 `/think adaptive`를 Gemini의 제공자 소유 동적 사고에 매핑합니다. Gemini 3 요청은 고정 `thinkingLevel`을 생략하고, Gemini 2.5 요청은 `thinkingBudget: -1`을 전송합니다. 고정 수준은 여전히 해당 모델 계열에 가장 가까운 Gemini `thinkingLevel` 또는 예산에 매핑됩니다.
|
||||
- Anthropic 호환 스트리밍 경로의 MiniMax(`minimax/*`)는 모델 매개변수 또는 요청 매개변수에서 사고를 명시적으로 설정하지 않는 한 기본값이 `thinking: { type: "disabled" }`입니다. 이는 MiniMax의 비네이티브 Anthropic 스트림 형식에서 `reasoning_content` 델타가 유출되는 것을 방지합니다.
|
||||
- Z.AI(`zai/*`)는 이진 사고(`on`/`off`)만 지원합니다. 비-`off` 수준은 모두 `on`으로 처리됩니다(`low`에 매핑).
|
||||
- Moonshot(`moonshot/*`)은 `/think off`를 `thinking: { type: "disabled" }`에 매핑하고, 비-`off` 수준은 모두 `thinking: { type: "enabled" }`에 매핑합니다. 사고가 활성화되면 Moonshot은 `tool_choice` `auto|none`만 허용합니다. OpenClaw는 호환되지 않는 값을 `auto`로 정규화합니다.
|
||||
|
||||
## 확인 순서
|
||||
## 해석 순서
|
||||
|
||||
1. 메시지의 인라인 지시문(해당 메시지에만 적용).
|
||||
2. 세션 재정의(지시문만 포함된 메시지를 보내 설정).
|
||||
3. 에이전트별 기본값(config의 `agents.list[].thinkingDefault`).
|
||||
4. 전역 기본값(config의 `agents.defaults.thinkingDefault`).
|
||||
5. 대체값: 사용 가능한 경우 공급자가 선언한 기본값입니다. 그렇지 않으면 reasoning 가능 모델은 해당 모델의 `medium` 또는 가장 가까운 지원 non-`off` 수준으로 확인되고, non-reasoning 모델은 `off`로 유지됩니다.
|
||||
1. 메시지의 인라인 지시어(해당 메시지에만 적용).
|
||||
2. 세션 재정의(지시어 전용 메시지를 보내 설정).
|
||||
3. 에이전트별 기본값(구성의 `agents.list[].thinkingDefault`).
|
||||
4. 전역 기본값(구성의 `agents.defaults.thinkingDefault`).
|
||||
5. 대체값: 제공자가 선언한 기본값이 있으면 사용합니다. 그렇지 않으면 추론 가능 모델은 `medium` 또는 해당 모델에서 지원되는 가장 가까운 비-`off` 수준으로 해석되고, 비추론 모델은 `off`로 유지됩니다.
|
||||
|
||||
## 세션 기본값 설정
|
||||
|
||||
- 지시문만 포함된 메시지를 보내세요(공백 허용). 예: `/think:medium` 또는 `/t high`.
|
||||
- 이는 현재 세션에 유지됩니다(기본적으로 발신자별). `/think:off` 또는 세션 유휴 재설정으로 지워집니다.
|
||||
- 확인 응답이 전송됩니다(`Thinking level set to high.` / `Thinking disabled.`). 수준이 유효하지 않으면(예: `/thinking big`) 명령은 힌트와 함께 거부되고 세션 상태는 변경되지 않습니다.
|
||||
- 인수 없이 `/think`(또는 `/think:`)를 보내 현재 thinking 수준을 확인하세요.
|
||||
- 지시어만 포함된 메시지를 보냅니다(공백 허용). 예: `/think:medium` 또는 `/t high`.
|
||||
- 이 설정은 현재 세션에 유지됩니다(기본적으로 발신자별). `/think:off` 또는 세션 유휴 재설정으로 해제됩니다.
|
||||
- 확인 답장이 전송됩니다(`Thinking level set to high.` / `Thinking disabled.`). 수준이 유효하지 않으면(예: `/thinking big`) 명령은 힌트와 함께 거부되고 세션 상태는 변경되지 않습니다.
|
||||
- 현재 사고 수준을 보려면 인수 없이 `/think`(또는 `/think:`)를 보냅니다.
|
||||
|
||||
## 에이전트별 적용
|
||||
|
||||
- **Embedded Pi**: 확인된 수준은 in-process Pi 에이전트 런타임으로 전달됩니다.
|
||||
- **내장 Pi**: 해석된 수준이 프로세스 내 Pi 에이전트 런타임에 전달됩니다.
|
||||
|
||||
## 빠른 모드(/fast)
|
||||
|
||||
- 수준: `on|off`.
|
||||
- 지시문만 포함된 메시지는 세션 빠른 모드 재정의를 토글하고 `Fast mode enabled.` / `Fast mode disabled.`로 응답합니다.
|
||||
- 모드 없이 `/fast`(또는 `/fast status`)를 보내 현재 유효한 빠른 모드 상태를 확인하세요.
|
||||
- OpenClaw는 다음 순서로 빠른 모드를 확인합니다.
|
||||
1. 인라인/지시문 전용 `/fast on|off`
|
||||
- 지시어 전용 메시지는 세션 빠른 모드 재정의를 전환하고 `Fast mode enabled.` / `Fast mode disabled.`로 답합니다.
|
||||
- 현재 유효한 빠른 모드 상태를 보려면 모드 없이 `/fast`(또는 `/fast status`)를 보냅니다.
|
||||
- OpenClaw는 빠른 모드를 다음 순서로 해석합니다:
|
||||
1. 인라인/지시어 전용 `/fast on|off`
|
||||
2. 세션 재정의
|
||||
3. 에이전트별 기본값(`agents.list[].fastModeDefault`)
|
||||
4. 모델별 config: `agents.defaults.models["<provider>/<model>"].params.fastMode`
|
||||
4. 모델별 구성: `agents.defaults.models["<provider>/<model>"].params.fastMode`
|
||||
5. 대체값: `off`
|
||||
- `openai/*`의 경우 빠른 모드는 지원되는 Responses 요청에서 `service_tier=priority`를 보내 OpenAI 우선 처리로 매핑됩니다.
|
||||
- `openai-codex/*`의 경우 빠른 모드는 Codex Responses에 동일한 `service_tier=priority` 플래그를 전송합니다. OpenClaw는 두 인증 경로에서 하나의 공유 `/fast` 토글을 유지합니다.
|
||||
- `api.anthropic.com`으로 전송되는 OAuth 인증 트래픽을 포함한 직접 공개 `anthropic/*` 요청의 경우, 빠른 모드는 Anthropic 서비스 티어로 매핑됩니다. `/fast on`은 `service_tier=auto`를 설정하고, `/fast off`는 `service_tier=standard_only`를 설정합니다.
|
||||
- Anthropic 호환 경로의 `minimax/*`의 경우 `/fast on`(또는 `params.fastMode: true`)은 `MiniMax-M2.7`을 `MiniMax-M2.7-highspeed`로 다시 씁니다.
|
||||
- 명시적 Anthropic `serviceTier` / `service_tier` 모델 매개변수는 둘 다 설정된 경우 빠른 모드 기본값을 재정의합니다. OpenClaw는 여전히 non-Anthropic 프록시 기본 URL에 대해서는 Anthropic 서비스 티어 주입을 건너뜁니다.
|
||||
- `openai/*`의 경우 빠른 모드는 지원되는 Responses 요청에서 `service_tier=priority`를 전송하여 OpenAI 우선 처리에 매핑됩니다.
|
||||
- `openai-codex/*`의 경우 빠른 모드는 Codex Responses에 동일한 `service_tier=priority` 플래그를 전송합니다. OpenClaw는 두 인증 경로 모두에서 하나의 공유 `/fast` 토글을 유지합니다.
|
||||
- OAuth 인증 트래픽이 `api.anthropic.com`으로 전송되는 경우를 포함하여 직접 공개 `anthropic/*` 요청의 경우 빠른 모드는 Anthropic 서비스 티어에 매핑됩니다. `/fast on`은 `service_tier=auto`를 설정하고, `/fast off`는 `service_tier=standard_only`를 설정합니다.
|
||||
- Anthropic 호환 경로의 `minimax/*`에서는 `/fast on`(또는 `params.fastMode: true`)이 `MiniMax-M2.7`을 `MiniMax-M2.7-highspeed`로 다시 씁니다.
|
||||
- 명시적 Anthropic `serviceTier` / `service_tier` 모델 매개변수가 설정된 경우 빠른 모드 기본값보다 우선합니다. OpenClaw는 여전히 비-Anthropic 프록시 기본 URL에 대해서는 Anthropic 서비스 티어 주입을 건너뜁니다.
|
||||
- `/status`는 빠른 모드가 활성화된 경우에만 `Fast`를 표시합니다.
|
||||
|
||||
## 상세 지시문(/verbose 또는 /v)
|
||||
## 상세 지시어(/verbose 또는 /v)
|
||||
|
||||
- 수준: `on`(최소) | `full` | `off`(기본값).
|
||||
- 지시문만 포함된 메시지는 세션 상세 출력을 토글하고 `Verbose logging enabled.` / `Verbose logging disabled.`로 응답합니다. 유효하지 않은 수준은 상태를 변경하지 않고 힌트를 반환합니다.
|
||||
- `/verbose off`는 명시적 세션 재정의를 저장합니다. Sessions UI에서 `inherit`을 선택하여 지우세요.
|
||||
- 인라인 지시문은 해당 메시지에만 영향을 줍니다. 그 외에는 세션/전역 기본값이 적용됩니다.
|
||||
- 인수 없이 `/verbose`(또는 `/verbose:`)를 보내 현재 상세 수준을 확인하세요.
|
||||
- verbose가 켜져 있으면 구조화된 도구 결과를 내보내는 에이전트(Pi, 기타 JSON 에이전트)는 각 도구 호출을 자체 메타데이터 전용 메시지로 다시 보내며, 사용할 수 있는 경우 `<emoji> <tool-name>: <arg>`가 접두사로 붙습니다(경로/명령). 이러한 도구 요약은 각 도구가 시작되는 즉시 전송되며(별도 말풍선), 스트리밍 델타로 전송되지 않습니다.
|
||||
- 도구 실패 요약은 일반 모드에서도 계속 표시되지만, 원시 오류 세부 정보 접미사는 verbose가 `on` 또는 `full`이 아닌 한 숨겨집니다.
|
||||
- verbose가 `full`이면 도구 출력도 완료 후 전달됩니다(별도 말풍선, 안전한 길이로 잘림). 실행 중에 `/verbose on|full|off`를 토글하면 이후 도구 말풍선은 새 설정을 따릅니다.
|
||||
- 지시어 전용 메시지는 세션 상세 출력을 전환하고 `Verbose logging enabled.` / `Verbose logging disabled.`로 답합니다. 유효하지 않은 수준은 상태를 변경하지 않고 힌트를 반환합니다.
|
||||
- `/verbose off`는 명시적 세션 재정의를 저장합니다. Sessions UI에서 `inherit`를 선택해 해제합니다.
|
||||
- 인라인 지시어는 해당 메시지에만 영향을 주며, 그 외에는 세션/전역 기본값이 적용됩니다.
|
||||
- 현재 상세 수준을 보려면 인수 없이 `/verbose`(또는 `/verbose:`)를 보냅니다.
|
||||
- 상세 출력이 켜져 있으면 구조화된 도구 결과를 내보내는 에이전트(Pi, 기타 JSON 에이전트)는 각 도구 호출을 자체 메타데이터 전용 메시지로 다시 전송하며, 가능한 경우 `<emoji> <tool-name>: <arg>` 접두사가 붙습니다. 이러한 도구 요약은 스트리밍 델타가 아니라 각 도구가 시작되는 즉시 별도 말풍선으로 전송됩니다.
|
||||
- 도구 실패 요약은 일반 모드에서도 계속 표시되지만, 원시 오류 세부 접미사는 상세 수준이 `on` 또는 `full`이 아닌 한 숨겨집니다.
|
||||
- 상세 수준이 `full`이면 완료 후 도구 출력도 전달됩니다(별도 말풍선, 안전한 길이로 잘림). 실행 중에 `/verbose on|full|off`를 전환하면 이후 도구 말풍선은 새 설정을 따릅니다.
|
||||
- `agents.defaults.toolProgressDetail`은 `/verbose` 도구 요약 및 진행 초안 도구 줄의 형태를 제어합니다. `🛠️ Exec: checking JS syntax` 같은 간결한 사람이 읽을 수 있는 레이블에는 `"explain"`(기본값)을 사용하고, 디버깅을 위해 원시 명령/세부 정보도 덧붙이려면 `"raw"`를 사용합니다. 에이전트별 `agents.list[].toolProgressDetail`은 기본값보다 우선합니다.
|
||||
- `explain`: `🛠️ Exec: check JS syntax for /tmp/app.js`
|
||||
- `raw`: `🛠️ Exec: check JS syntax for /tmp/app.js, node --check /tmp/app.js`
|
||||
|
||||
## Plugin 추적 지시문(/trace)
|
||||
## Plugin 추적 지시어(/trace)
|
||||
|
||||
- 수준: `on` | `off`(기본값).
|
||||
- 지시문만 포함된 메시지는 세션 Plugin 추적 출력을 토글하고 `Plugin trace enabled.` / `Plugin trace disabled.`로 응답합니다.
|
||||
- 인라인 지시문은 해당 메시지에만 영향을 줍니다. 그 외에는 세션/전역 기본값이 적용됩니다.
|
||||
- 인수 없이 `/trace`(또는 `/trace:`)를 보내 현재 추적 수준을 확인하세요.
|
||||
- 지시어 전용 메시지는 세션 Plugin 추적 출력을 전환하고 `Plugin trace enabled.` / `Plugin trace disabled.`로 답합니다.
|
||||
- 인라인 지시어는 해당 메시지에만 영향을 주며, 그 외에는 세션/전역 기본값이 적용됩니다.
|
||||
- 현재 추적 수준을 보려면 인수 없이 `/trace`(또는 `/trace:`)를 보냅니다.
|
||||
- `/trace`는 `/verbose`보다 범위가 좁습니다. Active Memory 디버그 요약 같은 Plugin 소유 추적/디버그 줄만 노출합니다.
|
||||
- 추적 줄은 `/status`와 일반 assistant 응답 뒤의 후속 진단 메시지에 나타날 수 있습니다.
|
||||
- 추적 줄은 `/status`에 표시되거나 일반 어시스턴트 답장 이후 후속 진단 메시지로 나타날 수 있습니다.
|
||||
|
||||
## Reasoning 표시(/reasoning)
|
||||
## 추론 표시(/reasoning)
|
||||
|
||||
- 수준: `on|off|stream`.
|
||||
- 지시문만 포함된 메시지는 thinking 블록을 응답에 표시할지 여부를 토글합니다.
|
||||
- 활성화되면 reasoning은 `Reasoning:` 접두사가 붙은 **별도 메시지**로 전송됩니다.
|
||||
- `stream`(Telegram만 해당): 응답이 생성되는 동안 reasoning을 Telegram 초안 말풍선으로 스트리밍한 다음, reasoning 없이 최종 답변을 보냅니다.
|
||||
- 지시어 전용 메시지는 답장에서 사고 블록을 표시할지 여부를 전환합니다.
|
||||
- 활성화되면 추론은 `Reasoning:` 접두사가 붙은 **별도 메시지**로 전송됩니다.
|
||||
- `stream`(Telegram만): 답장이 생성되는 동안 Telegram 초안 말풍선으로 추론을 스트리밍한 다음, 추론 없이 최종 답변을 전송합니다.
|
||||
- 별칭: `/reason`.
|
||||
- 인수 없이 `/reasoning`(또는 `/reasoning:`)을 보내 현재 reasoning 수준을 확인하세요.
|
||||
- 확인 순서: 인라인 지시문, 세션 재정의, 에이전트별 기본값(`agents.list[].reasoningDefault`), 대체값(`off`).
|
||||
- 현재 추론 수준을 보려면 인수 없이 `/reasoning`(또는 `/reasoning:`)을 보냅니다.
|
||||
- 해석 순서: 인라인 지시어, 그다음 세션 재정의, 그다음 에이전트별 기본값(`agents.list[].reasoningDefault`), 그다음 대체값(`off`).
|
||||
|
||||
잘못된 형식의 로컬 모델 reasoning 태그는 보수적으로 처리됩니다. 닫힌 `<think>...</think>` 블록은 일반 응답에서 숨겨진 상태로 유지되며, 이미 보이는 텍스트 뒤의 닫히지 않은 reasoning도 숨겨집니다. 응답이 닫히지 않은 단일 여는 태그로 완전히 감싸져 있고 그렇지 않으면 빈 텍스트로 전달될 경우, OpenClaw는 잘못된 여는 태그를 제거하고 나머지 텍스트를 전달합니다.
|
||||
잘못된 형식의 로컬 모델 추론 태그는 보수적으로 처리됩니다. 닫힌 `<think>...</think>` 블록은 일반 답장에서 숨겨지고, 이미 표시된 텍스트 뒤의 닫히지 않은 추론도 숨겨집니다. 답장이 하나의 닫히지 않은 여는 태그로 완전히 감싸져 있고 그렇지 않으면 빈 텍스트로 전달될 경우, OpenClaw는 잘못된 여는 태그를 제거하고 남은 텍스트를 전달합니다.
|
||||
|
||||
## 관련 항목
|
||||
|
||||
- 상승 모드 문서는 [상승 모드](/ko/tools/elevated)에 있습니다.
|
||||
|
||||
## Heartbeat
|
||||
## Heartbeats
|
||||
|
||||
- Heartbeat 프로브 본문은 구성된 Heartbeat 프롬프트입니다(기본값: `Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.`). Heartbeat 메시지의 인라인 지시문은 일반적인 방식으로 적용됩니다(단, Heartbeat에서 세션 기본값을 변경하는 것은 피하세요).
|
||||
- Heartbeat 전달은 기본적으로 최종 payload만 보냅니다. 별도 `Reasoning:` 메시지도 함께 보내려면(사용 가능한 경우) `agents.defaults.heartbeat.includeReasoning: true` 또는 에이전트별 `agents.list[].heartbeat.includeReasoning: true`를 설정하세요.
|
||||
- Heartbeat 프로브 본문은 구성된 Heartbeat 프롬프트입니다(기본값: `Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.`). Heartbeat 메시지의 인라인 지시어는 평소처럼 적용됩니다(단, Heartbeat에서 세션 기본값을 변경하지 않는 것이 좋습니다).
|
||||
- Heartbeat 전달은 기본적으로 최종 페이로드만 전송합니다. 별도의 `Reasoning:` 메시지도 전송하려면(사용 가능한 경우) `agents.defaults.heartbeat.includeReasoning: true` 또는 에이전트별 `agents.list[].heartbeat.includeReasoning: true`를 설정합니다.
|
||||
|
||||
## 웹 채팅 UI
|
||||
|
||||
- 웹 채팅 thinking 선택기는 페이지 로드 시 인바운드 세션 저장소/config에서 세션의 저장된 수준을 반영합니다.
|
||||
- 다른 수준을 선택하면 `sessions.patch`를 통해 세션 재정의를 즉시 기록합니다. 다음 전송을 기다리지 않으며 일회성 `thinkingOnce` 재정의가 아닙니다.
|
||||
- 첫 번째 옵션은 항상 `Default (<resolved level>)`이며, 확인된 기본값은 활성 세션 모델의 공급자 thinking 프로필과 `/status` 및 `session_status`가 사용하는 동일한 대체 로직에서 나옵니다.
|
||||
- 선택기는 Gateway 세션 행/기본값이 반환하는 `thinkingLevels`를 사용하며, `thinkingOptions`는 레거시 레이블 목록으로 유지됩니다. 브라우저 UI는 자체 공급자 regex 목록을 유지하지 않습니다. Plugin이 모델별 수준 집합을 소유합니다.
|
||||
- `/think:<level>`도 계속 작동하며 동일하게 저장된 세션 수준을 업데이트하므로 채팅 지시문과 선택기가 동기화된 상태를 유지합니다.
|
||||
- 웹 채팅 사고 선택기는 페이지가 로드될 때 인바운드 세션 저장소/구성의 세션 저장 수준을 반영합니다.
|
||||
- 다른 수준을 선택하면 `sessions.patch`를 통해 세션 재정의가 즉시 기록됩니다. 다음 전송을 기다리지 않으며 일회성 `thinkingOnce` 재정의도 아닙니다.
|
||||
- 첫 번째 옵션은 항상 `Default (<resolved level>)`이며, 해석된 기본값은 활성 세션 모델의 제공자 사고 프로필과 `/status` 및 `session_status`가 사용하는 동일한 대체 로직에서 나옵니다.
|
||||
- 선택기는 Gateway 세션 행/기본값이 반환한 `thinkingLevels`를 사용하며, `thinkingOptions`는 레거시 레이블 목록으로 유지됩니다. 브라우저 UI는 자체 제공자 정규식 목록을 유지하지 않습니다. Plugin이 모델별 수준 집합을 소유합니다.
|
||||
- `/think:<level>`은 여전히 작동하며 동일한 저장된 세션 수준을 업데이트하므로 채팅 지시어와 선택기가 동기화된 상태를 유지합니다.
|
||||
|
||||
## 공급자 프로필
|
||||
## 제공자 프로필
|
||||
|
||||
- 제공자 Plugin은 모델이 지원하는 수준과 기본값을 정의하기 위해 `resolveThinkingProfile(ctx)`를 노출할 수 있습니다.
|
||||
- Claude 모델을 프록시하는 제공자 Plugin은 직접 Anthropic 카탈로그와 프록시 카탈로그가 서로 맞게 유지되도록 `openclaw/plugin-sdk/provider-model-shared`의 `resolveClaudeThinkingProfile(modelId)`을 재사용해야 합니다.
|
||||
- 각 프로필 수준에는 저장된 정식 `id`(`off`, `minimal`, `low`, `medium`, `high`, `xhigh`, `adaptive` 또는 `max`)가 있으며 표시용 `label`을 포함할 수 있습니다. 이진 제공자는 `{ id: "low", label: "on" }`을 사용합니다.
|
||||
- Claude 모델을 프록시하는 제공자 Plugin은 직접 Anthropic 카탈로그와 프록시 카탈로그가 일치하도록 `openclaw/plugin-sdk/provider-model-shared`의 `resolveClaudeThinkingProfile(modelId)`를 재사용해야 합니다.
|
||||
- 각 프로필 수준에는 저장된 정식 `id`(`off`, `minimal`, `low`, `medium`, `high`, `xhigh`, `adaptive` 또는 `max`)가 있으며, 표시용 `label`을 포함할 수 있습니다. 이진 제공자는 `{ id: "low", label: "on" }`을 사용합니다.
|
||||
- 명시적 thinking 재정의를 검증해야 하는 도구 Plugin은 `api.runtime.agent.resolveThinkingPolicy({ provider, model })`와 `api.runtime.agent.normalizeThinkingLevel(...)`를 사용해야 하며, 자체 제공자/모델 수준 목록을 유지해서는 안 됩니다.
|
||||
- 구성된 사용자 지정 모델 메타데이터에 접근할 수 있는 도구 Plugin은 `resolveThinkingPolicy`에 `catalog`를 전달하여 `compat.supportedReasoningEfforts` 옵트인이 Plugin 측 검증에 반영되도록 할 수 있습니다.
|
||||
- 게시된 레거시 훅(`supportsXHighThinking`, `isBinaryThinking`, `resolveDefaultThinkingLevel`)은 호환성 어댑터로 유지되지만, 새 사용자 지정 수준 집합은 `resolveThinkingProfile`을 사용해야 합니다.
|
||||
- Gateway 행/기본값은 `thinkingLevels`, `thinkingOptions`, `thinkingDefault`를 노출하므로 ACP/채팅 클라이언트는 런타임 검증에서 사용하는 것과 동일한 프로필 ID와 레이블을 렌더링합니다.
|
||||
- 구성된 사용자 지정 모델 메타데이터에 접근할 수 있는 도구 Plugin은 `catalog`를 `resolveThinkingPolicy`에 전달하여 `compat.supportedReasoningEfforts` 옵트인이 Plugin 측 검증에 반영되도록 할 수 있습니다.
|
||||
- 게시된 레거시 훅(`supportsXHighThinking`, `isBinaryThinking`, `resolveDefaultThinkingLevel`)은 호환성 어댑터로 유지되지만, 새로운 사용자 지정 수준 집합은 `resolveThinkingProfile`을 사용해야 합니다.
|
||||
- Gateway 행/기본값은 `thinkingLevels`, `thinkingOptions`, `thinkingDefault`를 노출하여 ACP/채팅 클라이언트가 런타임 검증에서 사용하는 것과 동일한 프로필 ID와 레이블을 렌더링하도록 합니다.
|
||||
|
||||
@ -2,28 +2,28 @@
|
||||
read_when:
|
||||
- URL을 가져와 읽기 쉬운 콘텐츠를 추출하려는 경우
|
||||
- web_fetch 또는 해당 Firecrawl 폴백을 구성해야 합니다
|
||||
- web_fetch 제한과 캐싱을 이해하고 싶습니다
|
||||
- web_fetch 제한과 캐싱을 이해하려는 경우
|
||||
sidebarTitle: Web Fetch
|
||||
summary: web_fetch 도구 -- 읽기 쉬운 콘텐츠 추출을 포함한 HTTP 가져오기
|
||||
summary: web_fetch 도구 -- 읽기 가능한 콘텐츠 추출 기능이 있는 HTTP 가져오기
|
||||
title: 웹 가져오기
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T21:17:20Z"
|
||||
generated_at: "2026-05-04T02:26:25Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: f455da77c20049f0ed0246fa53e9f49d3cf2004e65bd64a0bf871861c6e93229
|
||||
source_hash: c8c3efbf4a640b2fd69cc9532dcb06a873a6830a2e8a85ab7510ab38207c8670
|
||||
source_path: tools/web-fetch.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
`web_fetch` 도구는 일반 HTTP GET을 수행하고 읽기 쉬운 콘텐츠를 추출합니다
|
||||
(HTML을 markdown 또는 텍스트로 변환). JavaScript는 실행하지 **않습니다**.
|
||||
`web_fetch` 도구는 일반 HTTP GET을 수행하고 읽을 수 있는 콘텐츠를 추출합니다
|
||||
(HTML을 markdown 또는 텍스트로 변환). JavaScript는 **실행하지 않습니다**.
|
||||
|
||||
JS 의존도가 높은 사이트나 로그인으로 보호된 페이지에는 대신
|
||||
[Web Browser](/ko/tools/browser)를 사용하세요.
|
||||
[웹 브라우저](/ko/tools/browser)를 사용하세요.
|
||||
|
||||
## 빠른 시작
|
||||
|
||||
`web_fetch`는 **기본적으로 활성화되어 있습니다** -- 설정이 필요 없습니다. agent는
|
||||
`web_fetch`는 **기본적으로 활성화되어 있습니다** -- 설정이 필요하지 않습니다. 에이전트가
|
||||
즉시 호출할 수 있습니다.
|
||||
|
||||
```javascript
|
||||
@ -37,7 +37,7 @@ await web_fetch({ url: "https://example.com/article" });
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="extractMode" type="'markdown' | 'text'" default="markdown">
|
||||
주요 콘텐츠 추출 후 출력 형식입니다.
|
||||
주요 콘텐츠 추출 후의 출력 형식입니다.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="maxChars" type="number">
|
||||
@ -52,15 +52,15 @@ await web_fetch({ url: "https://example.com/article" });
|
||||
보냅니다. 비공개/내부 호스트 이름을 차단하고 리디렉션을 다시 확인합니다.
|
||||
</Step>
|
||||
<Step title="Extract">
|
||||
HTML 응답에 Readability(주요 콘텐츠 추출)를 실행합니다.
|
||||
HTML 응답에서 Readability(주요 콘텐츠 추출)를 실행합니다.
|
||||
</Step>
|
||||
<Step title="Fallback (optional)">
|
||||
Readability가 실패하고 Firecrawl이 설정되어 있으면 봇 우회 모드로
|
||||
Firecrawl API를 통해 다시 시도합니다.
|
||||
</Step>
|
||||
<Step title="Cache">
|
||||
결과는 동일한 URL의 반복 가져오기를 줄이기 위해 15분 동안 캐시됩니다
|
||||
(설정 가능).
|
||||
동일한 URL을 반복해서 가져오는 일을 줄이기 위해 결과를 15분 동안
|
||||
캐시합니다(설정 가능).
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
@ -79,6 +79,7 @@ await web_fetch({ url: "https://example.com/article" });
|
||||
timeoutSeconds: 30,
|
||||
cacheTtlMinutes: 15,
|
||||
maxRedirects: 3,
|
||||
useTrustedEnvProxy: false, // let a trusted HTTP(S) env proxy resolve DNS
|
||||
readability: true, // use Readability extraction
|
||||
userAgent: "Mozilla/5.0 ...", // override User-Agent
|
||||
ssrfPolicy: {
|
||||
@ -91,10 +92,10 @@ await web_fetch({ url: "https://example.com/article" });
|
||||
}
|
||||
```
|
||||
|
||||
## Firecrawl fallback
|
||||
## Firecrawl 대체 경로
|
||||
|
||||
Readability 추출이 실패하면 `web_fetch`는 봇 우회와 더 나은 추출을 위해
|
||||
[Firecrawl](/ko/tools/firecrawl)로 fallback할 수 있습니다.
|
||||
[Firecrawl](/ko/tools/firecrawl)로 대체할 수 있습니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -128,39 +129,56 @@ Readability 추출이 실패하면 `web_fetch`는 봇 우회와 더 나은 추
|
||||
기존 `tools.web.fetch.firecrawl.*` 설정은 `openclaw doctor --fix`로 자동 마이그레이션됩니다.
|
||||
|
||||
<Note>
|
||||
Firecrawl이 활성화되어 있고 SecretRef가 해결되지 않았으며
|
||||
`FIRECRAWL_API_KEY` env fallback도 없으면 Gateway 시작이 빠르게 실패합니다.
|
||||
Firecrawl이 활성화되어 있고 해당 SecretRef가 확인되지 않았으며
|
||||
`FIRECRAWL_API_KEY` env 대체값도 없으면 gateway 시작이 빠르게 실패합니다.
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
Firecrawl `baseUrl` 재정의는 엄격히 제한됩니다. 호스팅된 트래픽은
|
||||
`https://api.firecrawl.dev`를 사용하며, 셀프 호스팅 재정의는 비공개 또는
|
||||
내부 endpoint를 대상으로 해야 하고 `http://`는 이러한 비공개 대상에만 허용됩니다.
|
||||
Firecrawl `baseUrl` 재정의는 제한됩니다. 호스팅 트래픽은
|
||||
`https://api.firecrawl.dev`를 사용하며, 자체 호스팅 재정의는 비공개 또는
|
||||
내부 엔드포인트를 대상으로 해야 하고, `http://`는 해당 비공개 대상에만 허용됩니다.
|
||||
</Note>
|
||||
|
||||
현재 런타임 동작:
|
||||
|
||||
- `tools.web.fetch.provider`는 fetch fallback provider를 명시적으로 선택합니다.
|
||||
- `provider`가 생략되면 OpenClaw는 사용 가능한 자격 증명에서 첫 번째 준비된 web-fetch
|
||||
provider를 자동 감지합니다. sandbox되지 않은 `web_fetch`는
|
||||
`contracts.webFetchProviders`를 선언하고 런타임에 일치하는 provider를 등록하는
|
||||
설치된 plugins를 사용할 수 있습니다. 현재 bundled provider는 Firecrawl입니다.
|
||||
- sandbox된 `web_fetch` 호출은 bundled providers로 제한됩니다.
|
||||
- Readability가 비활성화되어 있으면 `web_fetch`는 선택된 provider fallback으로
|
||||
바로 넘어갑니다. 사용 가능한 provider가 없으면 실패한 상태로 닫힙니다.
|
||||
- `tools.web.fetch.provider`는 가져오기 대체 공급자를 명시적으로 선택합니다.
|
||||
- `provider`가 생략되면 OpenClaw는 사용 가능한 자격 증명에서 준비된 첫 번째 web-fetch
|
||||
공급자를 자동 감지합니다. 샌드박스가 적용되지 않은 `web_fetch`는
|
||||
`contracts.webFetchProviders`를 선언하고 런타임에 일치하는 공급자를 등록하는
|
||||
설치된 plugins를 사용할 수 있습니다. 현재 번들 공급자는 Firecrawl입니다.
|
||||
- 샌드박스 적용 `web_fetch` 호출은 번들 공급자로만 제한됩니다.
|
||||
- Readability가 비활성화되어 있으면 `web_fetch`는 선택된 공급자 대체 경로로
|
||||
바로 건너뜁니다. 사용 가능한 공급자가 없으면 닫힌 상태로 실패합니다.
|
||||
|
||||
## 신뢰할 수 있는 Env 프록시
|
||||
|
||||
배포 환경에서 `web_fetch`가 신뢰할 수 있는 아웃바운드 HTTP(S) 프록시를
|
||||
거쳐야 하는 경우 `tools.web.fetch.useTrustedEnvProxy: true`를 설정하세요.
|
||||
|
||||
이 모드에서도 OpenClaw는 요청을 보내기 전에 호스트 이름 기반 SSRF 검사를
|
||||
적용하지만, 로컬 DNS 고정 대신 프록시가 DNS를 확인하도록 허용합니다. 프록시가
|
||||
운영자에 의해 제어되고 DNS 확인 후 아웃바운드 정책을 적용하는 경우에만 활성화하세요.
|
||||
|
||||
<Note>
|
||||
HTTP(S) 프록시 env var가 설정되어 있지 않거나 대상 호스트가
|
||||
`NO_PROXY`로 제외된 경우, `web_fetch`는 로컬 DNS 고정이 있는 일반 엄격 경로로
|
||||
대체됩니다.
|
||||
</Note>
|
||||
|
||||
## 제한 및 안전
|
||||
|
||||
- `maxChars`는 `tools.web.fetch.maxCharsCap`으로 제한됩니다
|
||||
- 응답 본문은 파싱 전에 `maxResponseBytes`로 제한됩니다. 너무 큰
|
||||
- 응답 본문은 파싱 전에 `maxResponseBytes`로 제한됩니다. 크기가 초과된
|
||||
응답은 경고와 함께 잘립니다
|
||||
- 비공개/내부 호스트 이름은 차단됩니다
|
||||
- `tools.web.fetch.ssrfPolicy.allowRfc2544BenchmarkRange` 및
|
||||
`tools.web.fetch.ssrfPolicy.allowIpv6UniqueLocalRange`는 신뢰할 수 있는
|
||||
가짜 IP 프록시 스택을 위한 좁은 opt-in입니다. 프록시가 해당 합성 범위를 소유하고
|
||||
자체 대상 정책을 적용하는 경우가 아니면 설정하지 마세요
|
||||
가짜 IP 프록시 스택을 위한 좁은 opt-in입니다. 프록시가 해당 합성 범위를
|
||||
소유하고 자체 대상 정책을 적용하는 경우가 아니면 설정하지 마세요
|
||||
- 리디렉션은 확인되며 `maxRedirects`로 제한됩니다
|
||||
- `web_fetch`는 최선의 방식입니다 -- 일부 사이트에는 [Web Browser](/ko/tools/browser)가 필요합니다
|
||||
- `useTrustedEnvProxy`는 명시적 opt-in이며 DNS 확인 후에도 아웃바운드 정책을
|
||||
적용하는 운영자 제어 프록시에만 활성화해야 합니다
|
||||
- `web_fetch`는 최선형 방식입니다 -- 일부 사이트에는 [웹 브라우저](/ko/tools/browser)가 필요합니다
|
||||
|
||||
## 도구 프로필
|
||||
|
||||
@ -177,6 +195,6 @@ Readability 추출이 실패하면 `web_fetch`는 봇 우회와 더 나은 추
|
||||
|
||||
## 관련 항목
|
||||
|
||||
- [Web Search](/ko/tools/web) -- 여러 providers로 웹 검색
|
||||
- [Web Browser](/ko/tools/browser) -- JS 의존도가 높은 사이트를 위한 전체 브라우저 자동화
|
||||
- [Firecrawl](/ko/tools/firecrawl) -- Firecrawl 검색 및 scrape 도구
|
||||
- [웹 검색](/ko/tools/web) -- 여러 공급자로 웹 검색
|
||||
- [웹 브라우저](/ko/tools/browser) -- JS 의존도가 높은 사이트를 위한 전체 브라우저 자동화
|
||||
- [Firecrawl](/ko/tools/firecrawl) -- Firecrawl 검색 및 스크래핑 도구
|
||||
|
||||
@ -1,25 +1,25 @@
|
||||
---
|
||||
read_when:
|
||||
- 브라우저에서 Gateway를 운영하려는 경우
|
||||
- SSH 터널 없이 Tailnet에 접근하려는 경우
|
||||
- SSH 터널 없이 Tailnet 액세스가 필요한 경우
|
||||
sidebarTitle: Control UI
|
||||
summary: Gateway용 브라우저 기반 제어 UI(채팅, 노드, 설정)
|
||||
title: 제어 사용자 인터페이스
|
||||
title: 제어 UI
|
||||
x-i18n:
|
||||
generated_at: "2026-05-03T06:22:40Z"
|
||||
generated_at: "2026-05-04T02:26:25Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 88959ccf435b31015039bf28c3043023d99f0b953a1489986ab2d0cbd261771c
|
||||
source_hash: c890d83da2c296b600e4b5a00a538f37e6bd54da31fbe62113ecd6177b15626e
|
||||
source_path: web/control-ui.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
Control UI는 Gateway에서 제공되는 작은 **Vite + Lit** 단일 페이지 앱입니다.
|
||||
Control UI는 Gateway가 제공하는 작은 **Vite + Lit** 단일 페이지 앱입니다.
|
||||
|
||||
- 기본값: `http://<host>:18789/`
|
||||
- 선택적 접두사: `gateway.controlUi.basePath` 설정(예: `/openclaw`)
|
||||
|
||||
동일한 포트에서 **Gateway WebSocket에 직접** 통신합니다.
|
||||
같은 포트의 **Gateway WebSocket**과 직접 통신합니다.
|
||||
|
||||
## 빠른 열기(로컬)
|
||||
|
||||
@ -27,16 +27,16 @@ Gateway가 같은 컴퓨터에서 실행 중이면 다음을 여세요.
|
||||
|
||||
- [http://127.0.0.1:18789/](http://127.0.0.1:18789/) (또는 [http://localhost:18789/](http://localhost:18789/))
|
||||
|
||||
페이지를 불러오지 못하면 먼저 Gateway를 시작하세요: `openclaw gateway`.
|
||||
페이지가 로드되지 않으면 먼저 Gateway를 시작하세요. `openclaw gateway`
|
||||
|
||||
인증은 WebSocket 핸드셰이크 중 다음을 통해 제공됩니다.
|
||||
|
||||
- `connect.params.auth.token`
|
||||
- `connect.params.auth.password`
|
||||
- `gateway.auth.allowTailscale: true`일 때 Tailscale Serve 신원 헤더
|
||||
- `gateway.auth.mode: "trusted-proxy"`일 때 신뢰할 수 있는 프록시 신원 헤더
|
||||
- `gateway.auth.allowTailscale: true`일 때 Tailscale Serve ID 헤더
|
||||
- `gateway.auth.mode: "trusted-proxy"`일 때 신뢰할 수 있는 프록시 ID 헤더
|
||||
|
||||
대시보드 설정 패널은 현재 브라우저 탭 세션과 선택한 gateway URL에 대한 토큰을 보관하며, 비밀번호는 유지하지 않습니다. 온보딩은 일반적으로 첫 연결 시 공유 비밀 인증용 gateway 토큰을 생성하지만, `gateway.auth.mode`가 `"password"`이면 비밀번호 인증도 작동합니다.
|
||||
대시보드 설정 패널은 현재 브라우저 탭 세션과 선택된 Gateway URL에 대한 토큰을 보관하며, 비밀번호는 유지하지 않습니다. 온보딩은 일반적으로 첫 연결 시 공유 비밀 인증용 Gateway 토큰을 생성하지만, `gateway.auth.mode`가 `"password"`이면 비밀번호 인증도 작동합니다.
|
||||
|
||||
## 기기 페어링(첫 연결)
|
||||
|
||||
@ -45,108 +45,108 @@ Gateway가 같은 컴퓨터에서 실행 중이면 다음을 여세요.
|
||||
**표시되는 내용:** "disconnected (1008): pairing required"
|
||||
|
||||
<Steps>
|
||||
<Step title="List pending requests">
|
||||
<Step title="대기 중인 요청 나열">
|
||||
```bash
|
||||
openclaw devices list
|
||||
```
|
||||
</Step>
|
||||
<Step title="Approve by request ID">
|
||||
<Step title="요청 ID로 승인">
|
||||
```bash
|
||||
openclaw devices approve <requestId>
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
브라우저가 변경된 인증 세부 정보(역할/범위/공개 키)로 페어링을 다시 시도하면 이전 대기 중 요청은 대체되고 새 `requestId`가 생성됩니다. 승인하기 전에 `openclaw devices list`를 다시 실행하세요.
|
||||
브라우저가 변경된 인증 세부 정보(역할/범위/공개 키)로 페어링을 다시 시도하면 이전 대기 요청은 대체되고 새 `requestId`가 생성됩니다. 승인하기 전에 `openclaw devices list`를 다시 실행하세요.
|
||||
|
||||
브라우저가 이미 페어링되어 있고 이를 읽기 액세스에서 쓰기/관리자 액세스로 변경하면, 이는 조용한 재연결이 아니라 승인 업그레이드로 처리됩니다. OpenClaw는 기존 승인을 활성 상태로 유지하고, 더 넓은 범위의 재연결을 차단하며, 새 범위 세트를 명시적으로 승인하도록 요청합니다.
|
||||
브라우저가 이미 페어링되어 있고 읽기 액세스에서 쓰기/관리자 액세스로 변경하면, 이는 조용한 재연결이 아니라 승인 업그레이드로 처리됩니다. OpenClaw는 이전 승인을 활성 상태로 유지하고 더 넓은 권한의 재연결을 차단한 뒤 새 범위 세트를 명시적으로 승인하도록 요청합니다.
|
||||
|
||||
승인되면 기기가 기억되며, `openclaw devices revoke --device <id> --role <role>`로 철회하지 않는 한 재승인이 필요하지 않습니다. 토큰 순환 및 철회는 [기기 CLI](/ko/cli/devices)를 참조하세요.
|
||||
승인되면 기기가 기억되며 `openclaw devices revoke --device <id> --role <role>`로 취소하지 않는 한 재승인이 필요하지 않습니다. 토큰 순환 및 취소는 [기기 CLI](/ko/cli/devices)를 참조하세요.
|
||||
|
||||
<Note>
|
||||
- 직접 local loopback 브라우저 연결(`127.0.0.1` / `localhost`)은 자동 승인됩니다.
|
||||
- `gateway.auth.allowTailscale: true`이고, Tailscale 신원이 검증되며, 브라우저가 기기 신원을 제시하면 Tailscale Serve는 Control UI 운영자 세션의 페어링 왕복 절차를 건너뛸 수 있습니다.
|
||||
- 직접 Tailnet 바인드, LAN 브라우저 연결, 기기 신원이 없는 브라우저 프로필은 여전히 명시적 승인이 필요합니다.
|
||||
- `gateway.auth.allowTailscale: true`이고 Tailscale ID가 검증되며 브라우저가 기기 ID를 제시하는 경우, Tailscale Serve는 Control UI 운영자 세션의 페어링 왕복 과정을 건너뛸 수 있습니다.
|
||||
- 직접 Tailnet 바인딩, LAN 브라우저 연결, 기기 ID가 없는 브라우저 프로필은 여전히 명시적 승인이 필요합니다.
|
||||
- 각 브라우저 프로필은 고유한 기기 ID를 생성하므로, 브라우저를 전환하거나 브라우저 데이터를 지우면 다시 페어링해야 합니다.
|
||||
|
||||
</Note>
|
||||
|
||||
## 개인 신원(브라우저 로컬)
|
||||
## 개인 ID(브라우저 로컬)
|
||||
|
||||
Control UI는 공유 세션에서 귀속 표시를 위해 보내는 메시지에 첨부되는 브라우저별 개인 신원(표시 이름 및 아바타)을 지원합니다. 이는 브라우저 저장소에 있으며 현재 브라우저 프로필로 범위가 제한되고, 실제로 보낸 메시지의 일반적인 transcript 작성자 메타데이터를 제외하고는 다른 기기에 동기화되거나 서버 측에 유지되지 않습니다. 사이트 데이터를 지우거나 브라우저를 전환하면 비어 있는 상태로 재설정됩니다.
|
||||
Control UI는 공유 세션에서 출처 표시를 위해 보내는 메시지에 첨부되는 브라우저별 개인 ID(표시 이름 및 아바타)를 지원합니다. 이는 브라우저 저장소에 저장되고 현재 브라우저 프로필로 범위가 제한되며, 실제로 보낸 메시지의 일반적인 트랜스크립트 작성자 메타데이터를 제외하고는 다른 기기와 동기화되거나 서버 측에 유지되지 않습니다. 사이트 데이터를 지우거나 브라우저를 전환하면 빈 상태로 재설정됩니다.
|
||||
|
||||
동일한 브라우저 로컬 패턴이 assistant 아바타 재정의에도 적용됩니다. 업로드된 assistant 아바타는 로컬 브라우저에서만 gateway가 확인한 신원 위에 표시되며 `config.patch`를 통해 왕복하지 않습니다. 공유 `ui.assistant.avatar` 구성 필드는 해당 필드를 직접 쓰는 비 UI 클라이언트(예: 스크립트된 gateways 또는 사용자 지정 대시보드)에서 여전히 사용할 수 있습니다.
|
||||
동일한 브라우저 로컬 패턴이 어시스턴트 아바타 재정의에도 적용됩니다. 업로드된 어시스턴트 아바타는 로컬 브라우저에서만 Gateway가 확인한 ID 위에 오버레이되며 `config.patch`를 통해 왕복하지 않습니다. 공유 `ui.assistant.avatar` 구성 필드는 해당 필드를 직접 쓰는 비 UI 클라이언트(예: 스크립트 기반 Gateway 또는 사용자 지정 대시보드)용으로 계속 사용할 수 있습니다.
|
||||
|
||||
## 런타임 구성 엔드포인트
|
||||
|
||||
Control UI는 `/__openclaw/control-ui-config.json`에서 런타임 설정을 가져옵니다. 해당 엔드포인트는 나머지 HTTP 표면과 동일한 gateway 인증으로 보호됩니다. 인증되지 않은 브라우저는 이를 가져올 수 없으며, 성공적으로 가져오려면 이미 유효한 gateway 토큰/비밀번호, Tailscale Serve 신원, 또는 신뢰할 수 있는 프록시 신원 중 하나가 필요합니다.
|
||||
Control UI는 런타임 설정을 `/__openclaw/control-ui-config.json`에서 가져옵니다. 이 엔드포인트는 HTTP 표면의 나머지 부분과 동일한 Gateway 인증으로 보호됩니다. 인증되지 않은 브라우저는 이를 가져올 수 없으며, 성공적인 가져오기를 위해서는 이미 유효한 Gateway 토큰/비밀번호, Tailscale Serve ID 또는 신뢰할 수 있는 프록시 ID 중 하나가 필요합니다.
|
||||
|
||||
## 언어 지원
|
||||
|
||||
Control UI는 첫 로드 시 브라우저 로케일을 기반으로 자체 지역화를 수행할 수 있습니다. 나중에 재정의하려면 **개요 -> Gateway 액세스 -> 언어**를 여세요. 로케일 선택기는 외관 아래가 아니라 Gateway 액세스 카드에 있습니다.
|
||||
Control UI는 첫 로드 시 브라우저 로캘을 기준으로 자체 지역화를 수행할 수 있습니다. 나중에 재정의하려면 **개요 -> Gateway 액세스 -> 언어**를 여세요. 로캘 선택기는 모양 아래가 아니라 Gateway 액세스 카드에 있습니다.
|
||||
|
||||
- 지원 로케일: `en`, `zh-CN`, `zh-TW`, `pt-BR`, `de`, `es`, `ja-JP`, `ko`, `fr`, `ar`, `it`, `tr`, `uk`, `id`, `pl`, `th`, `vi`, `nl`, `fa`
|
||||
- 지원되는 로캘: `en`, `zh-CN`, `zh-TW`, `pt-BR`, `de`, `es`, `ja-JP`, `ko`, `fr`, `ar`, `it`, `tr`, `uk`, `id`, `pl`, `th`, `vi`, `nl`, `fa`
|
||||
- 영어가 아닌 번역은 브라우저에서 지연 로드됩니다.
|
||||
- 선택한 로케일은 브라우저 저장소에 저장되고 이후 방문 시 재사용됩니다.
|
||||
- 선택한 로캘은 브라우저 저장소에 저장되고 이후 방문 시 재사용됩니다.
|
||||
- 누락된 번역 키는 영어로 대체됩니다.
|
||||
|
||||
문서 번역도 동일한 비영어 로케일 세트로 생성되지만, 문서 사이트에 내장된 Mintlify 언어 선택기는 Mintlify가 허용하는 로케일 코드로 제한됩니다. 태국어(`th`)와 페르시아어(`fa`) 문서는 publish repo에 계속 생성되지만, Mintlify가 해당 코드를 지원하기 전까지는 선택기에 표시되지 않을 수 있습니다.
|
||||
문서 번역은 동일한 비영어 로캘 세트에 대해 생성되지만, 문서 사이트에 내장된 Mintlify 언어 선택기는 Mintlify가 허용하는 로캘 코드로 제한됩니다. 태국어(`th`) 및 페르시아어(`fa`) 문서도 게시 저장소에 생성되지만, Mintlify가 해당 코드를 지원하기 전까지는 그 선택기에 표시되지 않을 수 있습니다.
|
||||
|
||||
## 외관 테마
|
||||
## 모양 테마
|
||||
|
||||
외관 패널은 내장 Claw, Knot, Dash 테마와 브라우저 로컬 tweakcn 가져오기 슬롯 하나를 유지합니다. 테마를 가져오려면 [tweakcn themes](https://tweakcn.com/themes)를 열고, 테마를 선택하거나 만든 다음 **공유**를 클릭하고 복사한 테마 링크를 외관에 붙여 넣으세요. 가져오기 도구는 `https://tweakcn.com/r/themes/<id>` registry URL, `https://tweakcn.com/editor/theme?theme=amethyst-haze` 같은 editor URL, 상대 `/themes/<id>` 경로, 원시 테마 ID, `amethyst-haze` 같은 기본 테마 이름도 허용합니다.
|
||||
모양 패널은 기본 제공 Claw, Knot, Dash 테마와 브라우저 로컬 tweakcn 가져오기 슬롯 하나를 유지합니다. 테마를 가져오려면 [tweakcn themes](https://tweakcn.com/themes)를 열고 테마를 선택하거나 만든 다음 **공유**를 클릭하고 복사한 테마 링크를 모양에 붙여넣으세요. 가져오기 도구는 `https://tweakcn.com/r/themes/<id>` 레지스트리 URL, `https://tweakcn.com/editor/theme?theme=amethyst-haze` 같은 편집기 URL, 상대 `/themes/<id>` 경로, 원시 테마 ID, `amethyst-haze` 같은 기본 테마 이름도 허용합니다.
|
||||
|
||||
가져온 테마는 현재 브라우저 프로필에만 저장됩니다. gateway 구성에 쓰이지 않으며 기기 간에 동기화되지 않습니다. 가져온 테마를 교체하면 하나의 로컬 슬롯이 업데이트됩니다. 이를 지우면 가져온 테마가 선택되어 있었던 경우 활성 테마가 Claw로 다시 전환됩니다.
|
||||
가져온 테마는 현재 브라우저 프로필에만 저장됩니다. Gateway 구성에 기록되지 않으며 기기 간에 동기화되지 않습니다. 가져온 테마를 교체하면 하나의 로컬 슬롯이 업데이트됩니다. 이를 지우면 가져온 테마가 선택되어 있었던 경우 활성 테마가 Claw로 다시 전환됩니다.
|
||||
|
||||
## 수행할 수 있는 작업(현재)
|
||||
## 할 수 있는 일(현재)
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Chat and Talk">
|
||||
- Gateway WS(`chat.history`, `chat.send`, `chat.abort`, `chat.inject`)를 통해 모델과 채팅합니다.
|
||||
- 브라우저 실시간 세션을 통해 대화합니다. OpenAI는 직접 WebRTC를 사용하고, Google Live는 WebSocket을 통한 제한된 일회용 브라우저 토큰을 사용하며, 백엔드 전용 실시간 음성 plugins는 Gateway relay transport를 사용합니다. relay는 provider 자격 증명을 Gateway에 유지하는 동안 브라우저가 `talk.realtime.relay*` RPC를 통해 마이크 PCM을 스트리밍하고, 더 큰 구성된 OpenClaw 모델을 위해 `openclaw_agent_consult` 도구 호출을 `chat.send`를 통해 다시 보냅니다.
|
||||
- Chat에서 도구 호출과 실시간 도구 출력 카드를 스트리밍합니다(agent 이벤트).
|
||||
<Accordion title="채팅 및 대화">
|
||||
- Gateway WS를 통해 모델과 채팅합니다(`chat.history`, `chat.send`, `chat.abort`, `chat.inject`).
|
||||
- 브라우저 실시간 세션을 통해 대화합니다. OpenAI는 직접 WebRTC를 사용하고, Google Live는 WebSocket을 통한 제한된 일회용 브라우저 토큰을 사용하며, 백엔드 전용 실시간 음성 Plugin은 Gateway 릴레이 전송을 사용합니다. 릴레이는 제공자 자격 증명을 Gateway에 유지하고, 브라우저는 `talk.realtime.relay*` RPC를 통해 마이크 PCM을 스트리밍하며, 더 큰 구성 OpenClaw 모델을 위해 `chat.send`를 통해 `openclaw_agent_consult` 도구 호출을 다시 보냅니다.
|
||||
- 채팅에서 도구 호출 + 실시간 도구 출력 카드를 스트리밍합니다(에이전트 이벤트).
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Channels, instances, sessions, dreams">
|
||||
- 채널: 내장 및 번들/외부 plugin 채널 상태, QR 로그인, 채널별 구성(`channels.status`, `web.login.*`, `config.patch`).
|
||||
- 인스턴스: presence 목록 및 새로고침(`system-presence`).
|
||||
- 세션: 목록 및 세션별 모델/thinking/fast/verbose/trace/reasoning 재정의(`sessions.list`, `sessions.patch`).
|
||||
- Dreams: dreaming 상태, 활성화/비활성화 토글, Dream Diary 리더(`doctor.memory.status`, `doctor.memory.dreamDiary`, `config.patch`).
|
||||
<Accordion title="채널, 인스턴스, 세션, 꿈">
|
||||
- 채널: 기본 제공 및 번들/외부 Plugin 채널 상태, QR 로그인, 채널별 구성(`channels.status`, `web.login.*`, `config.patch`).
|
||||
- 인스턴스: 프레즌스 목록 + 새로 고침(`system-presence`).
|
||||
- 세션: 목록 + 세션별 모델/생각/빠름/자세함/추적/추론 재정의(`sessions.list`, `sessions.patch`).
|
||||
- 꿈: Dreaming 상태, 활성화/비활성화 토글, Dream Diary 리더(`doctor.memory.status`, `doctor.memory.dreamDiary`, `config.patch`).
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Cron, skills, nodes, exec approvals">
|
||||
- Cron jobs: 목록/추가/편집/실행/활성화/비활성화 및 실행 기록(`cron.*`).
|
||||
<Accordion title="Cron, Skills, Node, 실행 승인">
|
||||
- Cron 작업: 목록/추가/편집/실행/활성화/비활성화 + 실행 기록(`cron.*`).
|
||||
- Skills: 상태, 활성화/비활성화, 설치, API 키 업데이트(`skills.*`).
|
||||
- Nodes: 목록 및 기능(`node.list`).
|
||||
- Exec approvals: `exec host=gateway/node`에 대한 gateway 또는 node allowlist 및 ask policy 편집(`exec.approvals.*`).
|
||||
- Node: 목록 + 기능(`node.list`).
|
||||
- 실행 승인: `exec host=gateway/node`에 대한 Gateway 또는 Node 허용 목록 + 요청 정책 편집(`exec.approvals.*`).
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Config">
|
||||
<Accordion title="구성">
|
||||
- `~/.openclaw/openclaw.json` 보기/편집(`config.get`, `config.set`).
|
||||
- 검증과 함께 적용 및 재시작(`config.apply`)하고 마지막 활성 세션을 깨웁니다.
|
||||
- 쓰기에는 동시 편집 덮어쓰기를 방지하기 위한 base-hash guard가 포함됩니다.
|
||||
- 쓰기(`config.set`/`config.apply`/`config.patch`)는 제출된 구성 페이로드의 refs에 대해 활성 SecretRef 해석을 사전 검사합니다. 해석되지 않은 활성 제출 refs는 쓰기 전에 거부됩니다.
|
||||
- 스키마 및 양식 렌더링(`config.schema` / `config.schema.lookup`, 필드 `title` / `description`, 일치하는 UI 힌트, 즉시 하위 요약, 중첩 객체/wildcard/array/composition 노드의 문서 메타데이터, 사용 가능한 경우 plugin 및 채널 스키마 포함). Raw JSON 편집기는 스냅샷이 안전한 raw 왕복을 지원할 때만 사용할 수 있습니다.
|
||||
- 스냅샷이 raw 텍스트를 안전하게 왕복할 수 없으면 Control UI는 해당 스냅샷에 대해 양식 모드를 강제하고 Raw 모드를 비활성화합니다.
|
||||
- Raw JSON 편집기의 "저장된 상태로 재설정"은 평탄화된 스냅샷을 다시 렌더링하는 대신 raw로 작성된 형태(서식, 주석, `$include` 레이아웃)를 보존하므로, 스냅샷이 안전하게 왕복할 수 있을 때 외부 편집이 재설정 후에도 유지됩니다.
|
||||
- 구조화된 SecretRef 객체 값은 우발적인 객체-문자열 손상을 방지하기 위해 양식 텍스트 입력에서 읽기 전용으로 렌더링됩니다.
|
||||
- 검증과 함께 적용 + 재시작(`config.apply`)하고 마지막 활성 세션을 깨웁니다.
|
||||
- 쓰기에는 동시 편집을 덮어쓰지 않도록 기본 해시 보호가 포함됩니다.
|
||||
- 쓰기(`config.set`/`config.apply`/`config.patch`)는 제출된 구성 페이로드의 참조에 대해 활성 SecretRef 확인을 사전 검사합니다. 확인되지 않은 활성 제출 참조는 쓰기 전에 거부됩니다.
|
||||
- 스키마 + 폼 렌더링(`config.schema` / `config.schema.lookup`, 필드 `title` / `description`, 일치한 UI 힌트, 즉시 하위 요약, 중첩 객체/와일드카드/배열/컴포지션 노드의 문서 메타데이터, 사용 가능한 경우 Plugin + 채널 스키마 포함). 원시 JSON 편집기는 스냅샷에 안전한 원시 왕복이 있을 때만 사용할 수 있습니다.
|
||||
- 스냅샷이 원시 텍스트를 안전하게 왕복할 수 없으면 Control UI는 폼 모드를 강제하고 해당 스냅샷의 원시 모드를 비활성화합니다.
|
||||
- 원시 JSON 편집기의 "저장된 상태로 재설정"은 평면화된 스냅샷을 다시 렌더링하는 대신 원시 작성 형태(서식, 주석, `$include` 레이아웃)를 보존하므로, 스냅샷이 안전하게 왕복할 수 있을 때 외부 편집이 재설정 후에도 유지됩니다.
|
||||
- 구조화된 SecretRef 객체 값은 실수로 객체가 문자열로 손상되는 것을 방지하기 위해 폼 텍스트 입력에서 읽기 전용으로 렌더링됩니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Debug, logs, update">
|
||||
- Debug: 상태/health/모델 스냅샷, 이벤트 로그, 수동 RPC 호출(`status`, `health`, `models.list`).
|
||||
- 로그: 필터/내보내기가 있는 gateway 파일 로그의 실시간 tail(`logs.tail`).
|
||||
- 업데이트: 재시작 보고서와 함께 package/git 업데이트 및 재시작(`update.run`)을 실행한 다음, 재연결 후 `update.status`를 폴링하여 실행 중인 gateway 버전을 확인합니다.
|
||||
<Accordion title="디버그, 로그, 업데이트">
|
||||
- 디버그: 상태/상태 확인/모델 스냅샷 + 이벤트 로그 + 수동 RPC 호출(`status`, `health`, `models.list`).
|
||||
- 로그: 필터/내보내기가 포함된 Gateway 파일 로그의 실시간 tail(`logs.tail`).
|
||||
- 업데이트: 패키지/git 업데이트 + 재시작(`update.run`)을 재시작 보고서와 함께 실행한 다음, 재연결 후 `update.status`를 폴링하여 실행 중인 Gateway 버전을 확인합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Cron jobs panel notes">
|
||||
- 격리된 작업의 경우 전달 기본값은 요약 발표입니다. 내부 전용 실행을 원하면 없음으로 전환할 수 있습니다.
|
||||
- 발표가 선택되면 채널/대상 필드가 표시됩니다.
|
||||
- Webhook 모드는 `delivery.mode = "webhook"`을 사용하고 `delivery.to`를 유효한 HTTP(S) webhook URL로 설정합니다.
|
||||
- 메인 세션 작업의 경우 webhook 및 없음 전달 모드를 사용할 수 있습니다.
|
||||
- 고급 편집 컨트롤에는 실행 후 삭제, agent 재정의 지우기, cron exact/stagger 옵션, agent 모델/thinking 재정의, best-effort 전달 토글이 포함됩니다.
|
||||
- 양식 검증은 필드 수준 오류와 함께 인라인으로 표시됩니다. 잘못된 값은 수정될 때까지 저장 버튼을 비활성화합니다.
|
||||
- 전용 bearer token을 보내려면 `cron.webhookToken`을 설정하세요. 생략하면 webhook은 인증 헤더 없이 전송됩니다.
|
||||
- 사용 중단된 fallback: `notify: true`가 있는 저장된 legacy jobs는 마이그레이션될 때까지 여전히 `cron.webhook`을 사용할 수 있습니다.
|
||||
<Accordion title="Cron 작업 패널 참고 사항">
|
||||
- 격리된 작업의 경우 전달 기본값은 요약 알림입니다. 내부 전용 실행을 원하면 없음으로 전환할 수 있습니다.
|
||||
- 알림이 선택되면 채널/대상 필드가 표시됩니다.
|
||||
- Webhook 모드는 `delivery.to`를 유효한 HTTP(S) Webhook URL로 설정한 `delivery.mode = "webhook"`을 사용합니다.
|
||||
- 메인 세션 작업의 경우 Webhook 및 없음 전달 모드를 사용할 수 있습니다.
|
||||
- 고급 편집 컨트롤에는 실행 후 삭제, 에이전트 재정의 지우기, Cron exact/stagger 옵션, 에이전트 모델/생각 재정의, 최선 노력 전달 토글이 포함됩니다.
|
||||
- 폼 검증은 필드 수준 오류와 함께 인라인으로 표시됩니다. 잘못된 값은 수정될 때까지 저장 버튼을 비활성화합니다.
|
||||
- 전용 베어러 토큰을 보내려면 `cron.webhookToken`을 설정하세요. 생략하면 Webhook이 인증 헤더 없이 전송됩니다.
|
||||
- 더 이상 권장되지 않는 폴백: `notify: true`가 있는 저장된 레거시 작업은 마이그레이션될 때까지 `cron.webhook`을 계속 사용할 수 있습니다.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
@ -155,84 +155,85 @@ Control UI는 첫 로드 시 브라우저 로케일을 기반으로 자체 지
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="전송 및 기록 의미 체계">
|
||||
- `chat.send`는 **비차단형**입니다. 즉시 `{ runId, status: "started" }`로 ack를 반환하고 응답은 `chat` 이벤트를 통해 스트리밍됩니다.
|
||||
- 채팅 업로드는 이미지와 비동영상 파일을 허용합니다. 이미지는 네이티브 이미지 경로를 유지하고, 다른 파일은 관리형 미디어로 저장되며 기록에는 첨부 링크로 표시됩니다.
|
||||
- 같은 `idempotencyKey`로 다시 전송하면 실행 중에는 `{ status: "in_flight" }`를 반환하고, 완료 후에는 `{ status: "ok" }`를 반환합니다.
|
||||
- `chat.history` 응답은 UI 안전을 위해 크기가 제한됩니다. 트랜스크립트 항목이 너무 크면 Gateway가 긴 텍스트 필드를 잘라내고, 무거운 메타데이터 블록을 생략하며, 크기가 너무 큰 메시지를 자리표시자(`[chat.history omitted: message too large]`)로 대체할 수 있습니다.
|
||||
- 어시스턴트/생성 이미지는 관리형 미디어 참조로 영구 저장되고 인증된 Gateway 미디어 URL을 통해 다시 제공되므로, 새로고침은 원시 base64 이미지 페이로드가 채팅 기록 응답에 계속 남아 있는지에 의존하지 않습니다.
|
||||
- `chat.history`는 표시되는 어시스턴트 텍스트에서 표시 전용 인라인 지시문 태그(예: `[[reply_to_*]]` 및 `[[audio_as_voice]]`), 일반 텍스트 도구 호출 XML 페이로드(`<tool_call>...</tool_call>`, `<function_call>...</function_call>`, `<tool_calls>...</tool_calls>`, `<function_calls>...</function_calls>` 및 잘린 도구 호출 블록 포함), 유출된 ASCII/전각 모델 제어 토큰도 제거하며, 표시되는 전체 텍스트가 정확히 무음 토큰 `NO_REPLY` / `no_reply`뿐인 어시스턴트 항목은 생략합니다.
|
||||
- 활성 전송 중 및 최종 기록 새로고침 중에 `chat.history`가 잠시 이전 스냅샷을 반환하더라도 채팅 뷰는 로컬 낙관적 사용자/어시스턴트 메시지를 계속 표시합니다. Gateway 기록이 따라잡으면 정식 트랜스크립트가 해당 로컬 메시지를 대체합니다.
|
||||
- `chat.inject`는 세션 트랜스크립트에 어시스턴트 메모를 추가하고 UI 전용 업데이트를 위한 `chat` 이벤트를 브로드캐스트합니다(에이전트 실행 없음, 채널 전달 없음).
|
||||
- 채팅 헤더의 모델 및 사고 선택기는 `sessions.patch`를 통해 활성 세션을 즉시 패치합니다. 이는 영구 세션 오버라이드이며, 한 턴에만 적용되는 전송 옵션이 아닙니다.
|
||||
- 제어 UI에 `/new`를 입력하면 새 채팅과 동일한 새 대시보드 세션을 만들고 전환합니다. `/reset`을 입력하면 현재 세션에 대해 Gateway의 명시적 제자리 재설정을 유지합니다.
|
||||
- 채팅 모델 선택기는 Gateway에 구성된 모델 뷰를 요청합니다. `agents.defaults.models`가 있으면 해당 허용 목록이 선택기를 구동합니다. 그렇지 않으면 선택기는 명시적인 `models.providers.*.models` 항목과 사용 가능한 인증이 있는 공급자를 표시합니다. 전체 카탈로그는 디버그 `models.list` RPC에서 `view: "all"`로 계속 사용할 수 있습니다.
|
||||
- 최신 Gateway 세션 사용량 보고서가 높은 컨텍스트 압박을 표시하면 채팅 작성 영역에 컨텍스트 알림이 표시되고, 권장 Compaction 수준에서는 일반 세션 Compaction 경로를 실행하는 압축 버튼이 표시됩니다. 오래된 토큰 스냅샷은 Gateway가 최신 사용량을 다시 보고할 때까지 숨겨집니다.
|
||||
- `chat.send`는 **논블로킹**입니다. `{ runId, status: "started" }`로 즉시 승인하고 응답은 `chat` 이벤트를 통해 스트리밍됩니다.
|
||||
- 채팅 업로드는 이미지와 동영상이 아닌 파일을 허용합니다. 이미지는 네이티브 이미지 경로를 유지하고, 다른 파일은 관리형 미디어로 저장되어 기록에 첨부 파일 링크로 표시됩니다.
|
||||
- 같은 `idempotencyKey`로 다시 보내면 실행 중에는 `{ status: "in_flight" }`를 반환하고, 완료 후에는 `{ status: "ok" }`를 반환합니다.
|
||||
- `chat.history` 응답은 UI 안전을 위해 크기가 제한됩니다. 대화 기록 항목이 너무 크면 Gateway가 긴 텍스트 필드를 잘라내고, 무거운 메타데이터 블록을 생략하며, 과도하게 큰 메시지를 자리표시자(`[chat.history omitted: message too large]`)로 대체할 수 있습니다.
|
||||
- 어시스턴트/생성 이미지는 관리형 미디어 참조로 유지되고 인증된 Gateway 미디어 URL을 통해 다시 제공되므로, 다시 로드할 때 원시 base64 이미지 페이로드가 채팅 기록 응답에 계속 남아 있는지에 의존하지 않습니다.
|
||||
- `chat.history`는 표시되는 어시스턴트 텍스트에서 표시 전용 인라인 지시문 태그(예: `[[reply_to_*]]` 및 `[[audio_as_voice]]`), 일반 텍스트 도구 호출 XML 페이로드(`<tool_call>...</tool_call>`, `<function_call>...</function_call>`, `<tool_calls>...</tool_calls>`, `<function_calls>...</function_calls>` 및 잘린 도구 호출 블록 포함), 유출된 ASCII/전각 모델 제어 토큰도 제거하며, 표시되는 전체 텍스트가 정확한 무음 토큰 `NO_REPLY` / `no_reply`뿐인 어시스턴트 항목은 생략합니다.
|
||||
- 활성 전송 중 및 최종 기록 새로 고침 중에 `chat.history`가 잠시 오래된 스냅샷을 반환하더라도 채팅 보기는 로컬 낙관적 사용자/어시스턴트 메시지를 계속 표시합니다. Gateway 기록이 따라잡으면 정식 대화 기록이 해당 로컬 메시지를 대체합니다.
|
||||
- 실시간 `chat` 이벤트는 전달 상태이고, `chat.history`는 내구성 있는 세션 대화 기록에서 다시 빌드됩니다. 도구 최종 이벤트 후 Control UI는 기록을 다시 로드하고 작은 낙관적 꼬리만 병합합니다. 대화 기록 경계는 [WebChat](/ko/web/webchat)에 문서화되어 있습니다.
|
||||
- `chat.inject`는 어시스턴트 메모를 세션 대화 기록에 추가하고 UI 전용 업데이트용 `chat` 이벤트를 브로드캐스트합니다(에이전트 실행 없음, 채널 전달 없음).
|
||||
- 채팅 헤더 모델 및 사고 선택기는 `sessions.patch`를 통해 활성 세션을 즉시 패치합니다. 이는 지속되는 세션 오버라이드이며, 한 턴에만 적용되는 전송 옵션이 아닙니다.
|
||||
- Control UI에서 `/new`를 입력하면 New Chat과 같은 새 대시보드 세션이 생성되고 전환됩니다. `/reset`을 입력하면 현재 세션에 대해 Gateway의 명시적 제자리 재설정이 유지됩니다.
|
||||
- 채팅 모델 선택기는 Gateway의 구성된 모델 보기를 요청합니다. `agents.defaults.models`가 있으면 해당 허용 목록이 선택기를 구동합니다. 그렇지 않으면 선택기는 명시적 `models.providers.*.models` 항목과 사용 가능한 인증이 있는 공급자를 표시합니다. 전체 카탈로그는 디버그 `models.list` RPC에서 `view: "all"`로 계속 사용할 수 있습니다.
|
||||
- 새 Gateway 세션 사용량 보고서가 높은 컨텍스트 압박을 보이면 채팅 작성 영역에 컨텍스트 알림이 표시되고, 권장 Compaction 수준에서는 일반 세션 Compaction 경로를 실행하는 압축 버튼이 표시됩니다. 오래된 토큰 스냅샷은 Gateway가 새 사용량을 다시 보고할 때까지 숨겨집니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="대화 모드(브라우저 실시간)">
|
||||
대화 모드는 등록된 실시간 음성 공급자를 사용합니다. `talk.provider: "openai"`와 `talk.providers.openai.apiKey`로 OpenAI를 구성하거나, `talk.provider: "google"`과 `talk.providers.google.apiKey`로 Google을 구성하세요. Voice Call 실시간 공급자 구성은 여전히 폴백으로 재사용할 수 있습니다. 브라우저는 표준 공급자 API 키를 절대 받지 않습니다. OpenAI는 WebRTC용 임시 Realtime 클라이언트 비밀 값을 받습니다. Google Live는 브라우저 WebSocket 세션용 일회용 제한 Live API 인증 토큰을 받으며, 지침과 도구 선언은 Gateway에 의해 토큰에 고정됩니다. 백엔드 실시간 브리지만 노출하는 공급자는 Gateway 릴레이 전송을 통해 실행되므로, 브라우저 오디오는 인증된 Gateway RPC를 통해 이동하는 동안 자격 증명과 벤더 소켓은 서버 측에 유지됩니다. Realtime 세션 프롬프트는 Gateway가 조립합니다. `talk.realtime.session`은 호출자가 제공하는 지침 오버라이드를 허용하지 않습니다.
|
||||
대화 모드는 등록된 실시간 음성 공급자를 사용합니다. OpenAI는 `talk.provider: "openai"`와 `talk.providers.openai.apiKey`로 구성하거나, Google은 `talk.provider: "google"`와 `talk.providers.google.apiKey`로 구성하세요. Voice Call 실시간 공급자 구성은 여전히 폴백으로 재사용할 수 있습니다. 브라우저는 표준 공급자 API 키를 절대 받지 않습니다. OpenAI는 WebRTC용 임시 Realtime 클라이언트 시크릿을 받습니다. Google Live는 브라우저 WebSocket 세션용 일회용 제한 Live API 인증 토큰을 받으며, 지침과 도구 선언은 Gateway에 의해 토큰에 고정됩니다. 백엔드 실시간 브리지만 노출하는 공급자는 Gateway 릴레이 전송을 통해 실행되므로, 자격 증명과 벤더 소켓은 서버 측에 머물고 브라우저 오디오는 인증된 Gateway RPC를 통해 이동합니다. Realtime 세션 프롬프트는 Gateway가 조립합니다. `talk.realtime.session`은 호출자가 제공하는 지침 오버라이드를 허용하지 않습니다.
|
||||
|
||||
채팅 작성기에서 대화 컨트롤은 마이크 받아쓰기 버튼 옆의 파형 버튼입니다. 대화가 시작되면 작성기 상태 행에 오디오가 연결되는 동안 `Connecting Talk...`, 오디오가 연결된 동안 `Talk live`, 또는 실시간 도구 호출이 `chat.send`를 통해 구성된 더 큰 모델에 문의하는 동안 `Asking OpenClaw...`가 표시됩니다.
|
||||
채팅 작성기에서 Talk 컨트롤은 마이크 받아쓰기 버튼 옆의 파형 버튼입니다. Talk가 시작되면 작성기 상태 행에 `Connecting Talk...`가 표시된 뒤 오디오가 연결되면 `Talk live`, 실시간 도구 호출이 `chat.send`를 통해 구성된 더 큰 모델에 문의하는 동안에는 `Asking OpenClaw...`가 표시됩니다.
|
||||
|
||||
유지관리자 라이브 스모크: `OPENAI_API_KEY=... GEMINI_API_KEY=... node --import tsx scripts/dev/realtime-talk-live-smoke.ts`는 OpenAI 브라우저 WebRTC SDP 교환, Google Live 제한 토큰 브라우저 WebSocket 설정, 가짜 마이크 미디어를 사용하는 Gateway 릴레이 브라우저 어댑터를 검증합니다. 이 명령은 공급자 상태만 출력하고 비밀 값은 기록하지 않습니다.
|
||||
유지관리자 실시간 스모크: `OPENAI_API_KEY=... GEMINI_API_KEY=... node --import tsx scripts/dev/realtime-talk-live-smoke.ts`는 OpenAI 브라우저 WebRTC SDP 교환, Google Live 제한 토큰 브라우저 WebSocket 설정, 가짜 마이크 미디어를 사용하는 Gateway 릴레이 브라우저 어댑터를 검증합니다. 이 명령은 공급자 상태만 출력하고 시크릿은 기록하지 않습니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="중지 및 중단">
|
||||
- **중지**를 클릭합니다(`chat.abort` 호출).
|
||||
- 실행이 활성 상태인 동안 일반 후속 메시지는 대기열에 들어갑니다. 대기 중인 메시지에서 **조정**을 클릭하면 해당 후속 메시지를 실행 중인 턴에 주입합니다.
|
||||
- 대역 외 중단을 위해 `/stop`(또는 `stop`, `stop action`, `stop run`, `stop openclaw`, `please stop` 같은 독립 실행형 중단 문구)을 입력합니다.
|
||||
- **Stop**을 클릭합니다(`chat.abort` 호출).
|
||||
- 실행이 활성 상태일 때 일반 후속 메시지는 대기열에 들어갑니다. 대기 중인 메시지에서 **Steer**를 클릭하면 해당 후속 메시지를 실행 중인 턴에 주입합니다.
|
||||
- 대역 외로 중단하려면 `/stop`(또는 `stop`, `stop action`, `stop run`, `stop openclaw`, `please stop` 같은 독립 중단 문구)을 입력합니다.
|
||||
- `chat.abort`는 해당 세션의 모든 활성 실행을 중단하기 위해 `{ sessionKey }`(`runId` 없음)를 지원합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="중단 부분 유지">
|
||||
<Accordion title="중단 부분 보존">
|
||||
- 실행이 중단되면 부분 어시스턴트 텍스트가 UI에 계속 표시될 수 있습니다.
|
||||
- Gateway는 버퍼링된 출력이 있을 때 중단된 부분 어시스턴트 텍스트를 트랜스크립트 기록에 영구 저장합니다.
|
||||
- 영구 저장된 항목에는 중단 메타데이터가 포함되어 트랜스크립트 소비자가 중단 부분과 일반 완료 출력을 구분할 수 있습니다.
|
||||
- Gateway는 버퍼링된 출력이 있을 때 중단된 부분 어시스턴트 텍스트를 대화 기록에 유지합니다.
|
||||
- 유지된 항목에는 중단 메타데이터가 포함되어 대화 기록 소비자가 중단 부분과 정상 완료 출력을 구분할 수 있습니다.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## PWA 설치 및 웹 푸시
|
||||
|
||||
제어 UI는 `manifest.webmanifest`와 서비스 워커를 제공하므로 최신 브라우저에서 독립 실행형 PWA로 설치할 수 있습니다. 웹 푸시는 탭이나 브라우저 창이 열려 있지 않아도 Gateway가 알림으로 설치된 PWA를 깨울 수 있게 합니다.
|
||||
Control UI는 `manifest.webmanifest`와 서비스 워커를 제공하므로 최신 브라우저에서 독립 실행형 PWA로 설치할 수 있습니다. Web Push를 사용하면 탭이나 브라우저 창이 열려 있지 않아도 Gateway가 설치된 PWA를 알림으로 깨울 수 있습니다.
|
||||
|
||||
| 표면 | 수행하는 작업 |
|
||||
| ----------------------------------------------------- | ------------------------------------------------------------------ |
|
||||
| `ui/public/manifest.webmanifest` | PWA 매니페스트입니다. 도달 가능해지면 브라우저가 "앱 설치"를 제공합니다. |
|
||||
| `ui/public/manifest.webmanifest` | PWA 매니페스트입니다. 접근 가능해지면 브라우저가 "Install app"을 제안합니다. |
|
||||
| `ui/public/sw.js` | `push` 이벤트와 알림 클릭을 처리하는 서비스 워커입니다. |
|
||||
| `push/vapid-keys.json`(OpenClaw 상태 디렉터리 아래) | 웹 푸시 페이로드 서명에 사용되는 자동 생성 VAPID 키 쌍입니다. |
|
||||
| `push/web-push-subscriptions.json` | 영구 저장된 브라우저 구독 엔드포인트입니다. |
|
||||
| `push/vapid-keys.json`(OpenClaw 상태 디렉터리 아래) | Web Push 페이로드에 서명하는 데 사용되는 자동 생성 VAPID 키 쌍입니다. |
|
||||
| `push/web-push-subscriptions.json` | 유지되는 브라우저 구독 엔드포인트입니다. |
|
||||
|
||||
키를 고정하려는 경우(다중 호스트 배포, 비밀 값 교체 또는 테스트) Gateway 프로세스의 환경 변수를 통해 VAPID 키 쌍을 오버라이드하세요.
|
||||
키를 고정하려는 경우(다중 호스트 배포, 시크릿 순환 또는 테스트) Gateway 프로세스의 환경 변수로 VAPID 키 쌍을 오버라이드하세요.
|
||||
|
||||
- `OPENCLAW_VAPID_PUBLIC_KEY`
|
||||
- `OPENCLAW_VAPID_PRIVATE_KEY`
|
||||
- `OPENCLAW_VAPID_SUBJECT`(기본값: `mailto:openclaw@localhost`)
|
||||
- `OPENCLAW_VAPID_SUBJECT`(기본값은 `mailto:openclaw@localhost`)
|
||||
|
||||
제어 UI는 브라우저 구독을 등록하고 테스트하기 위해 다음 범위 제한 Gateway 메서드를 사용합니다.
|
||||
Control UI는 브라우저 구독을 등록하고 테스트하기 위해 다음 범위 제한 Gateway 메서드를 사용합니다.
|
||||
|
||||
- `push.web.vapidPublicKey` — 활성 VAPID 공개 키를 가져옵니다.
|
||||
- `push.web.subscribe` — `endpoint`와 `keys.p256dh`/`keys.auth`를 등록합니다.
|
||||
- `push.web.unsubscribe` — 등록된 엔드포인트를 제거합니다.
|
||||
- `push.web.test` — 호출자의 구독에 테스트 알림을 보냅니다.
|
||||
- `push.web.test` — 호출자의 구독으로 테스트 알림을 보냅니다.
|
||||
|
||||
<Note>
|
||||
웹 푸시는 iOS APNS 릴레이 경로(릴레이 기반 푸시는 [구성](/ko/gateway/configuration) 참조) 및 네이티브 모바일 페어링을 대상으로 하는 기존 `push.test` 메서드와 독립적입니다.
|
||||
Web Push는 iOS APNS 릴레이 경로(릴레이 기반 푸시는 [Configuration](/ko/gateway/configuration) 참조) 및 네이티브 모바일 페어링을 대상으로 하는 기존 `push.test` 메서드와 독립적입니다.
|
||||
</Note>
|
||||
|
||||
## 호스팅된 임베드
|
||||
## 호스팅 임베드
|
||||
|
||||
어시스턴트 메시지는 `[embed ...]` 쇼트코드를 사용해 호스팅된 웹 콘텐츠를 인라인으로 렌더링할 수 있습니다. iframe 샌드박스 정책은 `gateway.controlUi.embedSandbox`로 제어됩니다.
|
||||
어시스턴트 메시지는 `[embed ...]` 쇼트코드로 호스팅된 웹 콘텐츠를 인라인 렌더링할 수 있습니다. iframe 샌드박스 정책은 `gateway.controlUi.embedSandbox`로 제어됩니다.
|
||||
|
||||
<Tabs>
|
||||
<Tab title="strict">
|
||||
호스팅된 임베드 내부의 스크립트 실행을 비활성화합니다.
|
||||
호스팅 임베드 내부의 스크립트 실행을 비활성화합니다.
|
||||
</Tab>
|
||||
<Tab title="scripts (default)">
|
||||
출처 격리를 유지하면서 대화형 임베드를 허용합니다. 이는 기본값이며 보통 독립형 브라우저 게임/위젯에 충분합니다.
|
||||
출처 격리를 유지하면서 대화형 임베드를 허용합니다. 이것이 기본값이며 일반적으로 자체 완결형 브라우저 게임/위젯에 충분합니다.
|
||||
</Tab>
|
||||
<Tab title="trusted">
|
||||
의도적으로 더 강한 권한이 필요한 동일 사이트 문서를 위해 `allow-scripts`에 더해 `allow-same-origin`을 추가합니다.
|
||||
의도적으로 더 강한 권한이 필요한 동일 사이트 문서에 대해 `allow-scripts`에 더해 `allow-same-origin`을 추가합니다.
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
@ -249,14 +250,14 @@ Control UI는 첫 로드 시 브라우저 로케일을 기반으로 자체 지
|
||||
```
|
||||
|
||||
<Warning>
|
||||
임베드된 문서에 동일 출처 동작이 실제로 필요할 때만 `trusted`를 사용하세요. 대부분의 에이전트 생성 게임과 대화형 캔버스에는 `scripts`가 더 안전한 선택입니다.
|
||||
임베드된 문서에 실제로 동일 출처 동작이 필요한 경우에만 `trusted`를 사용하세요. 대부분의 에이전트 생성 게임과 대화형 캔버스에는 `scripts`가 더 안전한 선택입니다.
|
||||
</Warning>
|
||||
|
||||
절대 외부 `http(s)` 임베드 URL은 기본적으로 계속 차단됩니다. 의도적으로 `[embed url="https://..."]`가 서드파티 페이지를 로드하게 하려면 `gateway.controlUi.allowExternalEmbedUrls: true`를 설정하세요.
|
||||
|
||||
## 채팅 메시지 너비
|
||||
|
||||
그룹화된 채팅 메시지는 읽기 쉬운 기본 최대 너비를 사용합니다. 와이드 모니터 배포에서는 번들 CSS를 패치하지 않고 `gateway.controlUi.chatMessageMaxWidth`를 설정해 이를 오버라이드할 수 있습니다.
|
||||
그룹화된 채팅 메시지는 읽기 쉬운 기본 최대 너비를 사용합니다. 와이드 모니터 배포에서는 번들 CSS를 패치하지 않고 `gateway.controlUi.chatMessageMaxWidth`를 설정해 오버라이드할 수 있습니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -268,13 +269,13 @@ Control UI는 첫 로드 시 브라우저 로케일을 기반으로 자체 지
|
||||
}
|
||||
```
|
||||
|
||||
이 값은 브라우저에 도달하기 전에 검증됩니다. 지원되는 값에는 `960px` 또는 `82%` 같은 일반 길이와 백분율, 그리고 제한된 `min(...)`, `max(...)`, `clamp(...)`, `calc(...)`, `fit-content(...)` 너비 표현식이 포함됩니다.
|
||||
값은 브라우저에 도달하기 전에 검증됩니다. 지원되는 값에는 `960px` 또는 `82%` 같은 일반 길이와 백분율, 그리고 제한된 `min(...)`, `max(...)`, `clamp(...)`, `calc(...)`, `fit-content(...)` 너비 표현식이 포함됩니다.
|
||||
|
||||
## Tailnet 접근(권장)
|
||||
|
||||
<Tabs>
|
||||
<Tab title="통합 Tailscale Serve(권장)">
|
||||
Gateway를 loopback에 유지하고 Tailscale Serve가 HTTPS로 프록시하도록 합니다.
|
||||
Gateway를 loopback에 유지하고 Tailscale Serve가 HTTPS로 프록시하게 하세요.
|
||||
|
||||
```bash
|
||||
openclaw gateway --tailscale serve
|
||||
@ -282,48 +283,48 @@ Control UI는 첫 로드 시 브라우저 로케일을 기반으로 자체 지
|
||||
|
||||
열기:
|
||||
|
||||
- `https://<magicdns>/`(또는 구성한 `gateway.controlUi.basePath`)
|
||||
- `https://<magicdns>/`(또는 구성된 `gateway.controlUi.basePath`)
|
||||
|
||||
기본적으로 `gateway.auth.allowTailscale`이 `true`이면 제어 UI/WebSocket Serve 요청은 Tailscale ID 헤더(`tailscale-user-login`)를 통해 인증할 수 있습니다. OpenClaw는 `tailscale whois`로 `x-forwarded-for` 주소를 확인하고 이를 헤더와 일치시켜 ID를 검증하며, 요청이 Tailscale의 `x-forwarded-*` 헤더와 함께 loopback에 도달할 때만 이를 허용합니다. 브라우저 장치 ID가 있는 제어 UI 운영자 세션의 경우 이 검증된 Serve 경로는 장치 페어링 왕복도 건너뜁니다. 장치가 없는 브라우저와 노드 역할 연결은 계속 일반 장치 검사를 따릅니다. Serve 트래픽에도 명시적인 공유 비밀 자격 증명을 요구하려면 `gateway.auth.allowTailscale: false`를 설정하세요. 그런 다음 `gateway.auth.mode: "token"` 또는 `"password"`를 사용하세요.
|
||||
기본적으로 `gateway.auth.allowTailscale`이 `true`이면 Control UI/WebSocket Serve 요청은 Tailscale ID 헤더(`tailscale-user-login`)를 통해 인증할 수 있습니다. OpenClaw는 `tailscale whois`로 `x-forwarded-for` 주소를 확인하고 이를 헤더와 일치시켜 ID를 검증하며, 요청이 Tailscale의 `x-forwarded-*` 헤더와 함께 loopback에 도달할 때만 이를 허용합니다. 브라우저 기기 ID가 있는 Control UI 운영자 세션의 경우, 이 검증된 Serve 경로는 기기 페어링 왕복도 건너뜁니다. 기기 없는 브라우저와 노드 역할 연결은 계속 일반 기기 검사를 따릅니다. Serve 트래픽에도 명시적 공유 시크릿 자격 증명을 요구하려면 `gateway.auth.allowTailscale: false`를 설정하세요. 그런 다음 `gateway.auth.mode: "token"` 또는 `"password"`를 사용하세요.
|
||||
|
||||
해당 비동기 Serve ID 경로에서는 동일한 클라이언트 IP와 인증 범위에 대한 실패한 인증 시도가 속도 제한 쓰기 전에 직렬화됩니다. 따라서 같은 브라우저에서 동시에 잘못된 재시도가 발생하면 두 개의 단순 불일치가 병렬로 경쟁하는 대신 두 번째 요청에 `retry later`가 표시될 수 있습니다.
|
||||
해당 비동기 Serve ID 경로에서는 같은 클라이언트 IP와 인증 범위에 대한 실패한 인증 시도가 rate-limit 쓰기 전에 직렬화됩니다. 따라서 같은 브라우저에서 동시에 잘못된 재시도가 발생하면 두 개의 단순 불일치가 병렬로 경합하는 대신 두 번째 요청에 `retry later`가 표시될 수 있습니다.
|
||||
|
||||
<Warning>
|
||||
토큰 없는 Serve 인증은 게이트웨이 호스트를 신뢰한다고 가정합니다. 신뢰할 수 없는 로컬 코드가 해당 호스트에서 실행될 수 있다면 토큰/비밀번호 인증을 요구하세요.
|
||||
토큰 없는 Serve 인증은 Gateway 호스트가 신뢰된다고 가정합니다. 신뢰할 수 없는 로컬 코드가 해당 호스트에서 실행될 수 있다면 토큰/비밀번호 인증을 요구하세요.
|
||||
</Warning>
|
||||
|
||||
</Tab>
|
||||
<Tab title="Tailnet에 바인딩 + 토큰">
|
||||
<Tab title="tailnet에 바인딩 + 토큰">
|
||||
```bash
|
||||
openclaw gateway --bind tailnet --token "$(openssl rand -hex 32)"
|
||||
```
|
||||
|
||||
그런 다음 열기:
|
||||
|
||||
- `http://<tailscale-ip>:18789/`(또는 구성한 `gateway.controlUi.basePath`)
|
||||
- `http://<tailscale-ip>:18789/`(또는 구성된 `gateway.controlUi.basePath`)
|
||||
|
||||
일치하는 공유 비밀을 UI 설정에 붙여넣습니다(`connect.params.auth.token` 또는 `connect.params.auth.password`로 전송됨).
|
||||
일치하는 공유 시크릿을 UI 설정에 붙여넣으세요(`connect.params.auth.token` 또는 `connect.params.auth.password`로 전송됨).
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## 안전하지 않은 HTTP
|
||||
|
||||
일반 HTTP(`http://<lan-ip>` 또는 `http://<tailscale-ip>`)로 대시보드를 열면 브라우저가 **비보안 컨텍스트**에서 실행되어 WebCrypto를 차단합니다. 기본적으로 OpenClaw는 장치 ID가 없는 제어 UI 연결을 **차단**합니다.
|
||||
일반 HTTP(`http://<lan-ip>` 또는 `http://<tailscale-ip>`)로 대시보드를 열면 브라우저는 **비보안 컨텍스트**에서 실행되고 WebCrypto를 차단합니다. 기본적으로 OpenClaw는 기기 ID가 없는 Control UI 연결을 **차단**합니다.
|
||||
|
||||
문서화된 예외:
|
||||
|
||||
- `gateway.controlUi.allowInsecureAuth=true`를 사용하는 localhost 전용 안전하지 않은 HTTP 호환성
|
||||
- `gateway.auth.mode: "trusted-proxy"`를 통한 성공적인 운영자 제어 UI 인증
|
||||
- `gateway.controlUi.allowInsecureAuth=true`를 사용한 localhost 전용 안전하지 않은 HTTP 호환성
|
||||
- `gateway.auth.mode: "trusted-proxy"`를 통한 성공적인 운영자 Control UI 인증
|
||||
- 비상용 `gateway.controlUi.dangerouslyDisableDeviceAuth=true`
|
||||
|
||||
**권장 수정:** HTTPS(Tailscale Serve)를 사용하거나 UI를 로컬에서 여세요.
|
||||
**권장 해결 방법:** HTTPS(Tailscale Serve)를 사용하거나 UI를 로컬에서 여세요.
|
||||
|
||||
- `https://<magicdns>/`(Serve)
|
||||
- `http://127.0.0.1:18789/`(게이트웨이 호스트에서)
|
||||
- `https://<magicdns>/` (Serve)
|
||||
- `http://127.0.0.1:18789/` (Gateway 호스트에서)
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="비보안 인증 토글 동작">
|
||||
<Accordion title="Insecure-auth toggle behavior">
|
||||
```json5
|
||||
{
|
||||
gateway: {
|
||||
@ -336,12 +337,12 @@ Control UI는 첫 로드 시 브라우저 로케일을 기반으로 자체 지
|
||||
|
||||
`allowInsecureAuth`는 로컬 호환성 토글일 뿐입니다.
|
||||
|
||||
- 비보안 HTTP 컨텍스트에서 localhost Control UI 세션이 기기 ID 없이 진행할 수 있게 합니다.
|
||||
- 비보안 HTTP 컨텍스트에서 localhost Control UI 세션이 디바이스 ID 없이 계속 진행되도록 허용합니다.
|
||||
- 페어링 검사를 우회하지 않습니다.
|
||||
- 원격(비-localhost) 기기 ID 요구 사항을 완화하지 않습니다.
|
||||
- 원격(non-localhost) 디바이스 ID 요구 사항을 완화하지 않습니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="긴급 상황에서만">
|
||||
<Accordion title="Break-glass only">
|
||||
```json5
|
||||
{
|
||||
gateway: {
|
||||
@ -353,52 +354,52 @@ Control UI는 첫 로드 시 브라우저 로케일을 기반으로 자체 지
|
||||
```
|
||||
|
||||
<Warning>
|
||||
`dangerouslyDisableDeviceAuth`는 Control UI 기기 ID 검사를 비활성화하며 심각한 보안 약화입니다. 긴급 사용 후에는 빠르게 되돌리세요.
|
||||
`dangerouslyDisableDeviceAuth`는 Control UI 디바이스 ID 검사를 비활성화하며 심각한 보안 다운그레이드입니다. 긴급 사용 후에는 신속하게 되돌리세요.
|
||||
</Warning>
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="신뢰할 수 있는 프록시 참고">
|
||||
- 성공한 신뢰할 수 있는 프록시 인증은 기기 ID 없이 **운영자** Control UI 세션을 허용할 수 있습니다.
|
||||
- 이는 node-role Control UI 세션에는 적용되지 않습니다.
|
||||
- 동일 호스트 루프백 리버스 프록시는 여전히 신뢰할 수 있는 프록시 인증을 만족하지 않습니다. [신뢰할 수 있는 프록시 인증](/ko/gateway/trusted-proxy-auth)을 참조하세요.
|
||||
<Accordion title="Trusted-proxy note">
|
||||
- 신뢰할 수 있는 프록시 인증에 성공하면 디바이스 ID 없이 **operator** Control UI 세션을 허용할 수 있습니다.
|
||||
- 이는 노드 역할 Control UI 세션에는 확장되지 않습니다.
|
||||
- 같은 호스트의 loopback 리버스 프록시는 여전히 신뢰할 수 있는 프록시 인증을 충족하지 않습니다. [신뢰할 수 있는 프록시 인증](/ko/gateway/trusted-proxy-auth)을 참고하세요.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
HTTPS 설정 지침은 [Tailscale](/ko/gateway/tailscale)을 참조하세요.
|
||||
HTTPS 설정 지침은 [Tailscale](/ko/gateway/tailscale)을 참고하세요.
|
||||
|
||||
## 콘텐츠 보안 정책
|
||||
|
||||
Control UI는 엄격한 `img-src` 정책과 함께 제공됩니다. **동일 출처** 애셋, `data:` URL, 로컬에서 생성된 `blob:` URL만 허용됩니다. 원격 `http(s)` 및 프로토콜 상대 이미지 URL은 브라우저에서 거부되며 네트워크 가져오기를 발생시키지 않습니다.
|
||||
Control UI는 엄격한 `img-src` 정책과 함께 제공됩니다. **same-origin** 자산, `data:` URL, 로컬에서 생성된 `blob:` URL만 허용됩니다. 원격 `http(s)` 및 프로토콜 상대 이미지 URL은 브라우저에서 거부되며 네트워크 가져오기를 발생시키지 않습니다.
|
||||
|
||||
실제로 이는 다음을 의미합니다.
|
||||
실제로는 다음을 의미합니다.
|
||||
|
||||
- 상대 경로(예: `/avatars/<id>`) 아래에서 제공되는 아바타와 이미지는 계속 렌더링됩니다. 여기에는 UI가 가져와 로컬 `blob:` URL로 변환하는 인증된 아바타 경로도 포함됩니다.
|
||||
- 상대 경로(예: `/avatars/<id>`)로 제공되는 아바타와 이미지는 계속 렌더링됩니다. 여기에는 UI가 가져와 로컬 `blob:` URL로 변환하는 인증된 아바타 경로도 포함됩니다.
|
||||
- 인라인 `data:image/...` URL은 계속 렌더링됩니다(프로토콜 내 페이로드에 유용).
|
||||
- Control UI가 생성한 로컬 `blob:` URL은 계속 렌더링됩니다.
|
||||
- 채널 메타데이터에서 내보낸 원격 아바타 URL은 Control UI의 아바타 헬퍼에서 제거되고 기본 제공 로고/배지로 대체됩니다. 따라서 손상되었거나 악의적인 채널이 운영자 브라우저에서 임의의 원격 이미지 가져오기를 강제할 수 없습니다.
|
||||
- 채널 메타데이터에서 내보낸 원격 아바타 URL은 Control UI의 아바타 헬퍼에서 제거되고 기본 제공 로고/배지로 대체되므로, 손상되었거나 악의적인 채널이 operator 브라우저에서 임의의 원격 이미지 가져오기를 강제할 수 없습니다.
|
||||
|
||||
이 동작을 얻기 위해 변경할 것은 없습니다. 항상 활성화되어 있으며 구성할 수 없습니다.
|
||||
이 동작을 얻기 위해 변경할 것은 없습니다. 항상 켜져 있으며 구성할 수 없습니다.
|
||||
|
||||
## 아바타 경로 인증
|
||||
|
||||
Gateway 인증이 구성된 경우 Control UI 아바타 엔드포인트에는 나머지 API와 동일한 Gateway 토큰이 필요합니다.
|
||||
Gateway 인증이 구성된 경우 Control UI 아바타 엔드포인트에는 API의 나머지 부분과 동일한 Gateway 토큰이 필요합니다.
|
||||
|
||||
- `GET /avatar/<agentId>`는 인증된 호출자에게만 아바타 이미지를 반환합니다. `GET /avatar/<agentId>?meta=1`은 동일한 규칙에 따라 아바타 메타데이터를 반환합니다.
|
||||
- 두 경로 중 어느 쪽에 대한 인증되지 않은 요청도 거부됩니다(동일 계층의 assistant-media 경로와 동일). 이렇게 하면 다른 방식으로 보호되는 호스트에서 아바타 경로가 에이전트 ID를 누출하지 못합니다.
|
||||
- Control UI 자체는 아바타를 가져올 때 Gateway 토큰을 bearer 헤더로 전달하고, 인증된 blob URL을 사용하므로 이미지가 대시보드에서 계속 렌더링됩니다.
|
||||
- 두 경로 중 하나에 대한 인증되지 않은 요청은 거부됩니다(동급 assistant-media 경로와 동일). 이렇게 하면 그 외에는 보호되는 호스트에서 아바타 경로가 에이전트 ID를 유출하지 못하게 됩니다.
|
||||
- Control UI 자체는 아바타를 가져올 때 Gateway 토큰을 bearer 헤더로 전달하고 인증된 blob URL을 사용하므로 이미지가 대시보드에서 계속 렌더링됩니다.
|
||||
|
||||
Gateway 인증을 비활성화하면(공유 호스트에서는 권장하지 않음) 나머지 Gateway와 마찬가지로 아바타 경로도 인증 없이 접근할 수 있게 됩니다.
|
||||
Gateway 인증을 비활성화하면(공유 호스트에서는 권장하지 않음) Gateway의 나머지 부분과 마찬가지로 아바타 경로도 인증 없이 접근할 수 있게 됩니다.
|
||||
|
||||
## UI 빌드
|
||||
|
||||
Gateway는 `dist/control-ui`에서 정적 파일을 제공합니다. 다음으로 빌드하세요.
|
||||
Gateway는 `dist/control-ui`에서 정적 파일을 제공합니다. 다음 명령으로 빌드하세요.
|
||||
|
||||
```bash
|
||||
pnpm ui:build
|
||||
```
|
||||
|
||||
선택적 절대 base(고정 애셋 URL을 원할 때):
|
||||
선택적 절대 base(고정 자산 URL을 원할 때):
|
||||
|
||||
```bash
|
||||
OPENCLAW_CONTROL_UI_BASE_PATH=/openclaw/ pnpm ui:build
|
||||
@ -410,19 +411,19 @@ OPENCLAW_CONTROL_UI_BASE_PATH=/openclaw/ pnpm ui:build
|
||||
pnpm ui:dev
|
||||
```
|
||||
|
||||
그런 다음 UI가 Gateway WS URL(예: `ws://127.0.0.1:18789`)을 가리키도록 설정합니다.
|
||||
그런 다음 UI가 Gateway WS URL(예: `ws://127.0.0.1:18789`)을 가리키도록 하세요.
|
||||
|
||||
## 디버깅/테스트: 개발 서버 + 원격 Gateway
|
||||
|
||||
Control UI는 정적 파일입니다. WebSocket 대상은 구성할 수 있으며 HTTP 출처와 다를 수 있습니다. 로컬에서는 Vite 개발 서버를 사용하고 Gateway는 다른 곳에서 실행하려는 경우에 유용합니다.
|
||||
Control UI는 정적 파일입니다. WebSocket 대상은 구성 가능하며 HTTP 원본과 다를 수 있습니다. 로컬에서는 Vite 개발 서버를 사용하고 Gateway는 다른 곳에서 실행하려는 경우 유용합니다.
|
||||
|
||||
<Steps>
|
||||
<Step title="UI 개발 서버 시작">
|
||||
<Step title="Start the UI dev server">
|
||||
```bash
|
||||
pnpm ui:dev
|
||||
```
|
||||
</Step>
|
||||
<Step title="gatewayUrl로 열기">
|
||||
<Step title="Open with gatewayUrl">
|
||||
```text
|
||||
http://localhost:5173/?gatewayUrl=ws%3A%2F%2F<gateway-host>%3A18789
|
||||
```
|
||||
@ -437,18 +438,18 @@ Control UI는 정적 파일입니다. WebSocket 대상은 구성할 수 있으
|
||||
</Steps>
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="참고">
|
||||
<Accordion title="Notes">
|
||||
- `gatewayUrl`은 로드 후 localStorage에 저장되고 URL에서 제거됩니다.
|
||||
- `gatewayUrl`을 통해 전체 `ws://` 또는 `wss://` 엔드포인트를 전달하는 경우, 브라우저가 쿼리 문자열을 올바르게 파싱하도록 `gatewayUrl` 값을 URL 인코딩하세요.
|
||||
- 가능하면 `token`은 URL 프래그먼트(`#token=...`)로 전달해야 합니다. 프래그먼트는 서버로 전송되지 않으므로 요청 로그와 Referer 누출을 방지합니다. 레거시 `?token=` 쿼리 매개변수도 호환성을 위해 한 번 가져오지만, 폴백으로만 사용되며 부트스트랩 직후 즉시 제거됩니다.
|
||||
- `password`는 메모리에만 보관됩니다.
|
||||
- `gatewayUrl`이 설정되면 UI는 구성 또는 환경 자격 증명으로 폴백하지 않습니다. `token`(또는 `password`)을 명시적으로 제공하세요. 명시적 자격 증명이 없으면 오류입니다.
|
||||
- `gatewayUrl`을 통해 전체 `ws://` 또는 `wss://` 엔드포인트를 전달하는 경우 브라우저가 쿼리 문자열을 올바르게 파싱하도록 `gatewayUrl` 값을 URL 인코딩하세요.
|
||||
- 가능하면 `token`은 URL 프래그먼트(`#token=...`)를 통해 전달해야 합니다. 프래그먼트는 서버로 전송되지 않으므로 요청 로그와 Referer 유출을 피할 수 있습니다. 레거시 `?token=` 쿼리 매개변수는 호환성을 위해 여전히 한 번 가져오지만, fallback으로만 사용되며 bootstrap 직후 즉시 제거됩니다.
|
||||
- `password`는 메모리에만 유지됩니다.
|
||||
- `gatewayUrl`이 설정되면 UI는 config 또는 환경 자격 증명으로 fallback하지 않습니다. `token`(또는 `password`)을 명시적으로 제공하세요. 명시적 자격 증명이 없으면 오류입니다.
|
||||
- Gateway가 TLS 뒤에 있는 경우(Tailscale Serve, HTTPS 프록시 등) `wss://`를 사용하세요.
|
||||
- 클릭재킹을 방지하기 위해 `gatewayUrl`은 최상위 창(임베드되지 않음)에서만 허용됩니다.
|
||||
- 비루프백 Control UI 배포는 `gateway.controlUi.allowedOrigins`를 명시적으로 설정해야 합니다(전체 출처). 여기에는 원격 개발 설정도 포함됩니다.
|
||||
- Gateway 시작 시 유효한 런타임 바인드와 포트에서 `http://localhost:<port>` 및 `http://127.0.0.1:<port>` 같은 로컬 출처를 시드할 수 있지만, 원격 브라우저 출처에는 여전히 명시적 항목이 필요합니다.
|
||||
- 엄격하게 제어되는 로컬 테스트를 제외하고 `gateway.controlUi.allowedOrigins: ["*"]`를 사용하지 마세요. 이는 "내가 사용하는 어떤 호스트든 일치"가 아니라 모든 브라우저 출처를 허용한다는 뜻입니다.
|
||||
- `gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true`는 Host 헤더 출처 폴백 모드를 활성화하지만, 이는 위험한 보안 모드입니다.
|
||||
- `gatewayUrl`은 clickjacking을 방지하기 위해 최상위 창(embedded가 아닌 경우)에서만 허용됩니다.
|
||||
- Non-loopback Control UI 배포는 `gateway.controlUi.allowedOrigins`를 명시적으로 설정해야 합니다(전체 origins). 여기에는 원격 개발 설정도 포함됩니다.
|
||||
- Gateway 시작 시 유효한 런타임 bind 및 port에서 `http://localhost:<port>` 및 `http://127.0.0.1:<port>` 같은 로컬 origins를 시드할 수 있지만, 원격 브라우저 origins에는 여전히 명시적 항목이 필요합니다.
|
||||
- 엄격히 통제되는 로컬 테스트를 제외하고 `gateway.controlUi.allowedOrigins: ["*"]`를 사용하지 마세요. 이는 "내가 사용하는 호스트와 일치"가 아니라 모든 브라우저 origin을 허용한다는 뜻입니다.
|
||||
- `gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true`는 Host-header origin fallback 모드를 활성화하지만, 위험한 보안 모드입니다.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
@ -470,6 +471,6 @@ Control UI는 정적 파일입니다. WebSocket 대상은 구성할 수 있으
|
||||
## 관련 항목
|
||||
|
||||
- [대시보드](/ko/web/dashboard) — Gateway 대시보드
|
||||
- [상태 확인](/ko/gateway/health) — Gateway 상태 모니터링
|
||||
- [상태 검사](/ko/gateway/health) — Gateway 상태 모니터링
|
||||
- [TUI](/ko/web/tui) — 터미널 사용자 인터페이스
|
||||
- [WebChat](/ko/web/webchat) — 브라우저 기반 채팅 인터페이스
|
||||
|
||||
@ -1,71 +1,80 @@
|
||||
---
|
||||
read_when:
|
||||
- 웹 채팅 액세스 디버깅 또는 구성
|
||||
summary: 채팅 UI를 위한 Loopback WebChat 정적 호스트 및 Gateway WS 사용법
|
||||
- WebChat 액세스 디버깅 또는 구성
|
||||
summary: 채팅 UI용 루프백 WebChat 정적 호스트 및 Gateway WS 사용
|
||||
title: 웹 채팅
|
||||
x-i18n:
|
||||
generated_at: "2026-05-03T06:22:45Z"
|
||||
generated_at: "2026-05-04T02:26:34Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 48024e58259901c6feb67168c5c1ce32f46b8ad9b6f4511e56d2000478a3ed60
|
||||
source_hash: bf435585a13a1cde5885714837017109eeeb61ffa5e33a400017706f676f57ea
|
||||
source_path: web/webchat.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
상태: macOS/iOS SwiftUI 채팅 UI는 Gateway WebSocket과 직접 통신합니다.
|
||||
|
||||
## 개요
|
||||
## 정의
|
||||
|
||||
- 게이트웨이를 위한 네이티브 채팅 UI입니다(임베디드 브라우저와 로컬 정적 서버 없음).
|
||||
- 게이트웨이를 위한 네이티브 채팅 UI입니다(내장 브라우저와 로컬 정적 서버 없음).
|
||||
- 다른 채널과 동일한 세션 및 라우팅 규칙을 사용합니다.
|
||||
- 결정적 라우팅: 답장은 항상 WebChat으로 돌아갑니다.
|
||||
- 결정적 라우팅: 응답은 항상 WebChat으로 돌아갑니다.
|
||||
|
||||
## 빠른 시작
|
||||
|
||||
1. 게이트웨이를 시작합니다.
|
||||
2. WebChat UI(macOS/iOS 앱) 또는 Control UI 채팅 탭을 엽니다.
|
||||
3. 유효한 게이트웨이 인증 경로가 구성되어 있는지 확인합니다(기본값은 shared-secret,
|
||||
loopback에서도 동일).
|
||||
3. 유효한 게이트웨이 인증 경로가 구성되어 있는지 확인합니다(기본값은 공유 비밀이며,
|
||||
루프백에서도 동일).
|
||||
|
||||
## 작동 방식(동작)
|
||||
|
||||
- UI는 Gateway WebSocket에 연결하고 `chat.history`, `chat.send`, `chat.inject`를 사용합니다.
|
||||
- `chat.history`는 안정성을 위해 제한됩니다. Gateway는 긴 텍스트 필드를 잘라내고, 무거운 메타데이터를 생략하며, 너무 큰 항목을 `[chat.history omitted: message too large]`로 대체할 수 있습니다.
|
||||
- `chat.history`는 최신 append-only 세션 파일의 활성 transcript 브랜치를 따르므로, 폐기된 rewrite 브랜치와 대체된 prompt 복사본은 WebChat에 렌더링되지 않습니다.
|
||||
- Compaction 항목은 명시적인 압축된 기록 구분선으로 렌더링됩니다. 구분선은 이전 턴이 체크포인트에 보존되어 있음을 설명하고, 권한이 허용되는 경우 운영자가 Compaction 이전 보기로 브랜치하거나 복원할 수 있는 Sessions 체크포인트 컨트롤로 연결합니다.
|
||||
- Control UI는 `chat.history`가 반환한 백킹 Gateway `sessionId`를 기억하고 후속 `chat.send` 호출에 포함하므로, 사용자가 세션을 시작하거나 재설정하지 않는 한 재연결 및 페이지 새로고침 후에도 동일한 저장 대화가 계속됩니다.
|
||||
- Control UI는 새 `chat.send` 실행 id를 생성하기 전에 동일한 세션, 메시지, 첨부 파일에 대한 중복 진행 중 제출을 병합합니다. Gateway는 동일한 idempotency key를 재사용하는 반복 요청도 계속 중복 제거합니다.
|
||||
- `chat.history`는 안정성을 위해 제한됩니다. Gateway는 긴 텍스트 필드를 잘라내거나, 무거운 메타데이터를 생략하거나, 너무 큰 항목을 `[chat.history omitted: message too large]`로 대체할 수 있습니다.
|
||||
- `chat.history`는 최신 추가 전용 세션 파일의 활성 트랜스크립트 분기를 따르므로, 버려진 재작성 분기와 대체된 프롬프트 복사본은 WebChat에 렌더링되지 않습니다.
|
||||
- Compaction 항목은 명시적인 압축된 기록 구분선으로 렌더링됩니다. 이 구분선은 이전 턴이 체크포인트에 보존되어 있음을 설명하고 Sessions 체크포인트 컨트롤로 연결합니다. 운영자는 권한이 허용하는 경우 여기에서 Compaction 이전 보기를 분기하거나 복원할 수 있습니다.
|
||||
- Control UI는 `chat.history`가 반환한 백엔드 Gateway `sessionId`를 기억하고 후속 `chat.send` 호출에 포함하므로, 사용자가 세션을 시작하거나 재설정하지 않는 한 재연결 및 페이지 새로고침 후에도 동일하게 저장된 대화가 계속됩니다.
|
||||
- Control UI는 새 `chat.send` 실행 ID를 생성하기 전에 동일한 세션, 메시지, 첨부 파일에 대한 중복 진행 중 제출을 병합합니다. Gateway는 여전히 동일한 멱등성 키를 재사용하는 반복 요청을 중복 제거합니다.
|
||||
- 워크스페이스 시작 파일과 대기 중인 `BOOTSTRAP.md` 지침은 WebChat 사용자 메시지에 복사되지 않고 에이전트 시스템 프롬프트의 Project Context를 통해 제공됩니다. 부트스트랩 잘림은 간결한 시스템 프롬프트 복구 알림만 추가하며, 상세 개수와 구성 조정값은 진단 화면에 유지됩니다.
|
||||
- `chat.history`는 표시용으로도 정규화됩니다. 런타임 전용 OpenClaw 컨텍스트,
|
||||
인바운드 envelope 래퍼, `[[reply_to_*]]` 및 `[[audio_as_voice]]` 같은
|
||||
인라인 전달 지시 태그, 일반 텍스트 tool-call XML payload
|
||||
(`<tool_call>...</tool_call>`,
|
||||
인바운드 봉투 래퍼, `[[reply_to_*]]` 및 `[[audio_as_voice]]` 같은 인라인 전달 지시문 태그,
|
||||
일반 텍스트 도구 호출 XML 페이로드(`<tool_call>...</tool_call>`,
|
||||
`<function_call>...</function_call>`, `<tool_calls>...</tool_calls>`,
|
||||
`<function_calls>...</function_calls>` 및 잘린 tool-call 블록 포함), 그리고
|
||||
누출된 ASCII/전각 모델 제어 토큰은 표시 텍스트에서 제거되며,
|
||||
전체 표시 텍스트가 정확한 silent token `NO_REPLY` / `no_reply`뿐인
|
||||
assistant 항목은 생략됩니다.
|
||||
- Reasoning 플래그가 지정된 reply payload(`isReasoning: true`)는 WebChat assistant 콘텐츠, transcript replay 텍스트, 오디오 콘텐츠 블록에서 제외되므로, thinking-only payload는 표시되는 assistant 메시지나 재생 가능한 오디오로 노출되지 않습니다.
|
||||
- `chat.inject`는 assistant note를 transcript에 직접 추가하고 UI로 브로드캐스트합니다(agent 실행 없음).
|
||||
- 중단된 실행은 부분 assistant 출력을 UI에 계속 표시할 수 있습니다.
|
||||
- Gateway는 버퍼링된 출력이 있을 때 중단된 부분 assistant 텍스트를 transcript 기록에 유지하고, 해당 항목에 중단 메타데이터를 표시합니다.
|
||||
`<function_calls>...</function_calls>`, 잘린 도구 호출 블록 포함),
|
||||
그리고 유출된 ASCII/전각 모델 제어 토큰은 보이는 텍스트에서 제거되며,
|
||||
전체 보이는 텍스트가 정확히 무음 토큰 `NO_REPLY` / `no_reply`뿐인 어시스턴트 항목은 생략됩니다.
|
||||
- 추론으로 표시된 응답 페이로드(`isReasoning: true`)는 WebChat 어시스턴트 콘텐츠, 트랜스크립트 재생 텍스트, 오디오 콘텐츠 블록에서 제외되므로, 사고 전용 페이로드가 보이는 어시스턴트 메시지나 재생 가능한 오디오로 표시되지 않습니다.
|
||||
- `chat.inject`는 어시스턴트 메모를 트랜스크립트에 직접 추가하고 UI로 브로드캐스트합니다(에이전트 실행 없음).
|
||||
- 중단된 실행은 부분 어시스턴트 출력을 UI에 계속 표시할 수 있습니다.
|
||||
- Gateway는 버퍼링된 출력이 있을 때 중단된 부분 어시스턴트 텍스트를 트랜스크립트 기록에 저장하고, 해당 항목에 중단 메타데이터를 표시합니다.
|
||||
- 기록은 항상 게이트웨이에서 가져옵니다(로컬 파일 감시 없음).
|
||||
- 게이트웨이에 연결할 수 없으면 WebChat은 읽기 전용입니다.
|
||||
|
||||
## Control UI agents tools 패널
|
||||
### 트랜스크립트 및 전달 모델
|
||||
|
||||
WebChat에는 두 개의 별도 데이터 경로가 있습니다.
|
||||
|
||||
- 세션 JSONL 파일은 지속성 있는 모델/런타임 트랜스크립트입니다. 일반 에이전트 실행의 경우 Pi는 세션 관리자를 통해 모델에 보이는 `user`, `assistant`, `toolResult` 메시지를 저장합니다. WebChat은 임의의 전달, 상태 또는 보조 텍스트를 해당 트랜스크립트에 쓰지 않습니다.
|
||||
- Gateway `ReplyPayload` 이벤트는 실시간 전달 투영입니다. WebChat/채널 표시, 블록 스트리밍, 지시문 태그, 미디어 임베딩, TTS/오디오 플래그, UI 폴백 동작에 맞게 정규화될 수 있습니다. 이것들 자체가 표준 세션 로그는 아닙니다.
|
||||
- WebChat은 Gateway가 일반 Pi 어시스턴트 턴 밖에서 표시된 메시지를 소유할 때만 어시스턴트 트랜스크립트 항목을 삽입합니다. `chat.inject`, 비에이전트 명령 응답, 중단된 부분 출력, WebChat 관리 미디어 트랜스크립트 보충 항목이 이에 해당합니다.
|
||||
- `chat.history`는 저장된 세션 트랜스크립트를 읽고 WebChat 표시 투영을 적용합니다. 실행 중 실시간 어시스턴트 텍스트가 나타났지만 기록 재로드 후 사라진 경우, 먼저 원시 JSONL에 어시스턴트 텍스트가 있는지 확인하고, 그다음 `chat.history` 투영이 이를 제거했는지 확인한 뒤, Control UI 낙관적 꼬리 병합이 로컬 전달 상태를 저장된 스냅샷으로 대체했는지 확인합니다.
|
||||
|
||||
일반 에이전트 실행 최종 답변은 Pi가 어시스턴트 `message_end`를 기록하므로 지속되어야 합니다. 전달된 최종 페이로드를 트랜스크립트에 미러링하는 폴백은 먼저 Pi가 이미 기록한 어시스턴트 턴을 중복하지 않아야 합니다.
|
||||
|
||||
## Control UI 에이전트 도구 패널
|
||||
|
||||
- Control UI `/agents` Tools 패널에는 두 개의 별도 보기가 있습니다.
|
||||
- **지금 사용 가능**은 `tools.effective(sessionKey=...)`를 사용하며 현재
|
||||
세션이 런타임에 실제로 사용할 수 있는 core, plugin, channel-owned 도구를 보여줍니다.
|
||||
- **도구 구성**은 `tools.catalog`를 사용하며 profiles, overrides,
|
||||
catalog semantics에 집중합니다.
|
||||
- 런타임 가용성은 세션 범위입니다. 동일한 agent에서 세션을 전환하면
|
||||
- **지금 사용 가능**은 `tools.effective(sessionKey=...)`를 사용하며, 현재
|
||||
세션이 런타임에서 실제로 사용할 수 있는 항목을 표시합니다. 여기에는 코어, Plugin, 채널 소유 도구가 포함됩니다.
|
||||
- **도구 구성**은 `tools.catalog`를 사용하며 프로필, 재정의, 카탈로그 의미 체계에 집중합니다.
|
||||
- 런타임 가용성은 세션 범위입니다. 같은 에이전트에서 세션을 전환하면
|
||||
**지금 사용 가능** 목록이 바뀔 수 있습니다.
|
||||
- config editor는 런타임 가용성을 의미하지 않습니다. effective access는 여전히 policy
|
||||
precedence(`allow`/`deny`, per-agent 및 provider/channel overrides)를 따릅니다.
|
||||
- 구성 편집기는 런타임 가용성을 의미하지 않습니다. 유효 접근은 여전히 정책
|
||||
우선순위(`allow`/`deny`, 에이전트별 및 제공자/채널 재정의)를 따릅니다.
|
||||
|
||||
## 원격 사용
|
||||
|
||||
- 원격 모드는 SSH/Tailscale을 통해 gateway WebSocket을 터널링합니다.
|
||||
- 원격 모드는 SSH/Tailscale을 통해 게이트웨이 WebSocket을 터널링합니다.
|
||||
- 별도의 WebChat 서버를 실행할 필요가 없습니다.
|
||||
|
||||
## 구성 참조(WebChat)
|
||||
@ -74,20 +83,20 @@ x-i18n:
|
||||
|
||||
WebChat 옵션:
|
||||
|
||||
- `gateway.webchat.chatHistoryMaxChars`: `chat.history` 응답의 텍스트 필드에 대한 최대 문자 수입니다. transcript 항목이 이 제한을 초과하면 Gateway는 긴 텍스트 필드를 잘라내고 너무 큰 메시지를 placeholder로 대체할 수 있습니다. 클라이언트는 단일 `chat.history` 호출에서 이 기본값을 재정의하기 위해 요청별 `maxChars`도 보낼 수 있습니다.
|
||||
- `gateway.webchat.chatHistoryMaxChars`: `chat.history` 응답에서 텍스트 필드의 최대 문자 수입니다. 트랜스크립트 항목이 이 제한을 초과하면 Gateway는 긴 텍스트 필드를 잘라내고 너무 큰 메시지를 플레이스홀더로 대체할 수 있습니다. 클라이언트는 단일 `chat.history` 호출에 대해 이 기본값을 재정의하도록 요청별 `maxChars`를 보낼 수도 있습니다.
|
||||
|
||||
관련 전역 옵션:
|
||||
|
||||
- `gateway.port`, `gateway.bind`: WebSocket 호스트/포트.
|
||||
- `gateway.auth.mode`, `gateway.auth.token`, `gateway.auth.password`:
|
||||
shared-secret WebSocket 인증.
|
||||
- `gateway.auth.allowTailscale`: 활성화된 경우 브라우저 Control UI 채팅 탭이 Tailscale
|
||||
Serve identity headers를 사용할 수 있습니다.
|
||||
- `gateway.auth.mode: "trusted-proxy"`: identity-aware **non-loopback** 프록시 소스 뒤의 브라우저 클라이언트를 위한 reverse-proxy 인증([Trusted Proxy Auth](/ko/gateway/trusted-proxy-auth) 참조).
|
||||
공유 비밀 WebSocket 인증.
|
||||
- `gateway.auth.allowTailscale`: 활성화하면 브라우저 Control UI 채팅 탭이 Tailscale
|
||||
Serve ID 헤더를 사용할 수 있습니다.
|
||||
- `gateway.auth.mode: "trusted-proxy"`: ID 인식 **비루프백** 프록시 소스 뒤의 브라우저 클라이언트를 위한 역방향 프록시 인증입니다([신뢰할 수 있는 프록시 인증](/ko/gateway/trusted-proxy-auth) 참조).
|
||||
- `gateway.remote.url`, `gateway.remote.token`, `gateway.remote.password`: 원격 게이트웨이 대상.
|
||||
- `session.*`: 세션 저장소 및 main key 기본값.
|
||||
- `session.*`: 세션 저장소 및 기본 키 기본값.
|
||||
|
||||
## 관련 항목
|
||||
|
||||
- [Control UI](/ko/web/control-ui)
|
||||
- [Dashboard](/ko/web/dashboard)
|
||||
- [대시보드](/ko/web/dashboard)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user