"๋น์ ์ ์ง์์ ๋น์ ์ ๋ฐฉ์์ผ๋ก" - Denote ๊ธฐ๋ฐ ๋ฒ์ฉ ์ง์๋ฒ ์ด์ค ๋ณํ ์์คํ
Memex-KB๋ ์ง์ ๊ด๋ฆฌ์ ์์์ ์ด์, RAG ํ์ดํ๋ผ์ธ์ ์ ๊ตฌ์ ๋๋ค.
์ ๋ฌธ์์๊ฒ "์ผ์ ํ ๊ท์น"์ ์ ๊ณตํ์ฌ, ์ฐ์ฌ๋ ์ง์์ ์ฒด๊ณ์ ์ผ๋ก ์ ๋ฆฌํ๊ณ , AI ํ์ ๊ฐ๋ฅํ ํํ๋ก ๋ณํํฉ๋๋ค.
๊ธฐ์ ๋ฐฐ๊ฒฝ:
โ
๊ฒ์ฆ๋ ๊ธฐ์ ์คํ (2025 Q3):
- n8n: 40+ ๋
ธ๋ ์ํฌํ๋ก์ฐ (AI Agent Automation)
- Supabase pgvector: ๋ฒกํฐ DB (2,945๊ฐ Org ํ์ผ ์๋ฒ ๋ฉ ์๋ฃ)
- Ollama: ๋ก์ปฌ ์๋ฒ ๋ฉ (multilingual-e5-large, GPU ํด๋ฌ์คํฐ)
- Airbyte: ETL ํ์ดํ๋ผ์ธ (Channel.io โ PostgreSQL ๋ฑ)
- Rerank API Server: ์์ฒด ๊ตฌ์ถ
โ ๊ธฐ์ ์คํ ์์ฒด๋ "๊ป๋ฐ๊ธฐ". ์ด๋ฏธ ๋ค ํด๋ดค์ต๋๋ค.
ํต์ฌ ๋ฌธ์ :
๊ทธ๋ฐ๋ฐ Legacy ๋ฌธ์(Google Docs, Dooray, Confluence...)๋ฅผ
์ด๋ป๊ฒ RAG-ready ํํ๋ก ๋ณํํ๋๊ฐ?
๋ณํ๋ง ํ๋ ๋๊ตฌ๋ ๋ง์ต๋๋ค.
Pandoc, Notion Exporter, Confluence API...
ํ์ง๋ง:
- ์ผ๊ด์ฑ ์๋ ํ์ผ๋ช
โ ๊ฒ์ ์ด๋ ค์
- ๋ถ๋ฅ ๊ธฐ์ค ๋ชจํธ โ ์ฐพ๊ธฐ ์ด๋ ค์
- ๋ฉํ๋ฐ์ดํฐ ์์ค โ ์ปจํ
์คํธ ๋ถ์กฑ
- Git ๋ฏธ์ฐ๋ โ ๋ฒ์ ๊ด๋ฆฌ ๋ถ๊ฐ
โ ์๋ฒ ๋ฉํด๋ ํ์ง์ด ๋ฎ์ต๋๋ค.
memex-kb์ ๋ ์ฐฝ์ ์ ๊ทผ:
1. Denote ํ์ผ๋ช
๊ท์น:
timestamp--ํ๊ธ-์ ๋ชฉ__ํ๊ทธ๋ค.md
โ ํ์ฑ ๊ฐ๋ฅ, ์๊ฐ ์ ๋ ฌ, ์๋ฏธ ๋ช
ํ
2. ๊ท์น ๊ธฐ๋ฐ ์๋ ๋ถ๋ฅ:
YAML ์ค์ ์ผ๋ก ์ผ๊ด์ฑ ํ๋ณด
โ LLM ๋น์ฉ 0์, ์ฌํ ๊ฐ๋ฅ
3. Git ๋ฒ์ ๊ด๋ฆฌ:
๋ชจ๋ ๋ณํ ๊ณผ์ ์ถ์
โ ํฌ๋ช
์ฑ, ๋กค๋ฐฑ ๊ฐ๋ฅ
4. Backend ์ค๋ฆฝ:
Adapter ํจํด์ผ๋ก ํ์ฅ
โ ๋๊ตฌ ๋ฐ๋์ด๋ ๋ฐ์ดํฐ๋ ์ ์ง
5. ์๋ฒ ๋ฉ ํ์ดํ๋ผ์ธ ํตํฉ (v2.0):
๋ณํ โ Denote โ Embedding โ Vector DB โ RAG
โ ๊ฒ์ฆ๋ ํ์ดํ๋ผ์ธ ์ฌ์ฌ์ฉ
๊ฒฐ๊ณผ:
๋จ์ ๋ณํ ๋๊ตฌ (๊ฐํฅ ์์)
โ
RAG ํ์ดํ๋ผ์ธ์ ์
๊ตฌ (๊ฐ์น ์์)
โ
Legacy ๋ฌธ์๊ฐ AI Second Brain์ด ๋ฉ๋๋ค.
-
Denote ํ์ผ๋ช ๊ท์น:
timestamp--ํ๊ธ-์ ๋ชฉ__ํ๊ทธ1_ํ๊ทธ2.md- ์๊ฐ ๊ธฐ๋ฐ ์ ๋ ฌ (๊ฒ์ ๋ถํ์)
- ์ธ๊ฐ ์นํ์ ์ ๋ชฉ (ํ๊ธ ์ง์)
- ๋ช ํํ ํ๊ทธ (์๋ ์ถ์ถ)
-
๊ท์น ๊ธฐ๋ฐ ์๋ ๋ถ๋ฅ: LLM ์์ด ํ ํฐ ์ ์ฝ
- YAML ์ค์ ํ์ผ๋ก ๊ฐ๋จ ๊ด๋ฆฌ
- ํค์๋ + ํจํด ๋งค์นญ
- ํ์ฅ ๊ฐ๋ฅํ ์นดํ ๊ณ ๋ฆฌ
-
Git ๋ฒ์ ๊ด๋ฆฌ: ๋ชจ๋ ๋ณ๊ฒฝ์ฌํญ ์ถ์
- ๋ก์ปฌ ์ฐ์ (๋ณด์)
- ํ์ ๊ฐ๋ฅ (GitHub/GitLab)
- ์๊ตฌ ๋ณด์กด
-
Backend ์ค๋ฆฝ: ์ฌ๋ฌ ์์ค ์ง์
- Google Docs (โ ๊ตฌํ๋จ)
- Threads SNS (โ ๊ตฌํ๋จ) - NEW!
- Dooray Wiki (๐ง ๊ฐ๋ฐ ์ค)
- Confluence (๐ ๊ณํ ์ค)
- โ ์ง์ ๊ด๋ฆฌ ์ ๋ฌธ์: "์ด๋์๋ถํฐ ์์ํด์ผ ํ ์ง ๋ชจ๋ฅด๊ฒ ์ด์"
- โ ํ์ฌ Wiki ๊ด๋ฆฌ์: "์ฐ์ฌ๋ ๋ฌธ์๋ฅผ ์ ๋ฆฌํ๊ณ ์ถ์ด์"
- โ ๋ณด์ ์ค์ ์ฌ์ฉ์: "ํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๋ก์ปฌ์ ๋ณด๊ดํ๊ณ ์ถ์ด์"
- โ Org-mode ์ฌ์ฉ์: "ํ์ฌ ๋ฌธ์๋ฅผ Emacs๋ก ๊ด๋ฆฌํ๊ณ ์ถ์ด์"
- โ ์๋ํ ์ ํธ์: "์์์ ์ ์ค์ด๊ณ ๊ท์น์ผ๋ก ๊ด๋ฆฌํ๊ณ ์ถ์ด์"
| ๋ฌธ์ | Memex-KB ํด๊ฒฐ์ฑ |
|---|---|
| ๋ฌธ์๊ฐ ์ฌ๊ธฐ์ ๊ธฐ ํฉ์ด์ ธ ์์ด์ | ํ ๊ณณ์ Markdown์ผ๋ก ํตํฉ |
| ํ์ผ๋ช ์ด ์ผ๊ด์ฑ ์์ด์ | Denote ๊ท์น์ผ๋ก ์๋ ์์ฑ |
| ๋ถ๋ฅ ๊ธฐ์ค์ด ๋ชจํธํด์ | YAML๋ก ๋ช ํํ ๊ท์น ์ ์ |
| ๋ฒ์ ๊ด๋ฆฌ๊ฐ ์ ๋ผ์ | Git์ผ๋ก ๋ชจ๋ ๋ณ๊ฒฝ์ฌํญ ์ถ์ |
| ํ์ฌ ๋๊ตฌ๊ฐ ๊ณ์ ๋ฐ๋์ด์ | Backend๋ง ๊ต์ฒด, ๋ฐ์ดํฐ๋ ๊ทธ๋๋ก |
[Backend Sources]
โโโ Google Docs (โ
๊ตฌํ๋จ)
โโโ Threads SNS (โ
๊ตฌํ๋จ) โ NEW!
โโโ Dooray Wiki (๐ง ๊ฐ๋ฐ ์ค)
โโโ Confluence (๐ ๊ณํ ์ค)
โ
[Backend Adapter] โ ํ์ฅ ๊ฐ๋ฅํ ์ค๊ณ
โ
[Markdown/Org Conversion]
โ
[๊ณตํต ํ์ดํ๋ผ์ธ]
โโโ DenoteNamer (ํ์ผ๋ช
์์ฑ)
โโโ Categorizer (์๋ ๋ถ๋ฅ)
โโโ Tag Extractor (ํ๊ทธ ์ถ์ถ)
โ
[Local Git Repository]
โโโ docs/
โ โโโ architecture/
โ โโโ development/
โ โโโ operations/
โ โโโ products/
โ โโโ _uncategorized/
โโโ .git/
โ
[๊ฐ์ธ ์ง์๋ฒ ์ด์ค]
โโโ Org-mode
โโโ Obsidian
โโโ ๊ธฐํ Markdown ๋๊ตฌ
memex-kb/
โโโ scripts/ # ๋ณํ ๋ฐ ๋๊ธฐํ ์คํฌ๋ฆฝํธ
โ โโโ adapters/ # Backend Adapters (ํ์ฅ ๊ฐ๋ฅ)
โ โ โโโ base.py # BaseAdapter (์ถ์ ํด๋์ค)
โ โ โโโ threads.py # Threads API Adapter โ
โ โโโ gdocs_to_markdown.py # Google Docs ๋ณํ โ
โ โโโ threads_exporter.py # Threads ํฌ์คํธ ๋ด๋ณด๋ด๊ธฐ โ
โ โโโ get_threads_token.py # Threads OAuth ํฌํผ โ
โ โโโ test_threads_api.py # Threads API ํ
์คํธ โ
โ โโโ denote_namer.py # Denote ํ์ผ๋ช
์์ฑ (๊ณตํต)
โ โโโ categorizer.py # ๋ฌธ์ ์๋ ๋ถ๋ฅ (๊ณตํต)
โโโ docs/ # ๋ณํ๋ ๋ฌธ์
โ โโโ threads-aphorisms.org # Threads ์ํฌ๋ฆฌ์ฆ ํตํฉ ํ์ผ โ
โ โโโ attachments/threads/ # Threads ์ด๋ฏธ์ง ์ฒจ๋ถํ์ผ
โ โโโ 2025*.org # ํ๋ก์ ํธ ๋ฌธ์๋ค
โโโ config/
โ โโโ .env # ํ๊ฒฝ๋ณ์ (gitignore)
โ โโโ .env.threads.example # Threads ์ค์ ์์
โ โโโ credentials.json # API ์ธ์ฆ (gitignore)
โโโ logs/ # ์คํ ๋ก๊ทธ
โโโ README.md # ์ด ํ์ผ
# Python ํจํค์ง ์ค์น
pip install -r requirements.txt
# Pandoc ์ค์น (๋ฌธ์ ๋ณํ์ฉ)
# Ubuntu/Debian
sudo apt-get install pandoc
# macOS
brew install pandoc
# NixOS
nix-shell -p pandoc# 1. Google Cloud Console์์ ํ๋ก์ ํธ ์์ฑ
# 2. Google Drive API ํ์ฑํ
# 3. Service Account ์์ฑ ๋ฐ ํค ๋ค์ด๋ก๋
# 4. credentials.json์ config/ ๋๋ ํ ๋ฆฌ์ ์ ์ฅ
# ํ๊ฒฝ๋ณ์ ์ค์
cp config/.env.example config/.env
# config/.env ํ์ผ ํธ์ง
# ๋จ์ผ ๋ฌธ์ ๋ณํ
python scripts/gdocs_to_markdown.py "DOCUMENT_ID"์ํฌ๋ฆฌ์ฆ์ ๋์งํธ๊ฐ๋ ์ผ๋ก: Threads ํฌ์คํธ๋ฅผ ๋จ์ผ Org ํ์ผ๋ก ํตํฉ
# ํ๊ฒฝ๋ณ์ ์ค์
cp config/.env.threads.example config/.env.threads
# config/.env.threads ํ์ผ ํธ์ง (APP_ID, APP_SECRET, REDIRECT_URI)# Step 1: Access Token ํ๋ (๋ํํ)
python scripts/get_threads_token.py
# โ Facebook ๋ก๊ทธ์ธ์ผ๋ก OAuth ํ๋ก์ฐ ์งํ
# โ config/.env.threads์ ACCESS_TOKEN ์๋ ์ถ๊ฐ
# Step 2: API ์ฐ๊ฒฐ ํ
์คํธ
python scripts/test_threads_api.py
# Step 3: ์ ์ฒด ํฌ์คํธ ๋ด๋ณด๋ด๊ธฐ
python scripts/threads_exporter.py --download-images
# ๊ฒฐ๊ณผ: docs/threads-aphorisms.org ์์ฑ
# - 193๊ฐ ํฌ์คํธ (์๊ฐ์ ์ ๋ ฌ)
# - 34๊ฐ ์ฃผ์ ๋ก ์๋ ๋ถ๋ฅ
# - ๋๊ธ ํฌํจ
# - ์ด๋ฏธ์ง ๋ค์ด๋ก๋ (docs/attachments/threads/)
# - Permalink ์ฐ๊ฒฐ
# - "์ด์ ๋ฆฌ์ฆ(Assholism)": ์ถ์ฒ ์๊ณ ๋ฆฌ์ฆ์ ๋์ด์ ์ง์ ํ ์ฐ๊ฒฐ* ์๋ก :META:
(ํ๋กํ ์ ๋ณด ๋ฐ ํต๊ณ)
* ์ฃผ์ : (๋ฏธ๋ถ๋ฅ)
:PROPERTIES:
:POST_COUNT: 160
:END:
** [ํฌ์คํธ ์ ๋ชฉ (์ฒซ ์ค 50์)]
:PROPERTIES:
:POST_ID: 18101712844662284
:TIMESTAMP: 2025-11-06T22:34:08+0000
:PERMALINK: https://www.threads.com/@junghanacs/post/...
:MEDIA_TYPE: IMAGE
:END:
[ํฌ์คํธ ๋ณธ๋ฌธ]
*** ์ด๋ฏธ์ง
- [[file:docs/attachments/threads/18101712844662284.jpg]]
*** ๋๊ธ
**** @username ([2025-11-06 Thu 22:34])
[๋๊ธ ๋ด์ฉ]
์ต์ :
# ํ
์คํธ๋ก 5๊ฐ๋ง ๋ด๋ณด๋ด๊ธฐ
python scripts/threads_exporter.py --max-posts 5
# ์ด๋ฏธ์ง ๋ค์ด๋ก๋ ํฌํจ
python scripts/threads_exporter.py --download-images
# ์ค๋๋ ์์ผ๋ก ์ ๋ ฌ
python scripts/threads_exporter.py --reverse์์ธ ๋ฌธ์: docs/20251107T123200--threads-aphorism-exporter-ํ๋ก์ ํธ__threads_aphorism_assholism.org
Legacy ๋ฌธ์๋ฅผ RAG-ready ํํ๋ก: Confluence Export๋ฅผ ์๋ฒฝํ Markdown์ผ๋ก ๋ณํ
๐ก ์ ์ด๊ฒ์ด memex-kb์ ํต์ฌ์ธ๊ฐ?
๋ณํ ๋๊ตฌ๋ ๋ง์ต๋๋ค. Pandoc, Notion Exporter, Confluence API... ํ์ง๋ง ๋ฌธ์ ์ธ์ฝ๋ฉ ํ๋๋ฅผ ์ ๋๋ก ์ฒ๋ฆฌํ์ง ๋ชปํ๋ฉด ๋ชจ๋ ๊ฒ์ด ๋ฌด๋์ง๋๋ค.
- ํ๊ธ์ด ๊นจ์ง๋ฉด? โ ๊ฒ์ ๋ถ๊ฐ๋ฅ
- NFD/NFC ํผ์ฌ? โ ํ์ผ ์์, ํธ์ง ๋ถ๊ฐ๋ฅ
- Quoted-printable ์ค๋ฅ? โ ๋ฐ์ดํฐ ์ ์ค
memex-kb๋ "๋ณํ"์ด ์๋ "์๋ฒฝํ ๋ณํ"์ ์ถ๊ตฌํฉ๋๋ค. ์ด๊ฒ์ด ๋จ์ ๋๊ตฌ์ RAG ํ์ดํ๋ผ์ธ ์ ๊ตฌ์ ์ฐจ์ด์ ๋๋ค.
๐ฏ ์ฒ ํ:
- ์ฒซ ๋ฒ์งธ ๋ณํ์์ ์๋ฒฝํ๊ฒ ์ฒ๋ฆฌ
- ์ธ์ฝ๋ฉ ๋ฌธ์ ๋ก ์ธํ ๋ฐ์ดํฐ ์์ค Zero
- RAG ์๋ฒ ๋ฉ ํ์ง์ ์ฒซ ๋จ๊ณ์์ ํ๋ณด
Confluence์์ Exportํ .doc ํ์ผ์ pandoc์ผ๋ก ๋ณํ ์:
- ํ๊ธ์ด ์ ๋์ฝ๋ escape ํ์(=EC=97=B0...)๊ณผ ์์ฌ์ ํ์
- Fenced div (
:::) ๋ฐ ๋ถํ์ํ HTML ์์ฑ ๋จ์ - ์ฝ๋ ๋ธ๋ก์ด ๋ณต์กํ ํ์์ผ๋ก ๋ณํ๋จ
์๋ฒฝํ MIME ํ์ฑ + Pandoc + ํ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ:
- Python
email๋ชจ๋๋ก MIME ๋ฉ์์ง ํ์ฑ - HTML ํํธ๋ฅผ UTF-8๋ก ์ถ์ถ
- Pandoc์ผ๋ก ๊นจ๋ํ Markdown ๋ณํ
- Fenced div ์ ๊ฑฐ ๋ฐ ์ฝ๋ ๋ธ๋ก ์ ๋ฆฌ
- Unicode NFD โ NFC ์ ๊ทํ (ํ๊ธ ์๋ฒฝ ๋ณด์กด)
# ๋จ์ผ ํ์ผ ๋ณํ
python3 scripts/confluence_to_markdown.py document.doc
# ์ถ๋ ฅ ํ์ผ๋ช
์ง์
python3 scripts/confluence_to_markdown.py document.doc output.md
# ์ผ๊ด ๋ณํ (๋๋ ํ ๋ฆฌ)
python3 scripts/confluence_to_markdown.py --batch input_dir/ output_dir/
# ์์ธํ ๋ก๊ทธ
python3 scripts/confluence_to_markdown.py -v document.docBefore (Raw Confluence Export):
# IoT Core Device =EC=97=B0=EB=8F=99=EA=B7=9C=EA=B2=A9=EC=84=9C v1.13
::::::::::::::::::: Section1
::: table-wrapAfter (Clean Markdown):
# IoT Core Device ์ฐ๋๊ท๊ฒฉ์ v1.13
| **๋ฒ์ ** | **์์ฑ์ผ** | **๋ณ๊ฒฝ ๋ด์ฉ** |
|----------|------------|---------------|
| v1.0 | 2025. 1. 21. | - ์ด์ ์์ฑ |- MIME ํ์ฑ:
email.message_from_binary_file()์ฌ์ฉ - Quoted-Printable ๋์ฝ๋ฉ: Soft line break ์๋ ์ฒ๋ฆฌ
- UTF-8 ์ ๊ทํ:
unicodedata.normalize('NFC')์ ์ฉ - Pandoc ์ต์
:
--wrap=none(๋ผ์ธ ๋ํ ๋ฐฉ์ง) - ์ฑ๋ฅ: 1.1MB ๋ฌธ์ โ 178KB (2์ด ์ด๋ด)
"Confluence๋ ์ฅ์ฝ์ด๋ค" - AI ์์ด์ ํธ ํ์ ์ ๊ด์ ์์
Confluence๋ ์ธ๊ฐ ํ์ ์ ํ๋ฅญํ์ง๋ง, AI ์์ด์ ํธ ํ์ ์ ์ต์ ์ ๋๋ค:
- ๋นํ์ค Export ํ์ (MIME HTML)
- ์ธ์ฝ๋ฉ ๋ฌธ์ (Quoted-printable)
- ๋ถํ์ํ ๋งํฌ์ (Fenced div, ๋ณต์กํ ์์ฑ)
- ํ๊ธ ์์ (NFD/NFC ํผ์ฌ)
๊ฒฐ๊ณผ: RAG ํ์ดํ๋ผ์ธ์ ๋ฃ์ผ๋ฉด ํ์ง ์ ํ
- ๊ฒ์ ์ ๋จ (๊นจ์ง ํ๊ธ)
- ์๋ฒ ๋ฉ ํ์ง ๋ฎ์ (๋ ธ์ด์ฆ ๋ง์)
- ์ปจํ ์คํธ ์์ค (๊ตฌ์กฐ ๋ถ๊ดด)
memex-kb๋ ํ์ ์ ํ์ ๋ฐ๊ฟ๋๋ค:
Confluence (์ธ๊ฐ ํ์ ) โ memex-kb (์๋ฒฝํ ๋ณํ) โ Denote Markdown (AI ํ์ ๊ฐ๋ฅ) โ RAG Pipeline (Second Brain)์ด๊ฒ์ ๋จ์ํ ๋ณํ ๋๊ตฌ๊ฐ ์๋๋๋ค. Legacy ์์คํ ์ AI ์๋๋ก ์ ํํ๋ ์ฒซ ๋จ๊ณ์ ๋๋ค.
์ฐธ๊ณ : Emacs ์ค์๊ฐ ํ๊ธ ์ ๋ ฅ ๋ฌธ์ ํด๊ฒฐ์ docs/20251112T194526--utf8-์ ๊ทํ-์๋ฒฝ-๊ฐ์ด๋-confluence-emacs__unicode_nfc_nfd_confluence_emacs.org ์ฐธ์กฐ
timestamp--ํ๊ธ-์ ๋ชฉ__ํ๊ทธ1_ํ๊ทธ2.md
# ์
๋ ฅ
title: "API ์ค๊ณ ๊ฐ์ด๋"
tags: ["๋ฐฑ์๋", "api", "๊ฐ์ด๋"]
# ์ถ๋ ฅ
20250913t150000--api-์ค๊ณ-๊ฐ์ด๋__backend_api_guide.md- ์๊ฐ ๊ธฐ๋ฐ ์ ๋ ฌ: ํ์ผ ํ์๊ธฐ์์ ์๋ ์ ๋ ฌ
- ์ธ๊ฐ ์นํ์ : ํ๊ธ ์ ๋ชฉ ์ ์ง (๊ฒ์ ์ฌ์)
- ๋ช ํํ ํ๊ทธ: ์ธ๋์ค์ฝ์ด๋ก ๊ตฌ๋ถ
- ํ์ฑ ๊ฐ๋ฅ: ํ๋ก๊ทธ๋๋ฐ์ผ๋ก ์ ๋ณด ์ถ์ถ
categories:
architecture:
name: "์์คํ
์ค๊ณ"
keywords: ["์ค๊ณ", "์ํคํ
์ฒ", "๊ตฌ์กฐ"]
patterns: ["^์์คํ
.*์ค๊ณ"]
file_hints: ["architecture", "design"]
development:
name: "๊ฐ๋ฐ ๊ฐ์ด๋"
keywords: ["๊ฐ๋ฐ", "API", "์ฝ๋"]
patterns: [".*๊ฐ์ด๋$"]
file_hints: ["dev", "api"]
classification:
min_score: 30 # ์ต์ ๋งค์นญ ์ ์
weights:
title_keyword: 10
title_pattern: 15
content_keyword: 5
file_hint: 20- ํค์๋ ๋งค์นญ: ์ ๋ชฉ/๋ณธ๋ฌธ์์ ํค์๋ ๊ฒ์
- ํจํด ๋งค์นญ: ์ ๊ท์์ผ๋ก ์ ๋ชฉ ํจํด ํ์ธ
- ํ์ผ ํํธ: ํ์ผ๋ช ์์ ํํธ ์ถ์ถ
- ์ ์ ๊ณ์ฐ: ๊ฐ์ค์น ํฉ์ฐ
- ์ต๊ณ ์ ์ ์ ํ: ๊ฐ์ฅ ๋์ ์ ์์ ์นดํ ๊ณ ๋ฆฌ๋ก ๋ถ๋ฅ
from abc import ABC, abstractmethod
class BaseAdapter(ABC):
"""Backend Adapter ์ถ์ ํด๋์ค"""
@abstractmethod
def authenticate(self):
"""์ธ์ฆ"""
pass
@abstractmethod
def list_documents(self):
"""๋ฌธ์ ๋ชฉ๋ก ์กฐํ"""
pass
@abstractmethod
def fetch_document(self, doc_id: str):
"""๋ฌธ์ ๋ด์ฉ ๊ฐ์ ธ์ค๊ธฐ"""
pass
@abstractmethod
def convert_to_markdown(self, content):
"""Markdown ๋ณํ"""
pass# scripts/adapters/dooray.py
from .base import BaseAdapter
class DoorayAdapter(BaseAdapter):
"""Dooray Wiki Adapter"""
def __init__(self, token: str):
self.token = token
def authenticate(self):
# Dooray API ์ธ์ฆ
pass
def list_documents(self):
# Wiki ๋ชฉ๋ก ์กฐํ
pass
def fetch_document(self, doc_id: str):
# Wiki ๋ด์ฉ ๊ฐ์ ธ์ค๊ธฐ
pass
def convert_to_markdown(self, content):
# Markdown ๋ณํ
pass# ๊ณตํต ํ์ดํ๋ผ์ธ ์ฌ์ฉ
from adapters.dooray import DoorayAdapter
from denote_namer import DenoteNamer
from categorizer import DocumentCategorizer
# Adapter ์ด๊ธฐํ
adapter = DoorayAdapter(token="YOUR_TOKEN")
# ๋ฌธ์ ๊ฐ์ ธ์ค๊ธฐ
content = adapter.fetch_document("DOC_ID")
markdown = adapter.convert_to_markdown(content)
# Denote ํ์ผ๋ช
์์ฑ (๊ณตํต)
namer = DenoteNamer()
filename = namer.generate_filename(
title="๋ฌธ์ ์ ๋ชฉ",
tags=["tag1", "tag2"]
)
# ์๋ ๋ถ๋ฅ (๊ณตํต)
categorizer = DocumentCategorizer()
category, score, all_scores = categorizer.categorize(
title="๋ฌธ์ ์ ๋ชฉ",
content=markdown
)# Google Docs โ Markdown โ Git
python scripts/batch_processor.py --backend gdocs
git add docs/
git commit -m "Backup: ๊ธฐ์ ๋ฌธ์ $(date +%Y%m%d)"
git push# Dooray Wiki โ Markdown โ Org-mode
python scripts/batch_processor.py --backend dooray
# ~/org/ ๋๋ ํ ๋ฆฌ์ ๋ณต์ฌ
cp -r docs/ ~/org/work/# Markdown โ GitHub Pages
git push origin main
# GitHub Actions๋ก ์๋ ๋ฐฐํฌ- ๋ก์ปฌ ์ฐ์ : ๋ชจ๋ ๋ฐ์ดํฐ ๋ก์ปฌ ์ ์ฅ
- Git ๋ฒ์ ๊ด๋ฆฌ: ๋ณ๊ฒฝ์ฌํญ ์ถ์ ๊ฐ๋ฅ
- .gitignore: credentials ํ์ผ ์ ์ธ
- Secretlint: ๋ฏผ๊ฐ ์ ๋ณด ์๋ ํ์ง
- API ํค๋ ํ๊ฒฝ๋ณ์ ์ฌ์ฉ
- credentials ํ์ผ์ ์ ๋ ์ปค๋ฐ ๊ธ์ง
- Private ์ ์ฅ์ ์ฌ์ฉ ๊ถ์ฅ
- ์ ๊ธฐ์ ๋ณด์ ์ค์บ (secretlint)
- โ Google Docs Adapter (Pandoc ๊ธฐ๋ฐ, 95% ์ ํ๋)
- โ Denote ํ์ผ๋ช ์์ฑ (ํ๊ธ ์ ๋ชฉ + ์์ด ํ๊ทธ)
- โ ๊ท์น ๊ธฐ๋ฐ ์๋ ๋ถ๋ฅ (LLM ๋น์ฉ 0์)
- โ Git ๋ฒ์ ๊ด๋ฆฌ
- โ Secretlint ๋ณด์ ์ค์บ
- ๐ง Dooray Wiki/Drive Adapter
- ๐ง Adapter ํจํด ๋ฆฌํฉํ ๋ง (Base โ Concrete)
- ๐ง CLI ๊ฐ์
- ๐ ๋ฌธ์ํ ๊ฐํ (๊ธฐ์ ๋ฐฐ๊ฒฝ, ์ ๊ทผ ๋ฐฉ๋ฒ๋ก )
- ๐ Confluence Adapter
- ๐ Notion Adapter (Airbyte ๊ฒฝํ ํ์ฉ)
- ๐ ์น UI
๋ฐฐ๊ฒฝ: n8n, Supabase pgvector, Ollama Embedding, Rerank API ์๋ฒ ๋ฑ ๊ธฐ์ ์คํ ๊ฒ์ฆ ์๋ฃ (2,945๊ฐ Org ํ์ผ ์๋ฒ ๋ฉ ์ฑ๊ณต)
๋ชฉํ: Legacy โ Denote โ RAG-ready ๋ณํ ์์คํ
memex-kb v1.x (Conversion)
โ Denote Markdown
memex-kb v2.0 (Embedding Pipeline) โ NEW!
โ Vector DB
n8n RAG Orchestration (๊ฒ์ฆ๋จ)
โ AI Second Brain
์ฃผ์ ๊ธฐ๋ฅ:
- ๐ก Denote Markdown โ Vector Embedding
- Ollama (mxbai-embed-large, ๋ก์ปฌ)
- ํด๋๋ณ ์ฐจ๋ณํ ์ฒญํน (meta 1500, bib 1200, journal 800, notes 1000)
- ๐ก Supabase pgvector ํตํฉ (๊ฒ์ฆ๋ ํ์ดํ๋ผ์ธ ์ฌ์ฌ์ฉ)
- ๐ก n8n RAG Workflow (Hybrid Search: ํค์๋ + ๋ฒกํฐ + ๊ทธ๋ํ)
- ๐ก ์ง์ ๊ณ์ธต ๊ตฌ์กฐ ๋ฐ์ (meta โ bib โ journal โ notes)
์ฐจ๋ณํ:
- ๋จ์ ๋ณํ ๋๊ตฌ์ ๋ค๋ฆ
- Legacy โ RAG ํ์ดํ๋ผ์ธ์ ์ ๊ตฌ
- ๊ฒ์ฆ๋ ๊ธฐ์ ์คํ ํตํฉ (์ค์ ๊ฒฝํ ๊ธฐ๋ฐ)
- ๋ ์ฐฝ์ ์ ๊ทผ: Denote + ๊ณ์ธต์ ์ง์ ๊ตฌ์กฐ + RAG
- ์ด ์ ์ฅ์๋ฅผ Fork
- Feature ๋ธ๋์น ์์ฑ (
git checkout -b feature/AmazingFeature) - ๋ณ๊ฒฝ์ฌํญ ์ปค๋ฐ (
git commit -m 'Add some AmazingFeature') - ๋ธ๋์น์ Push (
git push origin feature/AmazingFeature) - Pull Request ์์ฑ
์๋ก์ด Backend๋ฅผ ์ง์ํ๊ณ ์ถ์ผ์ ๊ฐ์?
scripts/adapters/base.py์ฐธ๊ณ- ์ Adapter ํด๋์ค ๊ตฌํ
- ํ ์คํธ ์ถ๊ฐ
- PR ์ ์ถ
ํ์ํ๋ ๊ธฐ์ฌ:
- Confluence Adapter
- Notion Adapter
- Obsidian Sync
- ๊ธฐํ Wiki/๋ฌธ์ ๋๊ตฌ
MIT License
๊ฐ์ธ/์์ ์ ์ฉ๋ ๋ชจ๋ ์์ ๋กญ๊ฒ ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค.
- Denote by Protesilaos Stavrou
- Org-mode by Carsten Dominik
- Obsidian - ๊ฐ์ธ ์ง์๋ฒ ์ด์ค ํธ๋ ๋
"The memex is a device in which an individual stores all his books, records, and communications, and which is mechanized so that it may be consulted with exceeding speed and flexibility."
โ Vannevar Bush, "As We May Think" (1945)
Memex-KB๋ Vannevar Bush์ Memex ๊ฐ๋ ์ ํ๋์ ์ผ๋ก ๊ตฌํํฉ๋๋ค.
- ๊ฐ๋ฐ์: Junghan Kim
- Email: [email protected]
- GitHub: junghan0611
- ๋ธ๋ก๊ทธ: ํฃ's ๋์งํธ๊ฐ๋
- SETUP_GUIDE.md - ์์ธ ์ค์น ๊ฐ์ด๋
- POC_RESULTS.md - POC ๊ฒฐ๊ณผ ๋ณด๊ณ ์
- README_SECURITY.md - ๋ณด์ ๊ฐ์ด๋
๋ฒ์ : 1.1.1 ์ต์ข ์ ๋ฐ์ดํธ: 2025-11-07 ์ํ: ๐ข ํ๋ฐํ ๊ฐ๋ฐ ์ค
"๋น์ ์ ์ง์์ ๋น์ ์ ๋ฐฉ์์ผ๋ก ๊ด๋ฆฌํ์ธ์."