@ygg-team/ygg-pi

通用 AI Agent:8 场景 5 工作流、规则表权限层、审查引擎、记忆系统、并行 Agent 与子代理。基于 pi coding agent 构建

Packages

Package details

extensionskillprompt

Install @ygg-team/ygg-pi from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@ygg-team/ygg-pi
Package
@ygg-team/ygg-pi
Version
0.5.2
Published
Nov 13, 2026
Downloads
493/mo · 192/wk
Author
wangygg
License
MIT
Types
extension, skill, prompt
Size
3.2 MB
Dependencies
0 dependencies · 5 peers
Pi manifest JSON
{
  "skills": [
    "./skills"
  ],
  "prompts": [
    "./configs/prompts"
  ],
  "extensions": [
    "./extensions/*.ts",
    "./extensions/tools/*.ts"
  ],
  "changelogPath": "./CHANGELOG.md"
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

ygg-pi

通用 AI Agent — 8 场景 5 工作流,规则表权限层,审查引擎,记忆系统,并行 Agent

基于 pi coding agent 的 Extension 系统构建。

✨ 特性

  • 🎯 8 个场景:代码开发、数据分析、写作助手、学习辅导、学术研究、办公效率、资料管理、生活助手
  • 🖼️ 多模态图片支持:通过 input 声明启用视觉模型,read 工具可直接读取并分析图片
  • 🔄 5 种工作流:React(编写修改)、Explore(分析研究)、Plan(规划设计)、Chat(闲聊问答)、Autopilot(全自动)
  • 🛡️ 规则表权限层:git 三档 / 危险命令 / 敏感文件 / 路径沙箱,常规任务 0 弹框,危险 100% 拦
  • 🔎 弹框带说明:拦截时显示命令用途,跑脚本会逐行扫描高危操作(rm -rf / sudo / curl \| sh 等)并单独标出「无法静态判断」的动态构造
  • 🧠 记忆系统:用户级 + 项目级双层存储,自动学习偏好和约定
  • 🔍 审查引擎:副模型独立审查(安全/正确/风格),流式输出
  • ⚡ 并行 Agent:多任务并行执行,实时面板显示进度
  • 🤖 子代理系统:自定义 Agent + Hooks 自动化
  • 📊 多行状态栏:领域/工作流/模型/思考级别/token/上下文进度/工具统计/任务列表,含缓存命中断崖告警与长上下文阈值提示。工具与技能那行只记可验证的事实(读过哪个 SKILL.md),不靠模型自述
  • 💰 成本可见:缓存命中率、输入/输出/缓存读实时统计,状态栏直接看到“钱花在哪”
  • 🧪 prompt 探测:YGG_PROMPT_DEBUG=1 把每轮的 prompt 分段长度写进日志,排查“某段到底生效了没”不用靠猜
  • 🛠️ 14 个自定义工具:任务管理、Web 搜索、文档读取、语法检查、学术搜索等
  • 💬 命令说明:工具行下方一句话说清「这条命令在干什么」(支持管道修饰、子命令),脚本会读它自己的首行注释
  • 📝 动态命令声明:脚本里有变量拼接 / eval / base64 时,# 动态命令:… 展开为 … 注释会被扫描器读入检查。声明只能加警不能减警,假声明绕不过去
  • 🔗 中断提示:ESC 中断后提醒改口句式,避免修正指令被当成补充指令
  • 🔒 配置守护:模型配置缺失时明确告知当前实际生效的模型,不静默回落
  • 📚 23 个内置 Skill:写作系列、文档处理、创作工具等(用户自装的会追加)

📦 安装

前置条件

  • Node.js 22.19+(pi 1.5.2 的 engines 要求;node:sqlite 需 22+)
  • pi coding agent 0.84.x 或 1.3.x~1.5.2(兼容矩阵见 pi 版本兼容)
  • npm 或 pnpm

方式 1:npm 安装(推荐)

npm install -g @ygg-team/ygg-pi

安装完成后会自动执行 postinstall:

  • 创建 ~/.ygg-pi/ 全局配置目录
  • 生成默认 settings.json 和 permissions.json
  • 复制 Skills 到 ~/.ygg-pi/skills/

方式 2:源码安装

# 1. 安装 pi coding agent
npm install -g @earendil-works/pi-coding-agent@1.5.2

# 2. 克隆项目
git clone https://gitee.com/yggxiaohuayuan/ygg-pi.git
cd ygg-pi

# 3. 安装依赖
npm install

# 4. 全局链接
npm link

🔑 配置模型(必做)

ygg-pi 需要一个模型 API 才能工作。两种方式,推荐第一种。

方式 1:/login(最简单,不用改任何文件)

启动 ygg-pi 后:

/login deepseek

按提示粘贴 API key。pi 会把它存到 ~/.pi/agent/auth.json,并自动使用该 provider 的默认模型 —— 不需要你查模型 ID。

实测:只放 auth.json、不传任何模型参数,pi 会直接用下列默认模型发请求。

provider 自动选用的模型 密钥申请
deepseek deepseek-v4-pro platform.deepseek.com
anthropic claude-opus-5-5 console.anthropic.com
openai gpt-6.1-sol platform.openai.com
google gemini-4-argon aistudio.google.com
zai glm-5.3(智谱) open.bigmodel.cn
moonshotai kimi-k2.7-code(月之暗面) platform.moonshot.cn
xai grok-4.7 x.ai
openrouter moonshotai/kimi-k2.7-code(聚合多家) openrouter.ai

支持 OAuth 的 provider(如 GitHub Copilot)选它会进浏览器授权流程。

方式 2:手写配置(需要指定非默认模型时)

编辑 ~/.ygg-pi/settings.json 的 model 段:

{
  "model": {
    "provider": "deepseek",
    "name": "deepseek-v4-pro",
    "apiKey": "sk-你的密钥",
    "thinkingLevel": "high"
  }
}

或者用 /config 交互式填(它写的是同一份 JSON)。

与 /login 的关系:两边都配时,这里的配置优先(bin 会把三个字段转成 CLI 参数,优先级高于 auth.json)。三个字段需同时填写 —— 缺任何一个就不会传给 pi,回退到 /login 的凭证。

thinkingLevel 可选:low / high / max(默认 high),也可用 Shift+Tab 在会话里临时切。

用代理 / 中转时加 baseURL

官方 API 不用填 baseURL。只有走代理、中转或自建网关时才需要,且要带 /v1 后缀:

"baseURL": "https://api.deepseek.com/v1"

❗ 填了 baseURL 时,name 必须是路由能识别的模型 ID。写错不会报错,但价格、上下文长度、思考级别都可能变回默认值 —— 把 YGG_PROMPT_DEBUG=1 开着排查。

改完 settings.json 要完全退出并重启 ygg-pi 才生效 —— 模型在进程启动时加载,不热更新。/login 则是即时生效。

🚀 使用

启动方式

# 方式 1:使用包装脚本(推荐,自动加载所有扩展)
ygg-pi

# 方式 2:指定会话名
ygg-pi --session my-project

# 方式 3:直接用 pi 加载扩展
pi -e ./extensions/*.ts -e ./extensions/tools/*.ts

# 方式 4:只加载部分扩展
pi -e ./extensions/safety.ts -e ./extensions/scene-router.ts

首次使用

  1. 配置模型(见上一节:/login deepseek 最快;已配好可跳过)
  2. 启动 ygg-pi
  3. 输入 /domain 切换到你需要的场景(默认是代码开发)
  4. 直接用自然语言描述任务,系统会自动分类工作流
  5. 或者输入 /workflow 手动选择工作流

没配模型也能启动,但会在对话时报错。启动时会看到一条提示告诉你缺什么。

基本交互

# 直接描述任务(系统自动分类)
帮我分析一下这段代码的性能问题     → 自动路由到 explore 工作流
修复这个 TypeScript 编译错误       → 自动路由到 react 工作流
给我一个微服务架构方案             → 自动路由到 plan 工作流

# 手动切换场景
/domain                          → 弹框选择场景

# 手动切换工作流
/workflow                        → 弹框选择工作流

# 全自动执行
/autopilot 帮我重构这个模块,运行测试确保通过

🖼️ 多模态图片支持

ygg-pi 支持视觉模型读取和分析图片。要启用图片能力,需要在 ~/.ygg-pi/settings.json 的 model 配置中声明 input 字段:

{
  "model": {
    "provider": "deepseek",
    "name": "deepseek-v4-flash-vision-exp",
    "apiKey": "sk-xxx",
    "baseURL": "https://api.deepseek.com/v1",
    "thinkingLevel": "high",
    "contextWindow": 1048576,
    "input": ["text", "image"]
  }
}

工作原理

  1. 启动时 bin/ygg-pi.js 读取 settings.json 中的 input 字段
  2. 自动生成带 input 声明的 models.json(~/.ygg-pi/pi-runtime/)
  3. pi 内核识别为多模态模型,read 工具读取的图片会以 ImageContent 传给模型

注意事项

  • 只有声明了 input: ["text", "image"] 且模型本身支持视觉时,图片才能正常读取
  • 如果模型不支持图片,read 工具会提示 Current model does not support images
  • 修改配置后需彻底退出并重启 ygg-pi 才能生效(进程启动时加载模型配置,不热更新)

支持的模型

  • DeepSeek:deepseek-v4-flash-vision-exp(支持 JPEG/PNG/GIF/WebP)
  • 其他支持视觉的 OpenAI 兼容模型均可通过此方式声明

🎯 场景系统

8 个场景,每个场景有不同的角色定义和工具集。

场景列表

场景 说明 特色工具
代码开发 全栈编程助手,精通 TypeScript/JavaScript/Python read/write/edit/bash/grep/find/ls
数据分析 数据分析专家 + db_query(SQLite 只读查询)
写作助手 写作润色专家 + grammar_check(语法检查)
学习辅导 学习引导者(不直接给答案) 引导思考模式
学术研究 学术研究助手 + scholar_search(论文检索)
办公效率 办公自动化专家 + send_email + doc_read
资料管理 资料库管理员:知识编译 + 文件归档(LLM Wiki 范式,原始/ 知识/ 归档/ 三层) /init 建库 + 体检
生活助手 生活推荐助手 web_search/web_fetch

切换场景

/domain                    # 弹框选择
/domain 代码开发            # 直接指定(TODO:当前版本用弹框)

场景持久化到 .ygg-pi/settings.json 的 domain 字段,下次启动自动恢复。

🔄 工作流系统

5 种工作流,自动或手动切换。

工作流列表

工作流 触发场景 行为
react 修改/创建/调试/实现功能 思考→行动→观察循环,批量读改验证
explore 分析/理解/研究/调查 只读模式,逐模块深入,够用就停
plan 设计/规划/方案/架构 先用 task 创建任务列表,确认后逐个执行
chat 闲聊/问答/问候 纯对话,跳过复杂流程
autopilot 手动触发 /autopilot <任务> 跳过普通确认;git 写放行,危险命令/敏感文件拒绝(详见安全系统)

自动分类

系统使用 LLM 自动分类用户输入(5 秒超时)。分类 prompt 外置在 configs/prompts/classify/{domain}.md,按当前领域取(找不到退 default.md,再退内置兜底)—— 不同领域的判别语义差很远,写死在代码里没法按领域换。

默认(default.md)支持检测:

  • [debug] 标记:用户报告 bug/错误 → 进入 debug 状态机
  • [plan] 标记:用户请求方案/设计 → 进入 plan 状态机

资料管理领域(vault.md)用另一套:按写操作范围切分(explore 只读 / react 局部写 / plan 全库写 / chat 兜底),不确定一律 explore,且不输出任何 tag——避免「PDF 打不开」被判 [debug] 去跑 tsc。

手动切换

/workflow                   # 弹框选择
/workflow react             # 直接指定(TODO:当前版本用弹框)

工作流持久化到 .ygg-pi/settings.json 的 workflow 字段。

资料管理:LLM Wiki 范式

不是"文件整理器",是知识编译系统:原始资料只读,编译后的知识页可查询、可累积。

<库根>/
├── AGENTS.md      框架说明(权威,跟着库走不跟工具走)
├── INDEX.md       总索引(也是检索入口)
├── 原始/          原始资料,只读。年-月/原文件名
├── 知识/          编译后的知识页。主题/页面.md(最多两层)
└── 归档/          不编译的文件(合同/发票/证件/照片)

双轨:需要被理解的(文章/论文/笔记)→ 编译成知识页;只需要被找到的(发票/照片)→ 原样归档 + 索引一行。

三个动作:归档(react)→ 判重 → 存 原始/ → 写页 → 更新 INDEX;查库(explore)→ 读 INDEX → 定位 → 带路径引用作答,找不到就说找不到;建库/改造(plan)→ 扫描 → 出方案表 → 确认 → 分批执行。

知识/未分类/ 不是垃圾桶,是"待富集的种子"——归不了类通常是库里还缺那个主题,等下一个相关来源进来就能凑成页。每次归档开始前自动重试归类,> 5 项必须先清到 ≤ 5。

/init 在资料库目录下:确定性建骨架(从 configs/templates/ 拷贝)+ 体检(INDEX 坏链、漏登记、source 悬空、双链未建、目录超层、主题过大、未分类堆积)。体检结果直接输出,不经 LLM 转述。

🛡️ 安全系统

判定逻辑在 extensions/utils/policy.ts(纯函数,可单测),safety.ts 只负责弹框、状态机和会话缓存。

决策表(顺序即优先级)

优先级 条件 动作
1 状态机不允许(debug 诊断阶段禁写 / plan 规划阶段禁写) deny
2 git 破坏性操作(push --force / reset --hard / clean -fdx / branch -D main) 确认
3 绝对危险(rm -rf / sudo / chmod 777 / curl|sh / mkfs) 确认
4 命令包装器(env / xargs / sh -c / eval) 确认
5 重定向到项目外 确认
6 写敏感文件(.env* / package.json / tsconfig.json / *.pem) 确认
7 git 写操作(add / commit / push / pull …) 确认 → 本会话记住
8 git 双态子命令带写参数(branch -D / tag -d / remote add / config) 确认
9 未识别的 git 子命令(可能是 alias) 确认
10 git 只读(status / log / diff / show / branch 无参…) 放行
11 读敏感路径(~/.ssh / ~/.aws / ~/.ygg-pi/settings.json / *.pem) 确认
12 只读工具 + bash 只读命令(项目外也放行) 放行
13 项目内写文件(非敏感) 放行
14 bash 构建 / 测试 / 依赖 / 项目内写命令 放行
15 无副作用工具(task / web_* / db_query / review…) 放行
16 其余 确认

弹框预算

场景 弹框次数
常规任务(读文件、改代码、跑测试、构建) 0
首次 git 写(add/commit)+ 首次 push 2(之后本会话不再问)
危险命令 / 敏感文件 每次
项目外路径写 首次(确认后信任该目录 7 天)

autopilot 模式

/autopilot <任务> 进入前会弹一次风险提示,之后:

操作 行为
项目内读写 / 普通命令 / git 写 放行
危险命令 / 敏感文件 / 敏感路径 deny(不弹框直接拒绝)
连续 3 次被拒绝 自动退出 autopilot 并通知

自定义安全规则

编辑 ~/.ygg-pi/permissions.json 或 <project>/.ygg-pi/permissions.json:

{
  "dangerous": ["\\brm\\s+-rf\\b", "\\bsudo\\b"],
  "sensitive": [".env", "package.json"],
  "trusted": ["^(npm|pnpm|yarn)\\s+(test|run|install)\\b"]
}
  • dangerous:匹配这些正则的命令需要用户确认
  • sensitive:修改这些文件需要用户确认
  • trusted:匹配这些正则的命令自动放行

三层配置取并集(内置 configs/permissions.json + 全局 + 项目):内置规则永远生效,用户只能往上加,不会因为全局文件是旧版就意外失效。

路径沙箱

  • 写操作(write / edit、bash 重定向)默认限制在项目根目录
  • 只读操作(read / grep / find / ls)不限制,但敏感路径要确认
  • 确认越界后,该目录被信任 7 天(~/.ygg-pi/trusted-paths.json)
  • 子代理(parallel_execute / spawn_agent)也挂同一个权限层,无 UI 所以 confirm 自动变成 deny

确认框会告诉你什么

弹框不只显示命令原文,还会给出:

【执行脚本】
bash deploy.sh
↳ 执行脚本 deploy.sh — 清理并重新部署
⚠ 脚本 deploy.sh 含 2 处危险、1 处无法静态判断:
    ⚠ rm -rf /var/www/old
    ? $CLEAN
    (动态构造的命令需人工查看,建议先 read 该脚本)
确认执行?
  • ⚠ 是确定的事实(规则判出来的)
  • ? 是诚实的不确定(动态构造,静态看不透)
  • 两者分开列,不混在一起让用户以为「看不清的部分也查过了」

Debug 状态机

当系统检测到用户报告 bug/错误时,自动进入 debug 模式:

诊断阶段(只读)
  ↓ ≥3 次只读操作 + 输出根因/修复方案
修复阶段(限制写入)
  ↓ ≤3 文件 × 50 行,每次改完需 tsc --noEmit 验证
汇总

Plan 状态机

当系统检测到用户请求方案/设计时,自动进入 plan 模式:

规划阶段(只读)
  ↓ 用 task 工具创建任务列表
执行阶段
  ↓ 逐个 task 执行
汇总

🧠 记忆系统

存储结构

  • 用户级:~/.ygg-pi/memories.json(跨项目共享)
  • 项目级:.ygg-pi/memories.json(仅当前项目)

记忆工具

# LLM 自动调用,也可手动触发
memory_search  { query: "偏好" }     # 搜索记忆
memory_save    { content: "...", category: "project" }  # 保存记忆

自动学习

系统通过 promptGuidelines 让 LLM 自动识别并保存:

  • 用户偏好("我喜欢..."、"偏好...")
  • 项目约定("这个项目用..."、"约定...")
  • 重复指令("以后..."、"总是...")

记忆注入

每次对话开始时,scene-router 自动注入最近记忆(上限 500 字符)到 system prompt。

🔍 审查引擎

配置

在 ~/.ygg-pi/settings.json 或 .ygg-pi/settings.json 添加:

{
  "review": {
    "apiKey": "your-api-key",
    "model": "gpt-4o-mini",
    "baseURL": "https://api.openai.com/v1/chat/completions"
  }
}

使用

LLM 在生成代码后可自主决定调用 review 工具:

# LLM 自动调用,无需手动触发
review { text: "要审查的代码", context: "上下文说明" }

审查维度:

  • 安全:是否泄露密钥/密码?是否有危险命令?
  • 正确:逻辑是否自洽?引用是否准确?
  • 风格:是否简洁?有无废话?

⚡ 并行执行

使用方式

LLM 自动将可并行的任务拆分调用:

parallel_execute {
  tasks: [
    "读取 src/utils.ts 的内容",
    "读取 src/config.ts 的内容",
    "搜索项目中所有 TODO 注释"
  ]
}

实时面板

执行过程中,status-bar 会显示实时进度:

▸ parallel_execute  2/3
  ✓ 1/3 读取 src/utils.ts  ·  2工具  ·  1轮  完成 3s
  ◉ 2/3 读取 src/config.ts  ·  执行中
  ○ 3/3 搜索 TODO  ·  等待

🤖 子代理系统

自定义 Agent

在 ~/.ygg-pi/agents/ 创建 .md 文件:

# 代码审查专家

description: 专注代码质量审查的子代理

你是一个代码审查专家。请仔细审查代码的安全性、可读性和性能。
发现问题时,给出具体的修复建议。

调用 Agent

LLM 自动决定是否需要调用子代理:

spawn_agent { agent: "代码审查专家", task: "审查 src/index.ts" }

Hooks 自动化

在 ~/.ygg-pi/hooks/ 创建 shell 脚本:

# ~/.ygg-pi/hooks/session-start.sh
echo "会话开始于 $(date)" >> ~/.ygg-pi/hooks.log

# ~/.ygg-pi/hooks/agent-end.sh
echo "任务完成" >> ~/.ygg-pi/hooks.log

支持的事件:

  • session-start / session-end
  • agent-start / agent-end
  • pre-compact / post-compact

🛠️ 工具列表

核心工具

工具 说明 依赖
task 任务管理(list/create/update/delete/set_all) —
parallel_execute 并行执行多个子任务 —
spawn_agent 调用子代理 —
review 副模型审查 需配置 review
memory_search 搜索记忆 —
memory_save 保存记忆 —
system_info 查询系统状态 git CLI

网络工具

工具 说明 依赖
web_search 四层降级搜索(DeepSeek→博查→DuckDuckGo→Wikipedia) DeepSeek 主模型 Key 或博查 Key(可选)
web_fetch 获取网页内容转 Markdown —
scholar_search 学术论文检索(Semantic Scholar) —

文档工具

工具 说明 依赖
doc_read 读取 Word/Excel/PPT 文档 python + python-docx/openpyxl/pptx
grammar_check 语法和拼写检查 LanguageTool API
send_email 发送邮件 需配置 SMTP
db_query SQLite 只读查询 Node 22+ node:sqlite

📋 命令列表

场景和工作流

命令 说明
/domain(/领域) 切换场景(弹框选择)
/workflow(/工作流) 切换工作流(弹框选择)
/autopilot(/全自动) 全自动执行任务

会话管理

命令 说明
/sessions(/会话) 查看会话列表
/sessions new <名称> 创建新会话
/sessions switch <名称> 切换会话
/sessions rename <名称> 重命名当前会话
/sessions delete <名称> 删除会话

配置和工具

命令 说明
/config 查看/编辑 settings.json
/skill 查看和管理 Skill(启用/停用)
/init 按领域分派:代码 → 生成/精简 AGENTS.md;资料库 → 建骨架 + 体检
/help 列出所有可用命令

pi 内置命令

命令 说明
/model 切换模型
/settings 打开设置菜单
/new 新建会话
/resume 恢复历史会话
/compact 手动压缩上下文
/tree 导航对话树
/copy 复制最后回复
/export 导出会话
/quit 退出程序

📚 Skill 系统

写作系列(12 个)

Skill 说明
story 写作主 Skill(大纲→章节→润色)
story-long-write 长篇写作
story-short-write 短篇写作
story-long-analyze 长篇分析
story-short-analyze 短篇分析
story-long-scan 长篇扫描
story-short-scan 短篇扫描
story-cover 封面设计
story-deslop 去 AI 味
story-import 导入分析
story-review 审稿
story-setup 初始化设定

文档处理(4 个)

Skill 说明
docx Word 文档处理
xlsx Excel 处理
pptx PPT 处理
pdf PDF 处理

创作工具(7 个)

Skill 说明
brainstorming 头脑风暴
frontend-design 前端设计指南
humanizer 文本人性化
skill-creator Skill 创建器
superpowers 完整开发方法论
audit-website 网站审计
browser-cdp 浏览器控制

管理 Skill

/skill                    # 查看所有 Skill
# 选择一个 Skill 可以启用/停用
# 停用会创建 .disabled 文件,下次对话生效

项目级 Skill 绑定:skills.always

Skill 列表默认只是「工具箱」,模型不一定用。想让某个 Skill 成为项目规定,在项目配置里声明:

// <project>/.ygg-pi/settings.json
{
  "skills": {
    "always": ["vue-best-practices", "vue-router-best-practices"]
  }
}

声明后 catalog 会把它单独提成「本项目必读技能」段,并且跨域可见(不受 domains 限制)。 名字写错会在会话启动时报 warning,不会静默失效。

技术栈探测:stack

/init 会扫描依赖清单(支持 JS / Java / Kotlin / Python / Go / Rust / PHP / Ruby / .NET / Dart), 把结果写进 stack 字段,每轮往 catalog 顶部注一行技术栈摘要:

{
  "stack": {
    "ecosystems": ["js"],
    "frameworks": ["pinia", "vue", "vue-router"],
    "manifests": 9
  }
}

模型看到这行 + 每个 Skill 的 description,自己判断该读哪个。 探测错了直接改这个字段即可,不影响其他配置。

两个字段的分工:stack 是事实(项目用了什么,自动探测),skills.always 是规定(必须读哪个,人工声明)。 /init 只写 stack,不替你决定 always。

📁 配置架构

三级优先级

项目 .ygg-pi/  >  全局 ~/.ygg-pi/  >  源码内置 configs/
  • 项目级:.ygg-pi/ 目录,只影响当前项目
  • 全局级:~/.ygg-pi/ 目录,影响所有项目
  • 源码内置:configs/ 目录,包默认值,升级会覆盖

全局配置:~/.ygg-pi/

~/.ygg-pi/
├── settings.json            # 主配置(模型/审查/Web搜索/SMTP/记忆)
├── permissions.json         # 安全规则(dangerous/sensitive/trusted)
├── memories.json            # 用户级记忆(跨项目共享)
├── trusted-paths.json       # 信任路径(当天有效)
├── agents/                  # 自定义 Agent
│   └── 代码审查专家.md
├── hooks/                   # 自动化脚本
│   ├── session-start.sh
│   └── agent-end.sh
├── skills/                  # Skill(postinstall 自动复制)
│   ├── story/
│   ├── brainstorming/
│   └── ...
└── prompts/                 # 自定义 prompt(可选)
    ├── domains/
    └── workflows/

项目配置:.ygg-pi/

.ygg-pi/
├── settings.json            # 项目设置(domain/workflow/statusBar.mode)
├── memories.json            # 项目级记忆
├── sessions.json            # 命名会话索引
├── sessions/                # 会话存储目录
├── SAFETY_RULES.md          # 安全操作规则
└── prompts/                 # 项目级 prompt 覆盖(可选)
    ├── domains/
    └── workflows/

早期版本这里还会生成 thinkingLevel,但它从未传给 pi —— 实际生效的是全局 model.thinkingLevel(bin/ygg-pi.js 转成 --thinking)。两个值不一致时状态栏会显示错的, 所以已停用:新项目不再写入,老项目里已有的也不再读(状态栏改为直接问 pi 运行时)。 要改思考级别用 Shift+Tab 循环、/thinking <级别> 指定,Ctrl+S 保存为默认。

settings.json 完整配置

{
  "model": {
    "provider": "deepseek",
    "name": "deepseek-flash",
    "apiKey": "sk-xxx",
    "thinkingLevel": "high"
  },
  "review": {
    "apiKey": "sk-xxx",
    "model": "gpt-4o-mini",
    "baseURL": "https://api.openai.com/v1/chat/completions"
  },
  "webSearch": {
    "apiKey": "your-bocha-api-key",
    "baseURL": "https://api.bocha.cn/v1/web-search",
    "deepseek": { "apiKey": "", "baseURL": "" }
  },
  "smtp": {
    "host": "smtp.gmail.com",
    "port": 465,
    "secure": true,
    "user": "your-email@gmail.com",
    "pass": "your-app-password"
  },
  "embedding": {
    "provider": "openai",
    "model": "text-embedding-3-small",
    "apiKey": "sk-xxx",
    "baseURL": "https://api.openai.com/v1"
  },
  "memory": {
    "maxItems": 200
  }
}

model 段:什么时候需要 baseURL

用官方 API 就不需要写 baseURL。 pi 内置目录已经给了正确的地址和全部元数据 (contextWindow、cost、thinkingLevelMap、compat)。实测 DeepSeek 官方直连:

{ "baseUrl": "https://api.deepseek.com", "contextWindow": 1000000, "maxTokens": 384000,
  "cost": { "input": 0.3, "output": 1.2, "cacheRead": 0.006, "cacheWrite": 0 } }

只有走中转 / 代理 / 私有网关时才配 baseURL。这时 bin/ygg-pi.js 会生成 ~/.ygg-pi/pi-runtime/models.json 并让 PI_CODING_AGENT_DIR 指向它。

⚠️ baseURL 必须带 /v1(kimi-coding 会自动补,其他 provider 不会),否则请求 404。

场景 写法
模型在内置目录里(绝大多数) 只写 baseURL。生成的文件只含 baseUrl/api/apiKey,pi 只改地址,其余字段全部保留
模型不在内置目录(自定义名称) 加 "defineModel": true,手写完整定义
{
  "model": {
    "provider": "deepseek",
    "name": "my-private-model",
    "apiKey": "sk-xxx",
    "baseURL": "https://my-gateway.example.com/v1",
    "defineModel": true,
    "contextWindow": 1000000,
    "maxTokens": 384000,
    "cost": { "input": 0.3, "output": 1.2, "cacheRead": 0.006, "cacheWrite": 0 },
    "thinkingLevelMap": { "low": "low", "high": "high", "max": "max" },
    "compat": { "thinkingFormat": "deepseek" }
  }
}

为什么要分两条路:pi 的 applyModelsJson 对 models.json 里声明的模型是整体替换 (models[i] = model,不是合并),缺失字段走默认值(contextWindow 128000、cost 全 0、 thinkingLevelMap 空)。以前无论什么情况都写完整定义,导致只配个地址就把内置目录的 1M 上下文、成本表、max 思考级别全部冲成默认值。

另外:同一个模型 id 在 pi 目录里可能有多个 provider 版本,价格差很多。 deepseek-flash 就有官方 0.3、Cloudflare 网关 1.32、Baseten 1.32 三个版本, 所以 provider 字段要写对。

🎨 状态栏

多行 Footer 布局

[代码开发] [auto/react] deepseek-flash high  my-project  (main)
Context ████░░░░░░░░░░░░░░░░ 45.2k|1.0M (4.5%)
累计 read ×5 • bash ×3 • edit ×2
工具 bash,read │ 技能 brainstorming │ 域外 story
任务 2/4
  ✓ 读取源码结构
  ✓ 分析依赖关系
  ◉ 编写测试用例
  ○ 更新文档

几条口径说明:

  • 思考级别、模型名、git 分支、上下文进度全部来自 pi 的运行时状态,不从配置文件猜
  • 工具/技能那行只记可验证的事实 —— “读过某个 SKILL.md”而不是“正在使用某个技能”
  • 域外技能用暗色显示:读到了当前领域 catalog 里没有的技能,是个有用的调试信号(不隐藏)
  • 不显示“哪个扩展提供的” —— 工具名去连字符后基本就是扩展名,多写一遍没信息量

Widget 区域

  • 上方 Widget:当前任务统计(输入/输出/耗时/LLM 调用次数)
  • 下方 Widget:Session 累计统计(输入/输出/缓存命中率/LLM 调用次数)

密度(全屏 TUI 适配)

pi 1.0 起 TUI 默认全屏(tuiMode: fullscreen),footer 可用高度变小。可在 .ygg-pi/settings.json 调整状态栏密度:

statusBar.mode 行为
auto(默认) 任务列表最多 6 行
compact 任务列表最多 3 行,技能最多 2 个
full 不限行数(0.84 时代观感)
{ "statusBar": { "mode": "compact" } }

如果全屏模式的观感不合适,也可以让 pi 回到普通模式:{ "tuiMode": "regular" }。

🔧 开发

源码结构

ygg-pi/
├── bin/ygg-pi.js                # 包装脚本:读配置,收集扩展,启动 pi
├── configs/                     # 源码内置默认值
│   ├── SYSTEM.md                # 通用系统提示词
│   ├── settings.json            # 默认配置
│   ├── permissions.json         # 默认安全规则
│   └── prompts/
│       ├── domains/             # 8 个场景 prompt
│       └── workflows/           # 25 个工作流 prompt
├── extensions/                  # 17 个顶层 Extension + 11 个工具/命令扩展
│   ├── safety.ts                # 权限编排(弹框/状态机/会话缓存)
│   ├── scene-router.ts          # 场景路由 + prompt 注入
│   ├── intent-classifier.ts     # LLM 自动分类
│   ├── reviewer.ts              # 审查工具
│   ├── parallel.ts              # 并行执行
│   ├── memory.ts                # 记忆系统
│   ├── session-mgr.ts           # 会话管理
│   ├── agents-hooks.ts          # 子代理 + Hooks
│   ├── header.ts                # 启动面板
│   ├── chinese-autocomplete.ts  # 命令补全中文化
│   ├── commands.ts              # /help + /skill
│   ├── edit-recovery.ts         # edit 失配时补定位提示
│   ├── interrupt-hint.ts        # 中断后提示改口句式
│   ├── command-hint.ts          # 工具行下方显示命令/脚本说明
│   ├── truncation-notice.ts     # 截断时补完整输出路径 + 展开开关
│   ├── model-guard.ts           # 模型配置未完备时提示
│   ├── status-bar.ts            # 多行状态栏(含缓存/上下文告警)
│   ├── tools/                   # 11 个工具/命令扩展(9 个工具 + 2 个命令)
│   │   ├── init.ts
│   │   ├── config.ts
│   │   ├── task-manager.ts
│   │   ├── web-search.ts
│   │   ├── web-fetch.ts
│   │   ├── system-info.ts
│   │   ├── db-query.ts
│   │   ├── doc-reader.ts
│   │   ├── email.ts
│   │   ├── grammar-check.ts
│   │   └── scholar-search.ts
│   └── utils/                   # 10 个共享模块
│       ├── paths.ts             # 三级查找 + JSON 读写 + 权限三级并集
│       ├── policy.ts            # 权限规则表(纯函数 classify)
│       ├── library.ts           # 资料库体检
│       ├── command-hints.ts     # 命令→人话规则库 + 脚本风险扫描
│       ├── sub-usage.ts         # 子会话用量上报
│       ├── sub-session.ts       # 子 session 的 safety 资源加载器
│       ├── cmd-log.ts           # 命令输出
│       ├── session-read.ts      # 跨 pi 版本读取子会话消息(容错)
│       ├── deepseek.ts          # DeepSeek Search/Fetch 配置
│       └── agent-loader.ts      # 子代理定义加载
├── skills/                      # 23 个内置 Skill
├── scripts/postinstall.js       # npm postinstall
├── tests/                       # 15 个测试文件,906 项断言
└── docs/
    ├── ARCHITECTURE.md          # 完整目录树、模块职责、实现细节
    ├── COMMENT_SPEC.md          # 注释规范
    ├── PI-UPGRADE.md            # pi 版本兼容、1.x 变更、验证清单
    └── ITERATION-0.5.0.md       # 0.5.0 迭代需求与技术评审记录

为什么根目录的 AGENTS.md 只有 140 行:pi 会把项目 AGENTS.md 全量注入系统提示, 每轮都发。所以它只放 agent 的行为约束(怎么做 / 不能做什么 / 踩过的坑), 目录树、模块职责、实现细节全部移到 docs/ARCHITECTURE.md,改代码前再读。 实测这样把注入量从 16,279 字符降到 5,729 字符。

代码规范

  • 每个 Extension export default 一个函数,接收 ExtensionAPI
  • 入口必须 try-catch,异常用 ctx.ui.notify 通知
  • 工具参数用 TypeBox schema
  • 跨 Extension 通信用 pi.events.emit/on(前缀 ygg:)
  • 文件操作通过 utils/paths.ts 的 findFile/readJson/writeJson

编译检查

npx tsc --noEmit

运行测试

npx tsx tests/extensions-test.ts   # 单个文件
npm test                            # 全部 15 个文件,906 项断言

⚠️ 注意事项

  1. pi 版本兼容:0.84.x 与 1.3.x~1.5.2 均已适配(系统提示增量注入 + 全屏状态栏密度),详见 docs/PI-UPGRADE.md

  2. Extension 独立加载,一个失败不影响其他

  3. configs/ 是内置默认值,自定义放 ~/.ygg-pi/ 或 .ygg-pi/

  4. debug 修复阶段限制:≤3 文件 × 50 行,每次 tsc 验证

  5. autopilot 不放弃安全:跳过普通确认,但危险命令/敏感文件直接拒绝,连续 3 次自动退出

  6. web_search 四层降级:DeepSeek 官方搜索(配了 key 时)→ 博查 → DuckDuckGo → Wikipedia

    DeepSeek 的 Search / Fetch 是官方自研搜索引擎,默认复用主模型 key(仅当 model.provider 或 model.baseURL 指向 DeepSeek 时),无需额外申请。也可单独配置或使用环境变量 DEEPSEEK_API_KEY:

    { "webSearch": { "deepseek": { "apiKey": "sk-xxx", "baseURL": "https://api.deepseek.com" } } }

    计费 5 元 / 1000 次成功请求(空结果、失败、超时不收费)。web_fetch 同样会优先走官方 Fetch 接口(直接返回干净 Markdown),失败自动回退本地抓取。

  7. parallel_execute 子 session 独立,结束后 dispose

  8. 会话文件锁:PID 写入 .lock,防止多实例冲突

  9. /init 不会把 AGENTS.md 写成大块头:它只读目录结构 + 关键配置(不全量读文件), 内容按优先级分流 —— 行为约束留 AGENTS.md,目录树/模块详解/实现细节进 docs/ARCHITECTURE.md。 更新已有文件时强制用 edit 不 write,只改事实错误,不重写不润色。 理由:pi 会把 AGENTS.md 全量注入每轮系统提示,它里面每多一行都变成永久的 token 支出。

  10. 排查 prompt 注入用 YGG_PROMPT_DEBUG=1:开启后每轮往 .ygg-pi/sections-debug.log 追加一行 JSON,记录各段 prompt 的字符长度。默认零开销(不设环境变量不碰磁盘)。

    YGG_PROMPT_DEBUG=1 ygg-pi
    cat .ygg-pi/sections-debug.log
    # {"at":"...","workflow":"auto/react","sections":{"ygg-domain":206,"ygg-workflow":464,...}}

为什么要这个:pi 的 session 文件并不每轮都写 system 快照(实测 742 轮只留了 7 条), 而“某段 prompt 到底有没有生效”只能看每一轮的真实注入。0.5.1 修的“工作流 prompt 只在 每任务第一轮生效”就是靠它定位的。

📖 最佳实践

代码开发

# 1. 切换到代码场景
/domain 代码开发

# 2. 描述任务
帮我重构 src/utils.ts,提取公共函数,添加单元测试

# 3. 系统自动:
#    - 分类为 react 工作流
#    - 读取文件分析结构
#    - 逐步重构
#    - 运行 tsc --noEmit 验证
#    - 汇报改动

调试 Bug

# 直接描述错误
运行 npm test 报错:TypeError: Cannot read property 'xxx' of undefined

# 系统自动进入 debug 模式:
# 1. 诊断阶段:读取相关文件,定位根因
# 2. 输出诊断报告和修复方案
# 3. 修复阶段:限制性修改
# 4. 验证修复

规划设计

# 描述需求
给我一个微服务架构方案,需要支持用户认证、订单管理、支付处理

# 系统自动进入 plan 模式:
# 1. 规划阶段:分析需求,创建任务列表
# 2. 确认后逐个执行

并行处理

# 描述多个独立任务
同时帮我:1) 分析 src/a.ts 的依赖 2) 检查 src/b.ts 的类型错误 3) 搜索项目中的 TODO

# 系统自动拆分并行执行

🤝 贡献

  1. Fork 项目
  2. 创建功能分支
  3. 提交改动
  4. 推送到分支
  5. 创建 Pull Request

📄 许可证

MIT