Skip to Content
KoUsersFeatures헤드리스 모드

헤드리스 모드

헤드리스 모드를 사용하면 대화형 UI 없이 커맨드라인 스크립트와 자동화 도구에서 Qwen Code를 프로그래밍 방식으로 실행할 수 있다. 스크립팅, 자동화, CI/CD 파이프라인, AI 기반 도구 구축에 적합하다.

개요

헤드리스 모드는 Qwen Code의 헤드리스 인터페이스를 제공하며 다음과 같은 기능을 지원한다:

- 커맨드라인 인자나 stdin을 통해 프롬프트를 전달 - 구조화된 출력(텍스트 또는 JSON) 반환 - 파일 리다이렉션 및 파이프 지원 - 자동화 및 스크립팅 워크플로우 지원 - 오류 처리를 위한 일관된 종료 코드 제공 - 현재 프로젝트에 한정된 이전 세션을 재개하여 다단계 자동화 가능

기본 사용법

직접 프롬프트

--prompt(또는 -p) 플래그를 사용하여 헤드리스 모드로 실행한다:

qwen --prompt "What is machine learning?"

Stdin 입력

터미널에서 Qwen Code로 입력을 파이프한다:

echo "Explain this code" | qwen

파일 입력과 결합

파일에서 읽어서 Qwen Code로 처리한다:

cat README.md | qwen --prompt "Summarize this documentation"

이전 세션 재개 (헤드리스)

헤드리스 스크립트에서 현재 프로젝트의 대화 컨텍스트를 재사용한다:

# 이 프로젝트의 가장 최근 세션을 이어받아 새 프롬프트 실행 qwen --continue -p "Run the tests again and summarize failures" # 특정 세션 ID를 직접 재개 (UI 없음) qwen --resume 123e4567-e89b-12d3-a456-426614174000 -p "Apply the follow-up refactor"

> [!note] > > - 세션 데이터는 ~/.qwen/projects/<sanitized-cwd>/chats 아래에 프로젝트 단위로 저장되는 JSONL이다. > - 새 프롬프트를 보내기 전에 대화 이력, 도구 출력, 대화 압축 체크포인트를 복원한다.

지속적인 목표 실행

헤드리스 모드에서는 프롬프트 전체로 /goal을 전달할 수 있다. 목표 상태는 세션과 함께 저장되므로, --continue 또는 --resume <sessionId>를 사용하여 이후 프로세스에서 동일한 Goal을 확인하거나 제어할 수 있다. 이를 위해서는 general.chatRecording이 계속 활성화되어 있어야 한다(기본값).

# Goal을 생성하고 워커 시작 qwen -p "/goal Finish the release checklist" # 동일한 세션에서 저장된 상태 확인 qwen --continue -p "/goal"

다른 작업에도 동일한 qwen --continue -p "<control>" 패턴을 사용한다:

제어동작
/goal모델을 호출하지 않고 저장된 상태를 보고한다.
/goal <objective> 또는 /goal set …Goal을 생성하거나 교체하고 헤드리스 Goal 작업을 시작한다.
/goal edit <objective>완료되지 않은 Goal을 수정한다. 결과 상태가 active이면 즉시 작업이 시작된다.
/goal pause모델을 호출하지 않고 active Goal을 일시 중지한다.
/goal resume재개 가능한 Goal을 재개하고 헤드리스 Goal 작업을 시작한다.
/goal clear확인이나 모델 호출 없이 Goal을 초기화한다.

런타임에 예약된 Goal 계속 세그먼트는 --max-session-turns에 포함되지 않지만, 실제 사용자 프롬프트는 포함된다. 명시적인 --max-wall-time--max-tool-calls 예산은 계속 적용되며, 어느 쪽을 초과하면 활성 Goal 작업이 일시 중지된 후 해당 예산 관련 오류로 런이 종료된다.

--output-format stream-json과 함께 사용하면, 각 Goal 상태 변경 시 event.typegoal_statestream_event가 발행된다. 이 표준 상태 이벤트는 --include-partial-messages 없이도 발행된다. partial 메시지가 활성화되면, 이전 active_goal 이벤트가 호환성 프로젝션으로 뒤따라 발행되며, 자동화에서는 goal_state를 권위 있는 이벤트로 취급해야 한다.

> [!note] > > 이 동작은 표준 헤드리스 CLI 런에 적용된다. ACP는 여전히 레거시 Goal 커맨드 경로를 사용한다.

메인 세션 프롬프트 커스터마이즈

공유 메모리 파일을 수정하지 않고도 단일 CLI 런의 메인 세션 시스템 프롬프트를 변경할 수 있다.

내장 시스템 프롬프트 오버라이드

--system-prompt를 사용하여 현재 런에서 Qwen Code의 내장 메인 세션 프롬프트를 교체한다:

qwen -p "Review this patch" --system-prompt "You are a terse release reviewer. Report only blocking issues."

추가 명령어 추가

--append-system-prompt를 사용하여 내장 프롬프트를 유지한 채 이번 런에 대한 추가 명령어를 추가한다:

qwen -p "Review this patch" --append-system-prompt "Be terse and focus on concrete findings."

두 플래그를 함께 사용하면 커스텀 기본 프롬프트와 런별 추가 명령어를 결합할 수 있다:

qwen -p "Summarize this repository" \ --system-prompt "You are a migration planner." \ --append-system-prompt "Return exactly three bullets."

> [!note] > > - --system-prompt는 현재 런의 메인 세션에만 적용된다. > - QWEN.md와 같은 로드된 메모리 및 컨텍스트 파일은 여전히 --system-prompt 뒤에 추가된다. > - --append-system-prompt는 내장 프롬프트와 로드된 메모리 뒤에 적용되며, --system-prompt와 함께 사용할 수 있다.

출력 형식

Qwen Code는 다양한 사용 사례에 대해 여러 출력 형식을 지원한다:

텍스트 출력 (기본값)

일반적인 사람이 읽을 수 있는 출력:

qwen -p "What is the capital of France?"

응답 형식:

The capital of France is Paris.

JSON 출력

JSON 배열로 구조화된 데이터를 반환한다. 모든 메시지는 버퍼링되었다가 세션이 완료될 때 함께 출력된다. 이 형식은 프로그래밍 방식 처리와 자동화 스크립트에 적합하다.

JSON 출력은 메시지 객체의 배열이다. 출력에는 여러 메시지 유형이 포함된다: 시스템 메시지(세션 초기화), 어시스턴트 메시지(AI 응답), 결과 메시지(실행 요약).

사용 예시

qwen -p "What is the capital of France?" --output-format json

출력 (실행 종료 시):

[ { "type": "system", "subtype": "session_start", "uuid": "...", "session_id": "...", "model": "qwen3-coder-plus", ... }, { "type": "assistant", "uuid": "...", "session_id": "...", "message": { "id": "...", "type": "message", "role": "assistant", "model": "qwen3-coder-plus", "content": [ { "type": "text", "text": "The capital of France is Paris." } ], "usage": {...} }, "parent_tool_use_id": null }, { "type": "result", "subtype": "success", "uuid": "...", "session_id": "...", "is_error": false, "duration_ms": 1234, "result": "The capital of France is Paris.", "usage": {...} } ]

Stream-JSON 출력

Stream-JSON 형식은 실행 중 발생하는 JSON 메시지를 즉시 발행하여 실시간 모니터링을 가능하게 한다. 이 형식은 각 메시지가 한 줄의 완전한 JSON 객체인 줄바꿈 구분 JSON을 사용한다.

qwen -p "Explain TypeScript" --output-format stream-json

출력 (이벤트 발생 시 스트리밍):

{"type":"system","subtype":"session_start","uuid":"...","session_id":"..."} {"type":"assistant","uuid":"...","session_id":"...","message":{...}} {"type":"result","subtype":"success","uuid":"...","session_id":"..."}

--include-partial-messages와 함께 사용하면, 실시간 UI 업데이트를 위한 추가 스트림 이벤트(message_start, content_block_delta 등)가 실시간으로 발행된다.

qwen -p "Write a Python script" --output-format stream-json --include-partial-messages

입력 형식

--input-format 매개변수는 Qwen Code가 표준 입력에서 입력을 소비하는 방식을 제어한다:

- text (기본값): stdin 또는 커맨드라인 인자에서의 표준 텍스트 입력 - stream-json: 양방향 통신을 위한 stdin 경유 JSON 메시지 프로토콜

> Note: Stream-json 입력 모드는 현재 구축 중이며 SDK 통합을 위한 것이다. --output-format stream-json이 설정되어 있어야 한다.

파일 리다이렉션

출력을 파일로 저장하거나 다른 명령어로 파이프한다:

# 파일로 저장 qwen -p "Explain Docker" > docker-explanation.txt qwen -p "Explain Docker" --output-format json > docker-explanation.json # 파일에 추가 qwen -p "Add more details" >> docker-explanation.txt # 다른 도구로 파이프 qwen -p "What is Kubernetes?" --output-format json | jq '.response' qwen -p "Explain microservices" | wc -w qwen -p "List programming languages" | grep -i "python" # 실시간 처리를 위한 Stream-JSON 출력 qwen -p "Explain Docker" --output-format stream-json | jq '.type' qwen -p "Write code" --output-format stream-json --include-partial-messages | jq '.event.type'

설정 옵션

헤드리스 사용 시 주요 커맨드라인 옵션:

옵션설명예시
--prompt, -p헤드리스 모드로 실행qwen -p "query"
--output-format, -o출력 형식 지정 (text, json, stream-json)qwen -p "query" --output-format json
--input-format입력 형식 지정 (text, stream-json)qwen --input-format text --output-format stream-json
--include-partial-messagesstream-json 출력에 partial 메시지 포함qwen -p "query" --output-format stream-json --include-partial-messages
--system-prompt이번 런의 메인 세션 시스템 프롬프트 오버라이드qwen -p "query" --system-prompt "You are a terse reviewer."
--append-system-prompt이번 런의 메인 세션 시스템 프롬프트에 추가 명령어 추가qwen -p "query" --append-system-prompt "Focus on concrete findings."
--debug, -d디버그 모드 활성화qwen -p "query" --debug
--safe-mode모든 커스터마이징 비활성화 — 컨텍스트 파일, hook, extension, skill, MCP 서버, 커스텀 서브에이전트(내장 서브에이전트만 로드), 권한 규칙, 설정 기반 승인 모드 오버라이드, 메모리 기능, 샌드박스 설정 — 하여 문제를 격리한다. CLI 플래그 --yolo--approval-mode는 여전히 적용된다. Troubleshooting 참조. QWEN_CODE_SAFE_MODE=true로도 설정 가능.qwen -p "query" --safe-mode
--model, -m이번 런에 사용할 모델qwen -p "query" --model qwen3-coder-plus
--include-directories추가 디렉토리 포함qwen -p "query" --include-directories src,docs
--yolo, -y모든 작업 자동 승인qwen -p "query" --yolo
--approval-mode승인 모드 설정 (plan, default, auto-edit, auto, yolo)qwen -p "query" --approval-mode auto-edit
--continue이 프로젝트의 가장 최근 세션 재개qwen --continue -p "Pick up where we left off"
--resume [sessionId]특정 세션 재개 (또는 대화형 선택)qwen --resume 123e... -p "Finish the refactor"
--max-session-turns런의 사용자/모델/도구 턴 수 상한qwen -p "..." --max-session-turns 30
--max-wall-time실제 경과 시간 예산. 90(초), 30s, 5m, 1h, 1.5h 허용qwen -p "..." --max-wall-time 10m
--max-tool-calls런의 누적 도구 호출 예산qwen -p "..." --max-tool-calls 50

사용 가능한 모든 설정 옵션, 설정 파일, 환경 변수에 대한 전체 세부사항은 설정 가이드를 참조한다.

무인 실행에서의 안전성

--yolo(또는 --approval-mode=yolo)와 결합된 헤드리스 / CI 런은 shell, write, edit를 포함한 모든 도구 호출을 자동 승인한다. --yolo는 샌드박스를 활성화하지 않는다 — 해당 도구들은 호스트 프로세스의 권한 수준에서 실행된다. Qwen Code가 샌드박스 없이 이 조합을 감지하면, 시작 시 stderr에 한 줄 경고를 출력한다. 트레이드오프를 검토한 후 QWEN_CODE_SUPPRESS_YOLO_WARNING=1로 경고를 억제할 수 있다.

런 수준 예산

Qwen Code는 다음 임계값 중 하나를 초과하면 무인 런을 중단할 수 있다. 각 값은 기본적으로 -1(무제한)이며, 어느 하나라도 설정하면 비정상 동작을 제한할 수 있다. 이미 SIGINT를 전달하는 동일한 AbortController에 대해 협력적으로 적용되므로, 예산 중단은 구조화된 FatalBudgetExceededError(종료 코드 55)를 발행한다. 이는 턴 상한 종료 코드 53 및 SIGINT의 130과 구별되므로 CI 스크립트에서 이유에 따라 분기할 수 있다.

플래그설정 키제한 대상
--max-wall-timemodel.maxWallTimeSeconds전체 런의 실제 경과 시간. 플래그는 90(초), 30s, 5m, 1h, 1.5h(소수 단위 지원)를 허용한다. 최소 1초 — 1초 미만 값은 오타로 간주하여 거부된다. 설정은 초 단위.
--max-tool-callsmodel.maxToolCalls메인 런 루프에서 디스패치된 누적 최상위 도구 호출 수(성공 실패 모두 포함 — 모델은 오류 시에도 토큰을 소비한다). 서브에이전트 / 구조화된 출력 면제에 대해서는 아래 “범위” 참조.
--max-session-turnsmodel.maxSessionTurns사용자/모델/도구 턴 수. 기존 기능. 초과 시 코드 53으로 종료(예산 종료 55와 구별).

범위

- --max-tool-calls는 최상위 디스패치만 계산한다. 모델이 agent 도구를 호출하면 디스패치는 1로 계산되며, 생성된 서브에이전트가 수행한 내부 도구 호출은 계산되지 않는다. 서브에이전트를 통해 작업을 전달하는 모델은 작은 최상위 예산으로도 무제한의 내부 작업을 수행할 수 있다. 더 엄격한 상한이 필요하면 --exclude-tools agent와 함께 사용한다. - structured_output--max-tool-calls에서 면제된다. --json-schema에서 모델의 종료 structured_output 호출은 실제 작업이 아닌 “완료” 계약이며, --max-tool-calls에 포함되지 않아 예산 경계에서의 완료가 오탐지로 중단되지 않는다. 이 면제는 무조건적이며(실패한 Ajv 검증 포함), 잘못된 출력 재시도 루프에 갇힌 모델은 --max-tool-calls로 제한되지 않는다. 재시도를 제한하려면 --max-session-turns 또는 --max-wall-time과 함께 사용한다. - structured_output--max-session-turns에서 면제되지 않는다. 이 카운터는 기존 것이며 종료 계약을 포함한 모든 턴에서 증가한다. --json-schema에서 N회의 실제 작업 턴을 허용하려면 --max-session-turnsN+1로 설정한다. - 단일 실행 vs --input-format stream-json: stream-json 입력 모드에서 데몬은 모든 사용자 메시지 시작 시 예산 카운터를 초기화한다. 예산은 프로세스 단위가 아닌 메시지 단위이다. - qwen serve / ACP 세션: 데몬 ACP 세션 경로는 현재 settings.json의 --max-wall-time / --max-tool-calls를 참조하지 않는다. 이 예산은 단일 실행 qwen -p 런과 --input-format stream-json 세션에만 적용된다. (qwen serve는 settings에 tools.approvalMode: 'yolo'가 설정되어 있으면 부트 시 YOLO-no-sandbox 경고를 발행한다.)

권장 조합

- 신뢰할 수 있는 격리 환경(임시 CI 러너, 컨테이너): qwen -p "..." --yolo --max-session-turns N --max-wall-time 10m --output-format json. 턴 예산과 실제 경과 시간 예산을 고정하여 멈춘 에이전트가 CI 분태를 소모하지 않도록 하고, --output-format json으로 런 후 사용량 / 도구 호출 감사를 위한 데이터를 캡처한다. - 로컬 머신 또는 공유 인프라: --sandbox를 추가하거나 QWEN_SANDBOX=1을 설정하여 shell / write / edit 도구가 샌드박스 이미지 내부에서 실행되도록 한다. - 레이트 리밋 재시도가 포함된 장시간 CI: QWEN_CODE_UNATTENDED_RETRY=1--max-wall-time과 함께 사용한다. 재시도 환경 변수는 일시적인 429 / 529 응답을 지나서 런을 유지하고, 실제 경과 시간 예산은 지속적으로 실패하는 프로바이더가 작업을 무기한 연장하지 못하도록 한다. - 제한된 감사 / 탐색: 읽기 전용 작업의 경우, --max-tool-calls 25로 모델이 grep / read를 얼마나 적극적으로 수행할 수 있는지 제한한다. --exclude-tools shell,write,edit와 함께 사용하여 제한을 의미 있게 만든다.

예시

코드 리뷰

cat src/auth.py | qwen -p "Review this authentication code for security issues" > security-review.txt

커밋 메시지 생성

result=$(git diff --cached | qwen -p "Write a concise commit message for these changes" --output-format json) echo "$result" | jq -r '.response'

API 문서

result=$(cat api/routes.js | qwen -p "Generate OpenAPI spec for these routes" --output-format json) echo "$result" | jq -r '.response' > openapi.json

배치 코드 분석

for file in src/*.py; do echo "Analyzing $file..." result=$(cat "$file" | qwen -p "Find potential bugs and suggest improvements" --output-format json) echo "$result" | jq -r '.response' > "reports/$(basename "$file").analysis" echo "Completed analysis for $(basename "$file")" >> reports/progress.log done

PR 코드 리뷰

result=$(git diff origin/main...HEAD | qwen -p "Review these changes for bugs, security issues, and code quality" --output-format json) echo "$result" | jq -r '.response' > pr-review.json

로그 분석

grep "ERROR" /var/log/app.log | tail -20 | qwen -p "Analyze these errors and suggest root cause and fixes" > error-analysis.txt

릴리스 노트 생성

result=$(git log --oneline v1.0.0..HEAD | qwen -p "Generate release notes from these commits" --output-format json) response=$(echo "$result" | jq -r '.response') echo "$response" echo "$response" >> CHANGELOG.md

모델 및 도구 사용량 추적

result=$(qwen -p "Explain this database schema" --include-directories db --output-format json) total_tokens=$(echo "$result" | jq -r '.stats.models // {} | to_entries | map(.value.tokens.total) | add // 0') models_used=$(echo "$result" | jq -r '.stats.models // {} | keys | join(", ") | if . == "" then "none" else . end') tool_calls=$(echo "$result" | jq -r '.stats.tools.totalCalls // 0') tools_used=$(echo "$result" | jq -r '.stats.tools.byName // {} | keys | join(", ") | if . == "" then "none" else . end') echo "$(date): $total_tokens tokens, $tool_calls tool calls ($tools_used) used with models: $models_used" >> usage.log echo "$result" | jq -r '.response' > schema-docs.md echo "Recent usage trends:" tail -5 usage.log

지속적 재시도 모드

Qwen Code가 CI/CD 파이프라인이나 백그라운드 데몬으로 실행될 때, 짧은 API 장애(레이트 리밋 또는 과부하)가 여러 시간에 걸친 작업을 중단시키면 안 된다. 지속적 재시도 모드는 Qwen Code가 일시적인 API 오류를 서비스가 복구될 때까지 무기한 재시도하도록 한다.

작동 방식

- 일시적 오류만: HTTP 429(레이트 리밋) 및 529(과부하)는 무기한 재시도된다. 다른 오류(400, 500 등)는 정상적으로 실패한다. - 상한이 있는 지수 백오프: 재시도 지연은 지수적으로 증가하지만 재시도당 5분으로 상한이 정해진다. - 하트비트 키프: 긴 대기 중에도 30초마다 stderr에 상태 줄이 출력되어, CI 러너가 비활성으로 인해 프로세스를 종료하지 않도록 한다. - 점진적 저하: 일시적이지 않은 오류와 대화형 모드는 전혀 영향을 받지 않는다.

활성화

QWEN_CODE_UNATTENDED_RETRY 환경 변수를 true 또는 1로 설정한다(대소문자 구분, 엄격 매칭):

export QWEN_CODE_UNATTENDED_RETRY=1

> [!important] > 지속적 재시도는 명시적 옵트인이 필요하다. CI=true만으로는 활성화되지 않는다 — 빠른 실패 CI 작업이 무한 대기 작업으로 전환되는 것은 위험하므로 침묵 중에 활성화되지 않는다. 파이프라인 설정에서 항상 QWEN_CODE_UNATTENDED_RETRY를 명시적으로 설정한다.

예시

GitHub Actions

- name: Automated code review env: QWEN_CODE_UNATTENDED_RETRY: '1' run: | qwen -p "Review all files in src/ for security issues" \ --output-format json \ --yolo > review.json

야간 배치 처리

export QWEN_CODE_UNATTENDED_RETRY=1 qwen -p "Migrate all callback-style functions to async/await in src/" --yolo

백그라운드 데몬

QWEN_CODE_UNATTENDED_RETRY=1 nohup qwen -p "Audit all dependencies for known CVEs" \ --output-format json > audit.json 2> audit.log &

모니터링

지속적 재시도 중 하트비트 메시지가 stderr에 출력된다:

[qwen-code] Waiting for API capacity... attempt 3, retry in 45s [qwen-code] Waiting for API capacity... attempt 3, retry in 15s

이 메시지는 CI 러너를 활성 상태로 유지하고 진행 상황을 모니터링할 수 있게 한다. stdout에는 표시되지 않으므로 다른 도구로 파이프되는 JSON 출력은 깨끗하게 유지된다.

리소스

- CLI 설정 - 전체 설정 가이드 - 인증 - 인증 설정 - 명령어 - 대화형 명령어 레퍼런스 - 튜토리얼 - 단계별 자동화 가이드

Last updated on