앞의 두 편(개념·동기, 아키텍처)이 글로 설명한 내용이라면, 이번엔 실제 화면이다. 블로그용으로 데모 팀 하나를 새로 만들고, 직원을 추가하고, 실제로 티켓 하나를 끝까지 돌려봤다. (평소 쓰는 팀에는 실제 회사 프로젝트 데이터가 들어있어서, 노출되면 안 되는 정보라 이번 데모는 별도 팀으로 진행했다.) 1. 빈 조직도 — 팀 하나 새로 만들기...
지난 포스트에서 ai-crew가 왜 필요했는지 다뤘다. 이번엔 실제로 어떻게 짜여 있는지 — 모노레포 구성, 배포 토폴로지, 티켓 하나가 큐에 들어가서 완료될 때까지 거치는 경로를 정리한다. 모노레포 구성 pnpm workspace 하나에 서버·프론트·러너·공유 타입이 다 들어있다. 혼자 개발하고, 서버·UI·러너가 티켓/이벤트 타입을 공유해야...
Claude Code 하나로 사이드 프로젝트를 여러 개 굴리다 보니 매번 같은 패턴을 반복하고 있었다. 터미널을 열고, 어느 프로젝트인지 확인하고, 컨텍스트를 설명하고, 작업을 시키고, 결과를 확인한다. 프로젝트가 7개면 이 사이클을 7번 반복한다. 그래서 “회사”를 하나 만들기로 했다. 팀장 1명이 요청을 받아 작업을 쪼개고, 적합한 직원에게 티켓...
personal-assistant를 배포하는 Jenkins 파이프라인이 갑자기 실패했다. 원인을 하나씩 쫓아가다 보니 겉으로 보인 에러들은 전부 곁가지였고, 진짜 문제는 몇 주 전에 실수로 설치된 snap docker가 도커 소켓을 조용히 가로채고 있었다는 것이었다. 삽질한 순서 그대로 정리한다. 문제 상황 personal-assistant 배포가...
이전 글에서 gateway → Azure Event Hubs(Kafka) → gateway-consumer-mongo 파이프라인을 구성한 이야기를 정리했다. 이번 글은 그 뒤에 이어지는 이야기로, MongoDB에 데이터를 저장하는 방식을 일별(YYYYMMDD) 컬렉션 구조에서 Time Series Collection 하나로 전환하면서 겪은 시행착오를 ...
이전 프로젝트에서는 Kafka KRaft 클러스터를 직접 VM에 구축해서 운영했다. 이번 신규 프로젝트를 시작하면서 Kafka Broker를 어떻게 구성할지 고민하다가, 처음부터 Azure Event Hubs의 Kafka 호환 엔드포인트를 사용하기로 결정했다. 선택 이유와 설정 과정, 파티션 설계 결정에 대해 정리한다. 왜 Azure Event Hu...
정규식으로 한국어를 파싱하는 로직이 프로젝트 여러 곳에 흩어져 있었다. 카테고리 추출, BM25 토크나이저, 긍정/부정 판별 — 모두 정규식 패턴과 하드코딩된 단어 목록에 의존했다. 실제로 쓰다 보면 “코오롱 업무에 저장해줘”처럼 조사 하나가 바뀌면 버그가 생겼고, “좋아요”나 “맞아요” 같은 활용형은 YES로 인식하지 못했다. kiwipiepy를 ...
Slack에서 파일을 보내면 저장해두고, 나중에 “회의록 파일 줘”라고 말하면 돌려주는 기능이 필요했다. 단순히 파일명으로만 찾으면 한 글자라도 틀리면 못 찾는다. 그래서 파일명과 날짜·종류를 ChromaDB에 임베딩해서 유사도 검색으로 찾는 방식을 선택했다. 전체 흐름 [파일 저장] 사용자가 Slack DM에 파일 전송 ↓ Slack...
배경 에이전트 구축기 (3)에서 ChromaDB 기반 RAG로 소스코드를 검색하는 방식을 구현했다. 에러가 발생하면 관련 파일을 청킹·임베딩해 벡터로 저장하고, 분석 시 유사도 검색으로 관련 청크를 가져오는 방식이었다. 실제 운영하면서 이 방식이 생각만큼 잘 동작하지 않는다는 걸 깨달았다. 이 포스트는 왜 RAG를 버렸는지, 어떻게 바꿨는지를 정리...
Slack 기반 AI 개인 비서에 LlamaIndex를 도입했다. 기억 저장/검색 파이프라인을 교체하고, 대화 히스토리 압축과 Knowledge Graph를 추가했다. 왜 LlamaIndex인가 기존 memory_service.py는 LlamaIndex 없이 직접 구현되어 있었다. # AS-IS: 수동 구현 async def _embed(te...