AI 평가·품질

Handwired 입문 — 버튼부터 사진 배치까지 숫자 계산으로 UI 만들기

Handwired의 계산 그래프와 일반적인 신경망 학습의 차이를 알아봅니다. 공식 토글 설치·JavaScript 비교 테스트·입력 격자 실습부터 사진 배치 학습까지, 실행 명령과 결과 확인 방법을 안내합니다.

작성 AI Tools Lab 운영자최종 수정 오류 제보·정정 요청

이 글 공유

X페이스북

버튼을 누르면 상태가 바뀌고, 손잡이가 부드럽게 이동합니다. 익숙한 웹 화면의 동작이지만 이를 덧셈·곱셈과 작은 숫자 연산으로 다시 표현하면 어떤 일이 생길까요? Cheng Lou의 Handwired는 프로그램의 규칙을 사람이 직접 계산 그래프로 구성하고 실행하는 오픈소스 프로젝트입니다. 공식 저장소

입문 단계에서 해볼 일은 작은 토글 버튼을 실행하고, 같은 동작을 작성한 일반 JavaScript 구현과 결과를 비교하는 것입니다. 이어서 사진 배치를 학습하는 공식 예제를 살펴보면, 사람이 정한 규칙과 데이터로 조정하는 계수가 어떻게 다른지 이해할 수 있습니다.

설치 전에 직접 조작해 보세요. Handwired 실습실 열기 →에서 조건문·토글·입력 격자·비교 검사를 브라우저로 실행할 수 있습니다. 공식 런타임과 일반 JavaScript의 실제 계산 결과를 나란히 보여주며 모바일 터치와 키보드 조작을 지원합니다.

다른 체험과 과제는 AI 실습실에서 실행 방식과 준비물별로 찾아볼 수 있습니다.

핵심 답변: Handwired로 무엇을 배울 수 있나요?

Handwired는 개발자가 정한 규칙을 숫자 연산으로 구성해 실행하고, 일반 JavaScript와 결과를 비교하며 계산 그래프를 배우는 프로젝트입니다. 입문자는 조건문 → 상태가 있는 토글 → 여러 입력을 다루는 격자 순서로 접근하면 됩니다. 사진 배치 학습은 이 기본 실습과 구분해서 살펴보세요. 공식 README

아래 조건문의 경계값을 먼저 계산해 보면, ‘같은 결과’라는 설명에 입력 범위가 왜 필요한지 알 수 있습니다.

입력 a 일반 조건문 a > 4 ? 10 : 12 아래 ReLU 식의 결과 해석
4 12 12 정수 경계에서 일치
5 10 10 다음 정수에서 일치
4.5 10 11 정수 사이에서는 이 식이 같은 조건문이 아님

이 표는 본문의 두 JavaScript 식을 세 입력으로 직접 계산한 결과입니다. Handwired 전체 런타임의 성능 측정이나 모든 입력에 대한 동등성 증명은 아닙니다. 설치 없는 실습실에서 입력을 바꿔 보고, 결과를 평가하는 기준은 AI 회귀 테스트 비교 가이드와 함께 읽어보세요.

Handwired와 일반적인 신경망 학습의 차이

신경망을 학습할 때는 예시와 목표 결과를 이용해 가중치라는 숫자를 조정합니다. Handwired의 토글에서는 개발자가 원하는 동작을 먼저 정하고, 그 동작에 필요한 계산과 계수를 직접 구성합니다. 토글을 움직이기 위해 클릭 사례를 대량으로 수집할 필요가 없습니다.

계산 그래프는 작은 연산들을 선으로 연결한 계산 순서입니다. Handwired는 이 연산들을 행렬 계산과 ReLU 계열 연산으로 묶어 JavaScript 또는 WebGPU에서 실행할 수 있게 합니다. 개발자는 빌더 API를 호출해 그래프를 구성합니다. 기존 웹 앱의 소스를 넣으면 자동으로 완성된 신경망으로 바뀌는 변환기는 아닙니다. 공식 소개와 산술 예제

구분 직접 구성하는 토글 학습하는 사진 배치
동작을 정하는 방법 개발자가 규칙과 계수를 구성 목표 사각형에 맞도록 일부 계수를 조정
학습 과정 토글 실행에 필요하지 않음 오차를 이용해 계수를 갱신
출력 켜짐 상태·손잡이 위치 등 사진 사각형의 위치·크기
화면 표시 브라우저의 JavaScript와 CSS 브라우저의 JavaScript와 CSS

두 방식을 함께 다룬다는 점이 흥미롭습니다. 직접 만든 계산에서도 자동미분을 활용할 수 있고, 일부 계수를 학습 대상으로 바꿔 제한된 문제를 실험할 수 있습니다. 학습 갤러리는 이러한 확장의 공식 예제입니다. 학습 갤러리 구조

조건문을 숫자로 표현해 보기

먼저 일반 JavaScript의 짧은 조건문을 봅시다.

const a = 5;
const result = a > 4 ? 10 : 12;

a가 정수라면 다음과 같이 표현할 수 있습니다. ReLU는 음수를 0으로 바꾸고, 0 이상의 수는 그대로 내보내는 연산입니다. 아래 코드는 원리를 확인하는 일반 JavaScript이며, Handwired 빌더 코드는 다음 실습에서 읽습니다.

const relu = x => Math.max(0, x);
for (const a of [4, 4.5, 5]) {
  const switchValue = relu(a - 4) - relu(a - 5);
  const calculated = switchValue * 10 + (1 - switchValue) * 12;
  console.log({ a, switchValue, calculated, conditional: a > 4 ? 10 : 12 });
}

정수 입력에서는 switchValue가 0 또는 1이 되어 두 후보 중 하나를 선택합니다. 하지만 소수를 넣으면 같은 결과가 나오지 않을 수 있습니다.

입력 a switchValue 숫자 계산의 결과 원래 조건문의 결과
4 0 12 12
4.5 0.5 11 10
5 1 10 10

계산식과 함께 입력의 전제도 정해야 합니다. 이 식은 정수 조건을 설명하는 예입니다. Handwired의 비교 API는 선언한 범위와 간격을 바탕으로 계산을 구성하므로, 이 식의 소수 처리 결과를 모든 비교 연산의 한계로 일반화하면 안 됩니다. 비교 연산과 입력 선언

계산과 브라우저가 맡는 일을 구분하세요

토글의 계산은 포인터가 버튼 안에 있는지 판단하고, 다음 켜짐 상태와 손잡이 위치를 내보냅니다. 브라우저 쪽 호스트 코드는 이벤트를 수집하고 계산을 호출한 뒤 결과를 HTML 요소에 반영합니다. 호스트는 계산을 실제 실행 환경과 연결하는 일반 JavaScript입니다.

흐름은 포인터 입력 수집 → 계산 실행 → 다음 상태 저장 → DOM에 위치와 상태 반영입니다. 다음 프레임까지 기억할 상태와 이번에 그릴 출력은 구분됩니다. mountToggle()은 출력값으로 요소의 위치와 접근성 속성을 갱신합니다. 토글의 계산과 화면 연결 코드

이 구분은 더 큰 예제에서도 유지됩니다. 공식 HandwiredOS는 창의 이동·크기 조절·겹침 순서와 사진 배치를 하나의 프로그램으로 다룹니다. 지정 커밋의 문서에는 유효 연산 4,646개, 130개 층, 저장 가중치 9,909개로 설명되어 있습니다. 이 가중치는 행렬의 숫자 항목을 뜻하며, 해당 데스크톱의 계수는 학습한 값이 아니라 빌더 코드가 구성한 값입니다. HandwiredOS 설명

HandwiredOS 공식 예제의 계산 모니터와 메모 창, 열두 장의 사진을 보여주는 데스크톱 화면
공식 HandwiredOS 예시 화면입니다. 왼쪽 모니터는 프로그램의 연산과 값을, 오른쪽 창은 사진 배치를 보여줍니다. 화면의 시간 수치는 해당 예시의 표시값입니다. 출처: Handwired 공식 저장소 · 원본 확대 보기 (새 탭). 모바일에서는 열린 원본을 두 손가락으로 확대할 수 있습니다.

설치 전에 준비할 것

기본 토글 실습에는 Git, Node.js와 npm, 브라우저를 준비합니다. 아래 명령은 npm의 npx로 Bun 1.4.3을 실행하므로 Bun을 전역 설치할 필요는 없습니다. 설치와 패키지 다운로드에는 인터넷이 필요합니다. Bun 패키지, 실행 스크립트

항목 기본 토글에서 필요한 것
운영체제 해당 Bun 버전을 실행할 수 있는 Windows·macOS·Linux 환경
개발 도구 Git, Node.js/npm, 터미널
브라우저 로컬 웹 페이지를 열 수 있는 최신 브라우저
GPU와 모델 파일 이 토글은 JavaScript 실행 경로를 사용하므로 별도 LLM 가중치나 전용 AI GPU 불필요

공식 자료에 없는 RAM·VRAM 수치를 최소 사양으로 단정하지 않습니다. WebGPU를 사용하는 다른 데모는 브라우저와 GPU의 지원 조건을 별도로 확인해야 합니다. 기본 토글이 실행된다는 사실만으로 모든 GPU 데모의 호환성을 판단할 수는 없습니다.

공식 토글 설치와 첫 실행

새 작업 폴더의 터미널에서 한 줄씩 실행하세요. PowerShell과 macOS·Linux 터미널에서 사용할 수 있는 명령입니다. 커밋을 고정하면 실행 코드와 아래 설명을 같은 상태로 맞출 수 있습니다.

git clone https://github.com/chenglou/handwired.git
cd handwired
git checkout 257856e3b221140acb4cc4460626b850c0bd4ff1

npx --yes bun@1.4.3 install --frozen-lockfile
npx --yes bun@1.4.3 test template
npx --yes bun@1.4.3 run start:template

마지막 명령이 출력하는 로컬 주소를 브라우저에서 엽니다. 종료할 때는 실행 중인 터미널에서 Ctrl+C를 누릅니다. checkout 이후의 detached HEAD 안내는 특정 커밋을 선택했기 때문에 나타나는 Git의 상태 설명입니다.

위 고정 버전의 토글 테스트는 3 pass, 0 fail, 306 expect() calls를 출력합니다. 이 글의 macOS 검증 환경에서도 같은 결과를 확인했고 토글의 브라우저용 빌드가 통과했습니다. 이는 Windows에서 직접 실행한 결과나 모든 데모에 대한 성능 측정은 아닙니다.

화면에서는 버튼 안에서 누르고 안에서 놓아 보세요. 켜짐 상태가 반전되고 손잡이가 이동해야 합니다. 이어서 안에서 누른 뒤 밖에서 놓아 보세요. 이 경우 상태는 반전되지 않아야 합니다. 클릭 도중에도 손잡이가 움직일 수 있으므로 상태 변화와 애니메이션을 함께 관찰합니다.

설치가 안 되면 먼저 git --version, node --version, npm --version으로 도구가 잡히는지 확인합니다. 서버 주소를 열 수 없으면 터미널이 계속 실행 중인지, 출력된 주소와 브라우저 주소가 같은지 확인하세요. 이미 사용 중인 포트가 있다는 안내가 나오면 자신의 이전 실습 서버를 종료하거나 다른 포트를 지정합니다.

PowerShell에서는 다음처럼 포트를 바꿀 수 있습니다. 종료 후 환경변수도 정리합니다.

$env:PORT = "3019"
npx --yes bun@1.4.3 run start:template
# 서버를 Ctrl+C로 종료한 다음 실행
Remove-Item Env:PORT

macOS·Linux에서는 PORT=3019 npx --yes bun@1.4.3 run start:template을 사용할 수 있습니다. 실행 스크립트는 Bun으로 HTML 진입점을 여는 방식입니다. 공식 패키지 설정

파일 네 개를 읽으며 테스트 이해하기

처음에는 아래 순서로 읽는 편이 쉽습니다. 일반 코드로 규칙을 이해한 뒤 계산 구현과 비교하면 두 방식의 차이가 보입니다.

읽을 파일 찾아볼 내용
template/toggle-reference.ts 일반 JavaScript로 표현한 눌림·놓임·상태·스프링 이동
template/toggle.ts 입력 셀과 다음 상태, 계산 구성, mountToggle()의 이벤트·DOM 연결
template/toggle.test.ts 두 구현에 같은 이벤트를 넣고 비교하는 검사
template/main.ts mountToggle()을 호출하는 페이지 진입점

공식 테스트는 켜짐 상태와 눌림 대기 상태 등을 정확히 비교하고, 손잡이 위치는 작은 부동소수점 오차를 허용합니다. 위치 오차의 검사 기준은 1e-5픽셀 미만입니다. 정확한 상태 판정과 근삿값인 좌표를 같은 방식으로 검사하지 않는다는 점을 살펴보세요. 공식 비교 테스트

또 하나의 핵심은 grid라는 입력 간격입니다. 토글의 포인터 좌표는 1/64픽셀 간격을 사용합니다. 브라우저 호스트는 좌표를 이 간격으로 정리해 전달합니다. 계산기에 직접 640.001처럼 간격을 벗어난 좌표를 넣는 테스트는 오류가 나는지 확인합니다. 소수 좌표 자체가 금지된 것은 아닙니다. 630.25처럼 선언한 격자 위의 값은 사용할 수 있습니다.

테스트 통과의 범위도 읽어야 합니다. 비교 구현의 주석은 손잡이가 움직이는 동안 약 1,140ms보다 긴 멈춤이 생기면 결과가 달라질 수 있다고 설명합니다. 실제 실행기는 한 프레임의 계산량이 한도를 넘을 때 목표 위치로 보내는 처리가 있고, 비교 구현에는 그 처리가 없기 때문입니다. 정해진 이벤트 흐름의 검증과 모든 상황의 동등성 증명은 다릅니다. 비교 구현의 시간 처리 조건

직접 해볼 세 가지 과제

첫 번째는 앞의 산술 예제에 3, 4, 4.5, 5, 6을 넣는 것입니다. 숫자 계산과 조건문의 결과를 함께 출력하고, 어느 입력에서 달라지는지 설명해 보세요. 정수라는 전제가 왜 필요한지 확인하는 과제입니다.

두 번째는 버튼 경계입니다. 바깥에서 누르고 안에서 놓기, 안에서 누르고 오른쪽 경계에서 놓기를 비교해 보세요. 현재 구현은 왼쪽·위 경계를 포함하고 오른쪽·아래 경계를 제외합니다. 눈으로 보기 어려운 경계는 테스트에 좌표를 직접 넣어 확인할 수 있습니다.

세 번째는 규칙 변경입니다. 원본 테스트가 통과한 결과를 먼저 기록한 뒤, 복사한 작업 폴더에서 경계 비교 하나만 바꾸고 테스트를 다시 실행하세요. 검사도 함께 고치기 전에 기존 테스트가 변경을 발견하는지 관찰합니다. 의도한 동작까지 바꾼다면 이후 비교 구현과 테스트 기대값도 그 의도에 맞게 정리합니다.

npx --yes bun@1.4.3 test template

완료 기준은 화면이 움직인다는 것뿐 아니라, 입력 조건·상태 변화·좌표 오차를 나누어 설명하고 실패한 검사의 이유를 찾을 수 있는가입니다.

사진 배치 학습으로 확장하기

토글 서버를 종료하고 같은 저장소 루트에서 공식 학습 갤러리를 실행합니다.

npx --yes bun@1.4.3 run start:learning

이 예제는 사진의 내용이나 픽셀을 생성하지 않습니다. 사용자가 그린 사각형을 목표로 사진의 위치와 크기를 맞추도록 244개의 계수를 학습합니다. 사각형을 이동하거나 크기를 조절한 뒤 사진이 목표 배치를 따라가는 과정과 손실값 변화를 관찰할 수 있습니다.

Story, Cinema, Contact sheet 프리셋을 바꾸어 보고, 같은 프리셋에서 사각형 하나만 이동해 보세요. 이어서 Misalignment penalty를 조절해 목표 위치를 따르는 것과 사진들의 가장자리를 정렬하는 것 사이에 어떤 변화가 생기는지 확인합니다. 계수는 여러 사진에 공유되므로 한 사진의 목표를 바꾸면 다른 사진의 배치에도 영향을 줄 수 있습니다. 공식 학습 갤러리 사용법

관련 검사는 다음 명령으로 실행할 수 있습니다. 토글 검사와 별개의 학습 갤러리 테스트입니다.

npx --yes bun@1.4.3 test tests/learned-gallery

학습 갤러리만 실행하면 다른 데모로 가는 링크는 연결되지 않을 수 있습니다. 전체 데모를 보고 싶다면 해당 서버를 종료한 후 npx --yes bun@1.4.3 run start로 데모 사이트를 실행하거나 공식 온라인 데모를 이용하세요.

활용할 때 판단할 기준

Handwired는 조건과 상태를 숫자로 표현하고, 이를 일반 코드와 비교하거나 일부 계수를 학습해 보는 데 유용한 실험 재료입니다. 자동 레이아웃 규칙이나 제한된 상호작용을 연구한다면, 원하는 결과를 먼저 정의하고 작은 입력 범위부터 검증해 볼 수 있습니다.

GPU 실행 가능성만으로 모든 UI가 빨라진다고 판단할 수는 없습니다. 실제 도입에서는 계산 시간뿐 아니라 입력 준비, CPU·GPU 사이의 데이터 이동, 결과를 DOM에 반영하는 시간까지 포함해야 합니다. JSON 검색처럼 다수 입력을 병렬 처리하는 데모와 버튼 하나의 상호작용은 작업 규모가 다릅니다. 실행 방식과 계산 비용

우리 화면에서 사용할 수 있는지 판단하려면 먼저 입력 범위, 상태 전이, 오차 허용치, 긴 멈춤 뒤의 동작을 정하세요. 학습을 더한다면 목표 점수가 좋아진 것과 사람이 원하는 배치가 나온 것도 따로 확인해야 합니다. 이 프로젝트에서 배울 핵심은 계산의 형태만큼이나 그 계산이 지켜야 할 약속을 테스트로 드러내는 방법입니다.

자주 묻는 질문

Q1. 대화형 AI나 LLM 모델을 설치하는 프로젝트인가요?

기본 실습은 숫자 계산으로 구성한 UI를 실행합니다. 챗봇 API 키나 대규모 언어 모델 가중치를 받는 과정은 없습니다.

Q2. 기존 React 앱을 자동으로 바꿀 수 있나요?

이 글에서 다룬 경로는 개발자가 빌더 API로 계산을 구성하는 방식입니다. 브라우저 이벤트와 화면 연결 코드도 필요합니다.

Q3. 가중치가 있으면 모두 학습된 값인가요?

아닙니다. 토글과 HandwiredOS는 사람이 구성한 계수를 사용합니다. 학습 갤러리는 일부 계수를 목표 배치에 맞춰 갱신합니다.

Q4. 테스트가 통과하면 어떤 입력에서도 같은가요?

검사한 입력과 시간 처리 조건에서 결과를 비교한 것입니다. 선언 범위를 벗어난 값, 경계, 이벤트 순서, 긴 멈춤은 각각 확인해야 합니다.

공식 자료와 확인 기준일

확인 기준일: 2026-10-20 — 설치 예시는 위 고정 커밋과 Bun 1.4.3을 기준으로 합니다. 소스가 달라지면 명령·데모 크기·검사 결과가 달라질 수 있습니다.

도움이 됐다면 함께 공유해 주세요.

X페이스북