글

라벨이 AI에이전트인 게시물 표시

사실 검증 조건: AI 검수자가 제안한 두 문장, 왜 다시 반려됐나

AI가 제안한 수정 문장도 원문과 다시 대조해야 한다. 출처가 존재하는지보다 그 출처의 조건이 실제 문장에 남아 있는지가 승인 기준이다. 2026년 10월 13일 검수 기록에는 이전 검수자가 제안한 문장 두 곳을 다시 FAIL로 돌린 사례가 남아 있다. AI의 설명을 문서나 안내문에 옮기는 개발자라면 이 차이가 중요하다. 검수 요청에 “사실을 확인해”만 적지 말고, 주장·출처·문장과 반려 조건을 같이 넘겨야 한다. 검수자의 문장도 왜 틀렸을까 해당 기록에서 형식 검사와 가독성 검사는 통과했다. 그런데 원고 A의 첫 답과 원고 B의 결론은 각 원고가 보관한 근거와 맞지 않았다. 두 문장 모두 앞선 검수자가 직접 제안했던 표현이었다. 한 문장은 적용 대상을 넓혔다. 다른 문장은 특정 선택지의 기한을 모든 선택지의 소멸로 바꿨다. 문장은 매끈했지만 출처가 허용한 범위보다 강했다. 이를 특정 모델의 우열로 해석하지 않는다. 확인된 것은 두 문장의 오류와 반려 이유다. 모델별 누락률이나 검수 정확도를 비교한 실험은 이 기록에 없다. 사례 A: 처음 계약의 조건이 빠졌다 원고 A는 계약을 중간에 끝낼 수 있는 조건을 설명했다. 검수 기록에 남은 전·후 문장은 다음과 같다. > 전: “해지 특약이 없다면 세입자 혼자 계약을 끝낼 수 없어서, 합의하지 못하면 만료일까지 월세를 내야 합니다.” > > 후: “처음 정한 계약기간 중이고 해지 특약이 없다면, 합의하지 못하는 한 만료일까지 월세를 내야 합니다.” ‘후’는 그다음 검수자가 새로 제시한 수정안이다. 이 기록만으로 수정 적용이나 최종 PASS까지 확인한 것은 아니다. 빠진 부분은 “처음 정한 계약기간 중”이다. 저장된 법령의 제6조의2는 묵시적으로 갱신된 계약에서 임차인이 언제든 해지를 통지할 수 있다고 정한다. 효력은 임대인이 통지를 받은 날부터 3개월이 지나면 생긴다. 제6조의3 제4항은 갱신요구권으로 갱신된 계약의 해지에도 제6조의2를 준용한다. 그래서 ‘특약이 없다’는 조건만으...

PTY REPL 멈춤: 띄운 지 1분 안에 write(2)에서 막힌 세션, 확인 순서와 우회법

PTY 기반 에이전트 세션에서 브라우저 자동화 CLI의 aside repl 을 장기 실행한 뒤 응답이 끊긴다면, REPL을 더 만지기 전에 출력 경로부터 확인해야 한다. 2026년 10월 12~13일 운영 기록에는 REPL을 띄운 지 1분 안에 세션이 세 번 멈췄고, 메인 스레드가 write(2) 에서 기다렸다고 남아 있다. 우회는 장기 REPL을 메인 세션 PTY에서 빼고 단발 실행이나 PTY 밖 FIFO 입력으로 돌리는 것이고, 커널 수준의 원인은 증명하지 못했다. 살아 있는 프로세스가 답하지 않았다 터미널 화면과 텔레그램 응답이 함께 멈췄다. 운영 메모에는 세 번 모두 메인 세션에서 REPL을 띄운 뒤 1분 안에 같은 정지가 나타났다고 적혀 있다. 한 번의 긴 작업이 아니라, 같은 실행 방식 뒤에 반복된 정지였다. 이 세션은 감시기(supervisor)가 띄운 PTY 안에서 돈다. 감시기가 PTY 출력을 계속 읽어 pty.log 에 남겨야 세션이 다음 출력을 쓸 수 있다. 그 pty.log 가 더 이상 진행하지 않았다. sample 로 본 메인 스레드는 쓰기 대기 상태였고, 감시기 쪽 PTY에는 읽을 출력이 없었다. REPL을 종료해도 응답이 돌아오지 않아 세션을 재시작해야 했다. 이 세 가지는 서로 다른 관찰이다. 로그 정지는 출력이 진행하지 않는다는 신호이고, 스택은 어느 호출에서 기다리는지를 보여 준다. REPL 종료 뒤에도 풀리지 않았다는 사실은 자식 프로세스 하나를 끄는 것으로 복구되지 않았다는 뜻이다. 처음에는 감시기를 잘못 의심했다 이틀 동안 정지는 네 번이었다. 그중 세 번이 aside repl 을 띄운 지 1분 안에 일어났고, 처음에는 이 연관을 보지 못했다. 첫 가설은 감시기가 빈 읽기를 한 번 만나면 출력 감시를 끊는다는 것이었다. 빈 읽기 뒤에도 감시를 다시 걸고, 그때마다 pty_eof 기록을 남기도록 고쳤다. 다음 정지 때 이 기록은 한 번도 남지 않았다. 두 번째 가설은 kqueue 가 "읽을 출력이 ...

발행 상태 검증, 재발행 버튼을 누르기 전에 확인할 4가지

AI에게 발행을 맡겼다면 보고를 읽은 뒤 실제 공개 상태를 따로 확인해야 한다. 공개 URL, 화면의 공개 상태, 게시 시각, 중복 URL이 맞는지 보고 나서 재시도를 결정한다. 2026년 10월 13일에는 중간에 멈춘 발행 작업이 발행 진행 중이라고 남긴 글이 후속 확인에서 이미 공개돼 있었다. 이 확인은 블로그 제작과 발행을 자동화하는 개발자를 위한 절차다. 목표는 완료 문구를 받는 데 있지 않다. 의도한 글이 의도한 상태로 남아 있고, 같은 글을 다시 올릴 필요가 없는지 판단하는 데 있다. 아직 발행하지 않았다는 보고를 받으면 바로 다시 올려도 될까? 당시 앞 작업은 실행 중간에 중단됐다. 마지막 보고는 앞선 시도가 발행에 도달하지 않았고, 발행은 진행 중이라는 내용이었다. 몇 분 뒤 시작한 후속 작업은 중복 확인부터 했다. 그 글은 이미 공개돼 있었고, 후속 작업은 공개 페이지에서 정확한 제목을 확인한 뒤 새 글을 만들지 않고 멈췄다. 여기서 확인한 결과는 단순하다. 재발행이 필요하다는 전제로 시작해도 실제 글이 공개돼 있으면 멈춰야 한다. 보고를 기준으로 새 글을 만들었다면 필요 없는 실행으로 이어질 상황이었다. 발행 버튼이 언제 눌렸는지, 어떤 시도가 공개를 끝냈는지는 남은 영수증만으로 확정할 수 없다. 그래도 다음 행동을 정하는 데 필요한 사실은 남아 있다. 마지막 보고는 완료가 아니라 진행 중이었고, 실제 상태는 공개였다. 최소 증거는 네 가지로 나눈다 공개 URL은 결과물을 찾는 기준으로 남긴다. 주소만 복사하지 말고 그 주소에서 의도한 제목과 본문이 보이는지 확인한다. 다른 글을 열어 놓은 채 성공으로 처리하지 않도록 대상 원고와 함께 대조한다. 화면의 상태는 별도 항목이다. 관리 목록에서 공개인지 예약인지 초안인지 적고, 공개가 목표라면 독자가 보는 페이지도 확인한다. 편집 화면에서 원고가 보이는 것과 공개 페이지에서 글이 보이는 것을 같은 증거로 취급하지 않는다. 게시 시각에는 날짜와 시간대를 같이 남긴다. 예약이 목표...

텔레그램 한 줄로 블로그 작업을 넘길 때 중복 실행을 막는 구조

이미지
답부터 말하면 텔레그램 메시지 ID를 요청 파일 이름과 처리 영수증의 공통 키로 써야 한다. 같은 메시지가 다시 들어와도 새 파일로 덮어쓰지 않고, 상태 파일이 있으면 에이전트에 다시 넣지 않는 구조다. 이 결론은 2026년 9월 28일 로컬 테스트 기준이다. 테스트 41개가 통과했고 실패는 0개였다. 다만 실제 텔레그램 사진 왕복과 장애 복구 시간은 아직 측정하지 않았다. 왜 명령 한 줄이 두 번 실행될 수 있나? 텔레그램에서 /blog 명령을 한 번 보냈다고 실행도 한 번이라고 볼 수 있을까. 수신 플러그인, 파일 감시, 에이전트 세션, 답장 전송 사이에는 각각 재시작과 재호출이 들어올 수 있다. 문제는 요청 내용이 아니라 경계다. 같은 업데이트를 플러그인이 다시 받거나, 파일 감시 이벤트가 반복되거나, 답장 전송 중 프로세스가 멈출 수 있다. 그래서 “이미 본 요청인가”를 각 단계가 같은 기준으로 판단해야 한다. 이 브리지는 메시지 본문 대신 텔레그램 메시지 ID를 기준으로 삼는다. 내용이 같은 두 요청은 서로 다른 작업일 수 있지만, ID가 같은 요청은 같은 전달 건이기 때문이다. 요청 파일은 어떻게 한 번만 만들어지나? 수신 단계는 먼저 임시 파일에 요청 전체를 쓴다. 파일을 동기화하고 닫은 뒤, requests/<메시지ID>.json 이라는 최종 이름에 배타적으로 연결한다. 최종 파일이 이미 있으면 덮어쓰지 않는다. 기존 파일 자체가 중복 수신 영수증이 된다. 소비자는 완성된 이름만 보므로 절반만 써진 JSON을 집어 들지 않는다. 임시 파일에 요청 전체를 기록한다. 파일 동기화와 닫기를 끝낸다. 메시지 ID 이름으로 배타적 링크를 만든다. 같은 이름이 있으면 기존 요청을 유지한다. 요청 파일은 처리 뒤에도 삭제하지 않는다. 2026년 9월 28일 테스트에는 같은 명령을 8개 동시에 넣어도 최종 요청 파일이 하나만 남는 검사가 있다. 파일 감시자가 처음 본 시점에 JSON 전체를 읽을 수 있는지도 별도로 확인한다...