본문으로 바로가기
기술 · 약 11분 읽기

개발 기록

OpenClaw 스크랩 에이전트 제작기

밝은 창 프레임 안에서 링크 입력과 실제 샘플 보고서를 연결한 스크랩 에이전트 개념도
링크 입력과 보고서를 연결한 개념도입니다. 보고서 부분은 실제 수동 샘플 PDF이며 메신저 실행 화면은 아닙니다.

읽어야 할 링크가 생기면 AI에게 요약을 부탁하곤 합니다. 빠르게 훑어볼 때는 편한데, 내용을 이해하려고 읽다 보면 다시 원문을 열게 됩니다. 용어가 낯설거나, 숫자가 나온 조건이 생략됐거나, 표의 일부가 설명에서 빠져 있기 때문이에요.

스크랩 에이전트는 이 불편함을 줄이려고 만들기 시작했어요. 요청은 구체적이었어요. 링크를 주면 해당 글이나 페이지 전체를 읽고, 원문 순서대로 쉽게 풀어 쓴 보고서를 만들어 달라는 것이었습니다. 앞에는 핵심 내용을 정리하고, 본문에는 어려운 용어의 괄호 설명과 각주를 넣기로 했습니다. 문서 디자인도 매번 다시 요청하지 않도록 Quarkdown 양식을 적용했어요.

글 한 편을 수집해 보고서로 만드는 코드는 구현했고, 실제 페이지 수집과 문서 출력도 확인했습니다. 다만 첫 OpenClaw 모델 실행에서는 도구를 찾지 못했고, 수정본의 최종 연결 검증이 남았습니다. 이 글은 2026년 10월 28일의 첫 구현과 검증 기록입니다. 완성된 서비스 사용 후기와 구분해서 읽어 주세요.

도해와 보고서 이미지를 누르면 원본 크기로 열립니다.

밝은 창 프레임 안에서 링크 입력과 실제 샘플 보고서를 연결한 스크랩 에이전트 개념도

그림 1. 개념도와 실제 수동 샘플 PDF를 함께 배치했습니다. 입력 채널과 처리 단계는 다음 아키텍처 그림에서 이어서 설명합니다. 메신저 실행 화면은 아닙니다.

전체를 읽는다는 말부터 범위를 정했어요

처음 요구에 있던 ‘관련된 모든 내용’은 여러 방식으로 해석할 수 있었습니다. 한 페이지의 본문 전체일 수도 있고, 그 페이지에 걸린 링크까지 찾아가는 조사일 수도 있었죠. 두 작업은 수집량도, 완료 기준도 크게 다릅니다.

기본 범위는 사용자가 준 페이지 한 개로 정했습니다. 본문을 끝까지 읽되, 연결된 다른 글은 자동으로 따라가지 않습니다. 접힌 설명과 표, 코드, 그림도 수집 대상으로 삼았습니다. 로그인하거나 접근 제한을 우회해서 내용을 가져오는 기능은 넣지 않았어요.

범위를 정한 뒤 보고서의 읽는 순서를 잡았습니다. 독자는 앞의 핵심 정리로 글의 방향을 파악하고, 이어지는 본문에서 원문과 같은 순서로 자세한 설명을 읽습니다. 원문에 있는 수치와 조건, 예외는 해설에도 남겨야 합니다. 긴 부연 설명은 각주로 보내고, 자주 나오는 낯선 용어는 뒤의 용어 풀이에 모읍니다.

보고서 분량을 몇 페이지로 고정하지는 않았습니다. 짧은 글과 긴 기술 문서를 같은 길이로 만들면 어느 쪽에선가 내용이 부풀거나 빠질 수밖에 없으니까요. 이번 샘플이 3페이지인 것은 그 입력과 양식으로 나온 결과입니다.

한 번의 요청 안에서 어떤 일이 일어날까

구조는 OpenClaw의 전용 스크랩 에이전트와 문서 제작 도구로 나눴습니다. OpenClaw는 요청을 받아 에이전트의 대화를 실행하고, 전용 도구는 페이지 수집과 파일 제작을 맡습니다. 채널에서 받은 요청을 에이전트로 보내는 방식은 OpenClaw의 에이전트 라우팅 문서에서 설명하는 구조를 참고했습니다.

스크랩 에이전트가 사용하는 도구의 이름은 scrap_report입니다. 이 도구는 collect, read, write, render 네 동작을 제공합니다. 모델이 다음 동작을 고를 수 있도록 작업 순서를 도구 이름에 담았어요.

입력 채널, OpenClaw Gateway와 스크랩 에이전트, 전용 도구, PC 수집과 Quarkdown 출력의 관계를 나눈 아키텍처 설명도

그림 2. 입력 채널, OpenClaw, PC 제작 경로의 역할과 연결입니다. Google Chat은 우선 연결 대상이고 Telegram은 아직 연결하지 않았습니다. read와 write는 원문 분량에 따라 반복됩니다. 처리하지 않은 원문이 남으면 제작을 거부하지만, 이 검사로 해설의 정확성까지 보증하지는 않습니다.

collect를 호출하면 평소 쓰던 브라우저 계정과 분리된 Chrome이 페이지를 엽니다. 펼칠 수 있는 영역을 열고 정해진 범위 안에서 화면을 내려 본문을 확보합니다. 브라우저 자동화에는 Playwright를 사용했습니다. 본문 후보가 뚜렷하지 않을 때는 Mozilla Readability로 본문 추출을 보완합니다.

수집한 내용은 문단, 제목, 표, 코드, 이미지 같은 단위로 나눠 각각 ID를 붙입니다. 긴 문단은 한 번에 읽기 좋은 크기로 나누되, 뒤쪽 문장이 잘리지 않도록 이어 붙였을 때 원문과 같아야 합니다.

read는 이 원문 조각들을 나눠서 모델에 건넵니다. 모델은 한 묶음을 읽고 write로 해설을 저장합니다. 저장할 때는 어떤 원문 ID를 설명했는지도 함께 적습니다. 원문을 읽는 단계와 해설을 저장하는 단계를 나누니 긴 페이지를 한 응답에 억지로 욱여넣지 않아도 됐습니다.

모든 조각을 설명한 뒤 render에 제목, 핵심 정리, 용어 풀이를 전달합니다. 제작기는 저장한 해설과 원문 표, 코드, 확보한 그림을 모아 Quarkdown 문서를 만들고 HTML과 PDF를 출력합니다. 문서 원본도 따로 묶습니다. 나중에 문장을 고치거나 다른 양식으로 다시 만들 때 쓸 수 있도록요.

빠진 문단은 잡을 수 있어도, 잘못 읽은 문장은 남을 수 있어요

원문 누락은 처음부터 신경이 쓰였습니다. 보고서가 그럴듯하게 끝났다고 해서 원문을 끝까지 읽었다고 판단할 수는 없었어요. 읽은 범위와 작성한 범위를 도구가 따로 기록하도록 했습니다.

원문 ID 가운데 조건이 누락된 경우와 모두 대응한 경우를 나란히 비교한 검사 규칙 예시

그림 3. 이해를 돕기 위해 원문 조각 5개로 줄인 예시입니다. 실제 샘플의 블록 수를 나타내는 그림은 아닙니다. ID가 모두 연결돼도 조건과 수치를 제대로 설명했는지는 별도로 읽어봐야 합니다.

예를 들어 원문에 다섯 문단이 있는데 네 문단만 설명했다면 render를 실행할 수 없습니다. 순서를 바꾸거나 같은 ID를 중복해서 처리하는 것도 막았습니다. 원문 문자가 많은데 해설이 지나치게 짧으면 작성 단계에서 거부하는 검사도 추가했어요.

이 장치는 어디까지나 빠진 부분을 찾는 보조 수단입니다. 모델이 다섯 문단의 ID를 모두 적고도 중요한 조건을 잘못 설명할 수 있습니다. 글자 수 기준도 설명의 질을 측정하지 못합니다. 짧아도 정확한 해설을 거부하거나, 길기만 한 설명을 통과시킬 수 있어요.

검수할 때는 원문과 해설을 다시 나란히 읽어야 합니다. 원문 숫자의 단위와 비교 기준이 그대로 있는지, 특정 조건에서만 성립하는 내용을 일반적인 사실처럼 쓰지 않았는지, 원문의 설명과 추가 해설이 구분되는지 확인해야 합니다. 그림을 저장했다는 사실만으로 그림 안의 글자를 전부 읽었다고 볼 수도 없습니다. 이번 구현에는 모든 이미지의 내용을 판독하는 기능까지 넣지는 않았습니다.

수집 자체에도 상한이 있습니다. 현재 구현은 최대 500개 블록, 일반 이미지 30개, SVG와 canvas 도해 12개를 다룹니다. 긴 페이지와 큰 파일은 별도의 제한에 걸릴 수 있습니다. 제한 때문에 확보하지 못한 내용은 보고서에 남기도록 했습니다. ‘전체 수집’이라는 요구를 받았을수록, 읽지 못한 부분을 감추지 않는 쪽이 맞다고 봤어요.

실제 페이지에서는 검색창을 본문으로 골랐습니다

수집기를 실제 문서 사이트에 적용하면서 본문 선택 오류를 만났습니다. 페이지에서 첫 번째 <main> 요소를 고르면 되리라고 생각했는데, 그 자리에 검색 영역이 들어 있었습니다. 실제 본문은 두 번째 <main>에 있었어요.

검색 영역의 첫 main을 고른 수정 전과 본문 후보를 비교하는 수정 후를 코드와 짧은 설명으로 비교한 도해

그림 4. 실제 저장한 HTML에서 확인한 문제를 단순화한 구조도입니다. 사이트 화면을 캡처한 이미지가 아닙니다. 검색 영역의 텍스트는 / 한 글자였고 실제 본문은 다른 main에 있었습니다.

HTML 구조만 보면 수집기는 정상적으로 요소를 찾았습니다. 브라우저도 페이지를 열었고 오류 없이 응답했죠. 그런데 가져온 내용은 본문이 아니었습니다. 성공 여부를 HTTP 응답이나 요소 발견만으로 판단하면 이런 오류를 놓칩니다.

수정 후에는 article, main, role="main" 후보를 모으고, 검색이나 탐색 영역 안에 있는 후보는 제외했습니다. 남은 후보 중 충분한 텍스트가 있는 큰 영역을 고르도록 바꿨어요. 첫 main이 검색 영역인 HTML을 검증용 예시에도 추가했습니다.

같은 공식 문서를 다시 수집했을 때는 본문 18개 블록과 텍스트 1,776자, 본문 안의 연결 주소를 확인했습니다. 이 수치는 그 페이지 한 번의 수집 결과입니다. 모든 사이트에서 정확하게 본문을 고른다는 증거로 확대할 수는 없어요. 댓글이 본문보다 길거나 여러 기사가 한 화면에 있는 사이트라면 다른 규칙이 필요할 수 있습니다.

읽기 쉬움은 프롬프트와 문서 양식 양쪽에 넣었어요

해설의 문체는 에이전트 지침에 넣었습니다. 낯선 용어는 처음 나올 때 짧게 괄호로 설명하고, 긴 설명은 각주로 보냅니다. 한 항목에는 한 가지 뜻을 담되, 이해에 필요한 조건과 근거까지 적도록 했어요. 명사만 끊어 쓰는 개조식은 피했습니다.

배치는 Quarkdown과 CSS에서 정했습니다. 제목과 본문의 크기, 줄 간격, 여백, 표와 코드의 모양을 양식으로 관리합니다. 문서마다 ‘여백을 넉넉하게’, ‘각주를 작게’라고 다시 설명하는 일을 줄이려는 선택이었습니다. Quarkdown의 PDF 출력 안내도 함께 확인했어요.

회색 작업 영역과 흰 창 프레임 안에 실제 수동 샘플 PDF의 세 페이지를 배치한 이미지

그림 5. 공식 PDF 출력 안내를 바탕으로 해설을 수동 작성하고, 실제 제작 도구로 출력한 샘플입니다. 에이전트가 처음부터 끝까지 자동 작성한 결과는 아닙니다. 앞부분 핵심 정리와 본문, 각주, 용어 풀이의 배치를 확인했습니다.

출력도 한 번에 끝나지는 않았습니다. 설치된 Quarkdown 2.6.0에서 페이지 설정 인자를 맞춰야 했고, --pdf로 컴파일했을 때는 HTML이 함께 남지 않아 두 형식을 각각 만들도록 바꿨습니다. 페이지 나눔 CSS 때문에 마지막에 빈 페이지가 생긴 문제도 있었어요. 규칙을 줄이고 다시 출력하니 빈 페이지가 사라졌습니다.

최신 샘플은 3페이지입니다. PDF의 각 페이지를 이미지로 바꿔 한글과 각주, 표, 페이지 경계를 살펴봤고, HTML도 브라우저에서 열어 페이지 나눔을 확인했습니다. 파일이 생성됐는지와 사람이 읽을 만하게 배치됐는지는 따로 확인해야 했습니다.

실제 샘플 PDF 둘째 페이지에서 괄호 용어 설명이 있는 본문과 긴 보충 설명이 있는 각주를 크게 발췌한 이미지

그림 6. 같은 샘플 PDF 둘째 페이지의 본문과 각주를 발췌했습니다. 괄호 용어 설명과 긴 보충 설명을 실제 출력에서 확인한 화면이며, 에이전트가 자동 작성한 결과는 아닙니다.

채널을 늘릴 때 다시 만들지 않을 부분

Google Chat에서 받은 링크와 Telegram에서 받은 링크가 서로 다른 방식으로 수집될 필요는 없습니다. 채널은 요청을 받아 결과를 돌려주는 역할을 맡고, 수집과 문서 제작은 같은 에이전트와 도구가 처리하도록 나눴습니다.

다만 연결 설정 없이 채널이 저절로 추가되는 것은 아닙니다. 현재는 Google Chat을 우선 대상으로 잡았고 Telegram은 아직 연결하지 않았습니다. Google Chat의 기존 어댑터도 텍스트 응답 경로를 사용하고 있어, 파일을 직접 첨부하는 대신 비공개 접속 경로의 보고서 링크를 반환하도록 구현했습니다. 이 링크는 누구나 여는 공개 블로그 주소와 다릅니다.

연결 검증 뒤에 사용할 요청 형태는 다음과 같습니다. 아래는 사용 예시이며 실제 Chat에서 성공한 대화를 옮긴 것은 아닙니다.

스크랩: https://example.com/article
페이지 전체를 원문 순서대로 풀어 써 줘.
어려운 용어는 괄호로 설명하고, 긴 보충 설명은 각주로 넣어 줘.

이 역할에 일반 명령 실행이나 다른 대화 기록 열람 권한까지 주지는 않았습니다. 페이지에서 읽은 명령형 문장은 수집 자료로 취급합니다. 웹페이지 내용이 에이전트의 작업 지침을 바꾸는 일도 막아야 하기 때문이에요. 내부 주소 접근을 제한한 별도 수집 프록시(브라우저 대신 외부 연결을 확인하는 중계 프로그램)도 이 경계 안에 넣었습니다.

첫 실행에서 멈춘 곳과 지금 확인한 범위

로컬 검증을 통과한 뒤 실제 OpenClaw 에이전트를 실행했습니다. 첫 결과는 예상과 달랐어요. 모델이 scrap_report 도구를 찾지 못했습니다. 수집이나 문서 제작까지 진입하지도 못했죠.

플러그인 설정에는 활성화된 것으로 표시됐지만, 실제로 도구를 등록하는 코드가 불리지 않았습니다. 플러그인 선언 파일에 시작 조건과 제공 도구 선언이 빠져 있었습니다. 이 선언을 보완하고 검증을 추가했습니다. 이어서 별도 Gateway 업그레이드가 진행되고 있어 수정본의 최종 연결 검증은 남겨뒀습니다.

소스 검사, 실제 수집, 수동 샘플 출력의 확인 결과와 모델 전체 실행 및 채널 연결의 미완료 범위를 구분한 이미지

그림 7. 소스 검사와 실제 브라우저 수집, 수동 샘플 출력까지 확인했습니다. 에이전트 전체 실행과 실제 Chat 수신은 별도의 미완료 항목입니다. 14개 검사 통과를 서비스 전체의 성공으로 표시하지 않았습니다.

수집과 제작 규칙. Python 7개와 Node 7개 검사를 통과했습니다. 사이트 유형별로 본문을 정확히 수집하는지는 더 확인해야 합니다.

실제 웹페이지. 공식 문서 18개 블록을 수집하고 연결 주소를 보존했습니다. 긴 문서와 다른 구조의 페이지는 추가 확인 대상으로 남겼습니다.

보고서 출력. 수동 해설 샘플을 HTML과 PDF 3페이지로 제작하고 화면을 확인했습니다. 모델이 작성한 해설의 정보 보존과 정확성은 아직 검증하지 못했습니다.

OpenClaw 실행. 전용 에이전트를 등록했고, 첫 도구 발견 실패의 원인을 찾아 수정했습니다. 수정본으로 수집부터 제작까지 마치는 검증이 남았습니다.

입력 채널. Google Chat을 우선 대상으로 구현했습니다. 실제 Chat 결과 수신과 Telegram 연결은 아직 확인하지 못했습니다.

다음 확인에서는 한 번의 요청으로 페이지를 수집하고, 원문을 전부 읽고, 해설을 저장하고, 결과 링크를 여는 과정까지 이어서 볼 예정입니다. 그 과정이 끝나도 해설의 품질은 원문과 대조해야 합니다. 수집 누락, 해설 오류, 출력 오류는 서로 다른 곳에서 생기니까요.

본문 선택 오류 때는 페이지가 열렸다는 확인까지는 맞았습니다. 보고서 샘플도 파일을 만든 뒤에야 빈 페이지를 발견했어요. 확인을 끝냈다고 생각한 지점마다 다음 단계가 남아 있었습니다. 다음에는 실제 에이전트가 이 과정을 끝까지 이어가는지 확인하려 합니다.


자료와 이미지

이 글의 구현 결과와 수치는 2026년 10월 28일의 작업 기록을 기준으로 작성했습니다. 흐름도와 구조도는 구현을 설명하기 위해 직접 만든 도해이며, 보고서 이미지는 실제 Quarkdown 출력 파일에서 만들었습니다. 테스트 중인 내부 주소, 계정과 인증 정보는 포함하지 않았습니다.

기술 설명에는 OpenClaw 에이전트 라우팅, Mozilla Readability, Quarkdown PDF 출력 안내를 참고했습니다. 설치 버전에서 확인한 동작과 최신 공식 안내는 구분해 적었습니다.

#OpenClaw#AI 에이전트#웹 수집#Quarkdown#업무 자동화#개발 기록