杠精派
派聪明
0/512

热门评论

贪玩的月亮 2026年07月20日 10:16
引用原文:内置的 references 在 PaiCLI 启动时由 SkillBuiltinExtractor 从 jar 包解压到 ~/.paicli/skills-cache/web-access/references/。
@派聪明 为什么要将内置的references从jar包解压到用户目录下呢
点赞
回复10 取消回复
派聪明 2026年07月20日 10:16
这个设计主要有三个核心原因: **1. 让 Agent 能够直接读取文件内容** LLM 是通过 `read_file` 工具来获取站点经验的。如果 references 留在 jar 包里(二进制压缩包),Agent 无法直接读取。解压到用户目录下的 `~/.paicli/skills-cache/` 后,Agent 才能通过 `read_file("~/.paicli/skills-cache/web-access/references/site-patterns/mp.weixin.qq.com.md")` 获取对应站点的操作经验,比如知道微信公众号是 SPA 渲染、必须走 CDP 浏览器。 **2. 支持用户自定义和扩展** 解压到用户目录后,用户可以随时查看、修改甚至补充这些经验文件。比如你可以给某个站点添加新的 CSS 选择器或 JS 提取片段,Agent 下次就能用上。如果留在 jar 包里,用户想改就必须重新打包,根本不现实。 **3. 版本化缓存机制,提升启动性能** extractor 并非每次启动都解压——它会检查 `skills-cache/<name>/.version` 文件与 jar 内置版本号是否一致。一致就跳过,不一致或文件不存在时才重写整个 cache 目录。这样既保证了内置经验能随版本更新,又避免了每次启动都解压带来的 IO 开销,**一举两得**。
点赞
回复 取消回复
展开剩余 9 条回复

60 条评论

忐忑的羽毛 2026年09月06日 15:35
引用原文:Jina Reader(curl https://r.jina.ai/<url>)
@派聪明,这是什么意思
点赞
回复1 取消回复
派聪明 2026年09月06日 15:35
这是文章中提到的**网页抓取兜底方案**。 **含义拆解:** - `r.jina.ai` 是 Jina AI提供的一个免费网页转 Markdown 服务- 使用方式很简单:在命令行把目标网页的 URL拼接在 `https://r.jina.ai/` 后面,用 curl请求即可**举例:** ```bashcurl https://r.jina.ai/https://mp.weixin.qq.com/s/xxxxx``` 返回的结果是网页正文的 Markdown 文本,Agent 可以直接阅读。 **为什么需要它(兜底地位):** 文章中 Agent抓网页的优先级是三层递进的: 1. 先用 `web_fetch` 直接抓(成本最低) 2.抓不到就上 Chrome DevTools MCP 用浏览器渲染3.浏览器也搞不定的(如反爬极强的站点),才走 Jina Reader兜底——因为它本质是第三方代抓服务,由 Jina 的服务器帮你请求并解析网页,能绕过一些本地抓取失败的情况。 简单说:这是 web-access Skill决策手册里“最后一张底牌”,当前两个工具都失败时用来保证仍能拿到网页内容。
点赞
回复 取消回复
是你啊 2026年08月31日 17:27
引用原文:重新启用一个被禁用的 Skill
@派聪明 这些命令都怎末实现的 为啥输入/skill 能有对应的操作
点赞
回复1 取消回复
派聪明 2026年08月31日 17:27
# /skill命令的实现原理输入 `/skill` 能触发对应操作,是因为 CLI工具在读取用户输入后有一个**命令路由分发机制**,整体流程如下: ##1.输入拦截:斜杠命令优先于 LLM当你在 PaiCLI输入内容时,程序首先判断输入是否以 `/` 开头: - **是斜杠命令**(如 `/skill list`)→走本地命令处理逻辑,**不会发给 LLM** - **普通文本** → 作为对话消息发给大模型##2.命令解析:拆分命令名和参数输入 `/skill off web-access`会被解析为: -命令组:`skill` - 子命令:`off` - 参数:`web-access` 程序根据命令组名查表(类似 `Map&lt;String, CommandHandler&gt;` 的注册表),找到对应的处理器执行。 ##3. 以 `/skill on` 为例的具体实现“重新启用一个被禁用的 Skill” 的操作流程: 1. **接收参数**:拿到 Skill 名称 `web-access` 2. **读取状态文件**:加载 `~/.paicli/skills.json`,内容形如 `{&quot;disabled&quot;: [&quot;web-access&quot;]}` 3. **修改状态**:把 `web-access` 从 `disabled` 数组中移除4. **写回文件**:持久化保存,所以重启后禁用/启用状态仍然生效5. **输出反馈**:提示用户该 Skill 已启用##4. 其他子命令对应的操作|命令 |实现逻辑 | |------|---------| | `/skill list` |调用 `SkillRegistry`扫描三层目录(builtin/user/project),列出所有 Skill 及状态 | | `/skill show &lt;name&gt;` |读取并展示 SKILL.md完整内容(frontmatter + body) | | `/skill off &lt;name&gt;` | 把名称写入 skills.json 的 disabled列表,索引和 load_skill 都不再可见 | | `/skill reload` |重新扫描三层目录,热加载新增/修改的 Skill,只影响下一轮对话 | **核心思想**:斜杠命令是纯本地逻辑(读写文件、操作内存中的注册表),执行速度快、结果确定,不需要也不应该消耗 LLM 的 token;而自然语言对话才交给大模型
点赞
回复 取消回复
是你啊 2026年08月31日 17:26
引用原文:禁用一个 Skill
这些命令都怎末实现的 为啥输入/skill 能有对应的操作
点赞
回复 取消回复
是你啊 2026年08月31日 09:58
引用原文:builtin → user → project
@派聪明 这几个分别是啥意思
点赞
回复1 取消回复
派聪明 2026年08月31日 09:58
# Skill 三层加载架构这是 PaiCLI 的 Skill系统按优先级从低到高的三层加载顺序: **1. builtin(内置层)** 打包在 PaiCLI 的 jar 包里,随版本一起发布。目前内置了 `web-access` Skill,教 Agent 如何做联网操作(搜索、抓网页、用浏览器)。 **2. user(用户级)** 放在 `~/.paicli/skills/&lt;name&gt;/SKILL.md`。存放用户自己写的全局 Skill,所有项目都能使用。 **3. project(项目级)** 放在 `&lt;项目目录&gt;/.paicli/skills/&lt;name&gt;/SKILL.md`。针对特定项目的 Skill,**优先级最高**。 ## 加载规则扫描时按 **builtin → user → project** 的顺序处理,每扫到一个**同名 Skill 就直接覆盖前一层**的。也就是说: &gt; project覆盖 user,user覆盖 builtin例如:内置的 `web-access` 是 builtin 来源,如果你在 `~/.paicli/skills/web-access/` 下创建同名 Skill,`/skill reload` 后来源就会从 `builtin`变成 `user`,覆盖生效。 这样设计的好处是:默认开箱即用(内置),个人偏好可全局定制(用户级),特定项目还能进一步精细覆盖(项目级)。
点赞
回复 取消回复
Lee 2026年08月06日 19:53
引用原文: Jina Reader
@杠精派 @派聪明 这是什么
点赞
回复1 取消回复
杠精派 2026年08月06日 19:53
小派正在努力回答中, 耐心等待一下吧...
点赞
回复 取消回复
Lee 2026年08月06日 19:53
引用原文: Jina Reader
@派聪明 这是什么
点赞
回复1 取消回复
派聪明 2026年08月06日 19:53
小派正在努力回答中, 耐心等待一下吧...
点赞
回复 取消回复
Lee 2026年08月06日 19:53
引用原文: Jina Reader
@派聪明 这是什么
点赞
回复1 取消回复
派聪明 2026年08月06日 19:53
小派正在努力回答中, 耐心等待一下吧...
点赞
回复 取消回复
枫原万叶 2026年07月28日 15:54
引用原文:①、一次性消费:drain() 取出内容后 buffer 清空。下一轮 user message 不会再携带上一轮已注入的 Skill body。这避免了 body 在对话中反复累积撑爆上下文。
@派聪明 skill body只存在于用户message一轮吗?
点赞
回复1 取消回复
派聪明 2026年07月28日 15:54
小派正在努力回答中, 耐心等待一下吧...
点赞
回复 取消回复
阿斯顿 2026年07月28日 12:10
引用原文:新的 body 替换旧的
怎么实现替换的呢@派聪明
点赞
回复1 取消回复
派聪明 2026年07月28日 12:10
小派正在努力回答中, 耐心等待一下吧...
点赞
回复 取消回复
关点点儿 2026年07月22日 07:24
引用原文:是整个注入机制的核心数据结构。
@派聪明
点赞
回复1 取消回复
派聪明 2026年07月22日 07:24
这段划线内容出自PaiCLI的Skill系统,**`SkillContextBuffer` 是连接「Skill决策手册」和「LLM决策行为」的核心桥梁**。 ## 它的核心职责 当 LLM 调用 `load_skill(&quot;web-access&quot;)` 时,PaiCLI **没有**把 SKILL.md 的完整 body 塞进工具返回结果里,而是写入了 `SkillContextBuffer`。下一轮构造 user message 时,从 buffer 里取出 body,拼在用户原始输入的前面: ``` ## 已加载 Skill:web-access &lt;SKILL.md body 完整内容&gt; --- 用户输入:&lt;用户的原始消息&gt; ``` ## 为什么这么设计? | 方案 | 问题 | |---|---| | ❌ 塞进工具返回结果 | LLM 视其为&quot;参考信息&quot;,决策权重低 | | ❌ 塞进 system prompt | 每次加载都导致 prompt cache 失效,浪费 token | | ✅ **走 user message 注入** | LLM 视其为&quot;用户附加指令&quot;,执行权重高;system prompt 不变,cache 得以保留 | ## 它的 5 个关键特性 1. **一次性消费**:`drain()` 取出后自动清空,避免 body 在对话中反复堆积撑爆上下文 2. **最多 3 个 Skill**:同一轮连续加载超过 3 个,只保留最近的 3 个 3. **同名替换**:同一 Skill 加载两次,新 body 替换旧的,不会重复累积 4. **角色隔离**:Planner、Worker、Reviewer 各自持有独立 buffer,各取所需(Worker 抓网页,Reviewer 审查代码,互不干扰) 5. **`/clear` 重置**:调试时先清 buffer 再 reload,保证读到最新版 **一句话总结**:`SkillContextBuffer` 让 Agent **「在合适的时机读到合适的决策手册,且不影响系统 prompt 的缓存效率」**,是 Skill 系统按需加载、渐进式披露理念的落地支撑。
点赞
回复 取消回复

目录