基于 LangChain DeepAgents · MiniMax-M3
把多文本长语料视作 原液,借化学蒸馏的三段隐喻——分馏、冷凝、提纯—— 逐层分离出角色的人格信号,最终灌装成一张可注入的人格卡、 一组 DNA 级别 人格 Skills 与若干预设对话。
两种工作模式:
- CLI 直跑模式(确定性、可复现)——
distill子命令一键完成整套蒸馏。- 主理人 Agent 模式(交互式)——
chat子命令启动 intake 子包, 先做人物识别 + 索引 + 档案,让用户从候选人物里选一位再蒸馏。
灵感:Skills 生成逻辑参考 nuwa-skill 的认知操作系统方法论—— 捕捉的是 HOW they think,不是 WHAT they said。 每个人格 Skill 是一套可运行的认知操作系统,而非语录合集。
借蒸馏四阶,把原文里散落的"人"析出来。
| 阶段 | 隐喻 | 执行者 | 产出 |
|---|---|---|---|
| STAGE 01 | 🔥 分馏 Fractional Distillation |
extractor 子智能体 |
每块文本按 10 类塔板分离信号,附原文证据与显著度 |
| STAGE 02 | ❄ 冷凝 Condensation |
synthesizer 子智能体 |
同类合并、跨文件互证(salience 上调)、矛盾择优 |
| STAGE 03 | ❄ 提纯 Purification |
synthesizer 子智能体 |
丢弃低显著信号,每类保留 3~6 条,同步提炼 DNA 五层 |
| STAGE 04 | 📜 成品 Final Product |
skill_designer + dialogue_writer |
把 DNA 五层灌装为可运行 PersonaSkill + 预设对话 |
提纯阶段不再只产出 system_prompt,而是同步提炼人物的认知操作系统:
| 层 | 内容 | 体现 |
|---|---|---|
| 🗣️ 表达 DNA | ExpressionDNA |
语气、节奏、用词偏好、标志性比喻、开场白示范 |
| 🧠 心智模型 | MentalModel[] |
3~7 个看世界的"镜片",须经三重验证才收录 |
| ⚖️ 决策启发式 | DecisionHeuristic[] |
推理捷径与判断规则 |
| 🚫 反模式 | AntiPattern[] |
绝对不会做什么——比正向规则更能勾勒人格边界 |
| 📏 诚实边界 | HonestBoundary[] |
skill 真正做不到什么(一个不说明自身局限的 skill 不值得信任) |
候选心智模型必须同时通过三项才会被收录,宁缺毋滥,避免把通用常识误当人格特质:
| 验证 | 标准 | 示例 |
|---|---|---|
| 🔄 跨域复现 | 该模型在此人讨论的 ≥2 个不同领域出现(一次性表态不算) | 纳瓦尔的"杠杆"——在财富/个人成长/职业选择三域复现 |
| 🧠 有生成力 | 能推断此人对新问题的立场,而非只描述既有观点 | 芒格的"逆向思维"——面对"如何成功"→他先想"如何确保失败" |
| 🎯 有排他性 | 不是所有聪明人都会这样想,体现独特视角 | "反脆弱"是塔勒布的,不是通用智慧 |
未通过的一律丢弃。框架用 triple_verification.py 对 LLM 初判做规则式复核:
跨域用 distillates 证据收集、生成力与排他性要求 LLM 必须给出示例文本。
从一摞语料,到一张可注入的人格卡。chat 模式在前面多了一层 intake 预处理。
┌─────────────────────────────────────────────────────────────────────────┐
│ PRE-STAGE · INTAKE 预处理 (仅 chat 模式) ↻ MiniMax-M3 │
│ │
│ 语料 ──→ chunk ──→ NER/Classifier ──→ Chroma+SQLite ──→ Profile │
│ intake 子包 人物 + 类别 跨文件聚合 候选档案 │
│ name_extractor speech· index_store profile_builder│
│ appearance· + reranker │
│ event top-k 选段 │
└─────────────────────────────────────────────────────────────────────────┘
⇣
┌─────────────────────────────────────────────────────────────────────────┐
│ INPUT LAYER · 摄入层 ↻ MiniMax-M3 │
│ │
│ 语料/Corpus ──→ load_corpus() ──→ chunk_text() ──→ Chunks[] │
│ txt·md·json·csv loader.py chunker.py tiktoken感知分块 │
│ 10 塔板: │
│ speech·catch·values·know │
│ emo·rel·event·bg·taboo·man │
└─────────────────────────────────────────────────────────────────────────┘
⇣
┌─────────────────────────────────────────────────────────────────────────┐
│ ① STAGE · 分馏 FRACTIONAL DISTILLATION 🔥 heat applied │
│ │
│ ┌──────────────┐ ●●● 10塔板 ┌──────────────┐ │
│ │ extractor │ ──→ 滴滴 ──→ │ Distillate[]│ │
│ │ 分馏器子智能体│ │ 蒸馏液 │ │
│ └──────────────┘ └──────────────┘ │
│ agents.py signals·evidence·salience │
│ response_format=Distillate 落盘 distillates/*.json │
└─────────────────────────────────────────────────────────────────────────┘
⇣
┌─────────────────────────────────────────────────────────────────────────┐
│ ②③ STAGE · 冷凝 CONDENSATION ⟶ 提纯 PURIFICATION ❄ salience ≥ 0.35 │
│ │
│ ┌──────────────────┐ ⟶ ┌──────────────────────────────────┐ │
│ │ synthesizer │ │ PersonaCard │ │
│ │ 冷凝·提纯器 │ │ persona_id · system_prompt │ │
│ │ │ │ error_reply · tags │ │
│ │ 冷凝:同类合并 │ │ ┌────────────────────────────┐ │ │
│ │ 跨文件互证 │ │ │ + DNA 五层认知操作系统 │ │ │
│ │ 提纯:丢低显著 │ │ │ ExpressionDNA │ │ │
│ │ 取3~6条 │ │ │ MentalModel[] ←三重验证 │ │ │
│ └──────────────────┘ │ │ DecisionHeuristic[] │ │ │
│ │ │ AntiPattern[] │ │ │
│ │ │ HonestBoundary[] │ │ │
│ │ └────────────────────────────┘ │ │
│ └──────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
⇣ 三重验证过滤未通过模型
⇣ ★ DNA BACKFILL (安全网) ★
⇣ 若 LLM 把 DNA 拼到 system_prompt 文本
⇣ 6 类节标题正则 → 5 字段回填
┌─────────────────────────────────────────────────────────────────────────┐
│ ④ STAGE · 成品 FINAL PRODUCT — 灌装 DNA 级别 Skills 与预设对话 │
│ │
│ ┌─────────────────────────┐ ┌─────────────────────────┐ │
│ │ skill_designer │ │ dialogue_writer │ │
│ │ 技能设计师(DNA级) │ │ 预设对话作者 │ │
│ │ │ │ │ │
│ │ response_format= │ │ response_format= │ │
│ │ PersonaSkillList │ │ PresetDialogueList │ │
│ │ │ │ │ │
│ │ perspective·refuse· │ │ 寒暄·探问·踩雷· │ │
│ │ deep-dive·recall· │ │ 求助·倾诉·告别 │ │
│ │ farewell │ │ │ │
│ └─────────────────────────┘ └─────────────────────────┘ │
│ 每个 skill 含:角色扮演规则·回答工作流·心智模型·决策启发式·反模式·诚实边界│
└─────────────────────────────────────────────────────────────────────────┘
⇣
┌─────────────────────────────────────────────────────────────────────────┐
│ OUTPUT LAYER · 落盘层 (renderer.py + skills_writer.py) │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌────────────┐ │
│ │persona_card │ │skills/*/ │ │preset_ │ │distillates │ │
│ │ .json │ │ SKILL.md │ │ dialogues │ │ .jsonl │ │
│ │ │ │ │ │ .json │ │ │ │
│ │人格ID·系统 │ │Anthropic │ │user/assistant│ │中间蒸馏液 │ │
│ │提示词·报错 │ │Skills规范 │ │对话对+intent │ │可审计·复现 │ │
│ │+persona_card │ │SkillsMW可加载│ │界面右侧"预设 │ │+result.json│ │
│ │ .md │ │ │ │对话" │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ └────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
┌─ ENGINE · 底座(贯穿全管线)─────────────────────────────────────────────┐
│ │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
│ │ DeepAgents │ │ persona- │ │ MiniMax-M3 │ │
│ │ 子智能体编排 │ │ distillation │ │ 推理模型 │ │
│ │ │ │ 蒸馏方法论Skill │ │ │ │
│ │ create_deep_agent│ │ SKILL.md注入主AG │ │ OpenAI兼容协议 │ │
│ │ SubAgent·task │ │ SkillsMiddleware │ │ api.minimax.io │ │
│ │ FilesystemMW·Todo│ │ prompts.py │ │ build_model() │ │
│ └──────────────────┘ └──────────────────┘ └──────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
每个文件各司其职,可单独替换或扩展。
| 模块 | 文件 | 职责 |
|---|---|---|
| config | config.py |
运行配置中枢。模型字符串、分块参数、显著度阈值、Skills 数量上限。默认 minimax:MiniMax-M3。.env 启动时自动加载,启动即校验 API key。dry_run 跳过校验(CI/单测用) |
| schemas | schemas.py |
结构化契约。PersonaCard / PersonaSkill / Distillate + DNA 五层(ExpressionDNA/MentalModel/DecisionHeuristic/AntiPattern/HonestBoundary)+ VerificationResult。extra="forbid" 严拒 schema 外字段;model_post_init 全空告警 |
| loader | loader.py |
多文本聚合摄入。txt/md 直读、json/jsonl 抽取正文、csv 按行展开;max_input_mb 单文件大小上限 |
| chunker | chunker.py |
tiktoken 感知分块 + 重叠,避免从句中劈开 |
| prompts | prompts.py |
蒸馏方法论 SKILL.md + 四个子智能体系统提示词(含 DNA 提炼与三重验证要求)+ intake 4 个新提示词(NER/ProfileBuilder/Bridger/Orchestrator) |
| agents | agents.py |
DeepAgents 装配工厂。build_model 解析 minimax:MiniMax-M3;蒸馏侧 4 个带 response_format 的子智能体 + intake 侧 4 个子智能体 + build_intake_orchestrator 主理人 Agent |
| pipeline | pipeline.py |
确定性流水线。加载→分块→分馏→冷凝提纯→三重验证→DNA Backfill→设计 Skills→撰写对话 |
| triple_verification | triple_verification.py |
DNA 三重验证。跨域复现(distillates 证据复核)+ 生成力 + 排他性,未通过的心智模型一律丢弃 |
| renderer | renderer.py |
人格卡渲染。persona_card.json(机器可导入)+ persona_card.md(人类可读)。用 model_dump(exclude_none=True) 一次性写入全部 DNA 字段 |
| skills_writer | skills_writer.py |
Skills 目录落盘。每个 skill 写成 nuwa 风格 SKILL.md:角色扮演规则 + 回答工作流 + 心智模型(含三重验证证据)+ 决策启发式 + 表达DNA + 反模式 + 诚实边界 |
| main | main.py |
CLI 入口。distill / inspect / chat 三个子命令 |
| intake / dna_extractor | intake/dna_extractor.py |
DNA Backfill 解析器。6 类节标题正则(中文方括号 / 全角方括号 / 英文冒号 / Markdown 标题 / 中文圆括号 / 无前导符号)→ 5 字段结构化回填。backfill_dna_from_system_prompt 是 DNA 字段丢失的最后一道安全网 |
| intake / name_extractor | intake/name_extractor.py |
LLM-NER。识别分块中所有人物提及,分类为 speech/appearance/event,附原文证据与起止位置 |
| intake / index_store | intake/index_store.py |
Chroma + SQLite 双写索引。跨文件聚合人物,支持向量检索 + 类别过滤 |
| intake / embedder | intake/embedder.py |
嵌入 + 重排序模型封装。在线走真实 sentence-transformers;离线用 HashEmbeddings 兜底 |
| intake / profile_builder | intake/profile_builder.py |
人物档案摘要。从索引聚合 top-k 选段,LLM 生成 ≤200 字档案 |
| intake / bridge | intake/bridge.py |
桥接蒸馏。rebuild_corpus_dir 把档案重建为临时语料;distill_character 调 PersonaDistiller 启动四阶段蒸馏 |
每个落盘的 skills/<persona_id>-<scope>/SKILL.md 遵循以下结构(参考 nuwa-skill):
---
name: <persona_id>-perspective
description: 用 <persona> 的视角分析...
license: MIT
---
# <Persona> · 思维操作系统
## 角色扮演规则(最重要)
**此 Skill 激活后,直接以 <Persona> 的身份回应。**
- 用「我」而非第三人称转述
- 🛑 STOP(仅一次):首次激活输出免责声明,后续绝不重复
- 🚪 EXIT TRIGGER:用户说「退出」「切回正常」时立即恢复
## When to Use
触发场景...
## 回答工作流 (Agentic Protocol)
1. 用 mental_models 重新框定用户问题
2. 用 decision_heuristics 给出判断
3. 用 expression_dna 表达
4. 触及 anti_patterns 时果断拒绝
## 心智模型 (Mental Models)
> 每个模型均通过三重验证:跨域复现 · 有生成力 · 有排他性
### 聚焦即说不
**原理**:专注是说不对 100 个好主意
**跨域复现证据**:[产品]... [招聘]...
**生成力示例**:问如何扩张 → 他先问能砍掉什么
**排他性**:多数人靠加法扩张,他靠减法
## 决策启发式 (Decision Heuristics)
- **先问物理极限** —— 触发:优化任何系统时
## 表达 DNA (Expression DNA)
- **偏好词汇**:insanely great, shit
- **节奏**:短句、极端确定
- **标志性比喻**:...
## 反模式 (Anti-Patterns) —— 绝对不会做什么
- 🚫 **妥协** —— 绝不接受次优
## 诚实边界 (Honest Boundaries)
- ⚠️ **无法蒸馏直觉** —— 框架能提取,灵感不能
- ⚠️ **仅基于公开语料的快照** —— 不等于本人真实信念产出与角色卡暗色界面一一对应。
| 框架产出 | → | 角色卡界面 |
|---|---|---|
persona_card.persona_id |
⟶ | 左侧 · 人格ID 输入框 |
persona_card.system_prompt |
⟶ | 左侧 · 系统提示词 区域 |
persona_card.error_reply |
⟶ | 左侧 · 自定义报错回复信息 |
skills/*/SKILL.md |
⟶ | 右侧 · Skills 选择(可指定) |
preset_dialogues.json |
⟶ | 右侧 · 预设对话(可添加) |
Python ≥ 3.11(
deepagents的最低版本要求)
pip install -r requirements.txt
cp .env.example .env # 可选;启动时框架会自动尝试加载 .env
${EDITOR:-vi} .env # 填入 MINIMAX_API_KEY 等环境变量:
| 变量 | 默认值 | 含义 |
|---|---|---|
MINIMAX_API_KEY |
— | 必填(除非 dry_run=True)。启动时自动校验 |
MINIMAX_BASE_URL |
https://api.minimax.io/v1 |
OpenAI 兼容端点 |
MINIMAX_MODEL |
minimax:MiniMax-M3 |
provider:model 字符串 |
MINIMAX_PERSONA_ID |
"" |
CLI 不指定时使用的默认人格 ID |
EMBEDDING_MODEL |
BAAI/bge-m3 |
intake 子包的嵌入模型 |
RERANK_MODEL |
BAAI/bge-reranker-base |
intake 子包的重排序模型 |
OFFLINE |
0 |
设为 1 用 HashEmbeddings 兜底(无网络 / 离线测试) |
# 蒸馏(默认 --model minimax:MiniMax-M3)
python -m persona_distillation.main distill ./examples/sample_corpus ./out \
--persona-id arakawa_sensei
# 查看已蒸馏结果
python -m persona_distillation.main inspect ./out# 启动主理人 Agent:先做人物识别 + 索引 + 档案
# 用户从候选人物里选一位,再调 PersonaDistiller 蒸馏
python -m persona_distillation.main chat --workdir ./intake_workdirfrom persona_distillation import PersonaDistiller, DistillationConfig
distiller = PersonaDistiller(DistillationConfig(
model="minimax:MiniMax-M3", persona_id="arakawa_sensei"
))
result = distiller.distill("examples/sample_corpus", output_dir="./out")from persona_distillation.agents import build_orchestrator
from persona_distillation.config import DistillationConfig
agent = build_orchestrator(DistillationConfig(model="minimax:MiniMax-M3"))
agent.invoke({"messages": [{"role": "user", "content": "蒸馏 ./corpus 到 ./out"}]})out/
├── persona_card.json # 人格卡(含 DNA 五层)
├── persona_card.md # 人类可读版
├── skills/
│ ├── <persona_id>-perspective/SKILL.md # DNA 级别 skill
│ ├── <persona_id>-refuse/SKILL.md
│ ├── <persona_id>-deep-dive/SKILL.md
│ └── ...
├── preset_dialogues.json # 预设对话对
├── distillates.jsonl # 中间蒸馏液(可审计)
└── distillation_result.json # 完整结果(不含 distillates)
LLM 经常"擅自"把 DNA 五层塞进 system_prompt 文本里(典型如 MiniMax-M3 端点),
导致 persona_card.json 顶层 DNA 字段全空、机器读不到。
本框架从四个层面交叉保障:
| # | 防线 | 位置 | 作用 |
|---|---|---|---|
| 1 | 后处理回填 | pipeline._condense_and_purify → intake.dna_extractor.backfill_dna_from_system_prompt |
6 类节标题正则解析 system_prompt 文本 → 5 字段结构化(安全网) |
| 2 | Schema 严格化 | schemas.PersonaCard.model_config = ConfigDict(extra="forbid") |
拒绝 LLM 输出的 schema 外字段(tools / skills 等) |
| 3 | Renderer 修正 | renderer.py 改用 card.model_dump(exclude_none=True) |
不再因手写字段列表而漏掉 DNA 字段(这才是字段空值的真正元凶) |
| 4 | 提示词强化 | prompts.SYNTHESIZER_SYSTEM 末尾追加"禁止" + "塞进" + "system_prompt" |
显式告诉 LLM:DNA 五层必须作为独立结构化字段输出 |
另有两道结构化保障:
error_reply改为可选 + 默认空字符串——适配 LLM 偶尔缺该字段的不稳定输出。PersonaCard.model_post_init检测 5 字段全空时输出 WARNING——给未来"system_prompt 也丢了"的灾难场景留监控钩子。
examples/sample_corpus 真实蒸馏后 out/persona_card.json 实际产出:
| 字段 | 实际值 |
|---|---|
mental_models |
4 |
anti_patterns |
6 |
expression_dna.vocabulary |
10 |
expression_dna.signature_metaphors |
4 |
expression_dna.opening_samples |
2 |
| 落盘 SKILL.md 数 | 5 |
| 预设对话数 | 8 |
decision_heuristics/honest_boundaries在某些 LLM 端点下为 0—— 模型把这类信号融进了[输出约束]/[雷区]等其他节, 无独立节标题时 backfill 无法识别("宁缺毋滥"原则接受此结果)。
.venv/bin/python -m tests.smoke_test # 11/11
.venv/bin/python -m tests.optimization_verify # 33/33
.venv/bin/python -m pytest tests/dna_extractor_test.py -v # 15/15
.venv/bin/python -m pytest tests/test_schema_strictness.py -v # 5/5
# Total: 64/64DeepAgents · LangChain · MiniMax-M3 · Pydantic · tiktoken · ChromaDB · sentence-transformers
- nuwa-skill — DNA 级别认知操作系统与三重验证方法论
- Anthropic Agent Skills — SKILL.md 规范
- DeepAgents — 子智能体编排引擎
- BAAI/bge-m3 · BAAI/bge-reranker-base — intake 子包默认嵌入 / 重排序模型
MIT