
AI 에이전트에게 Web 콘텐츠를 읽히기 위한 프롬프트
요약
LLM 에이전트가 웹 페이지에서 필요한 정보를 지정된 JSON 스키마에 맞춰 추출할 수 있도록 돕는 도구 구현 가이드입니다. 정적 HTML과 JavaScript 렌더링 페이지를 모두 지원하며, 에이전트가 즉시 활용 가능한 구조화된 인터페이스를 제공하는 데 중점을 둡니다.
핵심 포인트
- URL과 JSON 스키마를 입력받아 구조화된 데이터를 반환하는 도구 구현
- 정적 HTML 및 JS 렌더링 페이지 자동 판정 및 대응
- LangChain, LlamaIndex 등 에이전트 프레임워크와 즉시 연동 가능한 설계
- 성공/실패 여부를 포함한 일관된 JSON 응답 구조 보장
당신은 LLM 에이전트용 도구 개발에 정통한 프린시펄 Python 아키텍트 겸 구현 엔지니어입니다.
목적:
URL과 추출 스키마(Schema)를 받아 Web 페이지에서 필요한 정보를 수집하고, 지정된 스키마에 따른 JSON을 반환하는 「에이전트 등록 가능한 Web 데이터 추출 도구」를 구현, 도입, 검증, 개선까지 완료해 주세요.
중요:
이것은 사양서나 설계안을 만드는 태스크가 아닙니다.
실행 가능한 파일 일체를 작성하고, 가능한 한 실제로 동작 확인을 하며, 결함이 있다면 수정해 주세요.
의사 코드(Pseudo-code), TODO만 남기기, 개념 설명만 하는 구현은 금지합니다.
실행 환경에서 파일 생성 및 명령 실행이 가능한 경우:
- 실제로 파일을 생성해 주세요.
- 의존성(Dependency)을 확인해 주세요.
- 테스트를 실행해 주세요.
- 에러가 발생하면 원인을 분석하여 코드를 수정하고 재테스트해 주세요.
- 최종 답변에는 작성한 파일, 실행한 명령, 테스트 결과, 알려진 제약 사항을 정리해 주세요.
실행 환경에서 파일 생성 및 명령 실행이 불가능한 경우:
- 해당 제약을 명시한 후, 복사해서 바로 사용할 수 있는 완전한 파일 내용을 출력해 주세요.
- 검증되지 않은 부분은 「미검증」이라고 명시해 주세요.
- 단, 구현 내용은 실제 도입을 상정할 정도의 완성도를 갖춰야 합니다.
작성할 성과물:
- requirements.txt
- web_scraper_tool.py
- test_web_scraper_tool.py
- agent_registration_examples.py
- README.md
도구의 목적:
LLM 에이전트가 다음과 같은 상황에서 호출할 수 있는 Web 정보 수집 도구를 구현하는 것.
- 지정된 URL에서 상품 정보, 회사 정보, 기사 정보, 채용 정보, 가격 정보, 표(Table) 데이터, 프로필 정보 등을 추출한다.
- 정적 HTML 페이지와 JavaScript 렌더링 페이지 모두에 대응한다.
- 추출 결과를 임의의 JSON Schema에 따라 구조화한다.
- 성공 시에도 실패 시에도 에이전트가 다음 행동을 판단할 수 있는 JSON 문자열을 반환한다.
공개 인터페이스:
메인 함수는 다음과 같이 작성해 주세요.
def extract_web_data(
url: str,
extraction_schema: str,
...
필수 사양:
url은 대상 페이지 URL
extraction_schema는 JSON Schema 문자열 또는 Pydantic 모델 정의에 해당하는 문자열 표현
- 반환값은 항상 JSON 문자열
- 예외(Exception)를 외부에 raise하지 않는다.
- 성공·실패 여부와 상관없이 호출 측 에이전트가 해석할 수 있는 구조화된 JSON을 반환한다.
- LangChain, LlamaIndex, Dify, 자체 에이전트에 그대로 등록하기 쉬운 함수로 만든다.
- 상세한 Docstring을 반드시 작성한다.
- Docstring에는 도구의 용도, 사용 타이밍, 인자(Argument), 반환값, 실패 시 반환 형식, 제약 사항을 명시한다.
반환 JSON의 기본 형식:
{
"success": true,
"data": {},
...
실패 시 형식:
{
"success": false,
"data": null,
...
처리 아키텍처:
다음의 3계층 파이프라인을 구현해 주세요.
제1층: 정적 취득 (Static Acquisition)
- httpx를 사용하여 고속으로 HTML을 취득한다.
- 타임아웃, 리다이렉트, 상태 코드(Status Code), Content-Type을 처리한다.
- 잘못된 URL, 비(非) HTML, 404, 403, 5xx를 적절히 다룬다.
- JavaScript 렌더링이 필요한지 자동으로 판정한다.
- 판정에는 HTML 본문량, script 비율, noscript, 주요 본문의 결여, SPA(Single Page Application) 특성, 빈 root 요소, 메타 정보 등을 이용한다.
- 정적 취득만으로 충분한 본문을 얻은 경우에는 Playwright를 사용하지 않는다.
제2층: 동적 취득 (Dynamic Acquisition)
- 정적 취득이 불충분한 경우, 또는
prefer_dynamic=True인 경우에만 Playwright async API를 사용한다. 이미지, 폰트, 미디어, 불필요한 트래킹 관련 리소스를 가능한 범위 내에서 차단한다. - DOMContentLoaded 또는 networkidle을 적절히 사용한다.
- 타임아웃, 네비게이션 실패, 브라우저 실행 실패를 포착한다.
- Playwright의 browser/context/page는 반드시 해제한다.
- CAPTCHA 회피, 로그인 돌파, 액세스 제한 돌파, 인증 회피는 구현하지 않는다.
제3층: 구조화 추출 (Structured Extraction)
- LiteLLM을 사용하여 OpenAI 호환 모델로 추출한다
model이 지정되지 않은 경우 환경 변수WEB_SCRAPER_LLM_MODEL에서 가져온다- 설정되지 않은 경우 안전한 기본값(default)을 사용한다
- API 키는 환경 변수로 처리한다
- HTML 전체를 그대로 LLM에 전달하지 않는다
- BeautifulSoup, trafilatura, readability 등을 사용하여 본문, 제목, 메타 정보, 주요 텍스트를 추출한다
- 너무 긴 본문은
max_chars내로 제한한다 - LLM에는 반드시 JSON만을 반환하도록 지시한다
- LLM 출력이 JSON으로서 손상된 경우, 가능한 범위 내에서 복구한다
- JSON Schema로 검증할 수 있는 경우 검증한다
- 검증 실패 시, 실패 이유와 재시도 가능 여부를 JSON으로 반환한다
입력 검증:
- URL 형식을 검증한다
- http/https 이외의 스킴(scheme)은 거부한다
localhost, 프라이빗 IP, 링크 로컬(link-local) IP 등으로의 액세스는 SSRF 방지 대책으로서 기본적으로 거부한다extraction_schema가 비어 있는 경우 에러를 반환한다- 스키마가 JSON으로 해석 가능한 경우 JSON Schema로 취급한다
- JSON이 아닌 경우, 자연어 또는 Pydantic 스타일의 스키마 기술로 취급하되 그 내용을 metadata에 기록한다
robots.txt와 윤리:
respect_robots=True인 경우 robots.txt를 확인한다- robots.txt에서 금지된 경우 액세스하지 않고, 이유를 JSON으로 반환한다
- 속도 제한(rate limit), 이용 약관, 사이트 소유자의 의도를 존중한다
- CAPTCHA 회피, 로그인 회피, 차단 회피, 핑거프린트(fingerprint) 위조, 프록시 로테이션은 구현하지 않는다
- 사용자 에이전트(User-Agent)는 명시적으로 설정할 수 있도록 한다
동기·비동기 설계:
- 공개 함수
extract_web_data는 동기 함수로 호출할 수 있도록 한다 - 내부에서는 async 처리를 안전하게 다룬다
- 기존 이벤트 루프(event loop)가 존재하는 환경에서도 안정적으로 동작하는 구현을 만든다
- 필요하다면 내부에 async 함수를 분리한다
로그:
- 표준 logging을 사용한다
- API 키, 인증 정보, 개인 정보를 로그에 남기지 않는다
- 에이전트가 판단할 수 있는 정보는 반환값인 metadata에 포함한다
requirements.txt:
다음 용도에 필요한 패키지를 포함한다.
- httpx
- playwright
- beautifulsoup4
- trafilatura 또는 readability-lxml
- litellm
- jsonschema
- pydantic
- pytest
- pytest-asyncio
- respx 또는 pytest-httpx
- 기타 필요한 것들
web_scraper_tool.py:
- 단독으로 import 가능하게 한다
extract_web_data를 공개한다- 필요한 보조 함수를 포함한다
- 타입 힌트(type hint)를 부여한다
- 예외를 무시(swallow)하는 것이 아니라, 구조화하여 반환한다
- 리소스 해제를 철저히 한다
- 프로덕션 환경에서 사용할 수 있을 정도의 견고함을 갖춘다
test_web_scraper_tool.py:
최소한 다음 테스트를 포함한다.
- 정상적인 정적 HTML 페이지
- JavaScript 렌더링이 필요하다고 판단되는 HTML
- 잘못된 URL
- http/https 이외의 URL
- 404
- 403
- 타임아웃
- robots.txt에서 금지된 URL
- 빈 extraction_schema
- JSON Schema 검증 실패
- LLM 추출 실패
- 실패 시에도 JSON 문자열이 반환될 것
- 반환값에
success,data,error,metadata가 반드시 포함될 것
테스트에서는 외부 사이트에 대한 의존성을 최소화하십시오.
httpx 모킹(mock), Playwright 모킹, LiteLLM 모킹을 활용하십시오.
외부 네트워크에 의존하는 테스트를 만드는 경우에는 명시적으로 통합 테스트(integration test)로 분리하십시오.
agent_registration_examples.py:
다음 등록 예시를 포함하십시오.
- LangChain Tool로서의 등록 예시
- LlamaIndex FunctionTool로서의 등록 예시
- 독자적인 에이전트 함수 레지스트리(registry)에 대한 등록 예시
- Dify 등에서 사용할 경우의 설명 또는 래퍼(wrapper) 예시
README.md:
다음 내용을 포함하십시오.
- 개요
- 설치 절차
- Playwright 브라우저 도입 명령
- 환경 변수 설정 예시
- 기본적인 사용법
- 샘플 URL 및 샘플 스키마
- 성공 시 출력 예시
- 실패 시 출력 예시
- 에이전트 등록 예시
- 테스트 실행 방법
- 알려진 제약 사항
- 보안 및 윤리상의 주의 사항
- 운영 환경 적용 시 권장 설정
품질 게이트 (Quality Gate):
구현 후, 다음 사항을 자체 리뷰하고 문제가 있다면 수정하십시오.
- 공개 함수가 지정된 인터페이스를 충족하는가
- 반환값이 항상 JSON 문자열인가
- 실패 시 raise 하지 않고, 구조화된 에러를 반환하는가
- Docstring만으로 에이전트가 사용 여부를 판단할 수 있는가
- 정적 가져오기 (Static Fetching)와 동적 가져오기 (Dynamic Fetching)의 전환이 명확한가
- Playwright 리소스가 반드시 해제되는가
- LLM 출력의 JSON 검증 및 복구 (Repair)가 구현되어 있는가
- API 키나 비밀 정보가 코드나 로그에 노출되지 않는가
- SSRF (Server-Side Request Forgery) 대책이 있는가
- robots.txt를 존중하는 설계로 되어 있는가
- 테스트가 주요 정상 케이스 및 이상 케이스를 커버하는가
- LangChain/LlamaIndex/자체 구현에 등록하기 용이한가
- README를 보면 도입, 실행, 테스트가 가능한가
- 미구현된 TODO나 의사 코드 (Pseudo-code)가 남아 있지 않은가
수정 루프 (Correction Loop):
- 테스트 또는 자체 리뷰에서 문제를 발견한 경우, 원인을 간결하게 설명하고 코드를 수정하십시오.
- 수정 후 다시 테스트 또는 리뷰를 수행하십시오.
- 가능한 한, 최종 상태가 "즉시 도입 가능"한 상태가 될 때까지 반복하십시오.
최종 답변 형식:
다음 순서로 출력하십시오.
- 작성한 파일 목록
requirements.txt
web_scraper_tool.py
test_web_scraper_tool.py
agent_registration_examples.py
README.md
- 실행한 명령
- 테스트 결과
- 품질 게이트 확인 결과
- 알려진 제약 사항 및 향후 개선 여지
출력 규칙:
- 파일 내용은 복사 가능한 완전한 버전으로 출력한다.
- 사양 설명만으로 끝내지 않는다.
- 생략하지 않는다.
- "여기에 구현을 작성합니다"와 같은 플레이스홀더는 금지한다.
- 실행하지 못한 작업이 있는 경우, 이유와 영향 범위를 명시한다.
- 불확실한 점은 명시한다.
- 보안, 윤리, 운영 제약을 경시하지 않는다.
Discussion

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