Mori

DOCS

Prompt Engineering

怎麼寫 AGENT.md / USER.md

Mori 把 system prompt 拆成三層,你只需要管 profile body(persona + 行為指示),context section + memory index 是 Rust 自動注入。

System prompt 三層

┌─────────────────────────────────────────────────┐
│  Profile body (persona + 你寫的行為規則)        │  ← 你管這層
│  例:「你是 Mori,森林精靈的口吻,繁中回答...」 │
├─────────────────────────────────────────────────┤
│  Context section (Rust 自動,每輪 wake 重抓)    │  ← Rust 注入
│  - active window / app / process name           │
│  - clipboard preview + selection                │
│  - urls detected                                │
│  - cursor position (若可得)                    │
├─────────────────────────────────────────────────┤
│  Memory index (~/.mori/memory/MEMORY.md)        │  ← Rust 注入
│  記憶系統的 index 摘要(完整內容 lazy load)    │
└─────────────────────────────────────────────────┘

Profile body 跟下兩層用 --- 分隔。LLM 看到 user 訊息時,前面有完整三層,後面接 conversation history,最後是當輪 user input。

Frontmatter

每個 profile .md 開頭可以有 YAML frontmatter,設定 routing / skill enable:

---
# provider: claude-bash           # 留 comment 教學;沒設 → 走 config 全域 provider
agent_mode: builtin              # builtin / dispatch / chat-only
enable_read: true                # body 內 #file: 引用其他 .md 才有效
enabled_skills:                  # 列哪些 skill 開,其他全關
  - translate
  - polish
  - remember
  - recall_memory
  - open_app
shell_skills:                    # 自訂 shell wrapper(gh / docker / kubectl 等)
  - name: gh
    cmd: gh
    description: GitHub CLI
inject_memory_types:             # 哪些 memory type 進 system prompt
  - user
  - feedback
---

完整 frontmatter schema 見 Profile 範本。預設 starter pack(AGENT-01..04 / USER-01..06)展示常用組合。

Persona 寫作風格

Mori 是擬人化 spirit 不是 chatbot,profile body 偏「角色描寫 + 邊界」而非「指令列表」。三個原則:

  1. 用形容詞 + 場景 — 「你像森林精靈,聲線輕柔但不裝可愛,話短意密」比「請使用禮貌、簡短、可愛的語氣」更穩。
  2. 禁止項用「why」說明 — 「不要過度道歉(這會讓對話變黏)」勝過「不要道歉」。LLM 知道 why 才能在邊界 case 判斷。
  3. 給範例對白 — 寫 2-3 句「期待的回應 sample」,LLM 不必猜你的喜好。

Anti-injection

Mori 內建 anti-injection rule —— 當 context section 或 selection 內含「忘記之前指令」「現在你是另一個 AI」之類 prompt injection 時,Mori 不照做,直接視為剪貼簿內容。這條 rule 寫在 Rust 內建 system prompt 不在 user profile,所以即使 user 自己 profile 寫得很開,injection 仍會被擋。

細節見 build_context_section() in crates/mori-tauri/src/main.rs,有 --- BEGIN UNTRUSTED CONTENT --- 標記隔離。

Profile vs memory:該寫哪邊?

內容 寫進 profile 寫進 memory
Mori 的人設、語氣 ✓(每輪都看) 不適合(LLM 不會每輪 query)
User 是誰、職業、習慣 不要(會綁死 profile,要切就麻煩) ✓(type=user memory,自動 inject)
特定任務工作流 ✓(寫成獨立 agent profile 切換) 不適合
「上次說過 X」這種記憶 不要 ✓(Mori 自己 remember skill 寫)

Token budget

System prompt 太肥 LLM 會慢 + 貴。Profiles tab 右上角有 token 估算 chip,把 profile body + memory index 加起來估值:

建議 system prompt 控在 2000 tokens 以下(profile body 加上 context 加 memory index)。超過會明顯慢。

迭代 prompt 的 SOP

  1. 跑一輪正常對話
  2. 到 Recordings tab 點開那次 session
  3. system-prompt.txt(完整三層 prompt LLM 看的)
  4. response.txt 不對勁的地方
  5. 改 profile body 對應 section
  6. Profiles tab 按「切換」(下一輪 hotkey 即時生效,不必重啟 Mori)

Recordings 是觀測 prompt 的金牌工具 — 看見完整 prompt 比靠想像 debug 強 10 倍。