가이드

원격 AI 에이전트 접속

USB 하나로, 아무것도 안 깔린 낡은 PC를 내 AI 에이전트에 연결하는 법

헬퍼 · 아웃바운드 연결 · indiebizOS와 직접 구현

「필요한 건 오직 연결 2」에서 저는 하나의 연결을 이야기했습니다 — AI 에이전트가 깔려 있지 않은 낡은 PC를, 내 메인 컴퓨터의 AI 에이전트에 연결하는 것. USB를 꽂고 헬퍼를 더블클릭하면, 폰에서 "이 PC를 진단해줘", "여기에 kodi를 깔아줘" 한마디로 내 AI가 그 컴퓨터를 만집니다. 그 글은 무엇을만 그렸습니다. 이 글은 그게 왜 되는지, 그리고 어떻게 만드는지 — indiebizOS를 쓸 때와 안 쓸 때로 나눠 채웁니다.

1. 핵심 원리 — 왜 USB 하나로 되는가

겉보기엔 마법 같지만 밑바탕은 오래된 기술입니다. 원격 접속을 사람이 아니라 AI가 한다는 점만 새롭습니다. 세 가지 설계 결정이 이걸 간단하게 만듭니다.

① 두뇌는 내 컴퓨터에, USB엔 얇은 '손발'만

낡은 PC에 AI를 설치하는 게 아닙니다. 그 PC엔 명령을 받아 실행하고 결과를 돌려주는 작은 심부름꾼 프로그램(헬퍼) 하나만 잠깐 돕니다. 판단·기억·API 키 같은 두뇌는 전부 내 메인 컴퓨터(허브)에 남습니다. 그래서 USB엔 수 MB짜리 실행파일과 비밀번호가 아닌 접속 열쇠(key) 하나만 실리면 됩니다.

② 연결을 '바깥에서 안으로'가 아니라 '안에서 바깥으로'

남의 PC에 들어가려면 보통 그 PC의 방화벽·공유기를 뚫어야 합니다(포트포워딩). 번거롭고 위험하죠. 그래서 방향을 뒤집습니다. 헬퍼가 그 PC에서 내 허브로 먼저 전화를 겁니다(아웃바운드). 바깥으로 나가는 연결은 어떤 방화벽도 기본 허용하므로, 그 PC에서 설정할 게 하나도 없습니다.

③ 명령은 '큐 + 롱폴링'으로 오간다

연결된 뒤엔, 허브가 명령을 대기열(큐)에 넣고 헬퍼가 주기적으로 "제게 시킬 일 있나요?"라고 물어(롱폴링) 가져가 실행하고 결과를 돌려줍니다. 이게 전부입니다.

내 폰/브라우저 ──(인터넷)──▶ 내 메인 컴퓨터 = 허브(AI 두뇌·신원) ▲ │ ② 헬퍼가 바깥으로 전화를 검(아웃바운드) │ ③ "시킬 일 있나요?" 롱폴링 → 명령 받아 실행 → 결과 회신 │ 낡은 PC의 헬퍼(얇은 손발, USB에서 실행)
여기서 하나 짚을 것. 헬퍼가 '전화를 걸' 내 허브의 공개 주소가 있어야 합니다. 이건 앞 글 「공유창고 만드는 법」의 그 터널입니다 — Tailscale이나 Cloudflare로 내 컴퓨터에 바깥에서 닿는 주소를 하나 열어두면, 헬퍼가 그리로 붙습니다. 연결이 연결을 부르는 셈이죠.

2. 방법 A indiebizOS를 쓰는 경우

indiebizOS엔 이 헬퍼 체계가 USB 손발(guest-helper)이라는 기능으로 들어 있습니다. 직접 서버를 짜지 않고 아래 흐름만 따르면 됩니다. (전제: 허브가 켜져 있고, 공개 주소를 내는 터널이 살아 있을 것.)

1) USB 만들기 — 열쇠 발급

내 AI에게 "사무실 PC용 손발 USB 하나 만들어줘"라고 하면 이 어휘가 실행됩니다:

[self:limb]{op: "issue", alias: "사무실PC", ttl_days: 14, os: "win"}

2) 그 PC에서 헬퍼 실행

USB를 낡은 PC에 꽂고, 헬퍼 실행파일을 더블클릭합니다 (indiebiz-helper.json이 같은 폴더에 있어야 합니다). 헬퍼가 내 허브에 붙으면 자동으로 연결·승인되어 곧바로 쓸 수 있습니다. 그 PC엔 미리 깔아둘 게 없습니다.

3) 명령 내리기 (폰에서든 어디서든)

폰 창을 열어 자연어로 시키면 됩니다 — "이 PC 진단해줘", "kodi 깔아줘". 내부적으로는:

[limbs:guestpc]{op: "shell", cmd: "systeminfo", limb: "사무실PC"}      # 진단
[limbs:guestpc]{op: "list",  path: "C:/Downloads", limb: "사무실PC"}   # 폴더 보기
[limbs:guestpc]{op: "read",  path: "C:/note.txt", limb: "사무실PC"}    # 파일 읽기
[limbs:guestpc]{op: "write", path: "C:/out.txt", content: "…", limb: "사무실PC"}
[limbs:guestpc]{op: "info",  limb: "사무실PC"}                         # OS·호스트명

손발이 둘 이상이면 limb: "이름"으로 어느 PC인지 반드시 지정합니다. 이 강제가 곧 방어입니다 — 유출된 열쇠로 낯선 PC가 하나 더 붙으면 손발이 둘이 되어 이름을 요구받고, 그때 "어? 손발이 둘이네?" 하고 알아챕니다.

4) 볼일 끝 — 해제와 폐기

[limbs:guestpc]{op: "detach", limb: "사무실PC"}   # 지금 세션 종료(그 PC엔 무잔류)
[self:limb]{op: "revoke", target: "사무실PC"}      # USB 분실 시 이 열쇠만 영구 폐기

헬퍼는 설치·상주가 없어 창을 닫으면 끝이고, 그 PC엔 아무것도 남지 않습니다. 열쇠를 잃어버려도 그 열쇠 하나만 폐기하면 됩니다 — 허브 로그인·구독·데이터 키는 USB에 실리지 않으니까요.

3. 방법 B indiebizOS 없이 구현하기

원문의 말처럼 헬퍼 자체는 새로울 게 없는 기술입니다. 두 갈래로 만들 수 있습니다. 급하면 B-1(기성 도구 조합), 원문처럼 USB 더블클릭 경험을 원하면 B-2(헬퍼 직접 제작).

B-1. 기성 도구 조합 — 가장 빠른 길

"AI 에이전트 + 원격 셸"을 이미 있는 부품으로 조립합니다. 준비물은 둘입니다.

그러면 AI 에이전트에게 이렇게 시키는 것으로 끝납니다:

# 메인 컴퓨터의 AI 에이전트가 실행하는 명령 (낡은 PC = oldpc)
tailscale ssh oldpc "systeminfo"          # 진단
tailscale ssh oldpc "winget install kodi" # 설치 (윈도우 예시)
USB 더블클릭 감성을 살리려면. 낡은 PC에 Tailscale을 설치·로그인하는 한 번의 절차를 USB에 담은 설치 스크립트 한 줄로 만들어 두면, 원문의 "꽂고 실행" 경험에 가까워집니다. 다만 이 방식은 그 PC에 Tailscale이 설치된다는 점이 B-2와 다릅니다.

B-2. 헬퍼를 직접 만들기 — 원문이 한 방식

"아무것도 설치 안 된 PC에 USB만 꽂아 실행"에 가장 충실한 길입니다. 부품은 셋입니다.

① 허브(내 컴퓨터): 명령 큐 + 결과함. 아주 작은 웹서버면 됩니다(개념 예시):

# hub.py — 내 컴퓨터에서 실행. 공개 주소(터널)로 노출.
from fastapi import FastAPI, Header, HTTPException
import uuid
app = FastAPI()
KEY = "비밀-접속-열쇠"
jobs, results = [], {}

@app.post("/enqueue")            # AI 에이전트가 여기에 명령을 넣는다
def enqueue(cmd: dict):
    jid = str(uuid.uuid4()); jobs.append({"id": jid, "cmd": cmd["cmd"]}); return {"id": jid}

@app.get("/poll")                # 헬퍼가 시킬 일을 물어간다 (롱폴링)
def poll(x_key: str = Header("")):
    if x_key != KEY: raise HTTPException(401)
    return jobs.pop(0) if jobs else {}

@app.post("/result")             # 헬퍼가 결과를 돌려준다
def result(r: dict, x_key: str = Header("")):
    if x_key != KEY: raise HTTPException(401)
    results[r["id"]] = r; return {"ok": True}

② 헬퍼(낡은 PC, USB에서 실행): 폴링 루프.

# helper.py — 게스트 PC에서 실행. 허브로 아웃바운드 폴링.
import requests, subprocess, time
HUB = "https://내허브-공개주소"      # 터널/Tailscale로 연 내 컴퓨터 주소
KEY = "비밀-접속-열쇠"
while True:
    try:
        job = requests.get(f"{HUB}/poll", headers={"X-Key": KEY}, timeout=30).json()
        if job.get("cmd"):
            r = subprocess.run(job["cmd"], shell=True, capture_output=True,
                               text=True, timeout=120)
            requests.post(f"{HUB}/result", headers={"X-Key": KEY}, json={
                "id": job["id"], "stdout": r.stdout,
                "stderr": r.stderr, "code": r.returncode})
    except Exception:
        time.sleep(2)

파이썬이 없는 낡은 PC를 위해선 이 헬퍼를 PyInstaller나 Go로 단일 실행파일로 컴파일해 USB에 담습니다(원문의 저자는 Go 단일 파일을 썼습니다). 그러면 그 PC엔 정말 아무것도 필요 없습니다.

③ AI 에이전트: 허브에 명령을 넣는 도구 하나. Claude Desktop이라면 /enqueue를 호출하는 작은 MCP 도구 하나를, Claude Code라면 curl 한 줄이면 됩니다:

curl -s https://내허브-공개주소/enqueue \
  -H "Content-Type: application/json" \
  -d '{"cmd":"systeminfo"}'

이제 AI에게 "낡은 PC 진단해줘"라고 하면, AI가 이 호출로 명령을 큐에 넣고, 헬퍼가 가져가 실행하고, 결과가 돌아옵니다. 이것이 원문이 만든 연결의 뼈대 전부입니다. (실제로 쓰려면 여기에 결과 대기·타임아웃·여러 대 구분 정도만 더하면 됩니다.)

방법 비교

A. indiebizOSB-1. Tailscale + SSHB-2. 직접 만든 헬퍼
낡은 PC에 설치없음(USB 실행)Tailscale 설치없음(USB 실행)
만드는 수고가장 적음적음중간(허브·헬퍼 제작)
USB 더블클릭 UX△(설치 필요)
폰에서 자연어 명령내장따로 연결 필요따로 연결 필요

4. 보안 — 남의 컴퓨터에 셸을 여는 일이다

5. 한계


원문의 마지막 문장을 빌리면 — 중요한 건 연결을 상상하는 것입니다. 헬퍼도, 터널도, 폴링 루프도 새로운 기술이 아닙니다. 새로운 것은 "내 PC를 내 AI 에이전트에 연결하면 어떻게 될까?"라는 질문을 던지고, 그 구현을 AI에게 맡긴다는 자세입니다. 연결 하나가 열릴 때마다, 낡은 컴퓨터 한 대가 다시 살아납니다.

— 필요한 건, 오직 연결.