@ygg-team/ygg-pi
通用 AI Agent:8 场景 5 工作流、规则表权限层、审查引擎、记忆系统、并行 Agent 与子代理。基于 pi coding agent 构建
Package details
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
首次使用
- 配置模型(见上一节:
/login deepseek最快;已配好可跳过) - 启动 ygg-pi
- 输入
/domain切换到你需要的场景(默认是代码开发) - 直接用自然语言描述任务,系统会自动分类工作流
- 或者输入
/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"]
}
}
工作原理
- 启动时
bin/ygg-pi.js读取settings.json中的input字段 - 自动生成带
input声明的models.json(~/.ygg-pi/pi-runtime/) - 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-endagent-start/agent-endpre-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,不是合并),缺失字段走默认值(contextWindow128000、cost全 0、thinkingLevelMap空)。以前无论什么情况都写完整定义,导致只配个地址就把内置目录的 1M 上下文、成本表、max思考级别全部冲成默认值。另外:同一个模型 id 在 pi 目录里可能有多个 provider 版本,价格差很多。
deepseek-flash就有官方0.3、Cloudflare 网关1.32、Baseten1.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 项断言
⚠️ 注意事项
pi 版本兼容:0.84.x 与 1.3.x~1.5.2 均已适配(系统提示增量注入 + 全屏状态栏密度),详见 docs/PI-UPGRADE.md
Extension 独立加载,一个失败不影响其他
configs/ 是内置默认值,自定义放
~/.ygg-pi/或.ygg-pi/debug 修复阶段限制:≤3 文件 × 50 行,每次 tsc 验证
autopilot 不放弃安全:跳过普通确认,但危险命令/敏感文件直接拒绝,连续 3 次自动退出
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),失败自动回退本地抓取。parallel_execute 子 session 独立,结束后 dispose
会话文件锁:PID 写入 .lock,防止多实例冲突
/init不会把 AGENTS.md 写成大块头:它只读目录结构 + 关键配置(不全量读文件), 内容按优先级分流 —— 行为约束留AGENTS.md,目录树/模块详解/实现细节进docs/ARCHITECTURE.md。 更新已有文件时强制用edit不write,只改事实错误,不重写不润色。 理由:pi 会把AGENTS.md全量注入每轮系统提示,它里面每多一行都变成永久的 token 支出。排查 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
# 系统自动拆分并行执行
🤝 贡献
- Fork 项目
- 创建功能分支
- 提交改动
- 推送到分支
- 创建 Pull Request
📄 许可证
MIT