정리된 이전 대화
| # | 기간 | 메시지 | 요약 |
|---|
| 기능 |
자동 |
aiTree | 공개 |
공유 |
|---|
로그인한 뒤 아무런 작업(클릭·입력·스크롤, 페이지나 KIT 열기)이 없이 정한 시간이 지나면 자동으로 로그아웃합니다. 계정마다 따로 정하며 기본은 6시간입니다. 열어 둔 탭이 혼자 서버에 묻는 것(진행 상황 확인 등)은 작업으로 치지 않습니다.
백업·백업 삭제·복원, server_build.sh·server_start.sh·server_stop.sh의 전체 출력(마지막 줄 # exit N이 종료 코드)과 컨테이너 시작·정지·종료(종료 코드)·OOM 기록, 화면에 짧게만 안내한 labctrl 오류의 상세(앱 오류), 프로젝트/Git 탭에서 실행한 대화 압축(git gc) 기록입니다. 서버의 mempirelab/logs/system/ 폴더(labctrl 안에서는 읽기 전용 /system-logs)에 있어 서버에 접속한 AI 에이전트도 읽고 원인을 분석할 수 있습니다.
| 번호 | 관리 |
|---|
내 프로젝트, Google Drive로 옮겨진 원본, LLM 로그인·캐시, 내가 만든 KIT을 합친 크기입니다. 한도를 넘으면 공간을 비울 때까지 새 대화·업로드·브랜치 만들기가 멈춥니다(지우기, 설정, KIT 사용은 됩니다). 한도는 관리자가 정합니다.
여기서 로그인한 Claude·Gemini·Codex 계정은 내 작업공간에서만 쓰입니다(관리자나 다른 회원의 계정과 섞이지 않습니다). 내 브랜치 대화와 내 KIT의 aitree가 이 로그인을 씁니다.
"인증"을 누르면 Google 로그인 창이 열립니다. 로그인하고 "허용"을 누르면 창이 저절로 닫히고 "인증됨"으로 바뀝니다.
웹에서 인증 (권장) — 내 PC에 아무것도 설치하지 않아도 됩니다.
준비 (관리자, 한 번만)
localhost와 127.0.0.1을 다른 주소로 보므로 둘 다 넣습니다.
https://labctrl.mempirelab.com/api/aiauth/gdrive/callback http://127.0.0.1:5000/api/aiauth/gdrive/callback http://localhost:5000/api/aiauth/gdrive/callback
http/https, 포트, 끝의 /callback까지 한 글자도 다르면 안 됩니다(끝에 /를 붙이지 않음). 저장 후 Google에 반영되기까지 몇 분 걸릴 수 있습니다.GDRIVE_CLIENT_ID/GDRIVE_CLIENT_SECRET에 넣고 drive-sync를 다시 띄웁니다(docker compose up -d --build drive-sync). 예전 데스크톱 앱 값이 남아 있으면 아래 오류가 납니다."400 오류: redirect_uri_mismatch"가 뜨면: ① 위의 "지금 이 화면에서 등록해야 할 주소"가 리디렉션 URI에 있는지, ② .env 값이 웹 애플리케이션 클라이언트의 것인지, ③ 저장 직후라면 몇 분 뒤 다시 시도했는지 확인하세요. 창을 닫고 "취소" → "다시 인증"으로 다시 합니다.
내 OAuth 클라이언트로 안 되면(Google 오류 화면 등) 카드의 "rclone 공용 인증으로 로그인"을 누르세요. 이때는 로그인 후 "연결할 수 없음" 화면의 주소를 복사해 붙여 넣는 방식이며, 카드에 "OAuth 점검 필요"가 표시됩니다.
다른 방법: rclone 토큰 붙여 넣기 — 서버에 GDRIVE_CLIENT_ID가 없을 때 등에 씁니다. 서버(Docker)에는 브라우저가 없으므로 내 PC에서 로그인해 토큰을 받고, 그 토큰만 붙여 넣습니다.
.\, ./는 "현재 폴더의 rclone"이라는 뜻입니다).
.\rclone authorize "drive"
rclone authorize "drive"
./rclone authorize "drive"
rclone이 실행된다면 앞의 .\·./ 없이 rclone authorize "drive"만 입력하면 됩니다.GDRIVE_CLIENT_ID/GDRIVE_CLIENT_SECRET(내 Google OAuth 클라이언트)을 넣었다면 같은 값을 붙여 실행하세요. 넣지 않으면 rclone 공용 클라이언트를 쓰게 되어 Google이 요청을 자주 막아 Drive 작업이 1분 가까이 멈출 수 있습니다.rclone authorize "drive" "클라이언트ID" "클라이언트보안비밀"
{로 시작하는 한 줄이 출력됩니다. 이것이 토큰입니다.{"access_token":"ya29....","token_type":"Bearer","refresh_token":"1//...","expiry":"..."}{부터 }까지 그 한 줄 전체를 복사합니다.참고: 토큰에는 Drive 접근 권한이 들어 있으니 다른 사람에게 보여주지 마세요. 한 번 저장하면 계속 쓰이며(자동 갱신), "인증이 만료되었다"는 메시지가 나올 때만 같은 순서로 다시 하면 됩니다.
Google 로그인 창에서 로그인하고 "허용"을 누르세요. 끝나면 창이 저절로 닫히고 "인증됨"으로 바뀝니다.
"redirect_uri_mismatch" 오류가 뜨면 Google Cloud의 웹 애플리케이션 클라이언트 → 승인된 리디렉션 URI에 이 주소를 추가하세요:
제공자마다 API 키를 등록합니다(LG EXAONE 포함). 등록한 API는 설정 > aiTree의 LLM 목록에 나옵니다. 키는 vault가 암호화해 보관하고 끝 4자리만 보여 줍니다.
오른쪽의 Claude·Gemini·Codex 카드는 CLI에 로그인합니다(구독 계정, API 키 없음). 로그인 정보는 Docker 볼륨 claude-home에 남고 운영서버 백업에 들어갑니다.
| AI 제공자 | 모델 | 키 |
|---|
여기 등록한 MCP 서버는 Claude, Codex, Gemini가 대화 중에 모두 쓸 수 있고, 왼쪽 EXTENSIONS 목록에도 나타납니다. 저장하면 다음 대화 턴부터 바로 적용되며 서버를 재시작할 필요가 없습니다. 환경변수(토큰 등)는 화면에 다시 표시되지 않고, 에이전트에게는 명령줄이 아닌 환경으로만 전달됩니다. 내가 등록한 MCP와 그 설정은 나만 쓰며 다른 회원과 공유되지 않습니다. 회색으로 표시된 n8n은 관리자가 기본으로 설정한 MCP(내 n8n 계정)로, 대화에 항상 붙으며 켜고 끄거나 바꿀 수 없습니다. 회색으로 표시된 n8n은 기본으로 포함된 MCP(.env의 N8N_API_KEY)로, 항상 켜져 있고 바꿀 수 없습니다.
홈 화면 맨 위의 큰 제목입니다. 브라우저 탭의 이름으로도 쓰입니다. 비워서 저장하면 기본 문구로 돌아갑니다.
제목 아래에 흐린 글씨로 보이는 한 줄입니다.
부제 아래의 소개 글입니다. 빈 줄을 넣으면 문단이 나뉘고, `글자`처럼 ` 로 감싼 부분은 코드 글씨(강조색)로 보입니다.
소개 아래에 작은 글씨로 보이는 간이링크(KIT 번호 주소) 안내입니다. 빈 줄을 넣으면 문단이 나뉘고, `글자`처럼 ` 로 감싼 부분은 코드 글씨(강조색)로 보입니다.
PDF·이미지 같은 큰 원본은 Drive에 올리고, 서버에는 이 크기까지만 남깁니다. 넘으면 오래된 원본부터 서버에서 지우고(Drive에 같은 크기의 사본이 있을 때만) 필요할 때 다시 가져옵니다.
대화의 이력이 정리 시작 기준에 닿으면 가장 오래된 청크를 압축해 Drive(archive/history/대화별 폴더/청크별 폴더/)에 보관하고 이 서버에서 지웁니다. 요약은 남고, 원본은 대화의 Archives 탭 정리된 이전 대화에서 열 수 있습니다. Drive 보관을 확인하기 전에는 아무것도 지우지 않습니다. 기본값은 관리자와 회원이 같습니다: 메시지 6,000개 또는 16MB에 닿으면 앞부분의 3,000개 또는 8MB를 턴이 끝난 뒤 자동으로 정리합니다. 시작 기준과 하드 상한을 비워 두면 각각 청크의 2배, 시작 기준의 1.5배(메시지 9,000개 또는 24MB)입니다. 저장하면 재시작 없이 적용되며, 청크 단위를 바꿔도 이미 보관한 청크는 그대로이고 다음 정리부터 새 값을 씁니다.
모든 프로젝트(회원의 프로젝트 포함)의 대화 수와 대화 기록 저장소(.labctrl/git)의 용량입니다. 대화의 턴마다 커밋이 쌓이므로, 흩어진 객체가 많아지면 압축 필요로 표시됩니다. 압축은 그 저장소에 git gc를 실행하며(대화 내용은 바뀌지 않음), 시작과 결과는 계정/정보 탭의 시스템 로그(대화 압축)에 남습니다. 자동 압축이 켜져 있으면 흩어진 객체가 2,000개 또는 50MB를 넘을 때 턴이 끝난 뒤 낮은 우선순위로 같은 일을 합니다(30분에 한 번까지, 턴을 기다리게 하지 않음).
| 프로젝트 | 소유 | 대화 | 용량 | 상태 | 마지막 압축 | |
|---|---|---|---|---|---|---|
| 불러오는 중… | ||||||
서버의 KIT 저장소(kit/ → mempirelab_kit)에 쌓인 커밋을 GitHub로 올립니다. KIT 변경은 대화가 끝날 때마다 자동으로 커밋되고, 올리는 것은 여기서 누를 때만입니다.
n8n은 labctrl 계정으로 자동 로그인됩니다(n8n에 따로 가입하거나 비밀번호를 입력하지 않습니다). n8n 워크플로에서 MEMPIRELab KIT 노드로 내 KIT(run.py가 있는 것)을 실행할 수 있습니다. 노드의 자격 증명(MEMPIRELab KIT API)에 아래 토큰을 넣으세요. 토큰은 발급할 때 한 번만 보이며, 다시 발급하면 이전 토큰은 더 이상 쓰이지 않습니다.
KIT의 run.py를 실행하는 별도 컨테이너입니다. 중지하면 실행 중인 프로그램을 끝내고 새 실행을 받지 않습니다(컨테이너와 이 화면은 켜져 있어서 다시 실행할 수 있습니다). 다시실행은 컨테이너 프로세스를 끝내고 자동으로 다시 시작합니다.
KIT의 requirements.txt가 요구하지만 kit-runner 컨테이너에 없는 패키지입니다. 어떤 KIT이 요청했는지 확인하고, 관리자가 승인하면 설치합니다. wheel 파일만 설치하므로 설치 중에 패키지의 코드가 실행되지 않으며, 설치한 패키지는 모든 KIT이 쓸 수 있습니다.
KIT의 run.py를 정해진 주기로 자동 실행합니다. 작업을 등록하면 서버가 시간이 될 때마다 실행하고, 마지막 실행 결과와 로그를 이곳에서 볼 수 있습니다. 실패하면 텔레그램으로 알려 줍니다.
서버를 다시 만드는 데 필요한 모든 것(mempirelab 폴더 전체와 Docker 볼륨 workspace·claude-home·n8n-data·vaultwarden-data·rclone-config·kit-packages)을 restic으로 Google Drive에 암호화해 백업합니다(바뀐 부분만 올라갑니다). 백업하는 동안 KIT 컨테이너(kit-runner, 회원 KIT·세션을 실행하는 member-sandbox)를 잠시 멈추고, KIT 밖의 SQLite DB는 SQLite 백업 기능으로 복사해 넣습니다. 새 서버에서는 restore_fullserver.sh로 되돌린 뒤 빌드만 하면 됩니다.
-| 번호 | 백업 시각 | 구분 | 스냅샷 | 파일 | 크기 | 추가 | 관리 |
|---|
복원은 서버 전체(mempirelab 폴더와 Docker 볼륨)를 그 백업 시점으로 되돌립니다(운영 서버에서만). 그동안 모든 컨테이너가 멈추고 업그레이드 안내 화면이 보이며, 기존 mempirelab 폴더는 mempirelab_archived_YYMMDDHHMM으로 남습니다. 결과는 계정/정보 탭의 Version 카드에 표시됩니다. 각 백업은 그 시점의 전체이며("추가"는 새로 올라간 양일 뿐), 어느 백업을 삭제해도 다른 백업은 그대로 복원할 수 있습니다(다른 백업이 쓰는 데이터는 지워지지 않음). 삭제할 때도 스냅샷 아이디를 다시 입력합니다.
운영서버 백업본으로 복원하면 KIT 데이터와 Vaultwarden도 그 백업 시점으로 돌아가, 그 뒤에 쌓인 KIT 데이터와 저장한 비밀번호가 사라집니다. 복원하기 전에 아래 KIT 데이터 백업/복원과 Vaultwarden 백업/복원에서 현재 데이터를 별도로 백업해 두고, 운영서버 복원이 끝난 뒤 그 백업으로 각각 다시 복원할 것을 권고합니다.
저장한 주기와 시각(서버 시간대)마다 위의 백업을 자동으로 실행합니다. 그 시각에 다른 백업이 진행 중이면 이번 회차는 건너뜁니다.
운영서버 백업의 보관 기간입니다. 새로 백업할 때마다, 이 기간을 벗어난 백업을 가장 오래된 것부터 Google Drive에서 지웁니다(휴지통에 남기지 않고 영구 삭제). 0으로 두면 지우지 않습니다.
각 KIT 폴더 안의 data 폴더를 백업 날짜·시각이 들어간 이름(kit-data_YYYYMMDD-HHMMSS.zip)으로 압축해 Google Drive의 아래 폴더에 보관합니다(운영 서버는 backup/remote/kit-data, Local Dev는 __dev__/backup/remote/kit-data). 목록의 zip에서 복원을 누르면 그 안에 들어 있는 KIT들의 data 폴더를 백업 내용 그대로 되돌립니다. 지금의 data 폴더는 지워지며, 지우기 전에 현재 상태가 kit-data-before-restore_… 이름으로 같은 폴더에 먼저 보관됩니다. 백업에 없는 KIT은 건드리지 않습니다.
-Vaultwarden(vault.mempirelab.com)의 데이터(vaultwarden-data 볼륨: 모든 계정과 금고의 db.sqlite3, 서명 키, 첨부·Send)를 vaultwarden-data_YYYYMMDD-HHMMSS.zip으로 압축해 Google Drive의 아래 폴더에 보관합니다(운영 서버는 backup/remote/vaultwarden-data, Local Dev는 __dev__/backup/remote/vaultwarden-data). 백업하는 동안 Vaultwarden은 멈추지 않습니다. 복원하면 Vaultwarden을 잠시 멈추고 데이터를 백업 내용으로 바꾼 뒤 다시 시작하며, 바꾸기 전에 현재 상태가 vaultwarden-data-before-restore_… 이름으로 같은 폴더에 먼저 보관됩니다. 금고 내용은 각 사용자의 마스터 비밀번호로 암호화된 그대로 담깁니다.
-초대 링크를 만들어 전달하면, 받은 사람이 링크를 열어 이메일과 비밀번호를 정해 일반회원 계정을 만듭니다(n8n 계정도 자동으로 만들어지고, labctrl에서 n8n으로 가면 자동 로그인됩니다). 링크는 한 번만 쓸 수 있고 유효 기간이 지나면 쓸 수 없습니다. 일반회원은 자기 작업공간만 씁니다: labctrl 프로젝트 1개(브랜치는 여러 개), 자기 n8n, 자기가 만든 KIT. LLM(Claude·Gemini·Codex)은 회원 계정 안에서 따로 로그인하고, 회원의 에이전트와 KIT 프로그램은 member-sandbox에서 그 회원의 폴더만 보이게 실행됩니다.
회원의 프로젝트·Drive로 옮긴 원본·LLM 로그인과 캐시·KIT을 합친 크기입니다. 한도를 넘은 회원은 새 대화·업로드·브랜치 만들기가 멈춥니다. 회원마다 다른 한도는 각 행의 용량 한도로 정합니다.
로그인한 사람만 mempirelab.com과 KIT을 볼 수 있습니다. 계정이 없는 사람에게는 임시 아이디(영단어)와 임시 비밀번호(6자리 숫자)를 줄 수 있습니다. 임시 로그인은 KIT만 쓸 수 있고 labctrl 자체에는 들어올 수 없습니다.
공용으로 지정한 KIT은 유효 시간 동안 로그인 없이 누구나 열고(주소 /kit/<이름>/나 번호 주소) run.py를 실행할 수 있습니다. 다른 페이지와 labctrl은 여전히 로그인이 필요합니다. AI(aitree)를 쓰는 KIT을 공용으로 열면 누구나 AI를 쓸 수 있으니 신중하세요(AI 사용 여부는 aiTree 탭의 설정과 KIT별 사용중/사용중지를 그대로 따릅니다).
import labkit
data = labkit.read_input()
out = labkit.aitree(
"다음 리뷰의 감정을 판정해줘: {{review}}", # 미리 설계한 프롬프트
data={"review": data["review"]}, # 실행할 때 넣는 데이터
output={"sentiment": "positive", "score": 0.0}, # 받을 JSON 예시 (또는 JSON Schema)
# provider="codex", model="gpt-5.6-luna", # 선택: 이 호출만 다른 AI로
)
labkit.write_output(out)
# 이미지와 함께: 파일 경로, bytes, 또는 페이지가 보낸 data: URL
out = labkit.aitree(
"사진 속 물건을 모두 적어줘",
images=[data["photo"]], # 예: "data:image/jpeg;base64,..."
output={"items": [""]},
)
이미지는 PNG·JPEG·GIF·WebP, 장당 5MB까지이고 한 번에 보낼 수 있는 개수는 '보안 / 사용 제한'에서 정합니다. 페이지에서 run.py로 보내는 입력은 모두 합쳐 10MB까지이므로, 큰 사진은 페이지에서 줄여(예: 긴 변 1600px) 보내세요.
kit.json에 "aitree": {"sentiment": {"prompt": "...", "output": {...}}}처럼 레시피를 적어 두면 labkit.aitree("sentiment", data={...})로 부를 수 있습니다. AI 응답에는 시간이 걸리므로 kit.json에 "runTimeout": 150 이상을 지정하세요.
설정 > 인증 > AI 연동 설정에 등록한 API도 LLM으로 고를 수 있습니다(provider="api-anthropic"·"api-openai"·"api-gemini"·"api-exaone", 모델은 등록한 것 하나). 키는 vault 밖으로 나오지 않으며, OpenAI·Gemini·EXAONE API는 글만 받습니다(이미지·웹 검색 없음). 회원 KIT은 쓸 수 없습니다.
프롬프트 내용은 남기지 않고 KIT·모델·크기·결과만 기록합니다.
KIT의 run.py가 labkit.aitree(...)로 미리 설계한 프롬프트와 데이터를 보내면, 여기서 정한 AI가 처리해 정해진 JSON 형식으로 돌려줍니다. KIT가 따로 지정하지 않은 항목은 모두 이 기본값을 씁니다.
aitree가 AI에 보낸(입력)·받은(출력) 토큰입니다. 구간은 막대 하나가 그 시간 동안 쓴 양, 누적은 기간 처음부터 쌓인 양입니다. KIT별 목록에서 KIT마다 aitree를 사용중/사용중지로 바꿀 수 있습니다.
aitree는 AI에게 파일·명령·플러그인 도구를 주지 않고 빈 임시 폴더에서 실행하며, KIT 데이터는 '지시'가 아닌 '자료'로만 넘깁니다. 응답에 인증정보(로그인 토큰, API 키 등)로 보이는 값이 있으면 응답 전체를 차단합니다.
공용 KIT(설정 > 임시접근/공용)을 실행해서 생긴 aitree 호출을 KIT마다 따로 셉니다. 위의 'KIT별 1분당/하루 최대 호출'도 함께 적용되므로, 공용 실행에는 이 값으로 더 낮은 한도를 둘 수 있습니다.
저장된 기본값으로 한 번 호출해 봅니다(사용 제한에도 1회로 셉니다).
KIT에서 쓰려면 kit.json에 아래 레시피를 넣고 run.py에서 이렇게 부릅니다:
| # | 기간 | 메시지 | 요약 |
|---|