
Qwen 모델을 사용하여 아프리카 소상공인 및 판매자를 위한 AI 에이전트를 구축한 방법
요약
Qwen 모델을 활용하여 아프리카 소상공인을 위한 대화형 AI 장부 기록 서비스 'Kredex'를 구축한 사례를 소개합니다. 복잡한 양식 대신 자연어 대화만으로 재고, 매출, 외상을 관리할 수 있는 2단계 메모리 엔진과 MCP 활용법을 다룹니다.
핵심 포인트
- Qwen 모델 기반의 대화형 AI 에이전트 구축
- 지속적인 기억을 위한 2단계 메모리 엔진 설계
- 영어 및 나이지리아 피진 언어 지원
- MCP를 통한 메모리 노출 및 Alibaba Cloud 배포
모든 것을 머릿속에 담아두는 가게 주인
라고스(Lagos)의 어느 시장이라도 들어가 보면 그녀를 만날 수 있습니다. 식료품점을 운영하고, 쌀을 포대 단위로 팔며, 단골들에게는 "월말까지" 외상을 주고, 모든 사업을 기억력과 낡은 연습장 하나로 운영하는 여성입니다. 그녀는 아마카(Amaka)가 52,000나이라(₦52,000)를 빚졌다는 것을 알고 있습니다. 툰데(Tunde)가 항상 제때 결제한다는 것도 압니다. 가리(garri)가 가장 빨리 팔리는 품목이며 절대 재고가 떨어지면 안 된다는 것도 알고 있습니다. 그녀는 조용히, 아주 뛰어난 회계사입니다.
그녀가 무언가를 잊어버리는 날이 오기 전까지는 말이죠. 그리고 망각은 곧 돈의 손실로 이어집니다.
나이지리아에만 이러한 마이크로 비즈니스(micro-businesses)가 2,000만 개 이상 존재하며, 압도적인 대다수는 디지털 장부를 전혀 기록하지 않습니다. 계산을 못 해서가 아닙니다. 그들은 우리 대부분보다 계산을 더 잘합니다. 다만 시장에 나온 모든 앱이 양식을 채우고, 열(column)을 배우고, 스프레드시트(spreadsheet) 언어를 사용하라고 요구하기 때문입니다. 소프트웨어가 사용자에게 중간 지점에서 맞춰줄 것을 요구하지만, 그들은 결코 그렇게 하지 않습니다.
그래서 저는 방식을 뒤집었습니다. 저는 Kredex를 구축했습니다. 이는 일반적인 영어(English)나 나이지리아 피진(Nigerian Pidgin)으로 오직 대화만으로 운영할 수 있는 AI 장부 기록원입니다. 양식도 없고, 열도 없습니다. 오직 대화뿐입니다:
사용자: 아마카가 쌀 3포대를 외상으로 가져갔어, 다음 주 금요일에 낼 거야.
Kredex: 기록되었습니다 — 아마카는 102,000나이라(₦102,000)를 빚졌으며, 다음 주 금요일이 만기입니다. 현재 쌀 재고는 13포대입니다.
그리고 결정적으로, 이것은 모든 대화에 걸쳐 영원히 **기억(remembers)**합니다. 이러한 지속적이고 구조화된 메모리(memory)가 핵심이며, 이것이 바로 Kredex가 Qwen Cloud Global AI Hackathon의 MemoryAgent 트랙을 위해 구축된 이유입니다. 그 안에 담긴 모든 지능은 Qwen에 의해 구동됩니다.
이 포스트는 전체 이야기를 담고 있습니다: 왜 이것을 만들었는지, Qwen이 어떻게 이를 가능하게 했는지, 그 중심에 있는 2단계 메모리 엔진(two-tier memory engine), 어떻게 MCP를 통해 이를 노출했는지, 어떻게 Alibaba Cloud에 배포했는지 — 그리고 이를 현실로 만들기 위해 해결해야 했던 네 가지 어려운 엔지니어링 문제들에 대해 다룹니다.
Kredex landing page

Kredex가 할 수 있는 모든 것
방법을 알아보기 전에, 무엇을 할 수 있는지 — 일반 영어 또는 피진으로 된 하나의 채팅창에서 구동되는 제품의 전체 기능은 다음과 같습니다:
📒 대화를 통한 장부 기록
- 문장으로 재고 기록 (Log stock) — 원가, 판매가, 그리고 품목별 재주문 수준(예: "쌀이 5포대 미만으로 떨어지면 알려줘")을 포함하여 기록합니다.
- 현금 판매 기록 (Record cash sales) — 해당 재고를 자동으로 차감하고 매출을 집계합니다.
- 외상 판매 기록 (Record credit sales) — 채무자, 금액, 만기일을 추적합니다 (예: "Amaka가 3포대를 가져갔고, 금요일에 결제할 예정임").
- 결제 기록 (Record payments) — 고객의 미결제 채무에 적용되며, 잔액이 즉시 업데이트됩니다.
- 운영 비용 기록 (Record running-cost expenses) — 임대료, 운송비, 연료비 등을 기록하여, 이익이 '실제' 이익이 되도록 합니다.
❓ 비즈니스에 대해 무엇이든 질문하기
- "재고가 뭐가 있지?" — 실시간 수량이 포함된 전체 선반 현황을 보여줍니다.
- "재고가 부족해서 채워 넣어야 할 게 뭐야?" — 재주문 기준선을 넘은 품목을 정확히 알려줍니다.
- "누가 나한테 돈을 빚졌지?" — 모든 미결제 채무와 만기일을 한 번의 답변으로 제공합니다.
- "오늘 요약해줘" 및 "이번 달에 돈을 벌고 있나?" — 매출, 비용, 채무, 그리고 쉬운 영어로 된 손익(Profit & Loss)을 보여줍니다.
📸 타이핑 그 이상의 기능
- 영수증 OCR (Receipt OCR) — 공급업체 영수증을 사진으로 찍으면 Kredex가 품목과 금액을 읽어 재고에 기록할 준비를 합니다 (
qwen-vl-max기반). - 음성 기록 및 대화 (Voice logging & talk-back) — 장부를 말로 기록하면 Kredex가 소리 내어 답변합니다 (
qwen3-asr-flash+qwen3-tts-flash). 이는 타이핑보다 말하는 것을 선호하는 소유자들을 위한 기능입니다.
🧾 결제 관리 및 현황 파악
- 인보이스 (Invoices) — "Mr. Tunde에게 쌀 2포대에 대한 인보이스를 발행해줘"라고 하면 번호가 매겨진 다운로드 가능한 PDF가 생성됩니다.
- 알림 및 경고 (Reminders & alerts) — 알림을 설정하고(예: "월요일에 공급업체에 전화하라고 알려줘") 자동 재고 부족 알림을 받습니다.
🧠 모든 대화를 아우르는 기억력
- 세션 간 회상 (Cross-session recall) — 대화 기록이 전혀 없는 완전히 새로운 채팅을 시작하더라도, 기억(memory)은 스레드가 아닌 _비즈니스(business)_에 귀속되어 있기 때문에 Kredex는 여전히 귀하의 가격, 고객 및 규칙을 알고 있습니다.
- 한 번의 수정으로 모든 곳에 적용 (Correct it once, everywhere) — 가격을 변경하면 이전 값은 (기록은 유지된 채) 제자리에서 덮어쓰기 됩니다. 이후의 모든 답변은 새로운 사실을 반영합니다.
- 가시적인 메모리(Memory) 탭 — Kredex가 알고 있는 두 가지 계층, 즉 정확한 구조화된 사실(structured facts) 및 서사적 습관(narrative habits)을 각 항목이 얼마나 자주 회상되었는지와 함께 확인할 수 있습니다.
🧭 외부 탐색
- 기회 스카우트 (Opportunity Scout) — Kredex에게 귀하가 거래하는 곳을 알려주면, 귀하의 비즈니스가 실제로 신청할 수 있는 보조금, 대출 및 프로그램들을 실시간 웹에서 검색합니다.
📊 살아있는 대시보드
- 이번 달 매출, 총 미수금, 비즈니스 건강 점수, 시간에 따른 매출 차트, 그리고 "주의 필요" 피드 — 비즈니스 전체를 한눈에 파악할 수 있습니다.
🔌 그리고 재사용이 가능합니다
- **MCP 서버 (MCP server)**가 위의 모든 것 — 메모리 및 장부 기록 — 을 모든 MCP 클라이언트(Claude Desktop, IDE 에이전트 등)에 노출하므로, Kredex는 다른 도구들을 위한 메모리 백엔드(memory backend) 역할도 수행할 수 있습니다.
이제, 구현 방법을 알아보겠습니다.
이것을 구축하려면 AI 전문가가 되어야 하나요? 아니요.
제가 믿기까지 시간이 좀 걸렸던 솔직한 진실은 다음과 같습니다: REST API를 호출할 수 있다면, AI 에이전트를 구축할 수 있습니다. Kredex 어디에도 머신러닝(machine learning), GPU, 모델 학습(model training)은 없습니다. "AI"는 Qwen에 보내는 일련의 잘 구조화된 HTTP 호출이며, 엔지니어링의 핵심은 해당 호출을 둘러싼 모든 것 — 라우팅(routing), 메모리(memory), 도구(tools), 그리고 이를 연결하는 글루(glue) 코드입니다.
함께 따라오기 위한 유일한 전제 조건은 다음과 같습니다:
- JavaScript/TypeScript에 대한 숙련도 (Kredex는 Node.js + Express 기반) — 비록 여기의 모든 내용은 제가 보여드릴 Python과 1:1로 매칭되지만 말입니다.
- Qwen Cloud 계정 (무료 — 관대한 무료 티어에 대해서는 아래에서 더 자세히 설명합니다).
- 배포를 위한 Docker에 대한 기본적인 익숙함.
그게 전부입니다. Qwen이 이 과정을 얼마나 접근하기 쉽게 만드는지 보여드리겠습니다.
왜 Qwen인가 — 그리고 왜 이것이 시작하기 가장 쉬운 AI 플랫폼인가
저는 몇몇 제공업체를 평가했습니다. Qwen은 세 가지 구체적인 이유로 승리했습니다.
1. 진정으로 관대한 무료 티어 (Free Tier)
새로운 Qwen Cloud 계정은 모델 전반에 걸쳐 70M 이상의 무료 토큰을 제공받습니다. 참고를 위해 말씀드리자면, 저는 비전 (Vision), 추론 (Reasoning), 임베딩 (Embeddings) 등 모든 기능을 포함한 전체 멀티 모델 에이전트 (Multi-model Agent)를 구축, 디버깅, 시딩 (Seeding), 벤치마킹 및 데모까지 진행했음에도 불구하고, 개발 과정의 대부분을 무료 허용 범위 내에서 여유롭게 소화했습니다. 해커톤 참가자, 인디 해커 (Indie Hacker), 또는 아이디어를 테스트하는 학생들에게 이는 _시작_을 가로막는 가장 큰 장벽을 제거해 줍니다.
2. OpenAI와 Anthropic 방식을 모두 지원 — 새로 배울 것이 없음
이 부분이 저를 미소 짓게 만들었습니다. Qwen Cloud는 **OpenAI SDK와 Anthropic Messages API 모두와 호환 (Wire-compatible)**됩니다. 전용 SDK를 새로 배울 필요가 없습니다. 이미 알고 있는 도구를 Qwen의 엔드포인트 (Endpoint)로 지정하기만 하면 바로 계속 진행할 수 있습니다.
키 (Key)를 발급받는 데는 2분밖에 걸리지 않습니다 (공식 Quickstart 기준): qwencloud.com에서 가입하고, home.qwencloud.com/api-keys에서 키를 생성한 후 내보내기(export) 하세요. 보안 비밀 값(Secrets)을 코드에 직접 하드코딩하지 마세요:
export DASHSCOPE_API_KEY="sk-your-key-here"
해커톤의 베이스 코드는 Python으로 작성되었으며, 매우 간결합니다:
# Python — 공식 Quickstart
from openai import OpenAI
client = OpenAI(
...
Kredex는 Node.js를 사용하므로, 제가 실제로 배포한 언어로 작성된 _정확히 동일한 방식_을 보여드리겠습니다. 말 그대로 단 한 줄만 바꾼 OpenAI SDK입니다:
// Node — Kredex가 실제로 사용하는 방식 (src/lib/qwen.ts)
import OpenAI from "openai";
...
동일한 SDK. 동일한 메서드 이름 (Method names). 동일한 스트리밍 (Streaming), 동일한 함수 호출 (Function-calling). 당신의 아이디어가 Python, Node, 또는 생(raw) curl 중 어떤 언어로 구현되든, Qwen은 그곳에서 당신을 맞이합니다.
3. 하나의 클라이언트 아래, 모든 작업에 적합한 모델
진정한 제품은 단 하나의 모델 호출로 이루어지지 않습니다. Kredex는 7개의 Qwen 모델을 사용하며, 각 모델은 특정 작업을 위해 선택되었습니다. 이 모든 모델은 model 문자열만 변경함으로써 단 하나의 클라이언트를 통해 접근할 수 있습니다:
| 모델 | Kredex에서의 역할 | 선정 이유 |
|---|---|---|
qwen3.5-flash | 채팅 도구 호출 (tool-calling), 사실 및 메모리 추출, 기회 탐색 (Opportunity Scout) | 빠르고 저렴함 — 지연 시간 (latency)이 여러 라운드에 걸쳐 누적되는 에이전트 루프 (agent loop)에서 매우 중요함 |
| ... |
export const MODELS = {
brain: "qwen3.7-max", // 추론 (reasoning)
agent: "qwen3.5-flash", // 빠른 도구 호출 (tool-calling) — 핵심 작업 수행 (workhorse)
...
qwen3.5-flash는 특별히 언급할 가치가 있습니다: 도구 호출 (tool-calling) 에이전트에서는 단 하나의 사용자 메시지가 여러 번의 모델 왕복 (도구 결정 → 실행 → 다시 결정 → 최종 답변)을 유발할 수 있습니다. 각 단계(hop)가 느려지면 전체 시스템이 느리게 느껴집니다. Flash의 낮은 지연 시간 (low latency) 덕분에 Kredex는 메시지당 놀라울 정도로 많은 작업을 수행함에도 불구하고 즉각적인 반응을 보여줍니다.
기술 스택 (The tech stack)
더 깊이 들어가기 전에, 전체적인 그림은 다음과 같습니다:
- 프론트엔드 (Frontend): React + Vite + TypeScript + Tailwind, 커스텀 에디토리얼 "종이와 잉크 (paper & ink)" 디자인 언어 (Fraunces + JetBrains Mono) 적용.
- 백엔드 (Backend): Node.js + Express + TypeScript.
- 데이터베이스 (Database): MongoDB (Mongoose).
- AI: DashScope를 통한 Qwen Cloud (OpenAI 호환) — 채팅, 추론 (reasoning), 비전 (vision), ASR, TTS 및 임베딩 (embeddings)을 아우르는 7개의 모델.
- 상호 운용성 (Interop):
@modelcontextprotocol/sdk(Model Context Protocol 서버). - 인프라 (Infra): Docker + Docker Compose, Caddy (auto-HTTPS), nginx — Alibaba Cloud Simple Application Server 상에서 구동.
다음은 다이어그램 명세 역할을 겸하는 텍스트 기반 아키텍처입니다:
┌──────────────────────────────┐
상점 주인 (Shop owner) ─────▶ │ React 클라이언트 (채팅 UI) │
(영어 / 피진 (Pidgin)) └───────────────┬──────────────┘
...
에이전트 루프 (The agent loop)
주인의 메시지는 가장 저렴한 단계부터 시작하여 세 단계를 거쳐 흐릅니다:
메시지 (message)
│
├─ 1. 로컬 키워드 분류기 (local keyword classifier) (0ms, LLM 미사용) → 의도 추측 (intent guess)
...
1단계는 1밀리초(millisecond) 내에 수행되는 키워드 패스(keyword pass)입니다. LLM을 사용하지 않아 비용이 들지 않으며, 의도에 대한 첫 번째 추측을 제공합니다(그리고 소유자에게 "⚡ 로컬에서 판매로 인식됨"과 같은 피드백을 보여줍니다). 2단계는 Qwen이 빛을 발하는 단계입니다. Qwen은 난잡한 인간의 문장을 읽고 품목 이름, 수량, 가격, 고객 이름을 추출한 다음, 올바른 도구(tool)를 호출합니다.
const res = await completeWithFallback({
model: MODELS.agent, // qwen3.5-flash
messages,
...
**11개의 장부 관리 도구 (bookkeeping tools)**가 있습니다 — record_sale, record_credit_sale, record_payment, log_stock, query_debts, query_stock, daily_summary, record_expense, create_invoice, save_customer_phone, set_reminder — 각 도구는 MongoDB를 변경하고 모델이 소유자에게 다시 설명할 수 있는 결과를 반환하는 일반적인 함수입니다.
핵심 요소: 2계층 메모리 엔진 (two-tier memory engine)
MemoryAgent 트랙은 _세션 전반에 걸쳐 학습하고 회상하는 지속적이고 구조화된 메모리(persistent, structured memory)_를 요구합니다. 모든 것을 벡터 데이터베이스(vector database)에 쏟아붓는 단순한 방식은 비즈니스 관점에서 느릴 뿐만 아니라 잘못된 방식입니다. 왜냐하면 상점의 지식은 실제로는 두 가지 서로 다른 종류의 것이기 때문입니다:
- 정확하고 수정 가능한 값 (Exact, correctable values) — 쌀 가격, 전화번호, 재주문 수준 등. 하나의 현재 진실이 존재하며, 이는 변합니다.
- 모호하고 연상적인 지식 (Fuzzy, associative knowledge) — "Amaka는 5% 대량 할인을 받는다", "원가 미만으로는 절대 판매하지 마라", "금요일에는 기도를 위해 일찍 문을 닫는다" 등.
이 두 가지를 하나의 저장소에 강제로 넣으면, 가격이 어긋나거나(벡터는 근사치이기 때문) 습관이 경직되는 문제가 발생합니다. 그래서 저는 **두 계층(two tiers)**을 구축하고 각 사실을 적합한 계층으로 라우팅했습니다. 이는 단순히 더 깔끔할 뿐만 아니라 더 빠르며, 그 이유는 다음과 같습니다.
계층 1 — 정형화된 사실, 표준 키 트라이(canonical-key trie)에 저장
가격과 조건들은 category.subject.attribute 형태의 점 표기법 키(dotted keys)로 표준화(canonicalized)되어 **트라이(trie)**에 저장됩니다:
product.rice.sell_price = 40000 (1회 덮어쓰기됨)
product.rice.cost_price = 28000
customer.tunde.pays_on = "end of month"
...
작은 qwen3.5-flash 호출(이른바 "정규화기 (canonicalizer)")이 각 소유자의 메시지를 이러한 키가 지정된 사실(keyed facts)로 변환합니다. 쓰기 작업은 업서트 (upsert) 방식입니다. 즉, 새로운 값이 기존 값을 제자리에서 (in place) 덮어쓰며, 이전 값은 히스토리로 밀려납니다 ("예전에는 ₦34,000였습니다"). 검색(Recall)은 결정론적 (deterministic) 입니다. 쿼리가 언급하는 주체를 탐지하고, 트라이 (trie)를 접두사 순회(prefix-walk)하여 일치하는 항목을 반환합니다. 임베딩(embeddings)도, 유사도 임계값(similarity threshold)도, 읽기 시점의 모델 호출도 없습니다.
이 방식이 Kredex를 더 빠르게 만드는 이유: 소유자들이 가장 많이 묻는 질문들 — "쌀을 얼마에 팔아야 하지?", "Tunde의 번호가 뭐지?" — 은 API 지연 시간과 환각(hallucination) 발생 가능성이 전혀 없이, 마이크로초 단위의 인메모리 트라이(in-memory trie) 조회로 답변됩니다. 권위 있는 정보는 절대로 확률적인 추측에 맡기지 않습니다.
Tier 2 — 벡터 내의 서사적 메모리 (narrative memory)
습관과 규칙은 단일 값을 가지지 않으므로 벡터 스토어(text-embedding-v4)에 저장되며, 여기서 검색 점수가 산출됩니다:
score = 코사인 유사도 (cosine_similarity) × 중요도 (importance) × 최신성 (recency)
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기