반복되는 일은 로컬 AI로
카톡으로 들어오는 생산자 글과 사진을 데이터베이스로 쌓을 때
한 로컬푸드 협동조합에서 생산자용 카카오톡 채널 챗봇을 만들다가 클라우드 AI 사용 한도가 바닥난 일이 있었습니다. 가장 싼 모델로 바꿔도 마찬가지였습니다. 이 글은 그 현장에서 잰 숫자를 바탕으로, 메시지마다 되풀이되는 일은 조직 기계 위의 오픈소스 AI(로컬 AI)에 맡기는 원리와 방법, 그리고 그 기계의 최소 사양을 정리한 것입니다.
1. 무슨 일이 있었나
협동조합은 생산자 전용 카톡 채널을 열고 챗봇을 붙였습니다. 생산자가 채널에 말을 걸면 카카오 오픈빌더가 조합 서버를 부르고, 서버가 AI에게 답을 받아 돌려주는 구조입니다. 챗봇이 하는 일은 이렇습니다.
- 이름과 휴대폰 뒷자리로 생산자 본인 확인
- 「사과 매출」, 「이번 달 매출」 같은 물음에 POS 자료로 답하기
- 「사과 본점 5, 2호점 5」 같은 납품 글을 장부에 적기
- 생산자가 보낸 사진을 생산자별 폴더에 저장하기
- 매일 아침 전날 대화 요약을 담당 이사에게 보내기
열린 지 8일 동안 들어온 대화는 236건, 말을 건 사람은 82명, 저장된 사진은 15장이었습니다. 많은 날은 하루 95건이었습니다. 숫자 자체는 작습니다. 그런데도 한도가 찼습니다.
2. 왜 하이쿠로 바꿔도 찼나
원인은 두 갈래였습니다.
첫째, 메시지 하나가 AI 호출 하나였습니다. 챗봇은 글이 올 때마다 클라우드 AI(Claude)를 한 번씩 불렀습니다. 부를 때마다 안내문, 정산 규칙, 그 생산자의 판매 자료가 프롬프트에 함께 실려 갑니다. 생산자가 「네」 한 마디만 보내도 그만큼을 다시 보냅니다. 모델을 하이쿠로 바꾸면 한 번 부르는 값은 싸지지만, 부르는 횟수는 그대로입니다.
둘째, 챗봇과 사람의 작업이 같은 한도를 나눠 썼습니다. 챗봇은 담당 이사의 구독 계정으로 AI를 불렀습니다. 그 이사가 같은 계정으로 챗봇 코드를 고치는 작업 세션도 열고 있었습니다. 챗봇 본체 파일은 1,600줄이 넘었고 여러 세션이 번갈아 고쳤습니다. 그래서 고칠 때마다 큰 파일을 다시 읽어야 했습니다. 생산자 대화가 늘수록 사람이 일할 몫이 줄어드는 구조였습니다.
둘 중 어느 쪽이 더 컸는지는 재지 않았습니다. 다만 고칠 자리는 분명합니다. 되풀이되는 일이 사람의 작업과 같은 한도를 쓰고 있었다는 점입니다.
3. 원리 — 일을 세 칸으로 나눈다
품앗이가 리서치 자동화에서 쓰는 원칙이 있습니다.
| 칸 | 누가 | 하는 일 |
|---|---|---|
| 수집·계산 | 코드 | 카톡 글 받기, 본인 확인, POS에서 숫자 꺼내기, DB에 적기, 검산 |
| 골라내기·뽑아내기 | 로컬 AI | 이 글이 납품인가 질문인가, 품목·수량·매장 뽑기, 사진에 무엇이 찍혔나 |
| 설계·고치기·어려운 판단 | 클라우드 AI | 규칙 만들기, 코드 고치기, 로컬 AI가 헷갈린 글 다시 보기 |
기준은 하나입니다. 메시지마다 되풀이되는 일이면 로컬, 한 번 깊게 생각할 일이면 클라우드입니다. 챗봇이 생산자 글마다 하는 일은 거의 첫째와 둘째 칸입니다. 숫자 계산은 이미 코드가 하고 있었고, AI에게 남은 일은 글 종류를 가르고 답 문장을 만드는 것이었습니다. 이 정도는 작은 오픈소스 모델로도 됩니다.
로컬로 옮기면 세 가지가 달라집니다.
- 한 번 더 부르는 값이 0원이 됩니다. 전기값만 듭니다. 그러면 아까워서 하지 않던 일이 열립니다. 쌓인 대화 전체를 매일 밤 다시 분류하거나, 사진마다 설명을 붙이는 일입니다.
- 사람의 작업 한도를 챗봇이 깎지 않습니다. 클라우드 AI는 설계와 고치기에만 씁니다.
- 생산자 자료가 조합 기계 밖으로 나가지 않습니다. 생산자 이름, 판매 실적, 사진이 외부 회사로 가지 않습니다.
4. 로컬 AI에게 시킬 일과 시키지 않을 일
품앗이 서버에서 로컬 AI를 석 달 가까이 돌리며 정한 규칙입니다. 지능을 기대하지 말고 골라내기만 시킨다. 결과는 코드가 검산한다. 헷갈리면 위로 넘긴다.
시킬 일:
- 글 갈래 나누기: 납품 / 매출 질문 / 정산 질문 / 사진 / 인사 / 담당자 넘김
- 정해진 칸 뽑기:
{"품목": "사과(홍로)", "매장": "본점", "수량": 5}같은 JSON - 사진 짧게 설명하기: 「사과 상자 진열」, 「밭 전경」, 「거래명세서」
- 쌓인 대화에서 자주 나오는 질문 고르기
시키지 않을 일:
- 금액·정산 셈 (코드가 한다)
- 본인 확인 (코드가 한다)
- 정산 분쟁이나 불만에 답하기 (사람에게 넘긴다)
- 긴 글 요약이나 평가 (작은 모델은 그럴듯하게 틀린다)
실측에서 알게 된 함정도 있습니다.
temperature=0으로 해도 실행마다 결과가 조금씩 다릅니다. 같은 자료로 두 번 돌렸을 때 54건과 47건이 나왔습니다. 그래서 검산 칸이 반드시 있어야 합니다.- 손으로 확인해 보니 골라낸 것 가운데 8%가 틀렸습니다. 장부에 적는 일이라면 「확인 대기」 칸을 두고 사람이 한 번 보게 하는 편이 낫다고 봅니다.
- 너무 작은 모델은 쓰지 마십시오. 2.4B급 한국어 모델은 출력이 깨졌습니다. 7~8B가 하한입니다.
5. 방법 — 다섯 단계
① 로컬 AI 엔진 설치 (Ollama)
리눅스 서버라면 한 줄입니다.
curl -fsSL https://ollama.com/install.sh | sh설치하면 서버 안에서 http://127.0.0.1:11434로 부를 수 있습니다. 밖으로는 열지 않습니다.
② 모델 받기
| 쓰임 | 모델 | 크기 |
|---|---|---|
| 한국어 글 분류·뽑기 (주력) | exaone3.5:7.8b | 약 5GB |
| 비교용 (더 정확하지만 느림) | qwen3:8b | 약 5GB |
| 사진 보기 | qwen2.5vl:7b 또는 gemma3:12b | 6~8GB |
| 검색용 임베딩 (나중에) | bge-m3 | 1GB대 |
ollama pull exaone3.5:7.8b③ 챗봇 코드에서 부르는 곳 바꾸기
클라우드 AI를 부르던 자리를 로컬 주소로 바꿉니다. format에 JSON 틀을 주면 모델이 그 모양으로만 답합니다.
import requests
r = requests.post("http://127.0.0.1:11434/api/chat", json={
"model": "exaone3.5:7.8b",
"stream": False,
"options": {"temperature": 0},
"format": {"type": "object",
"properties": {"갈래": {"type": "string"},
"품목": {"type": "string"},
"매장": {"type": "string"},
"수량": {"type": "integer"}},
"required": ["갈래"]},
"messages": [
{"role": "system", "content": "생산자 글을 갈래(납품/매출질문/정산질문/사진/인사/기타)로 나누고, 납품이면 품목·매장·수량을 뽑아라."},
{"role": "user", "content": "사과 홍로 본점 5개 넣었어요"}]})
print(r.json()["message"]["content"])받은 JSON은 코드가 검산합니다. 매장 이름이 실제 매장 목록에 있는지, 품목이 그 생산자의 등록 품목인지 확인합니다. 통과하지 못하면 「확인 대기」로 적거나 클라우드 AI 또는 담당자에게 넘깁니다.
④ 데이터베이스 칸 정하기
처음에는 표 두 개면 됩니다. 원문은 늘 그대로 남깁니다. AI가 뽑은 값이 틀렸을 때 다시 돌릴 수 있어야 하기 때문입니다.
| 표 | 칸 |
|---|---|
생산자_글 | 받은 시각, 생산자 코드, 원문, 갈래, 뽑은 값(JSON), 검산 결과, 확인한 사람 |
생산자_사진 | 받은 시각, 생산자 코드, 파일 경로, AI 설명, 쓰임(진열·밭·서류), 홈페이지 사용 동의 |
⑤ 실시간 답과 밤 작업을 나누기
| 실시간 (카톡 답) | 밤 일괄 (DB 쌓기) | |
|---|---|---|
| 기다릴 수 있는 시간 | 카카오 스킬은 5초 안에 답해야 해서, 길어지면 콜백으로 나중에 보냄 | 몇 시간이어도 됨 |
| 맡길 곳 | GPU 있는 로컬 AI, 또는 정해진 답은 코드가 직접 | GPU 없는 기계의 로컬 AI도 됨 |
| 예 | 「이번 달 매출」 답, 납품 접수 확인 | 하루치 글 다시 분류, 사진 설명 붙이기, 자주 묻는 질문 뽑기 |
GPU가 없는 기계라면 밤 일괄부터 시작하십시오. 쌓인 글과 사진을 DB로 만드는 일은 급하지 않으니 느려도 됩니다. 실시간 답은 지금처럼 정해진 문장과 코드로 최대한 처리하고, 남는 자유 질문만 클라우드에 보냅니다. 그렇게만 해도 호출 횟수가 크게 줄어든다고 봅니다.
6. 컴퓨터 최소 사양
7~8B 모델을 4비트로 줄여(양자화) 돌리는 것을 기준으로 합니다.
| 구분 | GPU | 메모리(램) | 저장장치 | 할 수 있는 일 |
|---|---|---|---|---|
| GPU 없음 (지금 있는 사무실 PC) | 없음 | 16GB 이상 | SSD 여유 50GB | 밤 일괄 분류만. 실시간 답에는 느리다 |
| 최소 | NVIDIA, 그래픽 메모리 6~8GB | 16GB | SSD 여유 100GB | 글 분류·뽑기 실시간. 사진은 느림 |
| 권장 | NVIDIA, 그래픽 메모리 12GB (예: RTX 3060 12GB) | 32GB | SSD 여유 200GB | 글 모델과 사진 모델을 함께 띄움 |
| 대안 | Apple 실리콘 맥 미니, 통합 메모리 16GB 이상 | (통합) | 256GB 이상 | 조용하고 전기를 적게 먹음. 사진 모델은 24GB 이상 권장 |
근거로 삼은 실측과 주의할 점입니다.
- 품앗이 서버는 10년 가까이 된 GTX 1060(그래픽 메모리 6GB)으로
exaone3.5:7.8b를 초당 20.4토큰으로 돌립니다. 7~8B 모델은 그래픽 메모리 6GB에서도 돈다는 뜻입니다. 다만 이 카드 세대는 Ollama 새 버전에서 지원이 빠지는 중이라, 새로 산다면 RTX 30·40번대를 권합니다. - 현장 서버는 4세대 i3(4스레드), 램 19GB, GPU 없음입니다. 이 기계에서 로컬 AI 속도는 아직 재지 않았습니다. 시작 전에 하루치 대화를 한 번 돌려 보고 밤 일괄로 충분한지 확인하는 것이 첫 일입니다.
- 오래된 사무실 PC에 그래픽카드를 꽂을 때는 세 가지를 먼저 봅니다. 메인보드에 PCIe x16 슬롯이 있는지, 전원(파워)이 그래픽카드 보조전원 단자와 용량(대개 450W 이상)을 갖췄는지, 케이스에 카드 길이가 들어가는지입니다. 사무용 완제품 PC는 파워가 약해서 카드만 사서는 안 되는 경우가 많습니다.
- 부품값은 2026년 들어 메모리값이 크게 올랐습니다. 새 기계를 바로 사기보다, 먼저 GPU 없는 기계에서 밤 일괄로 시작해 효과를 본 뒤에 그래픽카드를 고르는 편이 안전하다고 봅니다.
7. 정리
- 하이쿠로 바꿔도 한도가 찬 것은 모델이 비싸서가 아니라 메시지마다 부르는 구조 때문이었습니다.
- 메시지마다 되풀이되는 골라내기는 조합 기계의 로컬 AI에, 설계와 어려운 판단은 클라우드 AI에 맡깁니다.
- 숫자 계산과 본인 확인은 처음부터 코드가 합니다. 로컬 AI가 뽑은 값도 코드가 검산합니다.
- GPU가 없어도 밤 일괄 DB 쌓기는 지금 있는 기계로 시작할 수 있습니다. 실시간까지 하려면 그래픽 메모리 8~12GB짜리 NVIDIA 카드가 필요합니다.
- 생산자 자료가 조합 밖으로 나가지 않는다는 점도 로컬 AI를 쓰는 이유입니다.
관련 글: 로컬서버 — 조직 명의의 기계 · AX의-첫-세팅은-데이터베이스-구축 · AI 토큰 사용량과 절약법