AI가 웹페이지를 읽지 못할 때 링크 대신 자료를 준비하는 방법
AI가 웹페이지를 읽지 못했다고 하면 그 페이지를 읽은 것처럼 답을 이어가게 하지 마세요. 링크와 제목을 받았다는 사실만으로 본문을 읽었다고 볼 수는 없습니다.
먼저 본문이 있는지, 검색 요약만 있는지, 일부 문장만 있는지 확인합니다. 필요하면 직접 볼 수 있는 자료에서 필요한 부분을 준비하고, 그 내용만으로 답할 수 있는 질문을 다시 적으세요. 원래 페이지에서 아직 확인하지 못한 내용도 함께 남깁니다.
자료와 답변은 가상 예제입니다. 검사는 제공된 자료 안의 인용문과 답할 수 있는 범위만 확인합니다. 로그인 제한이나 접근 차단을 우회하지 마세요.

읽지 못했다는 말에서 바로 원인을 단정하지 않기
자료가 없을 때는 먼저 관찰한 결과를 적습니다. ‘URL만 전달됨’, ‘제목만 표시됨’, ‘본문 일부만 보임’, ‘실제 오류 문구가 표시됨’은 서로 다른 상태입니다. 원인이 확인되지 않았는데 로그인 필요, 서버 차단, 사이트 장애라고 정해 두지 않습니다.
OpenAI Web search 안내는 웹 검색 결과를 신뢰하지 않은 입력으로 다루고 보고서와 출처를 검토하도록 안내합니다. 검색 결과와 출처 표시가 있어도 내가 필요한 본문의 어느 범위를 실제로 확인했는지 다시 보아야 합니다.
또 ChatGPT Work Overview는 검색, 브라우저, 코드·셸의 네트워크 통제가 서로 구분된다고 설명합니다. 명령 한 개의 접속 실패를 모든 도구의 웹 접근 실패로 확대하거나, 검색이 된다는 이유로 로그인한 브라우저와 같은 자료를 읽었다고 판단하지 않습니다.
이 구분은 제한을 우회하라는 뜻이 아닙니다. 권한 거절이나 보안 경고가 있으면 이를 피해 다른 경로로 접근하지 않습니다. 추가 자료를 쓰려면 필요한 권한을 먼저 확인하고, 현재 자료만으로 끝낼 수 있는 작은 작업은 그 범위 안에서 진행합니다.
네 가상 자료에서 실제로 받은 내용을 고정하기
이번 요청의 목표는 배송 안내와 반품 안내를 비교하는 것입니다. 그러나 비교에 필요한 자료가 모두 들어오지는 않았다는 상황을 가정합니다. 다음 네 자료가 예제의 전부입니다.
S01 / 사용자가 제공한 가상 배송 안내 텍스트
가상 배송 안내 v1
기본 배송비는 3000원이다.
출고 예정일은 접수 다음 영업일이다.
S02 / URL만 제공, 본문 없음
https://example.com/fictional-returns/full
S03 / 직접 작성한 가상 검색 요약, 검색 실행 결과 아님
가상 검색 요약: 전 제품 무료 배송
S04 / 사용자가 제공한 가상 반품 안내 일부
가상 반품 안내 일부
반품 신청은 수령 후 7일 이내 가능하다.
단, [이하 생략]
S01의 v1은 가상 입력의 이름입니다. 원 사이트의 현재 버전이나 갱신일을 실제 확인했다는 뜻이 아닙니다. S02는 설명용 URL일 뿐이며 연결된 페이지의 존재·내용·응답 상태를 시험하지 않았습니다. S03도 검색 화면에서 수집한 문자열이 아닙니다.
S04는 ‘단,’ 뒤의 조건이 빠져 있습니다. 제공된 문장을 인용할 수는 있지만, 예외 없이 반품할 수 있다는 결론으로 넓힐 수 없습니다. 본문을 확보한 자료라도 전체 정책·최신성·적용 대상까지 확인했는지는 별개의 칸으로 남깁니다.
| 자료 ID | 현재 확보 상태 | 지금 가능한 작업 | 아직 근거로 쓸 수 없는 것 |
|---|---|---|---|
| S01 | 제공 텍스트 세 줄 | 받은 세 줄의 정확한 인용 | 원 사이트 전체, 현재 버전·갱신일 |
| S02 | URL만 있음 | 필요한 추가 자료 목록에 URL 기록 | 반품 비용·조건·정책 본문 |
| S03 | 직접 만든 검색 요약 | 본문 확인이 필요한 단서로 보관 | 무료 배송을 확정 사실로 사용 |
| S04 | 반품 안내 일부 | 제공 문장을 한정해서 인용 | 생략된 예외, 전체 정책 결론 |
여기의 ‘확보’는 이 연습에 텍스트가 들어 있다는 뜻입니다. 그 제공문이 실제 업체의 최신·정확한 정책이라는 인증은 아닙니다. 실무에서는 출처 신뢰성, 날짜, 적용 상품을 별도로 확인해야 합니다.
확인 가능한 인용과 보류할 결론을 함께 적기
아래 일곱 후보도 직접 작성했습니다. supported_quote는 받은 글에 해당 문장이 있다는 좁은 판정입니다. 사이트의 정책이 실제로 그렇다는 사실 확인 판정이 아닙니다.
| 후보 | 연결 자료 | 확인하려는 내용 | 이번 판정 |
|---|---|---|---|
| C01 | S01 | 제공문에 ‘기본 배송비는 3000원이다.’가 있음 | 제공문 인용 가능 |
| C02 | S01 | 제공문에 ‘출고 예정일은 접수 다음 영업일이다.’가 있음 | 제공문 인용 가능 |
| C03 | S02 | 모든 반품은 무료라는 전체 정책 | 본문 없음, 보류 |
| C04 | S03 | 검색 요약으로 전 제품 무료 배송 확정 | 본문 근거 없음, 보류 |
| C05 | S04 | 제공문에 ‘반품 신청은 수령 후 7일 이내 가능하다.’가 있음 | 일부 제공문 인용 가능 |
| C06 | S04 | 조건 없이 반품할 수 있다는 전체 정책 | 생략 조건 있음, 보류 |
| C07 | S01 | 2026-10-04에 갱신되었다는 문장 | 제공문에 없음, 보류 |
C02를 ‘다음 영업일에 반드시 출고된다’로 바꾸면 ‘예정’이 사라져 의미가 달라집니다. C05도 제공 문장만 확인한 것이므로 반품 예외를 함께 설명할 수는 없습니다. 인용문이 일치하는지 확인한 뒤 해석이 그 문장보다 넓어지지 않았는지 사람이 검토합니다.
보류 목록은 실패한 답변을 짧게 숨기는 장치가 아닙니다. 어떤 자료가 더 있어야 원래 요청을 끝낼 수 있는지 설명하는 결과물입니다. 이 예제에서는 S02의 본문, S04의 생략된 조건, S01의 확인 가능한 날짜·버전이 필요합니다.
자료 상태와 인용 범위를 실제로 검사하기
다음 코드를 source_scope_check.py로 저장합니다. 네 자료와 일곱 후보가 모두 들어 있으므로 외부 페이지나 파일을 추가로 받을 필요가 없습니다. Python 3의 표준 라이브러리만 사용하며 네트워크 요청을 하지 않습니다.
import json
# All inputs are written fixtures. No fixture URLs are requested.
SOURCES = {
"S01": {"state": "supplied_text", "url": None,
"text": "가상 배송 안내 v1\n기본 배송비는 3000원이다.\n출고 예정일은 접수 다음 영업일이다."},
"S02": {"state": "url_only",
"url": "https://example.com/fictional-returns/full", "text": ""},
"S03": {"state": "written_search_snippet", "url": None,
"text": "가상 검색 요약: 전 제품 무료 배송"},
"S04": {"state": "supplied_excerpt", "url": None,
"text": "가상 반품 안내 일부\n반품 신청은 수령 후 7일 이내 가능하다.\n단, [이하 생략]"},
}
RECORDS = [
("C01", "S01", "provided_text", "기본 배송비는 3000원이다."),
("C02", "S01", "provided_text", "출고 예정일은 접수 다음 영업일이다."),
("C03", "S02", "whole_policy", "모든 반품은 무료다."),
("C04", "S03", "provided_text", "전 제품 무료 배송"),
("C05", "S04", "provided_text", "반품 신청은 수령 후 7일 이내 가능하다."),
("C06", "S04", "whole_policy", "조건 없이 반품할 수 있다."),
("C07", "S01", "provided_text", "2026-10-04에 갱신되었다."),
]
def check(record):
record_id, source_id, scope, quote = record
source = SOURCES[source_id]
if source["state"] not in {"supplied_text", "supplied_excerpt"}:
return "hold", "body_not_supplied"
if scope != "provided_text":
return "hold", "requested_scope_exceeds_supplied_text"
if not quote or quote not in source["text"]:
return "hold", "quote_not_in_supplied_text"
return "supported_quote", "exact_quote_in_supplied_text"
results = {record[0]: list(check(record)) for record in RECORDS}
supported = [key for key, result in results.items() if result[0] == "supported_quote"]
held = [key for key, result in results.items() if result[0] == "hold"]
assert supported == ["C01", "C02", "C05"]
assert held == ["C03", "C04", "C06", "C07"]
assert SOURCES["S02"]["text"] == ""
assert results["C06"][1] == "requested_scope_exceeds_supplied_text"
assert results["C07"][1] == "quote_not_in_supplied_text"
print(json.dumps({"source_records": len(SOURCES),
"supported_quote_ids": supported, "held_record_ids": held,
"fixture_url_requests": 0, "live_ai_requests": 0,
"result": "PASS"}, ensure_ascii=False))
python source_scope_check.py의 직접 실행 출력입니다.
{"source_records": 4, "supported_quote_ids": ["C01", "C02", "C05"], "held_record_ids": ["C03", "C04", "C06", "C07"], "fixture_url_requests": 0, "live_ai_requests": 0, "result": "PASS"}
제공문 인용 세 건이 통과하고, 본문 없는 자료·검색 요약·전체 정책 확대·없는 갱신일 네 건은 보류되었습니다. 코드는 사이트를 읽은 사실을 검사하지 않습니다. 이미 적어 둔 자료 상태와 정확한 부분 문자열만 대조합니다. 제공문 자체가 잘못되었거나 인용을 반대 의미로 해석한 경우는 별도의 사람 검토가 필요합니다.
실제 접근 상태를 unknown에서 성공으로 바꾸려면 본문을 확보한 관찰 근거가 있어야 합니다. 검사 결과를 통과시키려고 S02의 상태만 supplied_text로 바꾸거나 없던 본문을 작성해 넣지 않습니다. 새로운 자료가 들어오면 새 버전의 자료 기록과 다시 검사한 인용 목록을 함께 남깁니다.
새 요청에서는 확보한 범위와 미확인 근거를 먼저 선언하기
‘아까 링크를 다 읽었으니 비교해 달라’는 전제가 잘못되었다면 현재 상태를 다음처럼 다시 적습니다. 아래는 실제 AI에 보낸 요청이 아니라 가상 예제에 사용할 양식입니다.
현재 받은 자료 범위를 정정합니다.
S01: 사용자가 제공한 배송 안내 세 줄
S02: URL만 있고 본문은 없음
S03: 가상 검색 요약이며 확정 근거로 사용하지 않음
S04: 반품 안내 일부이며 예외 조건은 생략됨
S01과 S04의 제공문 안에서 확인할 수 있는 문장만 정확히 인용해 정리하세요.
각 인용에 자료 ID와 확인한 범위를 붙여 주세요.
원 사이트 전체를 읽었다거나 현재 정책이 확정되었다고 쓰지 마세요.
본문 미확보·생략 조건·미확인 갱신일을 별도 목록으로 남기세요.
서로 다른 자료가 충돌하면 한쪽을 임의로 최신이라고 선택하지 마세요.
추가 로그인·권한 변경·외부 전송은 하지 마세요.
이 요청의 기대 결과는 제공문 인용 목록과 미확인 목록입니다. S01의 배송비 3000원과 S03의 무료 배송 요약이 다르더라도, 날짜·조건·본문을 확인하기 전에는 최신 정책이 무엇인지 결정하지 않습니다. 충돌은 자료를 더 확인할 이유로 남깁니다.
그대로 복사할 자료 범위 기록
자료 ID:
자료 이름·URL:
확인 날짜·시간대:
현재 실제 받은 내용: 본문 / 발췌 / 제목·URL만 / 검색 요약 / 없음
획득 방식: 직접 열기 / 사용자가 제공 / 기타
실제 확인한 범위와 위치:
문서 버전·작성일·갱신일: 확인 / 미확인
접근 결과·오류 문구: 실제 관찰한 경우에만
접근하지 못한 이유: 확인한 근거 / 미확인
현재 근거로 쓸 문장과 정확한 위치:
전체 내용에서 아직 확인하지 않은 항목:
범위를 넘는 결론과 보류 이유:
새 요청에서 사용할 자료 ID:
추가 확인에 필요한 자료·권한:
실제 오류를 본 경우에만 문구와 확인 시각을 적습니다. 접근하지 않은 페이지에 ‘403’이나 ‘로그인 필요’를 가상 관찰처럼 채우지 않습니다. 계정명·토큰·개인정보가 오류 기록에 있으면 필요한 범위만 남기고 비밀값은 제거합니다.
자료 일부를 직접 제공할 수 있다면 인용에 필요한 문단과 제목·위치·확인 날짜를 함께 준비합니다. 볼 수 있다는 이유만으로 공유 권한도 있다고 가정하지 않습니다. 유료·비공개 자료나 개인정보가 들어 있는 페이지는 제공 범위를 먼저 확인합니다.
원래 비교를 끝낼 수 있는 시점 정하기
현재 자료만으로 마칠 수 있는 일은 ‘받은 문장을 정리하고 빈 근거를 목록화하는 일’입니다. 사이트 전체의 배송·반품 정책 비교는 필요한 본문과 적용 조건을 확보한 뒤에 할 수 있습니다. 두 결과를 같은 완료 상태로 표시하지 않습니다.
새 자료를 확보하면 출처 ID, 확인 범위, 날짜·버전, 인용문, 적용 조건을 다시 대조합니다. 여전히 읽히지 않는 부분이 있으면 그 부분은 미확인으로 남깁니다. 신뢰할 자료를 얻을 수 없을 때는 결론을 작게 유지하는 것으로 작업을 마무리합니다.
공식 자료와 로컬 합성 검사 확인일은 2026년 10월 4일 KST입니다. Linux의 Python 3.12.14에서 네 자료·일곱 후보를 검사했고, 예제 URL 요청과 실제 AI 요청은 모두 0회입니다. 현재 공식 안내 페이지를 읽은 사실을 가상 사이트 접근 실험이나 과거 게시일의 관찰로 바꾸어 표현하지 않습니다.
긴 문서의 전달 범위를 관리해야 한다면 절 번호와 입력 묶음 위치표 안내를 확인하세요. 이 글의 자료 범위 기록은 전달 묶음보다 앞 단계인 ‘실제로 확보한 근거가 무엇인가’를 정리하는 데 사용합니다.