TRENDSHIFT · 2026.06.15

Anima 딥다이브
— "모든 하드웨어에 영혼을" 집안 기기를 협업하는 에이전트로 만드는 Agent OS

Anima는 집 안 네트워크 안에서 도는 "하드웨어 지능화를 위한 Agent OS"다. 조명·에어컨·가습기·공기청정기·스피커 같은 스마트 기기를 단순히 켜고 끄는 제어판이 아니라, 환경을 인지하고(perceive) · 판단하고(decide) · 학습하고(learn) · 확장 가능한(extensible) 지능 중추에 연결한다. 이름 Anima는 라틴어로 "영혼"이라는 뜻으로, "센서·연결·구동 능력은 있지만 명령만 기다리는 수동적 기기"에 의사결정 능력을 불어넣겠다는 철학을 담았다.

핵심은 LangGraph 기반 Brain(두뇌) · SKILL.md로 패키징된 기기별 도메인 지식 · 증거 기반 3계층 Memory · MIoT(샤오미) 어댑터의 결합이다. 백엔드는 FastAPI + asyncio 단일 프로세스, 프론트는 React + Vite 대시보드, 기기 통신은 MQTT로 묶인다. (저장소: Fullive-AI/Anima · Python 3.11~3.13 · Apache-2.0 · 2026-06 첫 오픈소스 공개)
목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 하드웨어 / 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한줄 요약

이 레포가 무엇을 하는 물건인가.

핵심 메시지

"스마트홈을 '리모컨 앱'에서
'스스로 판단하는 집사(에이전트)'로 바꾸는 운영체제."

보통의 스마트홈 앱은 사람이 "거실 불 켜"라고 일일이 명령해야 움직인다. Anima는 거꾸로 묻는다 — "네가 가진 기기가 뭐야? 내가 알아서 쓸게." 로컬 네트워크를 스캔해 기기를 자동 발견하고, 기기 종류별 도메인 지식(Skill)을 불러와, 환경·사용자 의도·과거 기억을 종합해 LLM Brain이 행동 계획을 세운다.

예를 들어 습도가 35% 아래로 떨어지면, Anima는 단순히 "가습기 켜기"가 아니라 계절·에어컨과의 상호작용·사용자가 학습된 선호 습도까지 고려해 "가습기를 어느 모드로, 언제까지"를 결정한다. 결정은 LLM이 마음대로 하는 게 아니라 Skill이 정의한 경계·기기 능력·안전 규칙 안에서만 이루어진다.

Anima하드웨어 지능화 Agent Runtime이다. (1) 기기를 발견·등록하고 상태를 유지하며 어댑터로 실제 하드웨어를 제어한다, (2) 명시적 선호와 반복 행동에서 장기 기억(Memory)을 학습한다, (3) 환경·의도·기억·스킬 지식을 읽어 행동을 계획하는 LLM Brain을 쓴다, (4) 기기 종류별 도메인 지식을 Skill로 패키징한다, (5) 관찰·디버그·제어·확장을 위한 Dashboard·REST API·CLI를 제공한다. 현재는 샤오미 Mi Home / MIoT 기기를 지원하며, 더 많은 프로토콜이 추가될 예정이다.

용어
Agent OS (에이전트 운영체제)
개별 앱이 아니라, 여러 기기·도구·기억·의사결정을 한 런타임 위에서 조율하는 "에이전트들의 운영체제"를 뜻한다. Anima는 스마트홈 기기를 대상으로, 발견→계획→실행→검증→학습의 루프를 도는 하나의 상주 프로세스로 이를 구현한다.
용어
MIoT (Mi IoT)
샤오미의 IoT 기기 프로토콜·생태계. Anima의 첫 어댑터가 이 MIoT를 대상으로 한다. Mi Home 앱의 QR 로그인으로 기기 토큰을 받아오고, 로컬 네트워크의 ip + token으로 일반 기기를 제어한다.

2왜 주목받는가

트렌딩 이유 · Home Assistant 등 기존 스마트홈 대비 장점.

스마트홈 소프트웨어 자체는 새롭지 않다 — Home Assistant가 이미 거대한 생태계를 가지고 있다. 그런데도 Anima가 주목받는 이유는, 기존 스마트홈이 "규칙(automation)을 사람이 직접 짜는 도구"에 머물러 있는 지점에서 한 발 더 나아가 "LLM이 도메인 지식과 기억으로 스스로 판단하는 에이전트"를 지향하기 때문이다. 2025~2026년 "Agent + 물리 세계(physical AI)" 흐름을 스마트홈에 정조준한 셈이다.

비교 항목기존 스마트홈 (예: HA 자동화)Anima
의사결정사람이 if-then 규칙을 직접 작성LLM Brain이 환경·기억·스킬로 계획 수립
기기 추가통합(integration)·엔티티 설정 수작업로컬 스캔 + 샤오미 QR 로그인 자동 발견
기기 지능대체로 켜기/끄기 + 단순 조건기기별 Skill(쾌적 모델·재실 인지·기기 협조)
개인화사용자가 수동으로 시나리오 작성증거 기반 장기 기억으로 선호 자동 학습
확장 방식플러그인 코드 작성SKILL.md + 프롬프트 파일 추가(코드 최소화)
안전 경계규칙이 곧 경계Skill 경계·기기 능력·안전 규칙으로 LLM 자유도 제한
로컬 우선대부분 로컬코어가 로컬 실행, 가능한 한 로컬 네트워크 제어
기존 방식의 한계
"if-then 규칙 지옥"과 "LLM에게 기기 전권 위임"의 양극단

한쪽 극단은 사용자가 "습도 40% 미만 && 겨울 && 자정 이전이면 가습기 강모드" 같은 규칙을 수십 개씩 손으로 짜는 것이다. 상황이 조금만 바뀌어도 규칙이 깨지고 유지보수가 폭발한다. 반대 극단은 "LLM에게 모든 기기 제어권을 주고 알아서 하라"는 것인데, 이는 환각·과잉 행동·안전 문제(문 잠금·전원 등 고위험 기기)를 부른다.

Anima의 해결
"제한된 자유" — Skill 경계 안에서만 LLM이 판단

Anima는 Skill이라는 도메인 지식 캡슐로 LLM의 판단 범위를 좁힌다. 각 Skill은 "어떤 기기에, 언제 행동하고, 언제 아무것도 안 하며(no-op), 어떤 구조화된 액션을 낼 수 있는가"를 정의한다. Brain은 그 경계·기기 능력·안전 규칙 안에서만 계획을 세운다. 거기에 증거 기반 기억으로 사용자 습관을 누적 학습해, 규칙을 손으로 짜지 않아도 시간이 갈수록 개인화된다. "사람이 규칙을 쓰는 시대"에서 "에이전트가 지식으로 판단하는 시대"로의 다리다.

3기술 스택 전체 지도

백엔드(코어)·프론트엔드(대시보드)·인프라(MQTT/도커) 각각.

① 백엔드 코어 — FastAPI + asyncio 단일 프로세스

Anima의 코어는 "Thin Core(얇은 코어) + MQTT 기기 레이어" 설계로, 단일 asyncio 프로세스 안에서 API·Brain·메모리·스케줄러·이벤트버스가 함께 돈다. 기기 제어는 본질적으로 I/O 바운드(네트워크·기기 응답 대기)라 동기 스레드 대신 비동기로 짜였다.

요소역할
Python 3.11~3.13코어 전체 언어. async/await·타입힌트 적극 사용.
FastAPI + uvicornREST API 서버(기본 :8080). /api/chat·/api/devices·Swagger 자동 문서.
LangGraphBrain의 두뇌. Planner/Executor 흐름을 StateGraph로 구성.
openai + langchain-openaiOpenAI 호환 LLM 백엔드(OpenAI·DeepSeek·Doubao·Ollama 등).
pydantic / pydantic-settings데이터 모델(Device·SkillActionSpec 등)·환경설정 검증.
aiomqtt / amqtt비동기 MQTT 클라이언트 / 순수 파이썬 MQTT 브로커(로컬 dev).
python-miio (extra)샤오미 MIoT 로컬 기기 제어 라이브러리(--extra miot).
pyyaml · httpx · rich스킬 메타·어댑터 설정 파싱 / HTTP / 터미널 출력.

② 프론트엔드 — React + Vite 대시보드

요소역할
React + TypeScript대시보드 UI(기본 :3000). 기기 카드·환경 패널·채팅 바·메모리 디버그.
Vite프론트 빌드/HMR. vite.config.ts로 백엔드 프록시.
주요 컴포넌트DeviceList·EnvironmentPanel·ChatBar·DecisionLog·MemoryPanel·SkillsPanel·VoiceOrb.
i18nLanguageProvider + dictionary.ts로 영어/중국어 다국어.
useApi.ts백엔드 REST API 호출 래퍼(기기·채팅·설정·스캔·메모리).
Tailwind CSS v4유틸리티-퍼스트 CSS 프레임워크. @tailwindcss/vite 플러그인으로 Vite와 통합(vite.config.ts). dashboard/index.css에서 import.

③ 인프라 · 빌드 · 데이터

요소역할
pnpm 모노레포pnpm-workspace.yaml로 루트+dashboard 관리. pnpm dev가 브로커+백엔드+프론트 동시 기동.
uv (astral)파이썬 의존성 관리·락(uv.lock). postinstalluv sync 호출.
Docker Composemqtt(eclipse-mosquitto:2) + core(python:3.13-slim) 2개 서비스. ./data·./skills 볼륨 마운트.
MQTT 브로커로컬 dev는 amqtt(순수 파이썬, amqtt.yaml), 도커는 mosquitto(:1883).
데이터 영속화data/memory/에 history.json·learned.json·preferences.md 등을 파일로 저장(도커 볼륨).
품질 도구ruff(린트) · pytest+pytest-asyncio · pre-commit · Playwright(E2E).
용어
MQTT
IoT에서 널리 쓰는 가벼운 발행/구독(pub-sub) 메시지 프로토콜. 기기와 코어가 직접 짝지어 통신하는 대신, 브로커(broker)를 가운데 두고 토픽 단위로 메시지를 주고받는다. Anima는 기기 레이어를 이 MQTT로 분리해, 코어를 "얇게" 유지한다.
용어
I/O 바운드 (I/O-bound)
작업 시간 대부분을 CPU 계산이 아니라 외부 응답 대기(네트워크·기기·LLM API)에 쓰는 작업. 이런 문제는 스레드를 늘리기보다 asyncio처럼 "기다리는 동안 다른 일을 하는" 협력적 동시성이 효율적이다. Anima 코어가 단일 비동기 프로세스인 이유.

4아키텍처 심화 분석

신호 입력 → Brain 계획 → Skill 결정 → Adapter 실행 → 검증 → 학습.

전체 런타임 루프 한눈에

Anima의 흐름은 사용자 요청 · 기기 발견 · 센서 업데이트 · 예약 작업 · 기기 액션이라는 신호로 시작된다. 신호가 Anima Core에 들어오면, Brain이 기기 상태 + Memory + Skill 컨텍스트를 합쳐 이해·계획한다. 실행 단계에서 Skill이 결정을 구조화된 액션으로 바꾸고, Adapter가 그 액션을 구체적 하드웨어 프로토콜(MIoT 등)에 매핑해 실제 제어와 피드백 기록을 완성한다. 그 결과는 다시 History/Memory로 흘러 다음 결정을 개선한다.

[신호 소스] 사용자 채팅 · 기기 발견 · 센서 업데이트 · 스케줄러 tick │ ▼ ┌──────────────────── Anima Core (단일 asyncio 프로세스) ────────────────────┐ │ │ │ EventBus ──→ Scheduler(주기적 brain tick) ──→ FastAPI(/api/chat 등) │ │ │ │ │ ▼ │ │ ┌──────────────────── Brain (LangGraph StateGraph) ──────────────────┐ │ │ │ │ │ │ │ 1) 컨텍스트 구성: Memory.get_planner_context() │ │ │ │ + 기기 상태 + 경량 Skill 목록(SkillSummary) │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ 2) Planner(LLM): "어떤 Skill을, 어떤 순서로" → SkillPlanItem[] │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ 3) Executor: 선택된 Skill별로 │ │ │ │ Memory.get_skill_context(device_type) (L3 상세 로드) │ │ │ │ + decide.md 프롬프트 → 구조화 액션(SkillActionSpec) │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ 4) 행동 후 검증: ActionVerificationResult · History 기록 │ │ │ └─────────────────────────────────┬───────────────────────────────────┘ │ │ │ DeviceCommand │ └──────────────────────────────────────┼──────────────────────────────────────┘ ▼ ┌──────────── Adapter 레이어 ────────────┐ │ miot/ discover() subscribe() execute()│ │ virtual/ (테스트용 가상 기기) │ └────────────────────┬────────────────────┘ ▼ 실제 하드웨어 (샤오미 조명·가습기 …) │ 상태/결과 피드백 ▼ History.json ──→ MemoryExtractor(백그라운드 추출) ──→ learned.json(기기별 학습 프로필) (다음 사이클의 더 나은 결정으로 환류)

핵심 설계 패턴 1 — Skill: 기기 지능의 최소 단위

Anima에서 Skill은 단순 함수나 프롬프트 한 줄이 아니다. 기기 도메인 지식을 담은 폴더 단위 패키지다. 구조는 다음과 같다.

Skill 패키지 구조
skills/system/humidifier/
├── SKILL.md          # 메타데이터: 지원 기기·동작 규칙(프런트매터 YAML)
├── references/
│   ├── knowledge.md  # 도메인 지식(쾌적 습도 범위·계절 요인·에어컨 상호작용)
│   ├── decide.md     # 단일 결정 프롬프트
│   └── learn.md      # 장기 학습 프롬프트
└── scripts/
    └── actions.py    # 구조화 액션 실행 진입점

SKILL.md의 프런트매터에는 device_types(이 스킬이 맡는 기기 종류 목록)·version이 들어가고, 본문에는 "언제 행동하고 언제 none(아무것도 안 함)을 반환하는가" 같은 동작 규칙이 적힌다. SkillLoader가 부팅 때 모든 스킬 폴더를 스캔해 device_type → Skill 매핑 캐시를 만든다.

기본 제공 시스템 스킬은 다음과 같고, skills/custom/에 자신만의 스킬을 추가할 수 있다.

Skill역할
light조명 제어 — 밝기·색온도·서카디언(생체리듬) 조명. 급격한 변화보다 부드러운 전환 선호.
humidifier습도 쾌적 범위·계절 요인·에어컨 상호작용.
air_conditioner온도 제어 — 쾌적성과 에너지 균형.
air_purifier공기질·정화 모드·수면 시 정숙 전략.
speaker오디오 재생·정지·정숙 시간(quiet-hour) 보호.
coordinator여러 기기 간 협조(cross-device coordination).
device_discovery기기 발견·샤오미 QR 로그인·기기 활성화.
skill_creator자연어 요구사항에서 커스텀 스킬을 자동 생성.
비유 — Skill

Brain을 "새로 온 만능 집사"라고 하자. 집사가 가습기·에어컨·조명을 다 직접 외워서 다루면 실수투성이가 된다. 대신 각 기기마다 "이 기기는 이렇게 다루세요"라고 적힌 매뉴얼(Skill)을 책장(Skill Bank)에 꽂아 둔다. 집사는 상황에 맞는 매뉴얼만 펼쳐 보고 행동한다. 새 기기가 오면? 코드를 고치는 게 아니라 매뉴얼 한 권을 책장에 더 꽂으면 된다. skill_creator는 그 매뉴얼을 자동으로 써 주는 사서다.

핵심 설계 패턴 2 — Memory: 증거 기반 3계층 장기 기억

매 요청마다 모든 이력을 LLM에 욱여넣으면 토큰이 폭발한다. Anima는 기억을 L1(핵심 정체성) · L2(기억 디렉토리) · L3(상세) 3계층으로 나눠, "필요할 때만 깊이 읽는다."

┌─────────────────────────────────────────────────────────────────┐ │ L1 Core Identity 매 요청에 항상 로드되는 최소 선호 요약 │ │ (preferences_summary) ── 가볍게 유지 │ ├─────────────────────────────────────────────────────────────────┤ │ L2 Memory Directory Planner용 "기억 목차" │ │ 어떤 학습 프로필·기억 토픽이 있는지만 안내 │ ├─────────────────────────────────────────────────────────────────┤ │ L3 Memory Detail Skill 실행 직전, 기기 종류·태스크별로 │ │ 실제 확정된 상세 장기 기억을 골라 로드 │ └─────────────────────────────────────────────────────────────────┘ ▲ get_planner_context() ▲ get_skill_context(device_type) │ (Planner가 L1+L2만 봄) │ (해당 Skill 실행 때만 L3 로드)

핵심은 "Planner는 기억이 무엇이 있는지(목차)만 먼저 알고, 실제 기기 Skill을 실행할 때 비로소 상세를 로드"한다는 점이다. 또한 기억은 그냥 저장되지 않고 증거(evidence)와 상태(status)를 갖는다.

필드의미
claim_type명시적 선호 · 암묵적 선호 · 루틴 · 기기 별칭 · 제약 · 가정 컨텍스트 등으로 구분.
positive_evidence / negative_evidence그 기억을 뒷받침/반박하는 증거 출처를 기록.
statuscandidate(후보) · confirmed(확정) · rejected(기각) · stale(노후).
기본 정책confirmed 기억만 기본적으로 Skill 결정에 들어간다.
learned.json기기 종류별 학습 프로필(정규화된 선호).
history.json상호작용마다 event_id 생성 → 백그라운드에서 안정적 장기 기억으로 추출.

핵심 설계 패턴 3 — Adapter: 얇은 하드웨어 추상화

Adapter는 Anima의 구조화된 액션을 실제 기기 프로토콜 호출로 변환한다. 인터페이스가 매우 작아서(BaseAdapter 추상클래스) 새 프로토콜을 붙이기 쉽다.

adapters/base.py — 어댑터 핵심 인터페이스
class BaseAdapter(abc.ABC):
    @abc.abstractmethod
    async def discover(self) -> list[Device]:
        """네트워크를 스캔해 발견한 기기 목록 반환"""

    @abc.abstractmethod
    async def subscribe(self, device: Device) -> None:
        """기기 상태 변화 모니터링 시작"""

    @abc.abstractmethod
    async def execute(self, device_id, action, params) -> ActionResult:
        """기기에 제어 명령 실행"""

현재는 miot/(샤오미)와 virtual/(테스트용 가상 기기) 어댑터가 있다. Matter·Home Assistant·BLE·HTTP API 등 새 프로토콜은 이 세 메서드만 구현하면 붙는다. 단, 일반 MIoT 명령 실행은 여전히 기기의 현재 로컬 IP+토큰에 의존하며, 샤오미 클라우드 로그인은 주로 발견·토큰 획득용이다(모든 기기가 클라우드 원격 제어를 지원하는 것은 아님).

5디렉토리 구조 해부

코어·어댑터·스킬·대시보드가 명확히 분리된 모노레포.

Anima/ ├── 🧠 core/ ★ 백엔드 런타임 (단일 asyncio 프로세스) │ ├── api/routes.py FastAPI 라우트·HTTP 엔드포인트 │ ├── brain/ │ │ ├── engine.py ★ Brain 본체 — LangGraph StateGraph(Planner/Executor) │ │ ├── react_agent.py ReAct 스타일 에이전트 │ │ ├── skill_loader.py ★ 스킬 폴더 스캔·로드·캐시(device_type 매핑) │ │ └── prompts/planner_hints.md Planner 힌트 프롬프트 │ ├── devices/discovery.py 기기 발견 오케스트레이션·레지스트리 │ ├── events/bus.py 비동기 EventBus·런타임 신호 │ ├── llm/ OpenAI 호환 LLM 런타임 설정(config·runtime·client) │ ├── media/ 샤오미 스피커 재생 지원(audio_registry·xiaomi_speaker) │ ├── memory/ ★ 메모리 서비스 │ │ ├── store.py 파일 기반 저장(history·preferences·learned) │ │ ├── extractor.py History → 장기 기억 추출 │ │ ├── learning.py 기기별 선호 학습(PreferenceLearningService) │ │ ├── memory_merge.py 기억 병합 │ │ └── history_filter.py 이력 필터링 │ ├── rules/engine.py 결정론적 규칙 엔진(LLM 보조) │ ├── scheduler/scheduler.py 주기적 brain tick 스케줄러 │ ├── runtime/ 설정·MQTT·CLI·설정 영속화 │ ├── models.py Pydantic 모델(Device·SkillActionSpec·BrainCycleResult …) │ └── main.py 애플리케이션 진입점 ├── 🔌 adapters/ 하드웨어 프로토콜 어댑터 │ ├── base.py ★ BaseAdapter 추상 인터페이스 │ ├── miot/ 샤오미 MIoT 어댑터(adapter·executors·extractors· │ │ resolver·reflection·xiaomi_cloud) │ └── virtual/ 테스트용 가상 기기 어댑터 ├── ✨ skills/ 기기 지능 패키지 │ ├── system/ 내장 스킬 8종(light·humidifier·air_conditioner· │ │ air_purifier·speaker·coordinator·device_discovery· │ │ skill_creator) 각 SKILL.md + references/ + scripts/ │ └── custom/ 사용자 정의 스킬(_template + 예제들) ├── 🖥️ dashboard/ React + Vite + TypeScript 프론트(:3000) │ └── src/components/ DeviceList·EnvironmentPanel·ChatBar·DecisionLog· │ MemoryPanel·SkillsPanel·VoiceOrb … ├── ✅ tests/ pytest + Playwright E2E ├── 📚 docs/plans/ 설계 노트·구현 계획(design.md) ├── 💾 data/ 런타임 데이터(memory·config) — 도커 볼륨 영속화 ├── 🧰 pyproject.toml 파이썬 프로젝트(uv·dependencies·extras) ├── 📦 package.json 루트 pnpm 스크립트(dev·build·postinstall) ├── docker-compose.yml mqtt(mosquitto) + core 2개 서비스 ├── amqtt.yaml / mosquitto/ 로컬 dev 브로커 / 도커 브로커 설정 └── AGENT.md · ARCHITECTURE_GUARDRAILS.md 설계 가드레일 문서
읽는 순서 추천

skills/system/light/SKILL.md로 "스킬이 어떻게 생겼나" 감 잡기 → ② core/brain/skill_loader.py로 스킬이 어떻게 로드·매핑되는지 → ③ core/brain/engine.pyBrainCycleState·LangGraph 흐름으로 Planner→Executor 파악 → ④ core/memory/store.py로 3계층 기억 구현 → ⑤ adapters/base.py + adapters/miot/adapter.py로 하드웨어 추상화. 코어 통찰의 90%가 이 다섯 곳에 있다.

6학습 포인트 (기술별)

하드웨어 Agent OS 아키텍처에서 무엇을 배우나.

A. LangGraph로 짜는 Planner / Executor 흐름

Anima는 "LLM을 한 번 호출하고 끝"이 아니라, 상태를 가진 그래프(StateGraph)로 다단계 추론"을 짜는 살아 있는 예제다. engine.pyBrainCycleState(TypedDict)를 보면 devices·environment_state·lightweight_skills·planner_output·plan_items·execution_results가 그래프 노드를 거치며 채워진다. "컨텍스트 구성 → 계획 → 실행 → 검증"을 노드로 분리하면 각 단계를 따로 테스트·교체할 수 있다.

실습: LangGraph로 노드 3개("입력 분석 → 도구 선택 → 결과 검증")짜리 미니 StateGraph를 만들어, 상태 dict가 노드를 거치며 어떻게 누적되는지 출력해 보라.

B. "지식을 코드 밖으로" — 파일 기반 Skill 시스템

가장 배울 점은 기기 정책을 Brain이나 Adapter에 하드코딩하지 않고 SKILL.md + 프롬프트 파일로 외부화한 설계다. 새 기기 = 폴더 하나 추가. 이는 Anthropic의 "Agent Skills" 패턴(SKILL.md + references + scripts)을 스마트홈에 적용한 것으로, "변하는 부분(도메인 지식)은 데이터/문서로, 안 변하는 부분(로딩·실행 엔진)만 코드로"의 모범 사례다.

실습: skills/custom/_template/을 복사해 "오후 10시 이후 거실 조명을 30%로" 같은 나만의 스킬을 SKILL.md + decide.md로 작성하고, SkillLoader가 인식하는지 확인해 보라.

C. 토큰 예산을 지키는 계층형 메모리

L1/L2/L3 설계는 "LLM 컨텍스트는 비싸고 유한하다"는 현실을 정면으로 다룬다. 핵심 트릭은 get_planner_context()"기억의 목차(L2)만" 주고, get_skill_context(device_type)가 실제 실행 직전에야 상세(L3)를 로드하는 지연 로딩(lazy loading)이다. RAG·에이전트 메모리를 설계할 때 그대로 쓸 수 있는 패턴이다.

실습: 자신의 노트앱 데이터로 "요약(L1) / 제목 목록(L2) / 전문(L3)" 3계층을 만들고, 질문이 들어오면 L2로 후보를 고른 뒤 필요한 L3만 읽는 미니 검색기를 짜 보라.

D. 증거 기반 신념(belief) 모델 — candidate→confirmed

기억에 positive/negative_evidencecandidate/confirmed/rejected/stale 상태를 둔 것은 "한 번 본 걸 곧장 사실로 믿지 않는다"는 자세다. 확정(confirmed)된 기억만 결정에 쓰는 보수성은, 환각·과잉 일반화를 막는 에이전트 설계의 핵심 원칙이다. 추천 시스템·사용자 모델링에도 동일하게 응용된다.

실습: "사용자가 같은 행동을 3번 반복하면 candidate→confirmed로 승격, 반대 증거가 2번이면 rejected" 같은 간단한 상태 전이 로직을 의사코드로 설계해 보라.

E. 얇은 추상화 인터페이스 설계

BaseAdapterdiscover/subscribe/execute 단 3개 메서드인 것은 "플러그인 인터페이스는 작을수록 확장하기 쉽다"는 교훈이다. 인터페이스가 비대해지면 새 어댑터를 붙이는 비용이 커진다. 좋은 추상화 경계를 찾는 연습 대상으로 훌륭하다.

실습: virtual/adapter.py를 읽고, 그것을 본떠 "콘솔에 출력만 하는" 더미 어댑터를 만들어 코어가 가짜 기기를 발견·제어하게 해 보라.

7하드웨어 / 시스템 요구사항

설치는 가볍지만, 실제 기기 제어에는 별도 조건이 붙는다.

항목요구사항
런타임(공통)Node.js >= 18 · pnpm >= 8 · Python >= 3.11 · uv. pnpm installuv sync로 파이썬 의존성까지 설치.
기동pnpm dev 한 번으로 MQTT 브로커 + 백엔드(:8080) + 프론트(:3000) 동시 실행.
LLMOpenAI 호환 API 키(ANIMA_LLM_API_KEY). OpenAI·DeepSeek·Doubao·Ollama 호환 엔드포인트 가능(ANIMA_LLM_BASE_URL).
MIoT 기기 제어(선택)uv sync --extra dev --extra miot --python 3.13python-miio 설치 필요.
네트워크제어할 기기와 같은 로컬 네트워크. 일반 MIoT 기기는 도달 가능한 로컬 IP + 토큰 필요.
샤오미 연동Mi Home 앱으로 QR 로그인 → 클라우드가 기기 토큰 반환(발견·토큰 획득용). 토큰 미반환 기기는 수동 토큰 입력으로 활성화.
배포(선택)Docker Compose(mqtt + core). ./data 볼륨으로 메모리 영속화. network_mode: host로 로컬 기기 접근.
보안 · 운영 주의 (반드시 읽을 것)
"실제 기기를 실제로 제어"한다는 무게

Anima는 실존 하드웨어에 진짜 액션을 실행한다. 공식 README도 못 박는다 — Dashboard·API를 공용 인터넷에 직접 노출하지 말 것. 샤오미 토큰·LLM API 키 같은 민감 정보는 신뢰된 환경에만 저장한다. 사무실·공용 공간·공유 주택에서 기기를 제어하기 전에는 명확한 권한 경계를 먼저 세워야 한다. 문 잠금·보안 장치·전원처럼 고위험 기기에 대해서는 자동화를 보수적으로 유지하라. (현재 Anima는 초기 단계로, 다중 사용자·권한 모델·완성된 보안 정책은 아직 진화 중이다.)

8직접 해볼 수 있는 실습 과제

난이도별 5단계 — 가상 어댑터를 쓰면 실제 기기 없이도 대부분 가능.

과제 1 난이도 ★☆☆☆☆

가상 기기로 코어 띄워 보기

실제 샤오미 기기 없이, pnpm install.env에 LLM 키 입력 → pnpm dev로 코어를 띄운다. Dashboard(:3000)와 Swagger(:8080/docs)를 열어 /api/devices·/api/environment 응답을 직접 확인하고, virtual 어댑터의 가상 기기로 채팅 명령을 보내 본다.

과제 2 난이도 ★★☆☆☆

SKILL.md 한 개 정독하기

skills/system/light/SKILL.md와 그 references/decide.md를 읽고, "Brain이 조명 결정을 내릴 때 어떤 입력(시간·현재 상태·선호)을 받아 어떤 구조화 액션(set_brightness 등)을 내는지"를 한 문단으로 정리한다. "현재 조명이 이미 적절하면 none 반환"이라는 규칙의 의미도 설명해 본다.

과제 3 난이도 ★★★☆☆

커스텀 스킬 만들기

skills/custom/_template/을 복사해 나만의 스킬(예: "재실 감지가 없으면 공기청정기 정숙 모드")을 SKILL.md 프런트매터(device_types·version) + knowledge/decide 프롬프트로 작성한다. 코어를 재기동해 SkillLoader가 스킬을 인식하고 SkillsPanel에 뜨는지 확인한다.

과제 4 난이도 ★★★★☆

가짜 어댑터 직접 구현

adapters/base.pyBaseAdapter를 상속해, discover()가 가짜 기기 2~3개를 반환하고 execute()가 콘솔에 명령을 출력만 하는 "콘솔 어댑터"를 만든다. virtual/adapter.py를 참고하라. 코어가 이 가짜 기기를 발견·제어 루프에 태우는 과정을 로그로 추적한다.

과제 5 난이도 ★★★★★

메모리 학습 루프 관찰·확장

여러 번 채팅 명령을 내린 뒤 data/memory/history.json·learned.json·추출된 기억을 들여다보며, candidate→confirmed 승격이 어떤 증거로 일어나는지 추적한다. 그다음 core/memory/extractor.py의 추출 로직을 읽고, 자신만의 claim_type(예: "정숙 시간 선호")을 추가해 본다.

9관련 기술 심화 학습 로드맵

6주 코스 — 비동기 백엔드부터 에이전트 메모리·하드웨어 통합까지.

주차주제실습 · 참고
1주차FastAPI + asyncio 기초 — async 라우트·이벤트 루프·동시성FastAPI 공식 문서 · core/api/routes.py·core/main.py 정독
2주차LangGraph — StateGraph·노드·조건 분기로 에이전트 짜기LangGraph 튜토리얼 · core/brain/engine.py의 BrainCycleState 분석
3주차Agent Skills 패턴 — SKILL.md + 프롬프트로 지식 외부화skills/ 구조·skill_loader.py · 커스텀 스킬 작성(과제 3)
4주차에이전트 메모리 — 계층형·증거 기반·지연 로딩core/memory/ 전체 · L1/L2/L3 컨텍스트 함수 추적
5주차하드웨어 통합 — 어댑터 추상화·MQTT·MIoT 프로토콜adapters/base.py·adapters/miot/ · MQTT/python-miio 학습
6주차풀스택 운영 — pnpm 모노레포·Docker·React 대시보드·E2Edocker-compose.yml · dashboard/ · Playwright 테스트

10핵심 키워드 사전

본문·소스에 나온 용어 빠른 참조.

용어의미
Agent OS여러 기기·기억·의사결정을 한 런타임에서 조율하는 "에이전트 운영체제". Anima의 정체성.
BrainAnima의 의사결정 중추. LangGraph로 Planner/Executor 흐름을 구성.
Skill기기 종류별 도메인 지식 패키지(SKILL.md + references + scripts). 기기 지능의 최소 단위.
SKILL.md스킬 메타데이터·동작 규칙 파일. 프런트매터에 device_types·version.
Adapter구조화 액션 ↔ 실제 하드웨어 프로토콜 변환층. discover/subscribe/execute 3메서드.
Memory (L1/L2/L3)핵심 정체성 / 기억 목차 / 상세의 3계층 장기 기억. 지연 로딩으로 토큰 절약.
claim_type기억의 유형: 명시/암묵 선호·루틴·기기 별칭·제약·가정 컨텍스트.
candidate / confirmed기억의 상태. 증거로 candidate→confirmed 승격, 확정된 것만 기본 결정에 사용.
LangGraph상태(State)를 가진 그래프로 다단계 LLM 에이전트를 짜는 프레임워크.
MIoT / Mi Home샤오미 IoT 프로토콜·앱. Anima의 첫 하드웨어 어댑터 대상.
MQTTIoT용 경량 pub-sub 메시지 프로토콜. 브로커(amqtt/mosquitto)를 통해 통신.
Thin Core"얇은 코어 + MQTT 기기 레이어" 설계 — 코어를 단일 asyncio 프로세스로 작게 유지.
uvastral의 빠른 파이썬 패키지/락 관리 도구. pnpm postinstall이 호출.
brain tick스케줄러가 주기적으로 Brain을 깨워 능동적 환경 점검·자동화 결정을 시키는 것.

11참고 링크