
Yuxi Agent 中间件架构解析从文件、Skills 到审批与 Token 用量的 LangGraph 边界编排【免费下载链接】Yuxi可私有部署的多租户知识智能体平台统一 RAG、知识图谱、多智能体、MCP/Skills、沙盒与权限管理。Self-hosted knowledge agent platform for RAG, knowledge graphs and multi-agent workflows.项目地址: https://gitcode.com/GitHub_Trending/yu/Yuxi本篇技术指南围绕 Yuxi 私有化知识智能体平台中 docs/agents/middleware.md 讲解的 Agent 中间件体系展开系统梳理中间件如何把文件、Skills、子智能体、上下文压缩、工具审批和用量统计挂接到 LangGraph Agent 的模型调用、工具调用与 state 更新边界上并深入 中间件源码目录 与 ChatbotAgent graph 实现 验证每一层的真实装配顺序与底层原理。读者将掌握 Yuxi 中间件的完整清单、各中间件的职责边界、ChatbotAgent与SubAgentBackend的装配差异以及新增中间件时应遵循的工程约束。中间件在 Yuxi Agent 运行时中的定位Yuxi 的 Agent 运行时建立在 LangGraph 的create_agent之上模型调用、工具调用和 state 更新构成了 Agent 执行的主循环。中间件AgentMiddleware正是挂在这三条边界上的钩子让文件访问、Skills 注入、子智能体协作、上下文压缩、工具审批与用量观测这些横切能力可以被不同 Agent 复用而不必重复实现。在 Yuxi 中内置的ChatbotAgent智能助手和SubAgentBackend子智能体后端都在各自的get_graph()中组装中间件列表。从 backend/package/yuxi/agents/buildin/chatbot/graph.py 可以看到构建流程async def get_graph(self, *, context, **kwargs): if not getattr(context, _runtime_prepared, False): raise ValueError(构图需要已准备的 Context) await sync_agent_context_skills(context) backend create_agent_composite_backend(context) model_spec resolve_chat_model_spec(context.model) graph create_agent( modelload_chat_model(fully_specified_namemodel_spec, session_idcontext.thread_id), toolsawait resolve_configured_runtime_tools(context), system_promptbuild_prompt_with_context(context), middlewareawait _build_middlewares(context, backend), state_schemaChatBotState, checkpointerawait self._get_checkpointer(), ) return graph关键约束是Graph 创建之前系统必须先完成用户资源和权限的归一化中间件不应绕过这一步重新决定授权。也就是说中间件工作在资源快照已就绪的前提下它要做的是在对应边界上落实这些已经收敛好的能力而不是自行做一轮授权判断。Graph 创建前的准备prepare_agent_runtime_contextprepare_agent_runtime_context是中间件得以工作的前置条件定义于 backend/package/yuxi/agents/context.pyChatBotContext/SubAgentContext的运行时准备函数。它会根据当前用户和 Agent 配置完成以下归一化过滤内置工具、知识库、MCP、Skills 和子智能体只保留当前用户有权限访问的资源生成_visible_knowledge_bases等运行时可见集合展开 Skill 依赖根据配置的 Skills 与预加载 Skills生成_effective_skill_slugs和_runtime_skills供SkillsMiddleware在运行时直接读取补齐模型配置使用系统默认模型填充 Agent 配置中为空的模型字段。准备完成后工具解析器resolve_configured_runtime_tools把可执行工具解析出来build_prompt_with_context生成系统提示词随后才创建 Graph。文档特别强调工具执行时仍需检查具体目标准备阶段的资源快照不是授权替代品——快照决定了模型能看见什么而执行期的审批中间件决定敏感操作是否被允许。内置中间件装配顺序详解ChatbotAgent的常见装配顺序定义在 chatbot/graph.py 的_build_middlewares中可选项Memory、子智能体、审批只在对应能力启用时加入。对照源码可整理为下表顺序中间件作用源码位置1SteerMiddleware在安全生命周期边界发现待接替请求Steer提前结束当前 Run 让队列接管steer.py2create_agent_filesystem_middleware提供 Workdir、User Data、Skills 文件后端并卸载过大的工具结果yuxi.agents.backends3SkillsMiddleware注入 Skill 说明按激活状态开放依赖工具与 MCPskills.py4YuxiMemoryMiddleware可选Memory 开关开启且MEMORY.md有内容时注入用户记忆并提供受限工具memory.py5YuxiSubAgentMiddleware可选主智能体有可见子智能体时提供task和子智能体生命周期工具subagent_task.py6YuxiSummarizationMiddleware先确定性压缩工具结果仍达到同一阈值时才生成摘要summary.py7TodoListMiddleware保存待办列表供状态面板展示langchain agents 内置8PatchToolCallsMiddleware修正部分工具调用消息形态deepagents 内置9NetworkRetryMiddleware网络类错误按预算持续重试非网络错误按次数重试network_retry.py10ImageInputCompatibilityMiddleware桥接工具读取图片与模型输入格式必要时回退 OCRmodel_input.py11TokenUsageMiddleware记录近似上下文与主模型实际用量写入 LangGraph statetoken_usage.py12工具审批 middleware可选默认模式下拦截写文件、编辑文件和执行命令tool_approval.pySubAgentBackend的装配见 subagent/graph.py它复用文件系统、Skills、Summary、待办、重试、图片兼容和用量统计能力但不挂载子智能体 middleware子智能体本身不再嵌套调用子智能体并通过_SubAgentToolFilterMiddleware过滤不适合子智能体的敏感或交互工具。重试与容错NetworkRetryMiddleware的两类预算模型调用失败是 Agent 运行时最常见的故障来源。Yuxi 把重试分成两类合并进一个中间件文档中也解释了为何不拆成两个避免因装配顺序或外层重试放大网络预算实现于 network_retry.py网络类错误断网、连接拒绝、连接重置、连接超时、读超时、服务不可用、Bad Gateway 等按指数退避持续重试。初始延迟默认 2 秒、最大延迟 30 秒总预算默认 600 秒可通过环境变量YUXI_NETWORK_RETRY_BUDGET_SECONDS覆盖。预算内吞掉异常并继续预算耗尽才显式抛出Run 以failed结束避免假完成非网络错误限流、鉴权失败、参数非法、上下文超长等复用父类ModelRetryMiddleware的max_retries语义次数上限来自 Context 的model_retry_times默认 2。错误分类优先按异常链的类型与 HTTP 状态码判断5xx 视为网络可重试、4xx 视为非网络错误未知 SDK 异常才回退到文本标记匹配。同步与异步两条路径wrap_model_call/awrap_model_call都通过包装 handler 实现且网络预算起点在包装创建时固定跨父类非网络重试不会被放大。Skills 与知识库按需激活的门控设计SkillsMiddlewareskills.py在每次模型调用前做三件事注入 Skill 说明预加载 SkillContext 的preload_skills配置从首轮就注入完整说明并开放依赖普通 Skill 只注入摘要提示模型读取对应SKILL.md后才激活动态激活中间件包装read_file工具调用当模型读取的路径命中共享投影或个人 UserWorkspace 下的SKILL.md时把该 slug 追加进activated_skillsstate通过Command(update...)合并见_merge_activated_skill_update门控依赖工具未激活 Skill 的依赖工具对模型不可见从request.tools中剔除但仍在 ToolNode 中可执行门控只影响可见性激活后通过build_dependency_bundle展开依赖把本地工具与 MCP 工具追加进模型可见列表若发现 Skill MCP 工具名冲突会直接抛RuntimeError。知识库能力由内置knowledge-baseSkill 提供其三层边界分别由不同环节负责工具是否注册由工具组装决定、模型是否可见由 Skill 激活决定、参数是否能访问目标知识库由知识库权限检查决定。完整链路可参考 工具系统 与 知识库机制详解。文件与附件Workdir 与模型专用路径附件确认后写入当前 Project Workdir。每次 Run 会把线程历史附件的文件名和实时路径加入本轮用户消息让模型按需调用read_file而持久化的 Message 仍保存原始文本不会把这段模型专用路径混进用户可见消息——这保证了消息审计与界面展示的干净性。普通 Agent 和子 Agent 使用根 Conversation 的同一个runtime_scope_id和 Workdir。子 Agent 的 child thread 只隔离 LangGraph checkpoint不隔离共享文件Viewer、附件和 artifact API 直接访问 UserWorkspace 的持久文件不需要创建 file-bridge Sandbox。这一设计让子智能体与主智能体天然共享工作目录减少了文件搬运的复杂度。子智能体task与生命周期工具主智能体配置了可见子智能体时YuxiSubAgentMiddleware源码位于 subagent_task.py提供五类工具task同步调用子智能体并等待结果subagent_start/subagent_status/subagent_cancel/subagent_await异步工具按run_id查询和控制子 Run。子智能体使用自己的 Context 和 checkpoint但继承发起用户的权限、Workdir 和 execution runtime。与之配套SubAgentBackend在 subagent/graph.py 中定义了两层工具过滤集合_SUBAGENT_DISABLED_TOOLS frozenset({present_artifacts, ask_user_question, install_skill}) # 默认审批模式额外隐藏敏感 backend 工具避免子智能体绕过主线程逐项审批。 _SUBAGENT_DISABLED_TOOLS_DEFAULT_MODE _SUBAGENT_DISABLED_TOOLS | SENSITIVE_BACKEND_TOOLS_SubAgentToolFilterMiddleware不仅在模型可见的工具列表里剔除禁用工具还会在wrap_tool_call/awrap_tool_call中拦截显式传入的禁用工具调用返回与原 tool call 绑定的错误ToolMessage提示请把结果交回主智能体由主线程按审批流程执行该操作——即工具列表隐藏不构成执行边界显式调用也必须拒绝。详细的调用、busy、结果和文件边界见 子智能体。Summary 上下文压缩先压缩、再摘要、同阈值YuxiSummarizationMiddleware继承自 deepagents 的SummarizationMiddleware核心策略是先确定性压缩再按同一压力阈值决定是否生成摘要实现在 summary.py每次模型调用前对超大 ToolMessage 做确定性压缩超过tool_result_offload_token_limit默认 300 token的工具结果被写入 backend 保存带 SHA-256 与完整路径上下文中只保留首中尾预览query_kb与web_search的 JSON 结果走结构化预览保留条数、命中数、关键字段压缩 content_preview同时截断write_file/edit_file的超长参数默认上限 2000 字符保持消息顺序与标识不变重新计量压缩后仍达到触发阈值来自 Context 的summary_threshold单位 K默认值见DEFAULT_SUMMARY_THRESHOLD_K时才写入历史文件、调用摘要模型生成摘要并更新 checkpoint_summarization_event、_summarization_session_id。摘要生成用lc_sourcesummarization标记并带TAG_NOSTREAM不会当作用户可见回复输出也不会删除 PostgreSQL 聊天消息。压缩过程通过 stream writer 发出yuxi.context_compression事件started/completed/failed前端可据此展示进度。支持主动压缩的 Agent 复用同一摘要器create_summary_middleware_from_context并通过 service 在空闲线程的 canonical graph state 上更新 checkpoint——即压缩不限于请求触发也可以在后台主动执行。参数与状态细节见 上下文压缩机制。Token 用量近似估算与 Provider 实际用量双轨TokenUsageMiddlewaretoken_usage.py在每次主模型调用后构建一份完整的用量快照写入 LangGraph statetoken_usage字段同时记录两类数据近似上下文 token基于count_tokens_approximately对 state 消息、LLM 消息、system、tools 的估算并计算context_window取自模型 profile 的max_input_tokens、context_usage_ratio、remaining_context_tokens、summary_pressure_ratio等指标供摘要阈值决策与状态面板展示Provider 实际用量提取响应 AIMessage 的usage_metadata按模型身份分桶_bucket_key依次取配置 model spec、响应 model id、适配器兜底累计到 Run 与 Thread 两级聚合schema_version 2同时统计缓存命中 tokencache_read/priority_cache_read/flex_cache_read与缓存命中率。两点口径限制需特别注意Provider 用量黑名单siliconflow-cn和siliconflow当前位于TOKEN_USAGE_PROVIDER_BLACKLISTtoken_usage.py。这两个供应商仍可获得近似上下文统计但不会写入最近调用、Run 或 Thread 的 Provider 实际用量聚合before_agent还会剔除历史 checkpoint 中黑名单 Provider 的错误用量桶摘要模型调用不计入Summary 内部摘要模型调用lc_sourcesummarization不属于主模型用量口径。Run 终态时worker 把与当前run_id匹配的 state 快照写入AgentRun.token_usage且父 Run 与子 Run 分开保存便于账单核对与多 Agent 成本拆分。工具审批默认拦截敏感操作工具审批 middleware 由create_tool_approval_middleware创建模式来自 Context 的tool_approval_modecontext.pynormalize_tool_approval_mode会做合法性校验tool_approval.py模式行为default默认审批写文件、编辑文件或执行命令前请求用户确认always_trust完全信任敏感工具无需确认自动执行在ChatbotAgent中审批 middleware 使用current_project_pathruntime_workdir_path(context.workdir_relative_path)限定审批的作用范围在SubAgentBackend中则与_SubAgentToolFilterMiddleware配合默认模式下额外隐藏敏感 backend 工具避免子智能体绕过主线程的逐项审批。新增中间件时的工程约束文档对如何新增中间件给出了明确的边界纪律这也是 Yuxi 中间件体系可维护性的来源先说明要改变哪一条边界Prompt、模型调用、工具调用、文件访问、state 或观测必须明确其一避免职责重叠资源筛选和权限收敛放在 Graph 创建前通过prepare_agent_runtime_context完成而不是在中间件内重新做授权文件读写与工具结果卸载优先复用现有 filesystem middlewareSummary 的确定性压缩、filesystem 的工具结果卸载都在统一后端上完成避免各自为政新增模型可见输入或副作用时补充对应测试和失败案例仓库中如 test_summary_graph_config.py、test_network_retry.py、test_tool_approval.py 等测试即用于锁定这些边界行为。小结一条从准备到执行的完整链路Yuxi 的 Agent 中间件体系可以概括为一条清晰的责任链Graph 创建前由prepare_agent_runtime_context完成资源归一化与权限收敛Graph 创建时由get_graph按固定顺序装配可复用的中间件Steer → Filesystem → Skills → Memory/SubAgent → Summary → TodoList → PatchToolCalls → NetworkRetry → ImageCompatibility → TokenUsage → Approval执行时各中间件在模型调用、工具调用与 state 更新的边界上各司其职并且主智能体与子智能体通过不同的装配清单和工具过滤集合实现能力复用与边界隔离。对希望扩展平台的开发者来说遵循上述边界纪律新增中间件即可让新能力被所有 Agent 一致地复用。实现入口ChatbotAgent graph、子智能体 graph、中间件目录、运行时 Context 准备。【免费下载链接】Yuxi可私有部署的多租户知识智能体平台统一 RAG、知识图谱、多智能体、MCP/Skills、沙盒与权限管理。Self-hosted knowledge agent platform for RAG, knowledge graphs and multi-agent workflows.项目地址: https://gitcode.com/GitHub_Trending/yu/Yuxi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考