Skip to content

Latest commit

 

History

10 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FriendForge

FriendForge 是一个把聊天记录制作成可复用 AI 朋友分身的开源工作台。它不训练新模型,也不微调 LLM 权重,而是把一段关系里的聊天语气、回应习惯、常用表达和少量上下文整理成独立的 Persona Bundle,再让兼容的大模型按这个 Bundle 的约束进行回复。

这个项目的初衷很简单:我试过一些同类项目,效果并不稳定。有的只是把聊天记录粗暴塞进 prompt,有的没有关系维度,有的没有验收流程,也很难把结果分发给其他程序使用。FriendForge 想把这件事做得更工程化:从聊天记录导入、脱敏、风格蒸馏、示例检索、验收、试聊,到导出给不同宿主使用,都放进一套可复用的工具链里。

公开仓库只包含代码、配置模板和一个合成示例 Bundle:Alex__to__Sam。真实聊天记录、真实朋友分身、本地产物、私有配置和 API key 都不会提交。

最新更新

  • V3 P1 运行时底座已经完成本地验证;P2 已实现显式 Schema 升级、不可变快照、状态事件、根初始化、手动快照、Pin/Release、Restore Preview 和同分支补偿恢复。V3 仍处于开发阶段,未迁移真实 Bundle,也未接入现有 Web、CLI 或 Adapter 用户入口。
  • 将 Bundle 门禁决策集中到 Core,Web、CLI 和宿主适配器统一使用同一套规则。
  • 修正 passedapproved 的语义:已通过验收的 Bundle 保持 passed,旧审批记录不会覆盖它;只有验收未通过但被显式放行时才显示 approved
  • 对缺失、损坏、非 UTF-8 或结构不一致的验收报告与审批记录采用安全拒绝,避免错误放行和接口 500。
  • 恢复 Host → Adapter → Core → Bundle 单向分层,Web 与 CLI 不再直接加载 Persona 执行注入。
  • 后端自动化测试增至 38 项,并改用现代 ASGI 测试客户端,消除旧 TestClient 兼容层的弃用警告。

项目能做什么

FriendForge 会把聊天记录转换成一个个独立的 Persona Bundle

  • owner:要被 AI 扮演的人。
  • audience:这个分身正在对谁说话。
  • owner→audience:某个人在某段关系里的特定说话方式。

例如:

  • Alex__to__Sam:扮演 Alex 对 Sam 说话。
  • Sam__to__Alex:扮演 Sam 对 Alex 说话。

这两个方向不是同一个东西。所谓“反向蒸馏”不是把对话倒过来,而是从同一份聊天记录里抽取另一方的发言、风格、示例和近期上下文,重新制作一个独立 Bundle。

核心功能

  • 不微调模型:不训练、不微调 LLM 权重,降低成本和部署复杂度。
  • 关系级人格包:每个 (owner→audience) 都是独立目录,包含画像、风格、示例、近期上下文、验收报告等。
  • Web 工作台:用 Vue 3 + Vite 提供可视化界面,用于浏览 Bundle、创建任务、查看进度、试聊天和导出产物。
  • FastAPI 后端:提供 Bundle 浏览、制作任务、验收任务、配置、试聊、产物导出等接口。
  • 流式任务进度:制作和验收任务通过 WebSocket 推送进度。
  • 流式试聊:试聊窗口用 SSE 逐步输出模型回复。
  • BYOK 大模型接入:支持 OpenAI-compatible API、Ollama、本地模型或自定义 base URL、model、api key。
  • 导出门禁:未通过验收的 Bundle 默认不能导出 promptskillcard
  • 宿主适配器:可导出给 Agent、聊天程序、SillyTavern/角色卡等宿主使用。
  • 隐私默认保护:真实聊天 CSV、真实 Bundle、导出产物、本地密钥默认被 .gitignore 排除。

项目优点

很多同类项目只停留在“把聊天记录塞进 prompt”这一步。FriendForge 更强调完整闭环:

  • 把人格材料拆成可检查的 Bundle 文件,而不是一个不可维护的大 prompt。
  • 用验收报告和门禁决定是否允许导出,而不是默认放行。
  • 区分不同关系中的语气,避免“一个人对所有人都一个口吻”。
  • 支持正向和反向两个独立 Bundle。
  • Web 工作台和 CLI 同时可用,方便调试、演示和自动化。
  • 不绑定单一模型,运行时可以切换 LLM provider。
  • 真实数据默认不入库,更适合在本地制作私人分身。

大致架构

FriendForge 保持单向分层:

Host
  -> Adapter
      -> Core
          -> Persona Bundle

含义:

  • Host:真正使用分身的宿主,比如 Agent、聊天程序、角色卡程序。
  • Adapter:产物分发层,负责导出 promptskillcard
  • Core:核心逻辑层,负责制作、验收、检索、注入块渲染和增量更新。
  • Persona Bundle:每个朋友分身的独立资料包。

核心目录:

  • digital-twin/core/
    • build.py:从聊天 CSV 制作 Persona Bundle。
    • verify.py:执行 6 维验收并生成 report.json
    • retriever.py:根据输入消息检索相关 few-shot 示例。
    • injector.py:唯一对外注入接口,渲染纯文本 prompt block。
    • persona.py:加载 Bundle。
    • update.py:增量更新 Bundle。
  • digital-twin/adapters/
    • emit_prompt.py:生成运行时注入块。
    • emit_skill.py:导出 Agent skill。
    • emit_card.py:导出角色卡。
  • digital-twin/web/backend/
    • FastAPI 应用、任务管理、WebSocket、SSE、上传、配置和产物接口。
  • digital-twin/web/frontend/
    • Vue 3 + Vite + Pinia 工作台。
  • digital-twin/config/
    • 默认配置、schema 元数据和运行时配置加载。
  • digital-twin/personas/
    • 公开仓库默认只保留合成示例 Alex__to__Sam

目录结构

FriendForge/
  README.md
  digital-twin/
    cli/                  # CLI 入口:python -m cli.dtwin
    config/               # 默认配置、schema 和加载器
    core/                 # 制作、验收、检索、注入、更新
    llm/                  # BYOK 大模型客户端和预设
    adapters/             # prompt / skill / card 导出
    personas/             # 公开仓库只放合成示例
    tests/                # 后端和 API 测试
    web/
      backend/            # FastAPI 后端
      frontend/           # Vue 3 工作台

环境要求

推荐环境:

  • Windows 11
  • Python 3.13.12(digital-twin/.python-version
  • uv 0.11.16(由 pyproject.toml 强制匹配)
  • Node.js 20.19.4(前端 .nvmrc
  • npm 10.8.2(前端 package.json

可选依赖:

  • sentence-transformers 5.6.0 + torch 2.12.1+cpu:完整档用于本地 embedding 和较大样本检索。
  • BYOK LLM provider:例如 OpenAI-compatible API 或本地 Ollama endpoint。

快速启动

克隆仓库:

git clone https://github.com/1while1/FriendForge.git
cd FriendForge

首次安装标准开发环境:

.\scripts\setup_environment.ps1 -Profile standard

需要本地 Embedding 时改用 -Profile full。脚本会按 uv.lockpackage-lock.json 重建依赖,并验证 Python、uv、Node、npm 与 lockfile 一致;不需要预先准备 .venvnode_modules

启动后端:

cd digital-twin
uv run --locked --no-sync python -m uvicorn web.backend.app:app --host 127.0.0.1 --port 8000 --log-level warning

启动前端:

cd digital-twin/web/frontend
npm run dev

打开:

http://localhost:5173

健康检查:

http://127.0.0.1:8000/health
http://127.0.0.1:8000/api/stats

公开仓库自带 Alex__to__Sam 合成示例,所以启动后可以直接看到一个示例 Bundle。

Web 工作台使用说明

Web 工作台主要页面:

  • Dashboard:查看 Bundle 总数、门禁状态、策略分布和数据规模。
  • Bundles:浏览所有 Persona Bundle。
  • Bundle Detail:查看画像、风格、示例、验收报告、试聊和产物导出。
  • Make:上传 CSV,创建新的 Bundle 制作任务。
  • Jobs:查看制作、验收、更新任务的状态和流式日志。
  • Config:编辑 LLM、检索、Web 上传等配置。

典型流程:

  1. 准备聊天 CSV。
  2. 在 Make 页面填写 owneraudience
  3. 启动制作任务。
  4. 等待 WebSocket 进度完成。
  5. 进入 Bundle Detail 查看结果。
  6. 运行 Verify 或重新验收。
  7. 在试聊窗口测试语气。
  8. 验收通过后导出 promptskillcard

CLI 使用说明

所有 CLI 命令建议在 digital-twin/ 目录下运行:

cd digital-twin

制作 Bundle:

uv run --locked --no-sync python -m cli.dtwin make <chat.csv> --owner "Alex" --audience "Sam"

验收 Bundle:

uv run --locked --no-sync python -m cli.dtwin verify Alex__to__Sam

生成 prompt 注入块:

uv run --locked --no-sync python -m cli.dtwin emit prompt Alex__to__Sam --query "今天有点累"

导出 Agent skill:

uv run --locked --no-sync python -m cli.dtwin emit skill Alex__to__Sam

导出角色卡:

uv run --locked --no-sync python -m cli.dtwin emit card Alex__to__Sam

增量更新:

uv run --locked --no-sync python -m cli.dtwin update Alex__to__Sam --append-csv <new.csv> --only recent

通过 CLI 启动 Web 后端:

uv run --locked --no-sync python -m cli.dtwin web --reload

Bundle 文件说明

生成后的 Bundle 通常长这样:

personas/Alex__to__Sam/
  persona.json
  style.md
  recent_context.md
  examples.jsonl
  exemplars.jsonl
  report.json
  approval.json        # 可选,手动 approve 留痕
  embeddings/          # 可选,默认不入库

主要文件:

  • persona.json:Bundle 元数据和检索策略。
  • style.md:从聊天记录蒸馏出的风格指纹。
  • recent_context.md:近期上下文摘要。
  • examples.jsonl:few-shot 示例。
  • exemplars.jsonl:用于静态导出的代表性示例。
  • report.json:验收结果和门禁状态。
  • approval.json:手动放行记录。

验收与导出门禁

FriendForge 在导出产物前会检查门禁状态:

  • passed:验收通过,可以导出。
  • approved:验收未完全通过,但有手动 approve 记录。
  • refused:验收失败,且没有手动 approve。
  • pending:还没有验收报告。

这样可以避免把质量不足或未经检查的分身直接导出给宿主使用。

隐私说明

公开仓库按默认规则避免泄露个人数据:

  • 原始聊天 CSV 不入库。
  • digital-twin/personas/* 默认不入库,只保留合成示例。
  • digital-twin/dist/ 不入库。
  • digital-twin/config/config.toml 不入库。
  • .env*.env 不入库。
  • API key 应通过本地配置或环境变量提供,不要提交到 Git。

如果你要发布自己的 fork,建议先做一次 secret/PII 扫描,确认只有合成示例数据被 Git 跟踪。

致谢

感谢 WeFlow 这个开源项目。它帮助我非常方便地导出聊天记录,让 FriendForge 的数据准备流程顺畅了很多。

开发检查

后端测试:

cd digital-twin
uv run --locked --no-sync python -m unittest discover -s tests -v

前端构建:

cd digital-twin/web/frontend
npm ci
npm run build

环境契约检查:

digital-twin\.venv\Scripts\python.exe scripts\check_environment.py --profile standard

空白字符检查:

git diff --check

许可证

MIT

About

FriendForge 将聊天记录转化为可复用的 AI 朋友分身,无需微调模型。它提供 FastAPI + Vue Web 工作台,用于构建 owner→audience Persona Bundle,并支持流式验收、试聊天、产物导出、BYOK 大模型接入 和门禁发布检查。

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages