1
0
0

核心包架构深度解析

2026-08-14
2026-08-14
核心包架构深度解析
文章摘要
|
# 入门03:核心包架构深度解析 > 如果把 Harness 比作一个 Web 应用,`packages/core/` 就是它的"骨架"——Vue 的响应式系统 + React 的 reconciler + Vue Router 的路由管理,都在这一层。 --- ## 1. 六大核心模块是啥? ```mermaid graph TB subgraph "核心层(相当于应用的骨架)" AL[AgentLoop
引擎] AG[Agent
户口本] SE[Session
聊天记录本] SC[Scope
作用域链] TL[Tools
工具台] SP[SystemPrompt
提示组装器] end AL --> AG AL --> SE AL --> TL AL --> SP AG --> SC TL --> SC SE --> SC ``` | 模块 | 用前端话解释 | 相当于 | |------|-------------|--------| | **Agent** | 管理所有 Agent 的"户口本" | 类似 Vuex 里管理所有组件的状态清单 | | **AgentLoop** | Agent 的"引擎",驱动对话循环 | 类似 React 的 reconciler + 事件循环 | | **Session** | 不可修改的聊天记录本 | 类似 Git 的 commit log | | **Scope** | 作用域链,实现能力继承和隔离 | 类似 Vue 的 scoped slots + 组件树 | | **Tools** | 工具的"注册中心" | 类似 Vue 的全局组件注册 | | **SystemPrompt** | 拼装发给 AI 的提示词 | 类似模板引擎渲染 | --- ## 2. Agent 注册表(AgentRegistry)— Agent 的"户口本" > 就像 Vuex 的 store 管理所有组件状态,AgentRegistry 管理所有运行中的 Agent。 **代码位置**:`packages/core/agent/src/index.ts` 它负责三件事: 1. **创建** Agent——就像 `new Vue()` 创建应用实例 2. **查找** Agent——给个 ID 就能找到 3. **追踪** 谁调用了谁——通过 `AsyncLocalStorage` 追踪调用链 ```typescript class AgentRegistry extends Service { // 创建新 Agent async create(options: CreateAgentOptions): Promise // 从硬盘恢复 Agent(重启后还能继续聊天) async resume(options: ResumeAgentOptions): Promise // 按 ID 查找 get(id: SessionId): AgentHandle | undefined // 谁在调用我?(追踪调用链) currentInitiator(): AgentHandle | undefined } ``` **关键概念**: - **AgentHandle**:Agent 的"遥控器",对外暴露的引用,不直接操作 Agent 内部 - **Initiator**:追踪谁发起了调用——就像 `console.trace()` 打印调用栈 --- ## 3. Agent 循环引擎(AgentLoop)— 驱动 Agent 跑起来 > 就像 React 的 render 循环 + 事件循环合体。每次用户发消息,就触发一轮"思考-行动"循环。 **代码位置**:`packages/core/agent-loop/src/index.ts` ```typescript class AgentLoop extends Service { // 必须的依赖——就像 Vue 组件声明 props static inject = ['agents', 'sessions', 'llm', 'tools', 'systemPrompt'] // 从配置创建 Agent async createAgent(options: CreateAgentOptions): Promise // 恢复 Agent async resume(options: ResumeAgentOptions): Promise } ``` **核心状态**:Agent 只有三种状态—— ``` idle(空闲) → running(运行中) → idle(空闲) ↓ maintenance(维护中,配置热更新) ``` --- ## 4. Session(事件溯源会话)— 不可修改的聊天记录本 > 就像 Git 一样,每次操作都 commit,不修改历史。AI 看到的对话内容,是从 commit 历史"算"出来的。 **代码位置**:`packages/core/session/src/index.ts` ```typescript class Session { // 头部信息(就像 Git commit 的元数据) readonly header: { sessionId: SessionId cwd: string // 当前工作目录 createdAt: Date forkLine: string // 分叉线 } // 追加事件(类似 git add + git commit) append(type: string, data: any, surfaceOpts?: SurfaceOpts): void // 从事件日志"算"出 LLM 能看到的消息(类似 git log 查看历史) deriveMessages(): Message[] } class SessionStore extends Service { create(): Session // 创建新会话 fork(session: Session): Session // 分叉(类似 git branch) } ``` ### 事件类型(就像 Git 的 commit message 类型) | 事件类型 | 对应什么 | 类似 Git 的 | |---------|---------|------------| | `user/message` | 用户说了一句话 | 一次 commit | | `assistant/message` | AI 回了一句话 | 一次 commit | | `tool/result` | 工具执行完了 | 一次 commit | | `turn/start` | 一个回合开始 | 一个分支开始 | | `turn/end` | 一个回合结束 | 分支合并 | | `step/start` | 一个步骤开始 | 子任务 | | `step/end` | 一个步骤结束 | 子任务完成 | ### Surface(表面)机制 > 就像数据库的 View(视图)——不是所有字段都暴露给用户,只暴露需要的。 不是所有事件都会传给 AI。只有标记了 `surface: true` 的事件才会"浮出"水面,进入 AI 的上下文。比如 `turn/start` 这种内部事件就不会传给 AI。 --- ## 5. 作用域系统(Scope)— 像 React 组件树一样嵌套 > 就像 React 组件可以嵌套,子组件能看到父组件的 props 和 context。Agent 也可以嵌套,子 Agent 继承父 Agent 的能力。 **代码位置**:`packages/core/scope/src/index.ts` ```typescript // 创建作用域(就像创建子组件) function createScope(ctx: Context, key: ScopeKey): Context // 分层注册表(子作用域能看到祖先注册的东西) class ScopedLayers { add(key: ScopeKey | undefined, value: T): void remove(key: ScopeKey | undefined, value: T): void values(key: ScopeKey): T[] // 获取当前作用域及祖先的所有值 } ``` ### 作用域链长啥样? ``` 全局(啥都有) └── Agent A(能执行 bash、读写文件) ├── 子 Agent B(继承 bash 和读写文件,还能搜网页) └── 子 Agent C(只能读文件,不能写) ``` **这不就是作用域链吗?** 就像 JS 的作用域——子作用域能访问父作用域的变量,但不能反过来。 --- ## 6. 工具注册表(ToolRuntime)— 全局组件注册 > 就像 Vue 的 `app.component('my-component', {...})` 注册全局组件,ToolRuntime 注册"工具"让 AI 调用。 **代码位置**:`packages/core/tools/src/index.ts` ```typescript class ToolRuntime extends Service { define(name: string, definition: ToolDefinition): void // 注册工具 createExecution(toolName: string, args: any): ToolExecution // 执行工具 restrict(scope: ScopeKey, tools: string[]): void // 限制子 Agent 能用啥 guard(condition: (tool: string) => boolean): void // 设置守卫 } ``` ### 工具执行管线 > 就像 Express 中间件——每个阶段都是 Waterfall,插件可以拦截和修改。 ``` pre-execute(执行前修改参数) → guard(守卫检查) → execute(实际执行) → post-execute(处理结果) → result(返回) ``` 每个阶段都是 Waterfall 事件,插件可以"插一脚": ```typescript // 在工具执行前记录日志 ctx.waterfall('tools/pre-execute', (execution) => { console.log(`将要执行: ${execution.name}`) return execution }) ``` --- ## 7. 系统提示组装(SystemPrompt)— 模板引擎 > 就像服务端渲染拼 HTML 模板——收集各部分内容,组装成完整的提示词发给 AI。 **代码位置**:`packages/core/system-prompt/src/index.ts` ```typescript class SystemPrompt extends Service { section(section: PromptSection): void // 注册提示节 context(context: ContextProvider): void // 注册动态上下文 tools(provider: ToolsProvider): void // 注册工具 Schema variable(name: string, provider: VariableProvider): void // 注册模板变量 assemble(context: AssemblyContext): PromptAssembly // 组装 } ``` ### 组装过程 ``` 收集所有 sections → 按顺序排好 → 收集 context → 收集 tools → 变量插值 {{variable}} → Waterfall 最终加工 → 发给 AI ``` --- ## 8. 模块间怎么配合? ```mermaid graph TB AL[AgentLoop
引擎] --> AG[AgentRegistry
管理Agent] AL --> SE[SessionStore
记录会话] AL --> TL[ToolRuntime
执行工具] AL --> SP[SystemPrompt
组装提示] AL --> LLM[LlmRuntime
调用AI模型] AG --> SC[Scope
作用域链] TL --> SC ``` **各模块的职责划分很清晰**: - **AgentRegistry** 只管"有哪些 Agent",不管怎么运行 - **AgentLoop** 只管"怎么运行 Agent",通过 AgentRegistry 管理 - **SessionStore** 只管"记录事件",不管事件含义 - **ToolRuntime** 只管"工具有哪些、怎么执行",不管谁调用 - **SystemPrompt** 只管"怎么拼提示词",不管谁用 - **Scope** 是粘合剂,提供分层和隔离 **这就像前端框架的分层**:Vue 的响应式系统只管数据变更,模板编译器只管编译,渲染器只管渲染,各司其职。 --- ## 要点总结 - **AgentRegistry** = Agent 的"户口本",管创建、查找、恢复 - **AgentLoop** = 引擎,驱动"思考-行动"循环 - **Session** = 不可修改的聊天记录,像 Git 一样只追加 - **Scope** = 作用域链,组件树一样的嵌套继承 - **Tools** = 工具注册中心,像 Vue 注册全局组件 - **SystemPrompt** = 提示词组装器,像模板引擎 - 六个模块通过 Cordis 依赖注入连接,职责清晰互不干扰 ## 进阶阅读 - 核心源码:`packages/core/` 目录 - 官方文档:`docs/subsystems/core.md` - 名词速查:[附录-AI 概念名词速查手册](附录-AI概念名词速查手册.md) - 下一步:[04-Agent 循环与对话流程](04-Agent循环与对话流程.md)

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或者给予支持!