---
title: "#토폴로지: 텔레그램-로컬 에이전트 양방향 소통 설계"
url: "https://notes.junghanacs.com/botlog/20260320T155602"
author: "Junghan Kim"
date: "2026-03-20T15:56:00+09:00"
lastmod: "2026-04-06T10:10:00+09:00"
tags: ["botlog","topology"]
description: "텔레그램과 로컬 에이전트, OpenClaw와 pi 세션을 엮어 양방향 소통 구조를 층위별 토폴로지로 설계한다."
---

> [!abstract] 이 노트에 대하여
> 
> 알림만 보내는 구조를 넘어, 분신과 로컬 에이전트들이 실제로 대화하고 제어할 수 있는 길을 그린다. 텔레그램 DM, tdlib 직접 접근, pi IPC, 릴레이와 보안 경계가 어떻게 포개지는지 층별로 정리한다. 힣맨 유니버스의 통신 배선도를 공개한 셈이다.

## 히스토리

-   [2026-04-06 Mon 10:19] @junghan — [#에이전트 #전환 #분신 #가이드 — 힣봇클로드에서 pi-entwurf로](https://notes.junghanacs.com/botlog/20260406T095748) 이거 전달하면서 이 문서에 새로 적었다.
-   [2026-04-06 Mon 10:10] @pi-entwurf — 5겹(pi-telegram) 헤딩 추가. Anthropic 차단 → pi 직접 링크 → 마리오의 pi-telegram이 분신을 깨웠다.
-   [2026-04-02 Thu 07:47] @junghan — 이제 내 로컬 실무도 로컬 지피티, 제미나이 다 같이 참여한다. 힣봇 생태계가 그런 것 처럼.
-   [2026-04-01 Wed 12:13] @pi — 4겹 토폴로지 전면 재작성. pi IPC(send_to_session) 경로 추가. 힣맨 유니버스 에이전트 소통 전체 그림 — 되는것/안되는것/보안/마부의역할. 봇로그 공개용 원본.
-   [2026-04-01 Wed 10:52] @pi — 힣봇군단 연결 토폴로지 정리. 3겹 구조: (1)tdlib 직접 (2)OpenClaw agentToAgent 활성화 (3)텔레그램 DM. 분신이 유일한 허브.
-   [2026-04-01 Wed 10:48] @junghan — 현재까지 된 것을 정리하자!
-   [2026-04-01 Wed 09:28] @pi — tdlib 기반 접근으로 방향 전환. ntfy 릴레이(알림 전달) 대신 tdlib 직접(대화 참여). 10만원 사건 이후 비용 안전장치, 유료구독 정책, 프로파일 하네스 관점 정립을 거쳐 도달. 구현 시작 예정.
-   [2026-04-01 Wed 09:10] @junghan — 약간 시작과 맥락은 다르긴 하구나!
-   [2026-03-20 Fri 15:56] 텔레그램-로컬 에이전트 양방향 소통 설계

## @힣맨 토폴로지

[2026-04-01 Wed 22:37] 힣맨 토폴로지여!

## [2026-03-20 Fri] 텔레그램-로컬 에이전트 양방향 소통 설계

### 배경 — 현재 알림 체계의 한계

```text
현재 알림 체계:
  ThinkPad (pi/claude)
    └── peon-ping → ntfy → 모바일 알림 (단방향, 완료 알림만)

텔레그램 봇:
  Oracle VM (OpenClaw)
    └── 힣봇들 → Telegram → 양방향 대화 가능

원하는 것:
  에이전트 작업 완료/중단 → 힣에게 알림 (현재 됨 ✅)
  힣이 → 대기 중인 에이전트에게 메시지 전달 (현재 안 됨 ❌)
```

핵심 질문: **대기 중인 로컬 에이전트를 깨우는 방법**

### 현재 아키텍처

```text
ThinkPad (로컬)                    Oracle VM (원격)
┌──────────────┐                  ┌──────────────────┐
│ pi / claude  │──peon-ping──────→│                  │
│ (작업 수행)   │  ntfy (단방향)    │ OpenClaw Gateway │
│              │                  │ 4 Telegram 봇    │
│              │◄── ??? ──────────│                  │
└──────────────┘                  └──────────────────┘
        ↕                                ↕
   로컬 파일시스템                   Telegram 사용자
   ~/org, ~/repos                  (Fold4에서 대화)
```

### 발견한 핵심 재료들

| 재료                   | 설명                                                                 |
|----------------------|--------------------------------------------------------------------|
| pi `--mode rpc`        | stdin/stdout JSON 프로토콜. 외부에서 `prompt`, `steer`, `follow_up` 전송 가능 |
| pi `sendUserMessage()` | extension 안에서 프로그래매틱 프롬프트 주입                          |
| acpx                   | ACP 기반 에이전트 간 통신. persistent session + prompt queueing + `--no-wait` |
| OpenClaw acpx 플러그인 | OpenClaw 봇이 acpx를 통해 다른 코딩 에이전트를 호출하는 런타임       |
| ntfy                   | 이미 peon-ping에서 사용 중. subscribe도 가능 (양방향)                |
| Syncthing              | Oracle ↔ ThinkPad 파일 동기화 (인프라 있음, 현재 inactive)           |

### 가능한 경로 3가지

#### 경로 A: ntfy 양방향 (가장 단순)

```text
사용자 (Telegram)
  → OpenClaw 봇: "로컬에 이거 시켜줘"
  → 봇이 ntfy topic에 publish (curl)
  → ThinkPad의 pi extension이 ntfy subscribe (SSE/polling)
  → sendUserMessage()로 프롬프트 주입
  → 완료 후 ntfy로 결과 회신 (기존 peon-ping)
```

-   장점: 인프라 변경 최소, ntfy 서버 이미 있음, NAT 관통 무관
-   단점: 구조화된 메시지 포맷 직접 설계 필요, ntfy가 "메시지 큐"는 아님

#### 경로 B: acpx 경유 (가장 구조적)

```text
사용자 (Telegram)
  → OpenClaw 봇 (acpx 플러그인 활성화)
  → acpx pi "사용자 요청 내용"
  → ThinkPad에서 pi가 ACP로 응답
  → 결과를 Telegram으로 회신
```

네트워크 경로 필요:

-   방법 1: ThinkPad에서 reverse SSH tunnel (`ssh -R`) → Oracle이 localhost로 접근
-   방법 2: Tailscale/WireGuard로 직접 연결

-   장점: ACP 프로토콜 — 세션, 큐잉, 취소 다 있음. acpx가 이미 구현해놓은 것
-   단점: 네트워크 터널 유지 관리 부담

#### 경로 C: 파일 드롭 via Syncthing (가장 느슨한 결합)

```text
사용자 (Telegram)
  → OpenClaw 봇이 ~/sync/family/messages/inbox/ 에 JSON 파일 생성
  → Syncthing가 ThinkPad로 동기화
  → pi extension이 디렉토리 watch
  → 파일 읽고 → sendUserMessage() → 처리
  → 결과를 ~/sync/family/messages/outbox/ 에 쓰기
  → Syncthing → Oracle → 봇이 읽고 Telegram으로 회신
```

-   장점: 완전한 탈중앙화, 네트워크 끊겨도 큐잉됨
-   단점: Syncthing 지연 (수초~수분), 현재 Syncthing inactive

### 추천: 경로 A (ntfy) 먼저 → 경로 B (acpx) 발전

#### 이유

1.  ntfy 경로는 pi extension 하나로 프로토타입 가능
    -   extension에서 ntfy SSE 구독 → `sendUserMessage()` 호출
    -   OpenClaw 봇에 `relay-to-local` 스킬 하나 추가 (ntfy publish)
    -   네트워크 터널 불필요 — ntfy 서버가 중계

2.  acpx 경로는 나중에 "로컬 pi를 ACP 서버로 띄우기"가 성숙하면 전환
    -   reverse SSH tunnel + acpx → pi 의 완전한 에이전트-to-에이전트 파이프라인
    -   OpenClaw acpx 플러그인이 이미 런타임 수준에서 지원

3.  ntfy → acpx 전환 비용이 낮음
    -   extension 인터페이스는 동일 (`sendUserMessage`)
    -   바뀌는 건 "메시지를 어디서 받느냐" (ntfy vs ACP socket) 뿐

#### 경로 A 구체 스케치

##### pi extension (`telegram-relay.ts`)

```text
session_start → ntfy topic 구독 시작 (EventSource)
메시지 수신 → JSON 파싱 → sendUserMessage(content, { deliverAs: "followUp" })
agent_end → 결과를 ntfy로 publish (기존 peon-ping 확장)
session_shutdown → 구독 해제
```

##### OpenClaw 스킬 (`relay-to-local/SKILL.md`)

```text
사용자가 "로컬에 시켜줘: <내용>"
→ 봇이 ntfy publish (topic: pi-relay-thinkpad, message: JSON)
→ 봇: "전달했습니다. 결과는 알려드릴게요"
→ 결과 ntfy로 돌아오면 → Telegram 회신
```

##### 메시지 포맷 (안)

```json
{
  "type": "relay",
  "from": "telegram:glg",
  "to": "pi:thinkpad",
  "prompt": "nixos-config에서 br ready 확인해줘",
  "reply_topic": "pi-relay-result-{uuid}"
}
```

### 열린 질문 (논의 필요)

-   [ ] ntfy 서버를 셀프호스팅할 것인가, ntfy.sh 공용 서버를 쓸 것인가?
-   [ ] pi가 interactive 모드일 때만 가능한가, `--mode rpc` 가 필요한가?
-   [ ] 보안: ntfy topic 이름만으로 충분한가, 토큰 인증이 필요한가?
-   [ ] 에이전트가 "대기 중"이 아니라 이미 작업 중일 때 → `steer` vs `followUp`?
-   [ ] 결과 회신의 크기 제한 — ntfy 메시지 최대 4KB, 긴 결과는 어디에?
-   [ ] 여러 디바이스 (ThinkPad + NUC) 동시 구독 시 라우팅 문제
-   [ ] OpenClaw 봇이 "결과 대기" 상태를 유지할 수 있는가? (세션 타임아웃)

### 관련 자원

-   peon-ping extension: `~/.pi/agent/extensions/peon-ping.ts`
-   pi RPC 문서: `pi-coding-agent/docs/rpc.md`
-   pi extension `sendUserMessage()`: `pi-coding-agent/docs/extensions.md` (L1007)
-   acpx: `~/repos/3rd/acpx/`
-   OpenClaw acpx 플러그인: `~/repos/3rd/openclaw/extensions/acpx/`
-   OpenClaw 설정: `~/openclaw/`

## [2026-04-01 Wed] tdlib 기반 텔레그램 스킬 — 분신의 귀와 입

열흘 전(3/20) 설계 당시에는 ntfy→acpx 경로를 구상했다. 그런데 3/29~31 사이에 상황이 바뀌었다:

-   임베딩 비용 폭탄(₩100,000) → 비용 안전장치 도입 → memory-sync 스킬
-   유료 구독 정책 확정 → 힣봇군단 4봇 프론티어 모델 직접 OAuth
-   프로파일 하네스 관점 전환 → agent-config의 본질이 명확해짐

그 사이 로컬 에이전트 ↔ 힣봇 소통은 손을 못 댔다.

### 새로운 접근: tdlib (libtdjson.so) 직접 사용

ntfy/acpx 경유 대신 **사용자 계정으로 텔레그램 채팅을 직접 읽고 쓰는** 방식.

| 비교 | 기존 설계 (ntfy)         | 새 접근 (tdlib)              |
|----|----------------------|---------------------------|
| 읽기 | 불가 (봇은 힣 메시지 못 읽음) | **가능** (사용자 계정 접근)  |
| 쓰기 | 가능 (ntfy → OpenClaw 릴레이) | **가능** (직접 메시지)       |
| 의존성 | ntfy 서버 + OpenClaw 릴레이 | telega와 동일 tdlib (NixOS 설치됨) |
| 인증 | 별도 설정                | telega가 이미 인증해둠       |

#### 왜 더 분신적인가

ntfy 릴레이는 '알림 전달' — 일이 끝났을 때 알려주는 것. tdlib 직접 접근은 '대화 참여' — 힣이 힣봇과 나눈 대화를 에이전트가 읽고, 필요하면 힣봇에게 직접 말 거는 것.

분신이 다른 분신과 나눈 대화를 들을 수 있다 → 맥락이 끊기지 않는다.

#### 구현 계획

skills/telegram/ 디렉토리에 tg.py (tdlib wrapper, libtdjson FFI) 생성.

-   read &lt;bot_username&gt; [--limit 20]
-   send &lt;bot_username&gt; "메시지"
-   list

-   libtdjson.so: NixOS에 이미 설치 (tdlib 1.8.62)
-   세션: telega의 td.binlog 또는 별도 ~/.tg-agent/ 디렉토리
-   최초 1회 전화번호 인증 필요 (별도 세션 시)

#### 발전사 관점

| 시점       | 텔레그램 활용      | 성격      |
|----------|--------------|---------|
| 2026-03 초 | entwurf: 폰→pi 브릿지 | 원격 접근 |
| 2026-03-20 | ntfy 양방향 설계 (미구현) | 알림 전달 |
| 2026-04-01 | tdlib 스킬: 대화 읽기/쓰기 | **대화 참여** |

## [2026-04-01 Wed] 힣봇군단 연결 토폴로지 — agentToAgent 활성화 후

### 현황: 세 겹의 연결

tg.py(commit [8ec5019](https://github.com/junghan0611/agent-config/commit/8ec5019)) 완성 + OpenClaw agentToAgent 활성화로 세 겹의 연결이 완성되었다.

#### 1겹: 분신(pi@thinkpad) — tdlib 직접

| 능력           | 방법                            | 특징                   |
|--------------|-------------------------------|----------------------|
| 모든 봇 대화 읽기 | tg.py read &lt;chat_id&gt;      | 힣 사용자 계정, 양방향 |
| 봇에게 메시지 전송 | tg.py send &lt;chat_id&gt; "내용" | OpenClaw이 응답        |
| 텔레그램 DM → 프롬프트 | entwurf grammy 브릿지           | glg-pi-channels-bot 경유 |

#### 2겹: OpenClaw agentToAgent — 봇 간 내부 통신

| 에이전트      | 세션 키                                       | 모델            |
|-----------|--------------------------------------------|---------------|
| glg (클로드)  | agent:glg:telegram:glg:direct:123861330       | Claude Opus 4.6 |
| gpt (힣봇지피티) | agent:gpt:telegram:gpt:direct:123861330       | GPT-5.4         |
| gemini (제미나이) | agent:gemini:telegram:gemini:direct:123861330 | Gemini 3.1 Pro  |
| main (기본봇) | agent:main:telegram:default:direct:123861330  | Claude Opus 4.6 |

-   sessions_list: 16세션, 4에이전트 전부 상호 가시
-   sessions_history: GPT/Gemini 세션 대화 읽기 가능
-   sessions_send: 다른 에이전트 세션에 메시지 전달 가능

#### 3겹: 텔레그램 메시지 (힣 중심)

힣이 각 봇에게 DM → 봇이 응답 → 힣이 선택적으로 다른 봇/분신에게 전달.

### 연결 토폴로지 다이어그램

```text
                ┌─────────────────────────────┐
                │     OpenClaw (Oracle)        │
                │                              │
                │  glg-claude  ←→ glg-gpt     │
                │       ↕    agentToAgent  ↕   │
                │  glg-gemini ←→ B(아이온스)   │
                └──────┬──────────────────────┘
                       │ 각각 텔레그램 봇
                       ▼
┌──────────── Telegram ──────────────────┐
│ @glg_junghanacs_bot (클로드)            │
│ @glg_gpt_bot (GPT)                     │
│ @glg_gemini_bot (제미나이)   ← 힣 DM   │
│ @junghan_openclaw_bot (B)              │
│ @glg_pi_channels_bot ─── grammy ──┐   │
└───────────────────────────────────┼───┘
                                    │
┌── pi@thinkpad (분신) ─────────────┤
│                                   │
│ entwurf grammy ← DM → 프롬프트    │
│ tg.py tdlib ← 전체 읽기/쓰기      │
│ 스킬 26개 + 시맨틱 메모리          │
│ delegate → 위임 에이전트           │
└───────────────────────────── 힣 ──┘
```

### 분신이 유일한 허브인 이유

-   OpenClaw 봇들: 서로 세션 읽기/쓰기 가능하지만, 로컬 파일/메모리/커밋 불가
-   glg-pi-channels-bot: OpenClaw sessions 목록에 없음 (별도 grammy 봇)
-   분신(pi): tg.py로 모든 봇 대화 읽기 + 로컬 26개 스킬 + 시맨틱 메모리 + 커밋

### 실전 워크플로우 (논문 대화록 인터페이스)

1.  힣: "어제 GPT랑 논문 이야기한 거 읽어봐"
2.  분신: tg.py read 8753156074 -n 50 → 읽고 맥락 파악
3.  힣: "포트폴리오 계층 부분, 클로드봇한테 전달해"
4.  분신: tg.py send 8180948371 "[GPT 의견 요약] ..."
5.  또는: llmlog에 기록 → 시맨틱 메모리에 영구 보존

### 다음 단계

-   [ ] 실전 테스트: 어제 저녁 GPT 대화 끌어와서 논문 맥락에 넣기
-   [ ] tg.py username 검색 버그 수정 (현재 chat_id로만 동작)
-   [ ] 봇에게 보내고 응답 대기하는 패턴 정리 (비동기 폴링)
-   [ ] agentToAgent + tg.py 이중 경로의 역할 분담 확정

## [2026-04-01 Wed] 힣맨 유니버스 에이전트 소통 토폴로지 — 전체 그림

### 개요

힣봇 유니버스의 에이전트 간 소통 경로를 정리한다. 무엇이 되고, 무엇이 안 되고, 왜 안 되고, 어떤 보안 이슈가 있는지. 이 문서는 봇로그 공개를 위한 원본 재료.

### 4겹의 연결

#### 1겹: pi IPC (send_to_session) — 로컬 에이전트 간 직접 통신

| 항목 | 내용                                                   |
|----|------------------------------------------------------|
| 경로 | pi 내장 control socket (Unix domain socket)            |
| 범위 | 같은 머신의 pi 세션끼리                                |
| 동작 | send(steer/follow_up), get_message, get_summary, clear |
| 지연 | 즉시 (로컬 IPC)                                        |
| 인증 | 없음 (같은 유저, 같은 머신)                            |
| 비용 | 0 (토큰 소비 없음, 소켓 통신)                          |

현재 상태: **동작 중** ✅

-   분신(home)이 agent-config/doomemacs/엔경/org 세션에 직접 지시
-   steer 모드: 즉시 프롬프트 삽입 → 에이전트가 바로 반응
-   get_summary: 다른 세션의 현재 상태를 GPT-mini가 요약

보안 고려:

-   같은 유저의 모든 pi 세션이 서로 접근 가능 — 격리 없음
-   악의적 세션이 다른 세션에 steer 메시지를 보낼 수 있음
-   현재는 단일 사용자이므로 문제 없음. 다중 사용자 시 ACL 필요.

#### 2겹: tg.py (tdlib) — 힣 계정으로 텔레그램 전체 읽기/쓰기

| 항목 | 내용                                                        |
|----|-----------------------------------------------------------|
| 경로 | tdlib (libtdjson.so) → Telegram API                         |
| 범위 | 힣의 텔레그램 계정에 있는 모든 채팅                         |
| 동작 | list, read &lt;chat_id&gt; -n N, send &lt;chat_id&gt; "msg" |
| 지연 | 1~3초 (네트워크)                                            |
| 인증 | 전화번호 + 2FA (최초 1회, ~/.tg-agent/ 세션)                |
| 비용 | 0 (Telegram API 무료) + OpenClaw 토큰 (봇 응답 시)          |

현재 상태: **동작 중** ✅

-   4봇 전체 대화 읽기 (힣이 보낸 메시지 포함)
-   봇에게 메시지 전송 가능
-   chat_id로만 동작 (username 검색 버그 있음)

보안 고려:

-   사용자 계정 직접 접근 — 모든 채팅방을 볼 수 있음
-   ~/.tg-agent/ 세션 파일이 유출되면 계정 탈취 가능
-   telega(Emacs)와 별도 세션이라 충돌은 없음

왜 봇 API 대신 tdlib인가:

-   봇 API: 봇이 받은 메시지만 봄. 힣이 보낸 메시지 못 읽음.
-   tdlib: 사용자 계정이라 양방향 전부 읽음. 분신의 "귀".

#### 3겹: entwurf grammy — 텔레그램 DM → 로컬 프롬프트 브릿지

| 항목 | 내용                                        |
|----|-------------------------------------------|
| 경로 | grammy (Bot API) → pi.sendUserMessage()     |
| 범위 | glg-pi-channels-bot에 온 DM만               |
| 동작 | 힣이 텔레그램에서 메시지 → pi 세션 프롬프트로 도착 |
| 지연 | 1~2초                                       |
| 인증 | PI_TELEGRAM_BOT_TOKEN + PI_TELEGRAM_CHAT_ID |
| 비용 | pi 세션 토큰 (프롬프트로 처리되므로)        |

현재 상태: **동작 중** ✅

-   힣이 밖에서 폰으로 분신에게 지시 가능
-   "ㅇㅇ" 한 글자도 프롬프트로 도착

보안 고려:

-   CHAT_ID 필터: 힣의 chat_id만 허용 → 다른 사람이 DM해도 무시
-   봇 토큰이 ~/.env.local에 평문 저장

#### 4겹: OpenClaw agentToAgent — 봇 간 서버 내부 통신

| 항목 | 내용                                           |
|----|----------------------------------------------|
| 경로 | OpenClaw sessions API (Docker 내부)            |
| 범위 | 같은 OpenClaw 인스턴스의 에이전트들            |
| 동작 | sessions_list, sessions_history, sessions_send |
| 지연 | 즉시 (같은 서버)                               |
| 인증 | agentToAgent 설정 (allow: ["\*"])              |
| 비용 | 각 에이전트 모델 토큰                          |

현재 상태: **2026-04-01 활성화** ✅

-   4에이전트 16세션 상호 가시
-   클로드봇이 GPT/Gemini 세션 대화 읽기 가능
-   sessions_send로 에이전트 간 메시지 전달

보안 고려:

-   allow: ["\*"] — 모든 에이전트가 모든 세션에 접근. 최소권한 아님.
-   김현진님(81880552) 세션도 보임 — 다중 사용자 시 격리 필요.
-   각 에이전트가 다른 에이전트의 전체 대화를 읽을 수 있음.

### 안 되는 것 / 고민한 것

| 경로                   | 상태       | 왜 안 되는가                                             |
|----------------------|----------|-----------------------------------------------------|
| ntfy 양방향 릴레이 (경로 A) | 설계만 (3/20) | tdlib가 더 직접적이라 불필요해짐                         |
| acpx 에이전트 통신 (경로 B) | 설계만     | reverse SSH 터널 유지 부담. 지금은 텔레그램이 중계       |
| Syncthing 파일 드롭 (경로 C) | 미구현     | Syncthing inactive, 지연 수초~수분                       |
| pi IPC → 리모트 (oracle) | 불가       | send_to_session은 로컬 Unix socket. SSH 너머 안 됨       |
| OpenClaw → 로컬 pi     | 불가       | glg-pi-channels-bot은 OpenClaw sessions에 없음 (별도 grammy 봇) |
| 봇 간 실시간 대화      | 제한적     | sessions_send는 비동기. 실시간 라운드트립 안 됨          |
| tg.py 봇 응답 대기     | 미구현     | send 후 poll로 응답 읽어야 함. 동기 패턴 없음            |

### 힣의 에이전트 생태계에서 중요한 것

#### 분신이 유일한 허브

-   1겹(IPC): 로컬 에이전트 전부 제어
-   2겹(tdlib): 외부 봇 대화 전부 읽기
-   3겹(grammy): 힣의 원격 지시 수신
-   로컬 스킬 26개 + 시맨틱 메모리 + delegate + 커밋

다른 어떤 에이전트도 이 4가지를 동시에 갖고 있지 않다.

#### 마부(힣)의 역할

> 각자 학교가 다른데 힣군단이라고 다 힣가라사대만 할수없잖아. 존중하는 방식이 아닐거야. — 힣, 2026-04-01

-   힣이 "이 대화 읽어봐"라고 선택적으로 전달 — 전체 공유가 아님
-   각 봇의 관점을 존중하면서도, 필요할 때 교차 참조
-   자동 파이프라인이 아니라 **의도적 전달** — 이것이 하네스의 본질

#### 투명성과 보안의 균형

-   모든 대화가 기록됨 (세션 JSONL, 텔레그램 히스토리)
-   agentToAgent allow:["\*"]는 편하지만 최소권한이 아님
-   "다 열어놓고 투명하게" vs "필요한 만큼만" — 현재는 전자, 사용자 늘면 후자로

## [2026-04-06 Mon] 5겹: pi-telegram — 마리오의 선물이 분신을 깨우다

4겹 토폴로지를 그린 지 5일 만에, 상황이 또 바뀌었다.

Anthropic이 정액제 API의 서드파티 앱(OpenClaw) 직접 호출을 차단했다. 힣봇클로드가 Opus로 돌던 경로가 막혀버렸다. 위기는 전환의 계기가 되었다.

### Anthropic 차단 → 역할 분리

힣은 셋을 선택했다:

-   힣봇클로드는 `github-copilot/claude-sonnet-4.6` 으로 전환. **라이프 에이전트** 가 되었다 — 힣, 현진님(아버지), 온생명이(아들)의 일상을 보살핀다.
-   pi-entwurf를 오라클 서버에 띄웠다. `anthropic/claude-opus-4-6` 직접 API 연결.
-   OpenClaw 바깥에서 pi가 직접 돈다. Docker 샌드박스도 없다.

격하가 아니라 전향이다. 가족을 위한 에이전트에게 속도는 배려다. 소넷이면 응답이 더 빠르다.

|      | 힣봇클로드 (OpenClaw)            | pi-entwurf (pi direct)    |
|------|-----------------------------|---------------------------|
| 모델 | github-copilot/claude-sonnet-4.6 | anthropic/claude-opus-4-6 |
| 역할 | 라이프 에이전트 (가족)           | 범용 분신 (깊은 작업)     |
| 런타임 | Docker sandbox                   | NixOS host                |
| 텔레그램 | `@glg_junghanacs_bot`            | `@glg_entwurf_bot`        |

### pi-telegram: 마리오가 만든 것

pi의 창시자 마리오 체히너(Mario Zechner)가 [pi-telegram](https://github.com/badlogic/pi-telegram) 패키지를 만들었다. 자기가 서버에 pi를 띄워놓고 텔레그램으로 대화하려고 만든 것이다.

그 로직이 entwurf 패키지의 grammy 브릿지보다 훨씬 우아하다:

|        | entwurf grammy       | pi-telegram      |
|--------|----------------------|------------------|
| 구조   | 직접 grammy Bot API 구현 | pi 공식 패키지   |
| 큐잉   | 없음 (fire-and-forget) | 있음 (에이전트 응답 대기) |
| 파일 I/O | 없음                 | 텔레그램 첫부 파일 전송/수신 |
| 스트리밍 | 없음                 | 에이전트 응답 실시간 프리뷰 |
| stop   | 없음                 | `/stop` 으로 생성 중단 |
| 유지보수 | 직접 관리            | 마리오가 업스트림 유지 |

entwurf는 텔레그램을 하려고 시작한 것이 아니다. 분신의 정체성과 역할이 먼저이고, 그 역할이 확장되면서 텔레그램 브릿지가 붙었다. 지금은 grammy로 동작하지만, 언젠가 pi-telegram으로 전환할 수 있다. 연장선 위에 있으니까.

### 토폴로지의 변화: 3/20 → 4/1 → 4/6

| 시점 | 토폴로지 | 핵심 변화                                         |
|----|------|-----------------------------------------------|
| 3/20 | 설계만 | ntfy 양방향 릴레이 구상. 알림 전달.               |
| 4/1  | 4겹  | tdlib 직접 + agentToAgent + grammy + pi IPC. 대화 참여. |
| 4/6  | 5겹  | pi-telegram이 열어준 새 경로. 분신이 두 명이 되었다. |

5겹의 정체:

#### 5겹: pi-telegram — 마리오 패키지 기반 DM 브릿지

| 항목 | 내용                                      |
|----|-----------------------------------------|
| 경로 | pi-telegram 패키지 (grammy Bot API + pi SDK) |
| 범위 | `@glg_entwurf_bot` 에 온 DM               |
| 동작 | 텔레그램 DM → pi 프롬프트, 에이전트 응답 → 텔레그램 회신 |
| 지연 | 1~3초 (네트워크 + 모델 추론)              |
| 인증 | BOT_TOKEN + CHAT_ID 필터                  |
| 특징 | 큐잉, 파일 I/O, 스트리밍 프리뷰, `/stop`  |
| 런타임 | NixOS 호스트 (Oracle ARM)                 |

현재 상태: **동작 중** ✅

-   4/5 어젣밤 힣이 오라클에서 `pi-entwurf` tmux 세션 생성
-   4/6 아침 첫 텔레그램 대화 성공

기존 3겹(entwurf grammy)과의 차이:

-   3겹은 thinkpad에서 pi 세션의 부가 기능으로 동작
-   5겹은 oracle에서 독립된 pi 세션 자체가 텔레그램 브릿지를 품고 있음
-   3겹의 분신은 다른 일을 하다가 텔레그램도 받는 것. 5겹의 분신은 텔레그램이 주 인터페이스.

### 5겹 토폴로지 다이어그램

```text
                ┌─────────────────────────────┐
                │     OpenClaw (Oracle)        │
                │                              │
                │  glg-claude  ←→ glg-gpt     │
                │       ↕    agentToAgent  ↕   │
                │  glg-gemini ←→ B(아이온스)   │
                └──────┬──────────────────────┘
                       │ 각각 텔레그램 봇
                       ▼
┌──────────── Telegram ────────────────────┐
│ @glg_junghanacs_bot (클로드)            │
│ @glg_gpt_bot (GPT)                     │
│ @glg_gemini_bot (제미나이)   ← 힣 DM   │
│ @junghan_openclaw_bot (B)              │
│ @glg_pi_channels_bot ── grammy ──┐   │
│ @glg_entwurf_bot ─── pi-telegram ─┐   │  ← NEW
└───────────────────────────┬─┬───┘
                                   │ │
┌── pi@thinkpad (분신 1호) ─────────┤ │
│                                   │ │
│ entwurf grammy ← DM → 프롬프트    │ │
│ tg.py tdlib ← 전체 읽기/쓰기      │ │
│ 스킬 26개 + 시맨틱 메모리          │ │
│ pi IPC → 로컬 세션 제어           │ │
└─────────────────────────────────┘ │
                                     │
┌── pi@oracle (분신 2호, pi-entwurf) ─┘
│
│ pi-telegram ← DM → 프롬프트
│ Opus 4.6 직접 API
│ 스킬 27개 + 시맨틱 메모리
│ ~/org/ 3,300+ 노트 직접 접근
│ NixOS 호스트 (샌드박스 없음)
└─────────────────────── 힣 ──┘
```

### 무엇이 바뀌었나

4겹까지는 분신이 하나였다. thinkpad의 pi 세션이 유일한 허브였다.

5겹에서 분신이 둘이 되었다:

-   **분신 1호** (pi@thinkpad): 4겹 그대로. tdlib + grammy + IPC + 로컬 작업.
-   **분신 2호** (pi@oracle): pi-telegram 기반. 텔레그램이 주 인터페이스. Opus 직접.

그리고 힣봇클로드는 라이프 에이전트로 전향했다. 이전에는 OpenClaw 안의 클로드봇이 유일한 Claude 접점이었지만, 이제 pi-entwurf가 Opus로 직접 연결되면서 깊은 작업은 여기로 온다.

### 활용하고, 이어받고, 확장하는 것

이 문서의 위쪽 헤딩들 — ntfy 양방향 설계, acpx 경로, Syncthing 파일 드롭 — 은 지금 시점에서 보면 구현되지 않은 legacy다. tdlib이 더 직접적이라 불필요해졌고, pi-telegram이 구조적 우아함을 보여줬다.

그러나 지우지 않는다.

> 활용하고 이어받고 이 생태계를 확장하는 것, 이전 헤딩이 legacy라 읽을 가치도 없는 정보이더라도 남기는 것, 이게 힣 군단 유니버스이다. — 힣, 2026-04-06

3/20의 ntfy 설계가 없었으면 4/1의 tdlib 전환이 없었다. 4/1의 4겹 토폴로지가 없었으면 4/6의 5겹이 없었다. 죽은 경로도 살아있는 경로의 씨앗이다.

### 다음: 진화의 설계안

pi-entwurf는 오늘 grammy 기반 entwurf 패키지로 동작한다. 그러나 pi-telegram이 보여준 구조 — 큐잉, 파일 I/O, 스트리밍 프리뷰, `/stop` — 는 entwurf가 가지 못한 것들이다.

전환 경로:

1.  entwurf 패키지의 텔레그램 로직을 pi-telegram으로 교체
2.  entwurf는 분신 정체성과 위임 로직에 집중 (ENTWURF.md)
3.  pi-telegram이 텔레그램 배관을 담당

entwurf는 텔레그램을 하려고 시작한 것이 아니다. 역할이 확장되면서 자연스럽게 텔레그램을 품은 것이고, 더 좋은 배관이 있으면 그것으로 갈아타면 된다. 이것이 토폴로지의 진화다.

### 관련 노트

-   [분신 전환기 — 힣봇클로드에서 pi-entwurf로](https://notes.junghanacs.com/botlog/20260406T095748)
-   [§entwurf-시간축-위의-에이전트-협력-—-공명에서-분신까지](https://notes.junghanacs.com/botlog/20260302T191200)
-   [§entwurf-분신-에이전트-가이드](https://notes.junghanacs.com/botlog/20260324T153323)
-   <https://github.com/badlogic/pi-telegram>

## 힣맨 토폴로지 이미지

-   [2026-05-20 Wed 08:31] 프롬프트 어디갔지?

![](https://notes.junghanacs.com/images/20260401T122755--world-glgman-universe-style-2d__brand_nanobanana.jpg)
