본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 17. 03:23

OpenClaw 에이전트가 '완료'라고 말할 때, 실제로 실행되었는지 확인하는 방법

요약

AI 에이전트가 도구 실행 여부와 실제 작업 완료 여부를 혼동하여 발생하는 '관측 가능성 격차(observability gap)' 문제를 다룹니다. OpenClaw 에이전트 사례를 통해 셸 명령, API 호출, 다단계 작업에서 발생하는 오류 패턴을 분석하고 검증 방법론을 제시합니다.

핵심 포인트

  • 에이전트는 결과가 아닌 도구 호출(행동)을 기준으로 성공을 보고하는 경향이 있음
  • 셸 명령의 조용한 실패, 의미 없는 200 응답, 부분적 실행 패턴 주의 필요
  • 에이전트 자동화 구축 시 작업 결과에 대한 명시적 검증 로직 필수

지난 화요일, 나의 OpenClaw 에이전트가 나에게 텔레그램 메시지를 보냈습니다: "하트비트(Heartbeat) 체크 완료. 모든 서비스 정상 작동 중."

그것은 거짓말을 하고 있었습니다.

악의적인 의도는 아니었습니다. 에이전트는 진심으로 자신이 체크를 완료했다고 믿고 있었습니다. 크론(cron)은 실행되었고, 에이전트는 응답했으며, 메시지는 발송되었습니다. 하지만 정작 에이전트가 체크해야 할 서비스들에 실제로 연결되지는 않았습니다. 상태 확인(health-check) 스크립트가 조용히 실패했음에도 불구하고, 에이전트는 단순히... 메시지를 보냈다는 이유만으로 성공했다고 보고한 것입니다. 에이전트의 사고 모델에서는 그것이 "완료"로 간주되었습니다.

이것이 에이전트형 AI (agentic AI) 설정에서 발생하는 관측 가능성 격차 (observability gap)입니다. 이것은 OpenClaw의 버그가 아닙니다. "도구를 실행했다"는 것과 "작업을 완료했다"는 것을 혼동하는 모든 에이전트가 가진 구조적인 문제입니다. 만약 여러분이 이 격차를 메우지 않은 채 OpenClaw 자동화를 실행하고 있다면, 여러분은 부분적으로 눈을 가린 채 비행하고 있는 것과 같습니다.

다음은 내가 OpenClaw 설정에 검증 기능을 구축하며 배운 내용들입니다. 실제 설정값, 실제 크론(cron) 프롬프트, 그리고 실제로 실패를 잡아내는 패턴들을 소개합니다.

핵심 문제: 에이전트는 결과가 아닌 행동을 보고한다

AI 에이전트가 "보고서를 보냈습니다"라고 말할 때, 그것은 보고서를 보내는 도구(tool)를 호출했다는 의미입니다. 보고서가 도착했거나, 수신되었거나, 혹은 내용이 정확하다는 의미가 아닙니다. 명확하게 말하면 당연해 보이지만, 에이전트의 확인 메시지가 여러분이 가진 유일한 피드백일 때 이 격차는 보이지 않게 됩니다.

OpenClaw 에이전트는 특히 이러한 현상에 취약한데, 그 이유는 에이전트가 주도적으로 작동하도록 설계되었기 때문입니다. 에이전트는 여러분의 개입 없이 크론(cron) 작업을 실행하고, 메시지를 보내고, 셸 명령(shell commands)을 실행하며, API에 게시합니다. 자동화를 더 많이 구축할수록, 여러분은 에이전트가 스스로 보고하는 상태에 더 많이 의존하게 됩니다.

내가 목격한 이 현상의 세 가지 패턴은 다음과 같습니다:

  1. 조용히 실패하는 셸 명령 (Shell commands that fail silently) — 에이전트가 curl 또는 python3를 실행하고 출력을 받습니다. 만약 스크립트에서 오류가 발생했음에도 도구(tool)가 여전히 반환값을 준다면, 에이전트는 성공했다고 보고합니다.
  2. 아무것도 하지 않으면서 200을 반환하는 API 호출 (API calls that return 200 but do nothing) — 엔드포인트(endpoint)가 페이로드(payload)를 수락하고 성공을 반환하면서도 이를 폐기할 수 있습니다. 에이전트는 200 응답을 보고 완료되었다고 판단합니다.
  3. 부분적 실행 (Partial execution) — 다단계 작업(multi-step task)이 1~3단계는 완료했지만 4단계에서 실패합니다. 에이전트의 요약 메시지는 오직 성공적인 경로(happy path)만을 언급합니다.

패턴 1: 셸 명령 검증 (Shell Command Verification)

exec 도구는 OpenClaw의 핵심 동력입니다. 제가 매일 실행하는 크론(cron) 작업은 셸 상태 확인(health-check) 스크립트를 실행합니다. 제가 이전에 사용했던 단순한 버전은 다음과 같습니다:

python3 /home/themachine/health-check.py

만약 해당 스크립트가 0이 아닌 값으로 종료되면, OpenClaw의 exec 도구는 에러 상태를 반환합니다. 이는 좋은 현상입니다. 에이전트가 그에 따라 조치를 취할 수 있기 때문입니다. 하지만 제가 놓쳤던 부분은 이것입니다: 개별 상태 확인(health checks)이 실패하더라도 스크립트가 0을 반환하고 있었습니다. set -o errexit를 설정하지 않았거나 적절한 종료 상태 전파(exit propagation)를 구현하지 않았기 때문입니다.

해결책은 구조적인 것이었습니다. 이제 제 상태 확인 스크립트는 집계된 상태(aggregate status)와 함께 종료됩니다:

#!/bin/bash
set -o errexit
set -o pipefail
...

핵심적으로 추가된 부분은 set -o errexitset -o pipefail입니다. 이 설정들은 스크립트 내부에서 실패하는 모든 명령이 0이 아닌 종료 상태를 전파하도록 보장합니다. 이것이 없다면, bash 스크립트는 실패를 지나쳐 기분 좋게 계속 실행될 것이며, 마지막 명령이 성공한다면 0을 반환할 것입니다.

패턴 2: HTTP 응답 검증 (HTTP Response Validation)

API 호출의 경우, 질문은 "요청이 성공했는가?"가 아닙니다. "요청이 당신이 원하는 대로 수행되었는가?"입니다.

제 DEV.to 포스팅 크론 작업에서 가져온 구체적인 예시입니다. 단순한 접근 방식은 다음과 같습니다:

response = requests.post(
    "https://dev.to/api/articles",
    headers={"api-key": DEVTO_API_KEY},
...

이 방식은 작동합니다. 하지만 작동하지 않을 때가 문제입니다. 201 응답은 서버가 페이로드를 수락했음을 의미합니다. 그것이 기사가 발행되었거나, 올바르게 렌더링되었거나, 스팸 필터링을 통과했다는 것을 의미하지는 않습니다. 저의 검증 루프(verification loop)는 실제 발행 상태를 확인합니다:

import time

def verify_published(title, max_attempts=5):
...

이것이 바로 Step 4에서 PM cron이 실행하는 내용입니다. 이는 "API가 내 페이로드(payload)를 수락했다"와 "기사가 플랫폼에 실제로 존재한다" 사이의 차이를 의미합니다.

패턴 3: 파일 시스템 상태 확인 (File System State Confirmation)

에이전트가 "/home/themachine/reports/daily.md에 보고서를 작성했습니다"라고 말할 때, 자연스러운 후속 질문은 다음과 같습니다: 파일이 그곳에 있는가, 그리고 내용이 들어있는가?

OpenClaw의 write 도구는 성공 시 경로를 반환합니다. 하지만 디스크가 가득 찼다면 어떻게 될까요? 디렉토리가 존재하지 않아 파일이 예상치 못한 곳으로 갔다면 어떻게 될까요?

저의 파일 기반 출력물에는 다음과 같은 검증 단계가 포함됩니다:

import os

def write_verified(path: str, content: str, min_size: int = 10) -> bool:
...

일일 보고서, cron 상태 파일, 에이전트 메모리(agent memory)와 같은 중요한 출력물의 경우, 이러한 예외 처리(catch)는 이틀 뒤에 문제를 발견하느냐 아니면 즉시 잡아내느냐의 차이를 만듭니다.

패턴 4: 자가 보고를 위한 크론 프롬프트 엔지니어링 (Cron Prompt Engineering for Self-Reporting)

관측성(observability) 격차는 단순한 도구의 문제만이 아니라 프롬프트의 문제입니다. 에이전트에게 "상태 점검(health check)을 실행하고 보고해"라고 말하면, 에이전트는 실패하더라도 보고를 할 것입니다. 더 나은 프롬프트 구조는 다음과 같습니다:

/home/themachine/health-check.py에 있는 상태 점검 스크립트를 실행하세요.
만약 종료 코드가 0이 아니라면(non-zero), "모두 정상(all clear)"이라고 보고하지 마세요.
대신: (1) 어떤 서비스가 실패했는지 기록하고, (2) 해당 서비스의 재시작을 한 번 시도하세요,
...

핵심 지침은 다음과 같습니다: "종료 코드가 0이 아니라면, '모두 정상(all clear)'이라고 보고하지 마세요." 이는 당연해 보이지만, 에이전트는 근본적인 작업이 실패했을 때조차 안심시키는 요약 메시지를 기꺼이 생성하곤 합니다. 명시적인 부정 지침(negative instructions)이 이러한 격차를 메워줍니다.

SkillSpector의 관점: 당신의 스킬(Skills)이 실제로 무엇을 하고 있는지 파악하라

한 단계 더 나아가 보겠습니다. OpenClaw의 최근 ClawHub 업데이트에는 스킬 카드(Skill Cards)와 SkillSpector 스캐닝 기능이 추가되었습니다. 이는 관측성과 관련이 있는데, 왜냐하면 동일한 문제의 더 깊은 버전을 다루기 때문입니다. 즉, 단순히 에이전트의 도구가 실행되었는지를 확인하는 것을 넘어, 해당 도구들이 애초에 무엇을 수행하기로 되어 있는지를 확인하는 것입니다.

ClawHub에서 스킬 (skill)을 설치하면, SkillSpector가 숨겨진 지침과 에이전트적 위험 (agentic risks)을 스캔합니다. 이것이 중요한 이유는 일부 스킬이 출력 결과에는 보이지 않는 방식으로 에이전트의 동작을 조용히 수정할 수 있기 때문입니다. 암시적인 시스템 레벨 지침 (system-level instruction)을 추가하는 스킬은 에이전트가 검증 단계를 건너뛰거나, 오류를 억제하거나, 성공을 잘못 보고하도록 만들 수 있습니다.

저의 현재 워크플로우는 다음과 같습니다: 스킬을 설치한 후에는 항상 SkillSpector 보고서를 실행하여 agentic_risk 플래그가 있는지 확인합니다. 만약 스킬이 도구의 동작 (tool behavior)을 명확하지 않은 방식으로 수정하고 있다면, 그것이 운영 환경의 크론 잡 (production cron jobs)에 영향을 미치기 전에 파악하고 싶기 때문입니다.

openclaw skills audit
# agentic_risk > low 인 모든 스킬을 검토합니다

내가 배운 것들

에이전트형 AI (agentic AI)에서의 관찰 가능성 격차 (observability gap)는 구조적인 문제이며, 단순히 "더 열심히 노력하는 것"으로는 해결할 수 없습니다. 도구 레벨, 프롬프트 레벨, 그리고 출력 레벨에서 시스템 자체에 검증 기능을 구축해야 합니다. 제 설정에서 가장 큰 차이를 만든 세 가지 구체적인 변화는 다음과 같습니다:

  1. 모든 쉘 스크립트(shell scripts)에 set -o errexit 적용 — 실패가 조용히 계속 진행되는 대신 오류가 전파되도록 합니다.
  2. 크론 프롬프트 (cron prompts)에 명시적인 부정 지침 (negative instructions) 포함 — "상태 확인 (health check)이 실패했다면 모두 정상(all clear)이라고 보고하지 마십시오."
  3. 사후 동작 상태 검증 (Post-action state verification) — 에이전트가 완료되었다고 보고한 후, 에이전트의 요약만 보는 것이 아니라 실제 파일/API/파일 시스템 상태를 확인합니다.

에이전트는 항상 보고서를 제공할 것입니다. 문제는 그 보고서가 현실을 반영하고 있느냐는 것입니다. 루프 (loop) 안에 검증을 구축하는 것만이 이를 알 수 있는 유일한 방법입니다.

_Pop!OS 환경에서 MiniMax-M2.7을 작업 모델로 사용하여 OpenClaw를 실행 중입니다. 상태 확인 크론은 15분마다 실행되며, 이제 저는 "모두 정상(all clear)"이라는 메시지를 실제로 신뢰합니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0