DSH与Pi架构核心概念讲解
2026/9/8 17:50:48 网站建设 项目流程

目录

    • 1. 学习教程
    • 2. 常见黑话
    • 3. 学习课程
      • Agent是什么
      • Session
      • Agent怎么管理工具
      • System Prompt与LLM Adapter
      • Agent Loop
      • Plugin和Extension
      • Session Branch
      • Context
      • MCP

1. 学习教程

  1. pi框架
  2. mini-dsh

2. 常见黑话

Session:一次连续的对话(整段对话的历史)
Context:当前这一轮模型实际拿来思考的信息
Event Log:把Session里发生的事,按照时间一条一条记录下来(强调事实记录)
Memory:保存以后值得记录什么(对过往的Session的总结和提取,以后其他的Session也能用)
Tool Registry:工具注册表,agent loop只需要问registry有没有这个工具,如果有就执行它,所以tool registry是能力边界,它决定agent当前有哪些调用能力
Schema:是一个结构规则说明书,它还可以用来检验模型生成的Tool Call是否合法
System Prompt:给模型的最高层行为说明(在用户消息之前,系统先告诉模型你是谁、应该怎么做、规则是什么)
LLM Adapter:LLM是大语言模型,LLM Adapter负责把不同厂商的模型翻译成统一格式(也就是帮助Agent Loop接gpt/deepseek/claude)
Agent Loop

LLM Adapter
┌─────────┼─────────┐
↓ ↓ ↓
OpenAI DeepSeek Claude
context:这一轮模型知道有效的信息
messages:已经发生过的对话和工具调用历史
LLM Runtime:管理adapter、选择,模型、发请求、收结果
Steering:在agent正在执行任务时,用户临时改变方向
stream assistant:assistant的回复是边生成边不断发出来的,而不是等一次性全部生成完再显示
follow-up:当一轮完成以后,用户继续追加的问题或任务
Session branch:同一个session里,从过去节点分叉出去的一条新路线
MCP:一种统一的标准,让agent/llm用同一种方式连接外部工具、数据和服务
agent runtime:agent的调度中心(真正让agent跑起来、管理整个agent loop的执行环境)
mcp client:agent和mcp server之间的连接器

3. 学习课程

Agent是什么

  1. agent的运行机制

普通聊天:输入信息,模型回答,得到文本
Agent:输入目标,模型判断下一步需要什么,如果需要就请求工具,harness执行工具,工具把结果返回,模型根据结果继续判断,直到任务完成
Agent = LLM+Tools+Context+Loop

while (true) { response = await model(context, toolSchemas) //把当前聊天信息和可用工具告诉模型, if (!response.toolCalls?.length) return response.content //如果模型没有调用工具,那么说明它准备直接给答案 results = await tools.execute(response.toolCalls) //执行模型刚才请求的工具 context = context.append(response, results) }

上面的代码只是最小可理解框架,以后还有流式事件、权限、压缩、预算、会话持久化、UI
2. dsh和pi各自如何实现
DSH和pi都有agent loop,但是它们实现这些能力的方式不一样

DSH:把sessions、sysytemPrompt、tools、llm、agents和agentLoop作为组件的能力装进Context


Context不是普通聊天里的上下文,而是一个运行环境的容器,里面可以放很多系统能力,Context像一个插座板

Pi:把整个系统拆成三层
最底层pi-ai:模型协议(provider),负责和模型打交道
中间层pi-agent-core:agent状态与loop
最上层pi-coding-agent:产品体验(TUI、RPC、资源加载)
其中模型供应商和产品体验会变化,但核心Loop尽量稳定

Session

  1. 事实与投影

事实:SessionEvent[]
session/start
user/message
assistant/tool_calls
tool/result
assistant/message

投影:deriveMessages()
调用它时,事件被转换为模型协议需要的信息
user/message
assistant/tool_calls
tool/result
assistant/message

  1. 区别

DSH
更像一条时间线:
事件1

事件2

事件3

事件4

Pi
事件1

事件2

事件3
├── 分支A
│ └── 事件4A

└── 分支B
└── 事件4B

pi有会话持久性与树形分支的历史结构

Agent怎么管理工具

  1. 用Tool Registry进行管理,而不是把工具写死在Agent Loop里面,这也是dsh和pi的共同点:能力可以变化,核心循环可以不用跟着重写
  2. 工具

name/description/parameters要转成能被模型理解的tool schema
execute是真正执行工具功能的函数

DSH:
register(注册工具)

schemas(把工具schema提供给模型)

execute(执行工具)

renderResult(生成可读结果)

Pi:
beforeToolCall(先检查)

tool execution(真正执行)

afterToolCall(记录结果、更新状态)

System Prompt与LLM Adapter

  1. system prompt
  • mini-dsh
//section更像稳定规则 prompt.section({ name: "ritual-rules", order: 20, text: "先陈述牌面,再给出多种可能解释。" }) //context更像动态信息 prompt.context({ name: "today", order: 10, text: () => `今天是 ${new Date().toISOString()}` }) //把前面注册的section和context按order拼好,在拼成最终的system prompt const system = await prompt.assemble()
  • pi
prompt template / skill / extension + 当前 Session 上下文 ↓ AgentSession 整理 ↓ 交给 pi-ai ↓ LLM

prompt template是预先写好的提示词模板
skill是工作流程,可以影响模型怎么做这件事
extension是插件/扩展包,也就是给agent添加新的外围能力
AgentSession是当前这个对话的管理者

pi不是让Agent Loop自己找prompt、skill、extension,而是先由agentsession把当前需要的东西整理好,然后传给大模型

  1. llm adapter
const reply = await llm.chat({ system,//给模型的规则 messages,//之前的聊天和工作记录 tools: toolRegistry.schemas()//可以调用的工具 }, "deepseek/deepseek-v4-flash")//用什么大模型

Agent Loop

  1. 模型循环

模型决定直接回答还是请求工具
工具真正去执行动作,产生一个事实
事实回到模型,模型决定下一步
模型认为还需要新的工具事实,就继续;不需要了,就结束

  • dsh循环
while (true) { const reply = await llm.chat({ messages, tools }) //把message和tools发给模型 if (reply.tool_calls.length === 0) { session.append(reply) // 模型直接回答 return // 结束 } session.append(reply) // 记下模型请求了什么工具 for (const call of reply.tool_calls) { const result = await tools.execute(call) // 执行工具 session.append(result) // 记下工具事实 } // 回到 while:把事实交给模型再问一轮 }
  • pi循环

开始一轮

先检查 steering

调用模型,stream assistant

模型有没有 tool call?
├─ 有 → 执行工具 → 把结果放回历史 → 再进入下一轮
└─ 没有 → 检查有没有 follow-up
├─ 有 → 继续下一轮
└─ 没有 → agent_end

Plugin和Extension

  1. 区分Tool和plugin/extension

Tool:模型可以通过Tool Call请求调用的一项能力,通常包含name、description、schema、execute
Plugin/Extension:插件和扩展的作用是给Agent提供新的能力

  1. dsh与pi

共同原理:核心负责稳定的工作;外围模块负责变化的玩法
核心agent(请求模型、执行循环、保存状态)是比较稳定的,安装模块(Plugin/Extension)可以使agent获取新能力,卸载模块(能力消失,但核心agent不改)

区别(把能力接进去的区别)
dsh:Plugin通过Context往系统里注册能力
pi:如下

// pi.registerTool:给agent增加一个模型可以请求调用的Tool export default function (pi) { pi.registerTool({ name: "draw_card", description: "抽一张牌,只返回牌面事实", parameters: { /* 参数 schema */ }, execute: async () => ({ content: [{ type: "text", text: "太阳" }] }) }) //pi.on是监听事件,当session_start开始的时候 pi.on("session_start", async (_event, ctx) => { ctx.ui.notify("塔罗扩展已加载", "info") }) }

一个Extension不一定只能提供一个Tool,它可以提供很多东西

Tarot Extension

├── Tool
│ └── draw_card

├── Event Listener
│ └── session_start

├── Prompt

├── Command

├── UI

└── 其他扩展能力

Session Branch

  1. pi

用户:帮我看今天的状态
└─ 助手:抽到太阳
├─ 用户:给我积极解读
│ └─ 助手:今天适合主动行动
└─ 用户:给我谨慎解读
└─ 助手:行动前先观察节奏

pi的每个对话,不止有id,还有parentId,
树的当前末端叫active leaf

/tree:在同一个对话里,切换到另一个分支
/fork:从较早的用户信息创建一个新的对话
/clone:把当前branch复制成一个新的对话

Context

  1. dsh
    在mini-dsh里,session的完整历史是怎么变成这一轮真正发送给LLM的内容的
Session Event Log ↓ deriveMessages() ↓ messages + system prompt + tools ↓ llm.chat(...)

先从完整事件日志里,整理出来模型真正需要看的聊天记录(messages),然后加上全局提示词和tools一块交给llm

  1. pi
    pi会做compaction(上下文压缩),当旧的context太多的时候,pi会把context压短,这样给llm看的context就变短点了
旧消息很多 ↓ Pi 找出较早的一段内容 ↓ 让模型把旧内容总结成一份摘要 ↓ 保留:摘要 + 较新的消息 ↓ 用新的 Context 继续工作

MCP

MCP Server会告诉agent自己的能力,这个过程叫做Tool Discovery工具发现
agent把工具的Schema(调用工具的说明书)给 模型
模型产生Tool Call,模型提出请求
然后agent runtime收到请求,发现tool不是本地的,是mcp server提供的,接着通过mcp client和mcp协议,到mcp server才开始真正执行工具(这一步就是把模型产生的tool call 转发到真正拥有中国tool的外部服务
有结果以后,再让模型继续思考
外部服务怎么连接,是外围代码负责;Agent Loop 只处理统一的 Tool

  1. dsh
外部 ┌─────────────────────┐ │ Tarot MCP Server │ │ 真正有 draw_card │ └─────────┬───────────┘ │ MCP ↓ ┌─────────────────────┐ │ dsh-mcp-client │ │ 发现工具 + 转发调用 │ └─────────┬───────────┘ ↓ ┌─────────────────────┐ │ Tool Registry │ │ │ │ read_file │ │ bash │ │ draw_card ← MCP来的 │ └─────────┬───────────┘ ↓ ┌─────────────────────┐ │ Agent Loop │ └─────────────────────┘

mcp server是工具提供方,mcp client把外部的tool接进来,tool registry把它和本地的tool统一管理,agent tool不管工具来自哪里

  1. pi
pi.registerTool({ name: "draw_card", async execute(_id, params, signal) { const card = await remoteTarotService.draw(params, signal) //当这个工具被调用的时候,不是在本地抽牌,而是去远程tarot service,让远程服务器帮我抽,拿到结果以后,返还结果给agent return { content: [ { type: "text", text: card } ] } } })

extension是扩展模块,pi仅仅只是一个agent,它不知道什么是draw_card,如果想让它会塔罗。第一种是直接去改pi核心,也就是在agent loop里面改,这样子很麻烦,所以pi希望核心agent不动,从外面装extension。第二种是pi会给extension一个pi(对外提供的extension api),当pi加载这个扩展的时候,把自己的扩展接口pi给它,然后extension可以告诉pi,我要给你添加tool

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询