메뉴
HN
Hacker News • 9일 전

Jev Ultrafast: 동적 인덱스 기반 액션 공간을 가진 브라우저 에이전트

IMP
6/10
핵심 요약

TypeSafe의 Jev는 동적·인덱싱된 액션 공간을 활용해 브라우저 자동화를 수행하는 에이전트로, 하나의 목표만 주면 작업(operation)과 대상 요소(element)를 선택합니다. 취리히→런던 항공권 검색을 텍스트 생성과 로딩 대기 시간까지 포함해 7.1초 만에 완료했습니다. 사이트별 스크립트 없이 구조화된 상태만 사용해 빠르고 범용적인 브라우저 자동화가 가능하다는 점이 핵심입니다.

번역된 본문

Jev Ultrafast ⚡ 동적·인덱싱된 액션 공간(dynamic, indexed action space)을 가진 브라우저 에이전트입니다. 목표 하나만 주면 TypeSafe의 Jev가 작업(operation)과 요소(element)를 선택합니다. 작은 LLM은 작업이 TYPE_TEXT일 때만 텍스트를 생성합니다. 구글 항공권(Google Flights)에서 취리히→런던 검색이 7.1초 만에 완료됩니다. 자연어 목표 하나, 실제 텍스트 생성, 로딩 대기 시간까지 모두 포함된 시간입니다. MP4 영상 · 측정 결과 · 루프 과정 확인 가능합니다.

액션 공간 매 관찰(observation)마다 새로운 요소 테이블이 생성됩니다: [1] button 티켓 종류 변경 · 왕복 [2] combobox 출발지는? · 샌프란시스코 [3] combobox 도착지는? · 비어 있음 [4] textbox 출발일 · 비어 있음 ... 작업 종류는 CLICK, TYPE_TEXT, SELECT, SCROLL_UP, SCROLL_DOWN, WAIT, DONE, BLOCKED입니다. 지원되는 작업과 대상만 제공됩니다.

하나의 TypeSafe 요청: 페이지 → 요소 테이블 → 작업, click_target, type_text_target, select_target(있는 경우)이 함께 출력되고, 해당하는 타깃이 브라우저로 전달됩니다. CLICK [7] 또는 TYPE_TEXT [3]처럼 사용되며, TYPE_TEXT의 경우 작은 LLM이 텍스트를 생성해 브라우저로 전달합니다.

타깃 질문들은 가상의 것입니다. 작업이 CLICK이면 click_target만 실행될 수 있습니다. 두 가지 결정이 네트워크 왕복 한 번으로 이루어집니다. 각 타깃 헤드에는 호환되는 요소만 포함됩니다. 네이티브 드롭다운 선택 항목은 관찰된 요소/옵션 인덱스를 가집니다. 정책(policy)에는 사이트별 액션 스크립트나 미리 준비된 필드 문자열이 없습니다. 항공권 예시는 목표를 제공하고 결과를 독립적으로 검증합니다. 스크린샷 렌더러는 나중에 라벨을 추가할 뿐이며 브라우저를 구동하지 않습니다.

사용해 보기 git clone https://github.com/browser-use/jev-ultrafast.git cd jev-ultrafast uv sync cp .env.example .env # TYPESAFE_API_KEY와 TEXT_MODEL_API_KEY를 추가하세요. uv run jev http://127.0.0.1.8766 을 열고 Start demo → Run automatically를 클릭하세요. 인스펙터는 번호가 매겨진 요소, 작업 확률, 타깃 확률, 실행된 액션을 보여줍니다. Choose next를 선택하면 실행 전에 일시정지됩니다.

Chrome은 uv sync로 설치되는 Browser Harness를 통해 연결됩니다. 연결이 필요하면 uv run browser-harness --doctor를 실행하세요. 메시지가 표시되면 Chrome에서 원격 디버깅을 허용하세요. TEXT_MODEL_API_KEY는 예제 설정에서 OpenRouter 키입니다. 현재 데모는 추론(reasoning)을 비활성화한 inception/mercury-2.5를 사용합니다. Gemini, GLM, DeepSeek도 OpenAI 호환 텍스트 헬퍼를 사용할 수 있으며, 적절한 모델, 엔드포인트, 추론 설정을 구성하면 됩니다.

라이브러리 사용법 from jev_ultrafast import Agent

with Agent( "https://www.google.com/travel/flights?hl=en", "2026년 9월 20일 취리히에서 런던까지, 성인 1명, 이코노미 편도 항공권을 찾으세요. " "일치하는 항공편 옵션이 보이면 중지하세요.", ) as agent: for state in agent.run(): print(state["elapsed_ms"], state["status"])

uv run --env-file .env python your_script.py 로 실행하세요. 같은 정책으로 다른 작업도 실행할 수 있습니다: uv run --env-file .env python examples/run.py --url https://en.wikipedia.org/wiki/Main_Page --goal '괴델의 불완전성 정리에 관한 위키백과 문서를 찾아 여세요.'

uv run --env-file .env python examples/flights.py --keep-open 은 항공권 검색을 수행하고, 실제 노선/날짜/결과를 확인하며, 실행 기록(trace)을 저장합니다. 항공편을 선택하거나 예약하지는 않습니다.

빠른 이유 결정 주기당 요청 한 번: 작업 헤드와 타깃 헤드가 같은 관찰 상태를 공유합니다. 기본 에이전트 루프에서 스크린샷 없음: Jev는 구조화된 상태를 소비합니다. 인스펙터에서만 스크린샷을 옵트인하며, 영상은 별도의 연속 스크린캐스트를 사용합니다. 스냅샷당 브라우저 호출 한 번: 보이는 컨트롤과 그 이름, 값, 텍스트를 원자적으로(atomically) 읽습니다. 실제 DOM 노드에 대한 참조를 유지합니다. 선택된 타깃 검증: 클릭은 문서, 폼 값, 타깃, 주변 컨텍스트를 확인합니다. 애니메이션만으로는 새로운 예측을 강제하지 않습니다. 입력 전 기하 구조 확인: 현재 기하 정보를 확인하고 가려진 컨트롤은 거부합니다. 유용한 상태 대기: 콤보박스에 입력한 후에는 보이는 추천 항목을 최대 200ms까지 기다립니다. 다른 상호작용은 최대 두 개의 애니메이션 프레임 또는 50ms를 받습니다. 이러한 읽기는 실행이 기록된 후에 이루어집니다.

원문 보기
원문 보기 (영어)
Jev Ultrafast ⚡ A browser agent with a dynamic, indexed action space. Give it one goal. TypeSafe's Jev picks an operation and an element. A small LLM writes text only when the operation is TYPE_TEXT . Zürich → London on Google Flights in 7.1 seconds. One natural-language goal, actual text generation, and loading waits included. Watch the MP4 · Measurements · Read the loop The action space Every observation produces a new element table: [1] button Change ticket type · Round trip [2] combobox Where from? · San Francisco [3] combobox Where to? · empty [4] textbox Departure · empty ... The operations are CLICK , TYPE_TEXT , SELECT , SCROLL_UP , SCROLL_DOWN , WAIT , DONE , and BLOCKED . Only supported operations and targets are offered. one TypeSafe request ┌───────────────────────────┐ page → element table → operation │ │ click_target │ │ type_text_target │ │ select_target, if present │ └─────────────┬─────────────┘ use the matching target │ CLICK [7] ─────┤──→ browser TYPE_TEXT [3] ─────┘ ↓ small LLM → text → browser Target questions are speculative. If the operation is CLICK , only click_target can execute. Two decisions, one network round trip . Each target head contains only compatible elements. Native dropdown choices carry an observed element/option index. There are no site-specific action scripts or prepared field strings in the policy. The Flights example supplies a goal and independently verifies the outcome. The screenshot renderer adds labels afterward; it does not drive the browser. Try it git clone https://github.com/browser-use/jev-ultrafast.git cd jev-ultrafast uv sync cp .env.example .env # Add TYPESAFE_API_KEY and TEXT_MODEL_API_KEY. uv run jev Open http://127.0.0.1:8766 and click Start demo → Run automatically . The inspector shows numbered elements, operation probabilities, target probabilities, and executed actions. Choose next pauses before execution. Chrome connects through Browser Harness , installed by uv sync . Run uv run browser-harness --doctor if it needs connecting. Allow remote debugging in Chrome when prompted. TEXT_MODEL_API_KEY is an OpenRouter key in the example configuration. The current demo uses inception/mercury-2.5 with reasoning disabled. Gemini, GLM, and DeepSeek can also use the OpenAI-compatible text helper; configure the appropriate model, endpoint, and reasoning setting. Use the library from jev_ultrafast import Agent with Agent ( "https://www.google.com/travel/flights?hl=en" , "Find one-way flights from Zurich to London on September 20, 2026, " "for one adult in economy. Stop when matching flight options are visible." , ) as agent : for state in agent . run (): print ( state [ "elapsed_ms" ], state [ "status" ]) Run with uv run --env-file .env python your_script.py . The same policy can run a different task: uv run --env-file .env python examples/run.py \ --url https://en.wikipedia.org/wiki/Main_Page \ --goal ' Find and open the Wikipedia article about Gödel’s incompleteness theorems. ' uv run --env-file .env python examples/flights.py --keep-open performs the flight search, checks the actual route/date/results, and saves its trace. It does not select or book a flight. Why it moves One request per decision cycle. Operation and target heads share the same observed state. No screenshots in the default agent loop. Jev consumes structured state. The inspector opts into screenshots; the video uses a separate continuous screencast. One browser call per snapshot. Read visible controls, their names, values, and text atomically. Keep references to the actual DOM nodes. Validate the selected target. Clicks check the document, form values, target, and nearby context. Animation alone does not force another prediction. Resolve current geometry and reject covered controls before input. Wait for useful state. After typing into a combobox, wait for visible suggestions, capped at 200 ms. Other interactions get at most two animation frames or 50 ms. These reads happen after execution is logged. Keep hidden tabs rendering. Focus emulation prevents background animation throttling without switching Chrome's visible tab. Send visible text. Offscreen article bodies and footers do not fill the model context. Reuse an interrupted text request. A generated value survives a stale-page retry only if the entire text-helper input is unchanged. Every executed target is resolved from an observed node. The executor rechecks page freshness and click occlusion. Model output never becomes selectors, coordinates, shell commands, or executable JavaScript. Text-helper output must parse as a small JSON object before typing. Small enough to read File Job agent.py The complete loop and text-helper handoff snapshot.js Atomic DOM snapshot, indexed controls, freshness guards browser.py Browser connection, current geometry, execution model.py Dynamic operation/target heads and text generation questions.py Model instructions demo.py Local inspector Evidence and limits The current video is a 7,073 ms Google Flights run. Timing starts after initial page observation and includes model calls, generated text, browser work, stale decisions, and loading waits. A fresh independent check verifies the one-way setting, Zürich, London, September 20, 2026, and visible flight options. The video plays at 1×, with no opening hold and a 0.5-second final hold. In six alternating runs with identical models and settings, both versions passed 3/3 . Median task time went from 9.450 s → 7.092 s , a 25% reduction ; median browser protocol calls went from 1,092 → 101 . This is three repeats of one task on one browser profile, not a general reliability benchmark. The same policy opened the requested Wikipedia article in 2.798 s and passed a local hotel search/filter task in 1.896 s . Runs, failures, source hashes, and measurement boundaries are in performance.md . A DONE choice still requires independent outcome verification. The DOM reader handles common HTML and ARIA controls, not the full accessible-name specification. Shadow roots, frames, canvas, uploads, pop-up tabs, nested scrolling, and arbitrary keyboard widgets remain outside this MVP. Owned tabs share the existing Chrome profile. Development uv run ruff check . uv run pytest node --check jev_ultrafast/static/app.js node --check jev_ultrafast/snapshot.js uv build Tests are offline. uv run python scripts/check_guards.py checks real controls in a local browser without model calls. Live examples and recording scripts make paid API calls. scripts/record_flights.py <new-folder> captures original browser timestamps; scripts/render_demo.py <recording-folder> renders that verified run at 1× and crops out the Google account strip. Credentials and raw traces stay ignored. Browser Use · Browser Harness · TypeSafe speculative fan-out