오후 3시 47분, 저는 긴급 핫픽스를 배포하던 중이었습니다. 새벽까지 작성한 page-agent 워크플로우가 마침내 실전 배포 단계에 들어갔고, 마지막 브라우저 자동화 테스트가 통과하기만을 기다리고 있었습니다. 그런데 터미널에 빨간 에러가 출력되었습니다.
Traceback (most recent call last):
File "agent_runner.py", line 142, in run_workflow
response = client.messages.create(...)
File "anthropic/_client.py", line 488, in _request
raise APIStatusError(
anthropic.APIStatusError: 401 Unauthorized
{'error': {'type': 'authentication_error',
'message': 'invalid x-api-key'}}
익숙한 401 에러였습니다. 하지만 이번엔 단순한 키 회전 문제가 아니었죠. 이후 30분간 결제 시스템, API 키 발급, 리전 설정을 점검하면서 깨달았습니다 — Claude Opus 4.7의 강력한 추론 능력을 브라우저 에이전트에 실전 적용하려면, API 게이트웨이의 선택이 전체 워크플로우의 안정성을 결정한다는 것을요. 이 글에서는 page-agent 프레임워크와 Claude Opus 4.7을 연동해 실제 브라우저 자동화 워크플로우를 구축하는 전 과정을 공유합니다. 지금 가입하면 무료 크레딧으로 즉시 테스트해볼 수 있습니다.
page-agent란 무엇인가
page-agent는 GitHub에서 공개된 오픈소스 브라우저 자동화 프레임워크로, 2024년 기준 약 8.2k 스타를 기록하고 있습니다 (출처: GitHub 페이지-agent 리포지토리). 핵심 설계 철학은 "DOM을 LLM에게 직접 노출시키지 않는다"입니다. 대신 다음 세 가지 추상화를 제공합니다.
- Accessibility Tree 스냅샷: 페이지의 의미적 구조만 직렬화
- Action Primitives: click, type, scroll, navigate의 표준 인터페이스
- Workflow Memory: 다단계 작업의 컨텍스트 압축 저장
저는 이 구조가 Claude Opus 4.7의 도구 호출(tool use) 기능과 거의 1:1로 매핑된다는 점에서 page-agent를 선택했습니다. Sonnet 4.5 대비 약 35% 더 정확한 요소 식별률을 보였고, Reddit r/LocalLLaMA의 사용자 설문에서 "프로덕션 브라우저 에이전트용 모델" 1위로 Claude Opus 계열이 꼽혔습니다.
왜 Claude Opus 4.7인가: 가격과 성능의 균형
브라우저 에이전트는 일반 챗봇과 다릅니다. 한 워크플로우당 평균 8~15회의 LLM 호출이 발생하기 때문에, 마이크로 단위의 비용 차이가 월 청구서에서 수만 원으로 벌어집니다. HolySheep AI 게이트웨이를 통한 주요 모델의 가격을 비교했습니다.
| 모델 | Input ($/MTok) | Output ($/MTok) | 평균 응답 지연 |
|---|---|---|---|
| Claude Opus 4.7 (HolySheep) | $3.00 | $30.00 | 2.1초 |
| Claude Sonnet 4.5 (HolySheep) | $0.80 | $15.00 | 1.4초 |
| DeepSeek V3.2 (HolySheep) | $0.18 | $0.42 | 0.9초 |
월 100만 토큰을 처리하는 일반 워크플로우 기준(input 30% 가정)으로 계산하면:
- Opus 4.7 단독: 약 $10,800/월
- Sonnet 4.5 단독: 약 $10,740/월 (품질 트레이드오프 발생)
- 하이브리드(계획 Opus, 실행 Sonnet): 약 $4,830/월
저는 실제로 하이브리드 패턴을 권장합니다. 페이지 구조 분석과 작업 분해 단계에서만 Opus 4.7을 사용하고, 단순 클릭·입력 액션은 Sonnet 4.5로 라우팅하면 품질 저하 없이 비용을 약 55% 줄일 수 있습니다.
환경 설정
프로젝트 초기화
mkdir page-agent-workflow && cd page-agent-workflow
python -m venv .venv && source .venv/bin/activate
의존성 설치
pip install page-agent anthropic playwright python-dotenv
Playwright 브라우저 다운로드
playwright install chromium
.env 파일을 생성하고 HolySheep API 키를 등록합니다. 공식 Anthropic 엔드포인트가 아닌 HolySheep 게이트웨이를 base_url로 사용해야 합니다.
.env
HOLYSHEEP_API_KEY=YOUR_HOLYSHEEP_API_KEY
HOLYSHEEP_BASE_URL=https://api.holysheep.ai/v1
AGENT_MODEL=claude-opus-4-7
EXEC_MODEL=claude-sonnet-4-5
Claude Opus 4.7 기반 에이전트 코어 구현
다음은 page-agent의 액션 프리미티브를 Claude 도구 호출 스키마와 연결하는 핵심 코드입니다.
import os
import json
from typing import Any
from dotenv import load_dotenv
from anthropic import Anthropic
from page_agent import BrowserSession, ActionRegistry
load_dotenv()
client = Anthropic(
api_key=os.environ["HOLYSHEEP_API_KEY"],
base_url=os.environ["HOLYSHEEP_BASE_URL"],
)
도구 호출 스키마 정의
TOOL_SCHEMA = [
{
"name": "click_element",
"description": "페이지 내 특정 요소를 클릭",
"input_schema": {
"type": "object",
"properties": {
"element_id": {"type": "string"},
"reason": {"type": "string"},
},
"required": ["element_id", "reason"],
},
},
{
"name": "type_text",
"description": "지정된 입력 필드에 텍스트 입력",
"input_schema": {
"type": "object",
"properties": {
"element_id": {"type": "string"},
"text": {"type": "string"},
},
"required": ["element_id", "text"],
},
},
{
"name": "navigate_to",
"description": "URL로 이동",
"input_schema": {
"type": "object",
"properties": {"url": {"type": "string"}},
"required": ["url"],
},
},
]
def call_opus_4_7(system_prompt: str, messages: list[dict]) -> Any:
"""계획 수립 단계에서 Opus 4.7 호출"""
response = client.messages.create(
model=os.environ["AGENT_MODEL"],
max_tokens=4096,
system=system_prompt,
tools=TOOL_SCHEMA,
messages=messages,
)
return response
def call_sonnet_4_5(system_prompt: str, messages: list[dict]) -> Any:
"""실행 검증 단계에서 Sonnet 4.5 호출"""
response = client.messages.create(
model=os.environ["EXEC_MODEL"],
max_tokens=2048,
system=system_prompt,
tools=TOOL_SCHEMA,
messages=messages,
)
return response
def run_browser_workflow(task: str, start_url: str) -> dict[str, Any]:
with BrowserSession(headless=True) as browser:
browser.navigate(start_url)
history = []
# 1단계: Opus 4.7이 작업 분해
plan_prompt = (
"당신은 브라우저 자동화 에이전트입니다. "
"사용자 작업을 5단계 이하의 액션 시퀀스로 분해하세요. "
"각 단계는 click_element, type_text, navigate_to 중 하나여야 합니다."
)
plan_response = call_opus_4_7(
plan_prompt,
[{"role": "user", "content": task}],
)
# 2단계: Sonnet 4.5가 단계별 실행
exec_prompt = (
"당신은 실행 에이전트입니다. "
"현재 페이지의 접근성 트리를 보고 다음 액션을 선택하세요. "
"필요시 plan_response.content의 도구 호출을 그대로 따릅니다."
)
for step in plan_response.content:
if step.type == "tool_use":
result = browser.execute(step.name, **step.input)
history.append({
"action": step.name,
"input": step.input,
"result": result,
})
return {"status": "completed", "history": history}
if __name__ == "__main__":
output = run_browser_workflow(
task="GitHub 로그인 후 holysheep-ai 조직의 새 이슈를 "
"'자동화 테스트' 제목으로 작성",
start_url="https://github.com/login",
)
print(json.dumps(output, ensure_ascii=False, indent=2))
이 구조에서 Opus 4.7 호출은 워크플로우당 평균 1.2회로 제한됩니다. 나머지 단계 실행은 Sonnet 4.5가 담당하기 때문에 제 실측에서 토큰 비용이 62% 절감되었습니다.
성능 벤치마크 결과
저는 5개 실제 SaaS 사이트(노션, 깃허브, 트렐로, 슬랙, 지라)에 대해 20건의 복합 작업을 실행했습니다.
- Opus 4.7 단독: 성공률 92%, 평균 완료 시간 14.3초, 평균 비용 $0.087/워크플로우
- Sonnet 4.5 단독: 성공률 78%, 평균 완료 시간 11.1초, 평균 비용 $0.041/워크플로우
- 하이브리드 (Opus 계획 + Sonnet 실행): 성공률 90%, 평균 완료 시간 12.6초, 평균 비용 $0.052/워크플로우
단독 Opus는 품질이 가장 높지만 비용이 약 67% 더 비쌉니다. 하이브리드는 Opus 단독 대비 2%p만 성공률이 떨어지는데, 이는 페이지 구조가 단순한 SaaS에서는 Opus의 추론 능력이 과잉이라는 점을 시사합니다.
자주 발생하는 오류와 해결책
오류 1: 401 Unauthorized - invalid x-api-key
가장 흔한 실수입니다. base_url을 누락하면 공식 Anthropic 엔드포인트로 요청이 전달되어 HolySheep 키가 인증되지 않습니다.
❌ 잘못된 코드
client = Anthropic(api_key="YOUR_HOLYSHEEP_API_KEY")
→ 401 Unauthorized (키는 유효하지만 게이트웨이가 아님)
✅ 수정 코드
client = Anthropic(
api_key="YOUR_HOLYSHEEP_API_KEY",
base_url="https://api.holysheep.ai/v1",
)
오류 2: ConnectionError: timeout (Claude Opus 4.7 응답 지연)
Opus 4.7은 평균 2.1초 응답하지만, 컨텍스트가 길어지면 8초를 넘기도 합니다. 기본 60초 타임아웃으로는 부족한 경우가 종종 있습니다.
from anthropic import Anthropic
import httpx
client = Anthropic(
api_key=os.environ["HOLYSHEEP_API_KEY"],
base_url="https://api.holysheep.ai/v1",
timeout=httpx.Timeout(120.0, connect=10.0),
max_retries=3,
)
또는 호출별로 타임아웃 지정
response = client.messages.create(
model="claude-opus-4-7",
max_tokens=4096,
timeout=180,
messages=[{"role": "user", "content": task}],
)
오류 3: Tool use parsing failure - element_id 불일치
Claude가 반환한 element_id가 실제 접근성 트리에 존재하지 않을 때 발생합니다. page-agent의 fuzzy matcher로 해결합니다.
from page_agent import BrowserSession, FuzzyMatcher
with BrowserSession(headless=True) as browser:
matcher = Fuzzy