AGENT SKILL

embedding

Use when you need to find things by meaning instead of exact words — reusing a previously generated image that fits the scene, recalling past events or notes from long sessions (RAG over memory.md / logs), looking up reference docs or cheatsheets, grouping similar items, or finding near-duplicate images. Local EmbeddingGemma 2 (multilingual text + images). Covers the four call paths (MCP vector_search / vector_upsert / vector_manage, persona tool context.vectors, panel __panelBridge.vectors), scopes, collection design, and how to read scores. Do not use for exact lookups (ids, names in a JSON file) — read the file instead.

License 许可
MIT
最近更新
2026-10-07
Stars
★ 3
Forks
0

01 前言 Front Matter

name
embedding
description
Use when you need to find things by meaning instead of exact words — reusing a previously generated image that fits the scene, recalling past events or notes from long sessions (RAG over memory.md / logs), looking up reference docs or cheatsheets, grouping similar items, or finding near-duplicate images. Local EmbeddingGemma 2 (multilingual text + images). Covers the four call paths (MCP vector_search / vector_upsert / vector_manage, persona tool context.vectors, panel __panelBridge.vectors), scopes, collection design, and how to read scores. Do not use for exact lookups (ids, names in a JSON file) — read the file instead.

03 SKILL.md 正文

임베딩·의미 검색 (EmbeddingGemma 2)

글이나 이미지를 768차원 벡터로 바꿔 두고, 나중에 뜻이 가까운 것을 찾는다.

  • 다국어를 지원한다. 한글로 물어도 영어 문서를 찾고, 그 반대도 된다.
  • 텍스트와 이미지가 같은 공간에 있어서 글로 이미지를 찾을 수 있다.
  • 로컬 GPU에서 돌아서 호출 비용이 없다.
  • 실측: 쿼리 한 건 약 0.05~0.1초, 이미지 한 장 약 0.1초. 첫 호출은 모델 로드 때문에 약 10~15초 걸린다.

역할 분담

  • 임베딩은 "비슷한 것 찾기"만 한다.
  • 찾은 결과를 읽고 판단하고 서술하는 일은 LLM(지금 이 대화)이 한다.
  • 키·이름·숫자처럼 정확히 일치하는 값을 찾을 때는 파일을 직접 읽어라. 임베딩은 철자가 아니라 뜻을 본다.

네 가지 호출 경로

어디서 어떻게
세션 AI (지금 이 대화) MCP vector_search · vector_upsert · vector_manage
페르소나 도구 tools/*.js await context.vectors("search", { collection, query })
패널·앱 화면 JS await __panelBridge.vectors("search", { collection, query })
HTTP POST /api/sessions/{id}/vectors 본문 { action, ...params }

네 경로 모두 src/lib/vector-index.ts의 같은 액션을 부른다. 액션은 search, upsert, index_dir, index_file, list, info, delete, drop, embed, warmup이다. 빌더 세션에서는 MCP 도구가 동작하지 않는다(세션 전용). embed 액션은 768개 숫자 배열을 그대로 돌려준다. 도구와 패널 코드용이라 세션 AI가 직접 부를 일은 없다. 검색은 vector_search로 해라.

⚠️ 페르소나 도구는 10초 제한이 있다. 모델이 내려가 있으면 첫 호출이 이 제한을 넘을 수 있다.

  • 패널이 열릴 때나 세션 시작 액션에서 vectors("warmup")을 먼저 불러 둬라. warmup은 기다리지 않고 바로 돌아온다.
  • 월드 엔진 step() 안에서는 부르지 마라. 200ms 월드 시계가 멈춘다.

스코프: 어디에 저장하나

scope 위치 쓰임
session (기본) {세션}/vectors/{이름}.json 이 세션의 기억, 대화 기록, 세션 이미지
persona {페르소나}/vectors/{이름}.json 그 페르소나의 모든 세션이 같이 쓰는 갤러리와 설정 문서
global data/vectors/{이름}.json 모든 페르소나가 같이 쓰는 참조 자료(LoRA 치트시트 등)
  • 경로 파라미터(image, dir, file)는 스코프 폴더 기준 상대 경로다. data/ 밖으로는 나갈 수 없다.
  • 검색 결과의 source도 같은 기준이다.

활용 패턴

1. 생성 이미지 재사용 ("한번 생성한 이미지는 반드시 재사용한다")

vector_manage { action: "index_dir", collection: "gallery", dir: "images" }
  → remaining > 0 이면 같은 호출을 반복한다 (한 번에 200장)
vector_search { collection: "gallery", query: "비 오는 옥상에서 우산을 든 유나", topK: 3 }
  → hits[0].source = "images/yuna_rain.png" → $IMAGE:images/yuna_rain.png$
  • index_dir는 증분이다. 바뀌지 않은 파일은 건너뛰고, 지워진 파일은 인덱스에서 뺀다(prune). 새 이미지를 만든 뒤 다시 불러도 비용이 거의 없다.
  • _로 시작하는 파일(빌더 미리보기 등)은 건너뛴다.
  • 페르소나 폴더 이미지(scope: "persona")를 쓸 때 토큰은 $IMAGE:persona:파일명$이다. images/를 빼고 쓴다.
  • 글로 이미지를 찾을 때는 정확도가 낮다. 텍스트↔이미지 점수는 0.6대에 몰려 있다. 정확도를 높이려면 이미지를 생성한 직후 그 프롬프트(장면 설명)를 같은 source로 함께 넣고 dedupeBySource: true로 검색해라.
    vector_upsert { collection: "gallery", items: [
      { id: "images/yuna_rain.png#caption", text: "유나, 비 오는 밤 옥상, 우산, 젖은 교복", source: "images/yuna_rain.png" } ] }
    vector_search { collection: "gallery", query: "...", dedupeBySource: true }
    
  • 비슷한 이미지 찾기(이미지↔이미지)는 정확하다. 같은 캐릭터의 다른 컷이 0.9 안팎으로 나온다. image: "images/x.png"로 검색하면 된다.

2. 긴 세션의 기억 회상 (RAG)

vector_manage { action: "index_file", collection: "memory", file: "memory.md", chunkChars: 500 }
vector_search { collection: "memory", query: "희명이 유나에게 했던 약속", topK: 3 }
  • index_file은 파일을 제목(#)과 문단 단위로 자른다. 각 조각 앞에는 [제목]이 붙는다.
  • 같은 파일을 다시 넣으면 그 파일의 이전 조각을 전부 갈아 끼운다. 파일이 바뀌지 않았으면 건너뛴다.
  • chunkChars는 조각 하나의 최대 크기다. 문단을 이 크기까지 합친다.
    • 사건 로그처럼 한 줄이 한 사실인 파일은 300~500으로 작게 잡아라.
    • 설정 문서는 800~1200이 적당하다.
  • 장면이 바뀔 때나 오래된 떡밥이 다시 나올 때 검색해라. 결과의 text를 읽고 서사에 반영하면 된다. 검색 결과를 사용자에게 그대로 보여주지 마라.
  • 직접 요약한 기억 조각을 쌓을 수도 있다. vector_upsert { collection: "episodes", items: [{ id: "day7-goblin", text: "...", meta: { day: 7, npc: "유나" } }] }처럼 넣고, filter: { npc: "유나" }로 좁혀 찾는다.

3. 참조 문서 조회

LoRA 치트시트, 세계관 설정집, 아이템 도감처럼 길어서 매번 통째로 읽기 부담스러운 문서에 쓴다. scope: "global" 또는 "persona"로 한 번 index_file 해 두고, 필요할 때 vector_search로 관련 조각만 꺼낸다.

4. 페르소나 도구·패널에서

// tools/engine.js — NPC가 비슷한 과거 사건을 떠올린다
const r = await context.vectors("search", { collection: "episodes", query: situationText, topK: 2, minScore: 0.6 });
const recalled = r.hits.map((h) => h.text);

// 패널 — 검색창
const { hits } = await __panelBridge.vectors("search", { scope: "persona", collection: "gallery", query: input.value, topK: 12, dedupeBySource: true });

컬렉션 설계 규칙

  • 컬렉션 하나에는 한 종류만 넣어라. 기억, 갤러리, 문서를 섞으면 순위가 흐려진다. 섞어야 한다면 meta로 구분하고 filter로 좁혀라.
  • id는 다시 넣었을 때 같은 값이 나오게 정해라(파일 경로, day7-goblin 등). 같은 id로 다시 넣으면 교체된다.
  • dim은 컬렉션을 만들 때 한 번 정해지고 바뀌지 않는다.
    • 기본값 768을 쓰면 된다.
    • 수천 개가 넘는데 정확도가 덜 중요하면 256이나 512를 써라.
    • 다른 dim을 섞으려 하면 409로 거부된다. 바꾸려면 drop 후 다시 만든다.
  • 모델이 바뀌면 컬렉션도 다시 만들어야 한다. 헤더의 model이 다르면 검색이 거부된다.

점수 읽는 법

  • 점수는 코사인 유사도(-1~1)다.
  • 같은 종류끼리만 비교해라.
    • 텍스트↔텍스트: 관련 있으면 0.75 이상, 무관하면 0.6대.
    • 텍스트↔이미지: 전체가 0.6대에 몰려 있어서 순위만 의미가 있다.
    • 이미지↔이미지: 같은 캐릭터나 장면이면 0.85 이상.
  • minScore는 같은 종류끼리 검색할 때만 걸어라. 텍스트 기억 검색이라면 0.65~0.7 정도에서 시작해 결과를 보며 조정해라.
  • 1위만 믿지 말고 topK 3~5개를 읽은 뒤 LLM이 고르는 게 정확하다.

task (쿼리 프롬프트)

  • 텍스트에는 모델에 내장된 task 프롬프트가 붙는다. 이미지에는 붙지 않는다.
  • 기본값은 넣을 때 document, 찾을 때 query다(질문으로 문서 찾기).
  • 문장끼리 얼마나 비슷한지 비교할 때(중복 감지 등)는 넣을 때와 찾을 때 모두 task: "STS"를 줘라.
  • 이 밖에 QuestionAnswering, CodeRetrieval, Classification, Clustering도 쓸 수 있다.

실패 처리

상태 뜻 대응
503 임베딩 서버 없음 (gpu-manager/venv-embed 미설치 또는 EMBED_ENABLED=false) 기능을 건너뛰고 평소대로 진행한다. 사용자에게 장애처럼 알리지 마라
504 시간 초과 (콜드 로드 + 큰 배치) warmup 후 다시 시도하거나, limit을 줄인다
409 dim이나 모델 불일치 기존 컬렉션의 dim을 따르거나 drop 후 다시 만든다
404 컬렉션이나 파일이 없음 vector_manage { action: "list" }로 확인한다

참고

  • 설계: docs/specs/2026-10-07-embedding-core-design.md
  • 서버: gpu-manager/embed_server.py (전용 venv, GPU Manager와 별개 프로세스. 이유는 maintenance-playbook §5.19)

04 同仓库更多 Skills

DevelopmentDummy
DevelopmentDummy/claude-play

generate-video

claude-play-bridge MCP 서버로 영상을 생성한다. 로컬 ComfyUI의 영상 워크플로 패키지(MiniMax H3 = 영상+오디오 동시 생성, WAN 2.2 i2v, Z-Image→영상)를 호출한다. 렌더가 수 분~수십 분 걸리므로 async 큐잉 + 파일 폴링이 기본 절차다. "영상", "동영상", "비디오", "video", "i2v", "t2v", "클립 만들어", "움직이는", "애니메이션 영상" 요청에 트리거된다.

图像与多媒体Skill与智能体开发
★ 3
DevelopmentDummy
DevelopmentDummy/claude-play

generate-image

claude-play-bridge MCP 서버로 이미지를 생성한다. 기본 백엔드는 ComfyUI(로컬 GPU, 워크플로 패키지 기반)이고, 사용자가 명시적으로 요청할 때만 GPT/Gemini 백엔드를 사용한다.

图像与多媒体Skill与智能体开发
★ 3
DevelopmentDummy
DevelopmentDummy/claude-play

generate-image-openai

OpenAI/GPT 이미지 생성(GPT Image 품질 / 텍스트 렌더링·이미지 편집 강점). 기본 백엔드는 Codex CLI 구독(건당 과금 없음). ⚠️ 사용자가 이 백엔드를 명시적으로 지정했을 때만 사용한다(예 "GPT로/OpenAI로 그려줘"). 기본 이미지 생성은 generate-image(ComfyUI)이며, 사용자가 콕 집어 요청하지 않았다면 절대 OpenAI를 자동으로 선택하지 마라.

图像与多媒体
★ 3
DevelopmentDummy
DevelopmentDummy/claude-play

generate-spritesheet

Gemini 이미지 생성으로 게임용 아이콘 스프라이트시트를 만들고 자동 슬라이스한다. 아이콘, UI 리소스, 뱃지, 마커 등 여러 개의 동일 카테고리 에셋이 필요할 때 사용한다.

★ 3
DevelopmentDummy
DevelopmentDummy/claude-play

generate-image-gemini

Gemini API로 이미지를 생성한다. 패널 배경, UI 리소스, 아이콘, 장면 삽화 등 디자인 리소스 제작에 사용한다. ComfyUI가 없을 때의 이미지 생성 대안이기도 하다.

图像与多媒体
★ 3
DevelopmentDummy
DevelopmentDummy/claude-play

workflow-research

새 ComfyUI 워크플로우를 설계하거나 신규 모델, 양자화 모델, LoRA 개발 전략을 비교할 때 분석 틀을 잡는다.

资料检索与研究Skill与智能体开发
★ 3