Локальный MVP-пайплайн:
- Забирает готовые транскрипции из Plaud в
raw/. - Строит план атомизации под правила из
AGENTS.md. - Создаёт и обновляет заметки в
vault/. - Обновляет
index.mdиlog.md.
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .envЗаполните .env, затем проверьте Plaud:
python3 scripts/fetch_plaud.py list --limit 5Сухой прогон последней записи:
python3 scripts/run_ingest.py --latest 1 --dry-runПолный локальный прогон:
python3 scripts/run_ingest.py --latest 1Если хотите обработать конкретный raw-файл без запроса к Plaud:
python3 scripts/run_ingest.py --raw-file raw/2026-04-14__Example__abc123.jsonraw/*.json— канонические выгрузки Plaud.state/processed.json— реестр уже обработанных source.state/plans/*.plan.json— сохранённые планы атомизацииvault/**/*.md— итоговые заметкиconfig/plaud_folder_map.yaml— mapping Plaud tags/folders -> vault roots
raw/не редактируется вручную.- Если LLM недоступен, пайплайн попробует создать упрощённый fallback-план из Plaud summary и транскрипта.
- Для OpenRouter укажите
LLM_BASE_URL=https://openrouter.ai/api/v1и при необходимости заполнитеLLM_HTTP_REFERER.
Подходит для OpenAI API, OpenRouter и похожих endpoint-ов.
LLM_BACKEND=openai_compatible
LLM_API_KEY=...
LLM_BASE_URL=https://api.openai.com/v1
LLM_MODEL=gpt-4.1-miniПодходит, если на машине установлен Codex CLI и вы вошли в него через ChatGPT account или API key.
LLM_BACKEND=codex_exec
CODEX_MODEL=
CODEX_SANDBOX=read-onlyПодготовка машины:
npm i -g @openai/codex
codex loginПосле этого Python-пайплайн будет вызывать codex exec как внешний LLM-бэкенд и LLM_API_KEY не понадобится.
Если вы хотите потом обернуть проект в OpenClaw, лучше не менять пайплайн. Пусть OpenClaw просто вызывает готовую команду:
cd /path/to/Plaud2Obsidian
source .venv/bin/activate
python scripts/run_ingest.py --latest 1Для разового dry-run:
python scripts/run_ingest.py --latest 1 --dry-runOpenClaw в такой схеме становится orchestration- и reasoning-слоем. Инжест, запись в vault/, index.md, log.md и работа с Plaud остаются внутри этого репозитория.
Рабочая production-схема сейчас такая:
Plaud— источник записей и tag metadataVPS— runtime, где живёт репозиторий и исполняется pipelineOpenClaw— reasoning-слой, который строитplan.jsonvault/— итоговая knowledge base для ObsidianMac + Obsidian Desktop— просмотр, поиск и ручная работа с заметками
На сервере должен быть:
Codex CLIс выполненнымcodex login --device-authOpenClawс модельюcodex/gpt-5.4agents.defaults.workspacepointing at repo root
Проверка smoke-test:
env -i HOME="$HOME" PATH="$PATH" TERM="${TERM:-xterm}" \
openclaw agent --agent main --local --message 'Ответь одной строкой: OK'Если ответ OK, production-flow готов к ingest.
Для следующей записи больше не нужно вручную собирать контекст, prompt и apply по отдельности. Используйте:
./bin/openclaw_ingest_next.sh --latest 1Для конкретного Plaud file id:
./bin/openclaw_ingest_next.sh --file-id 2d252b44aec6a216587d0242f0e1539fДля конкретного raw-файла:
./bin/openclaw_ingest_next.sh --raw-file raw/example.jsonДля dry-run без записи в vault/:
./bin/openclaw_ingest_next.sh --latest 1 --dry-runЕсли raw оказался неполным или вы обновили Plaud parsing logic, перетяните источник заново:
./bin/openclaw_ingest_next.sh --file-id <FILE_ID> --refresh-raw --reprocessДля подготовки context/prompt файлов без вызова OpenClaw:
./bin/openclaw_ingest_next.sh --latest 1 --prepare-onlyЭтот wrapper делает весь production-цикл:
- строит
ingest_context.json - сохраняет
system_prompt.txt,user_prompt.txt,raw_file.txtв.state/openclaw/ - вызывает
openclaw agent --agent main --local - валидирует
.state/openclaw/plan.json - применяет
apply-plan
На VPS:
git status --short
find vault -maxdepth 6 -type f | sort
sed -n '1,220p' index.md
sed -n '1,220p' log.mdЕсли результат корректный, коммитите только осмысленные project-файлы:
git add raw vault index.md log.md config/plaud_folder_map.yaml
git commit -m "ingest: <source title>"
git pushНа Mac:
- откройте локальную копию репозитория как
vaultвObsidian Desktop - после каждого серверного ingest делайте
git pull - проверяйте новые файлы в
vault/domains/...,vault/ideas/...,vault/meetings/...
config/plaud_folder_map.yaml — это основная policy-точка для routing.
Рекомендуемая практика:
peopleиprojectsдержать глобальноideas,concepts,meetingsмаршрутизировать доменно- новые корни добавлять только для реально устойчивых папок/tag-ов Plaud
Репозиторий должен хранить knowledge base и pipeline, но не runtime-мусор.
Уже должны быть игнорированы:
.venv/.codex/.openclaw/.env.save- server-local notes вроде
HEARTBEAT.md,IDENTITY.md,SOUL.md,TOOLS.md,USER.md
VPS должен быть runtime-машиной, а не местом постоянного ручного редактирования всего проекта.
Проверьте, что рабочий контур проходит все пункты:
- Plaud API жив:
python scripts/fetch_plaud.py list --limit 5
python plaud_client.py tags- routing работает:
python plaud_client.py route-context <FILE_ID>- OpenClaw/Codex runtime жив:
env -i HOME="$HOME" PATH="$PATH" TERM="${TERM:-xterm}" \
openclaw agent --agent main --local --message 'Ответь одной строкой: OK'- wrapper-ингест проходит:
./bin/openclaw_ingest_next.sh --latest 1-
заметки появляются в
vault/,index.md,log.md -
тот же source при повторном запуске не плодит дубли
Raw JSON в raw/ остаётся каноническим источником. При apply-plan дополнительно создаётся Markdown-копия полного источника в:
vault/raw/<raw_filename>.md
Это нужно, чтобы Obsidian индексировал полный transcript, а не только атомарные заметки.
Важно: OpenClaw не всегда должен получать весь transcript в один prompt. По умолчанию planning prompt получает excerpt до LLM_MAX_SOURCE_CHARS=22000, а полный transcript сохраняется в raw/ и vault/raw/.
Проверить, будет ли transcript усечён для prompt-а:
python scripts/audit_raw_integrity.py
python scripts/audit_raw_integrity.py --raw-file raw/example.jsonJSON-вывод для автоматических проверок:
python scripts/audit_raw_integrity.py --jsonЕсли видите prompt_would_truncate=true, это не значит, что transcript потерян. Это значит, что для reasoning нужен chunked/deep ingest режим, если вы хотите извлечь все детали из очень длинной записи.
Если audit показывает long recording has suspiciously short transcript text или no transcript text, сначала перетяните raw:
./bin/openclaw_ingest_next.sh --file-id <FILE_ID> --refresh-raw --prepare-only
python scripts/audit_raw_integrity.py --raw-file raw/<REFETCHED_FILE>.jsonЕсли raw стал нормальным, запускайте reprocess:
./bin/openclaw_ingest_next.sh --file-id <FILE_ID> --refresh-raw --reprocessПрактические правила:
raw/*.json— полный источник, не редактироватьvault/raw/*.md— полный Markdown transcript для Obsidian-поискаvault/ideas,vault/concepts,vault/meetings— атомарные знания, извлечённые из источника- если запись очень длинная и важна "от и до", используйте повышенный
LLM_MAX_SOURCE_CHARSили отдельный chunked ingest режим
Для ручного увеличения prompt лимита на один запуск:
LLM_MAX_SOURCE_CHARS=80000 ./bin/openclaw_ingest_next.sh --file-id <FILE_ID>Не ставьте слишком большой лимит по умолчанию: лучше хранить полный transcript в Obsidian и отдельно запускать deep ingest для длинных источников.
Базовая схема синхронизации:
VPS -> git push -> GitHub -> git pull -> Mac -> Obsidian
Obsidian сам не забирает файлы с VPS. Он видит локальную папку. Чтобы не делать git pull руками, используйте один из вариантов.
В Obsidian установите community plugin Obsidian Git.
Рекомендуемые настройки:
- Pull on startup: enabled
- Auto pull interval: 5 minutes
- Auto commit: disabled, пока не нужна двусторонняя синхронизация
- Auto push: disabled, пока не нужна двусторонняя синхронизация
Создайте скрипт:
mkdir -p ~/bin
cat > ~/bin/plaud2obsidian-pull.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
cd "/Users/a0000/Desktop/Прога/Plaud2Obsidian"
git pull --ff-only
EOF
chmod +x ~/bin/plaud2obsidian-pull.shПотом создайте launchd job:
mkdir -p ~/Library/LaunchAgents
cat > ~/Library/LaunchAgents/com.plaud2obsidian.pull.plist <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.plaud2obsidian.pull</string>
<key>ProgramArguments</key>
<array>
<string>/Users/a0000/bin/plaud2obsidian-pull.sh</string>
</array>
<key>StartInterval</key>
<integer>300</integer>
<key>RunAtLoad</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/plaud2obsidian-pull.out</string>
<key>StandardErrorPath</key>
<string>/tmp/plaud2obsidian-pull.err</string>
</dict>
</plist>
EOF
launchctl load ~/Library/LaunchAgents/com.plaud2obsidian.pull.plistПроверка:
launchctl list | grep plaud2obsidian
tail -50 /tmp/plaud2obsidian-pull.errДля серверной интеграции добавлен единый router:
python scripts/openclaw_router.py status
python scripts/openclaw_router.py ingest --latest 1 --dry-run
python scripts/openclaw_router.py ingest --latest 1
python scripts/openclaw_router.py ingest-context --latest 1
python scripts/openclaw_router.py apply-plan --raw-file raw/<file>.json --plan-file /tmp/plan.json
python scripts/openclaw_router.py query "Что обсуждалось с Алексом?"
python scripts/openclaw_router.py lintЭтот router:
- возвращает JSON, который OpenClaw может разбирать без markdown-парсинга;
- для ingest подмешивает
CONTEXT.md,AGENTS.md,index.md, routing config и релевантные существующиеvault/заметки в planning prompt; - поддерживает brain-mode: OpenClaw может сам запросить
ingest-context, сам построить план и затем применить его черезapply-plan; - позволяет OpenClaw быть orchestration-мозгом, а репозиторию оставаться долговременной памятью и deterministic execution layer.
Текущий write-target — vault/, а не wiki/.
Базовая структура:
vault/peoplevault/projectsvault/ideasvault/conceptsvault/meetingsvault/synthesisvault/inboxvault/domains/*
Plaud folder/tag metadata подтягивается через /filetag/ и сохраняется в raw metadata. Mapping задаётся в config/plaud_folder_map.yaml.