Yuxi 工具系统架构与开发指南:内置工具、知识库工具与 MCP 的三层装配与权限门控
Yuxi 工具系统架构与开发指南内置工具、知识库工具与 MCP 的三层装配与权限门控【免费下载链接】Yuxi可私有部署的多租户知识智能体平台统一 RAG、知识图谱、多智能体、MCP/Skills、沙盒与权限管理。Self-hosted knowledge agent platform for RAG, knowledge graphs and multi-agent workflows.项目地址: https://gitcode.com/GitHub_Trending/yu/YuxiYuxi 是一个可私有部署的多租户知识智能体平台其工具系统采用内置工具、知识库工具、MCP 工具三层结构并在 Graph 构图时完成可执行工具注册、运行时再按用户权限与 Skill 激活状态决定模型可见性。本文基于 docs/agents/tools-system.md 展开结合yuxi.agents.toolkits源码完整讲解工具注册规范、内置能力清单、知识库工具机制、四步组装流程以及新增工具时的检查清单帮助开发者在 Yuxi 中正确接入、扩展与审计工具。三层工具体系的整体定位Yuxi 的工具按来源分为三类对应不同的注册方式与生命周期层级注册位置是否默认对模型可见说明内置工具backend/package/yuxi/agents/toolkits/buildin由 Agent 配置的tools字段决定使用tool装饰器注册提供文件、OCR、交互、搜索等能力知识库工具backend/package/yuxi/agents/toolkits/kbs否需激活内置knowledge-baseSkill以tool(categoryknowledge)注册由 Skills middleware 统一开放MCP 工具由 MCP 服务器提供经 backend/package/yuxi/agents/mcp/service.py 发现由 Agent 配置的mcps字段与禁用列表决定连接与工具发现由 MCP 服务负责整个生命周期遵循两个关键原则Graph 创建时准备可执行工具Agent 构图时把配置范围内、依赖满足的工具注册进 ToolNode保证可执行运行时决定模型可见性模型每轮调用前根据当前用户权限、Agent 配置和 Skill 激活状态筛选模型可见的工具 schema。注册一个内置工具普通内置工具使用tool装饰器注册该装饰器定义在 registry.py它基于langchain.tools.tool做了扩展在创建 LangChain 工具对象的同时把附加元数据写入全局注册表from yuxi.agents.toolkits.registry import tool tool(categorybuildin, tags[示例], display_name示例工具) def example_tool(text: str) - str: 返回处理后的文本。 return text各参数的语义与底层影响category用于前端分组常见值是buildin、knowledge和debug从源码中的ToolExtraMetadata注释还可看到mysql、subagents等取值。服务层通过 service.py 的get_tool_instances_by_category按分类拉取工具实例tags用于展示和筛选例如内置工具的[搜索]、[文件, 交付物]、[交互]display_name给用户看的名称合并元数据时display_name的优先级高于tool.name见 service.py工具 ID即函数名才是给代码和模型协议使用的稳定名称icon、config_guide分别为前端图标与使用前配置提示属可选元数据。装饰器内部的注册动作registry.py包括应用 LangChain 装饰器生成tool_obj、把ToolExtraMetadata写入_extra_registry、设置tool_obj.handle_tool_error True并将实例追加进_all_tool_instances。注意工具的注册不等于授权。装饰器只是让工具存在产生文件、网络或数据库副作用的工具必须在执行边界再次校验当前用户和目标资源。这一点在下面的执行处授权中会反复强调。工具模块的导入与元数据暴露装饰器只有在模块被导入时才会执行。toolkits包的 __init__.py 通过from . import buildin, debug触发各模块的tool装饰器执行自动完成注册。因此工具模块必须被toolkits包导入装饰器才会执行注册。工具元数据通过服务层暴露给前端与组装流程get_tool_metadata(category)延迟加载全部工具元数据含slug、name、description、args、category、tags、config_guide供工具管理界面使用get_tool_instances_by_category(category)按分类返回真实工具实例供 Graph 组装时注册进 ToolNode。当前内置能力常用内置工具实现在 buildin/tools.py 与 install_skill.py工具作用源码要点ask_user_question等待用户回答交互式问题通过interrupt()暂停执行使用normalize_questions规范化问题结构支持单选/多选/Other 文本ocr_parse_file把工作区中受支持的 PDF、Office 或图片转换为 Markdown结果写入当前 Project Workdir 的outputs/ocr/下返回结果路径与短预览1200 字符而非全文present_artifacts展示当前用户可见的文件产物通过Command(update{artifacts: ...})登记交付物前端在对话结束后渲染结果文件卡片install_skill从允许的沙盒路径或 Git 来源安装个人 Skill子智能体不可用校验 slug 合法性、沙盒路径范围Git 安装时必须传skill_namesweb_search使用已配置的豆包或 Tavily 搜索网页按WEB_SEARCH_PROVIDER或环境变量自动探测选择供应商几个值得注意的实现细节web_search 的供应商解析buildin/tools.py_WEB_SEARCH_PROVIDERS映射了doubaoDOUBAO_SEARCH_API_KEY与tavilyTAVILY_API_KEY。若设置了WEB_SEARCH_PROVIDER环境变量则按其选择否则按环境中存在的 API Key 自动探测。两个供应商产出的工具名统一为web_search。豆包搜索参数包括query1-100 字符、count1-50默认 10、time_rangeOneDay/OneWeek/OneMonth/OneYear或YYYY-MM-DD..YYYY-MM-DD、sites最多 20 个域名、block_hosts最多 5 个、content_formattext/markdown。文件读写和命令执行由 Agent 的 Sandbox backend 提供不属于上述内置工具表。present_artifacts推荐展示当前 Project 的outputs/文件且其_normalize_presented_artifact_path会强制校验路径位于当前 Workdir、虚拟用户数据路径或 Skills 路径范围内越界立即抛错。large_tool_results和会话摘要等内部文件不会作为交付物展示。图片生成能力由内置image-genSkill 提供不再作为独立的 Python 工具注册具体依赖和文件位置以该 Skill 的说明为准。知识库工具知识库工具以tool(categoryknowledge)注册在 kbs/tools.py但不默认出现在模型工具列表。Agent 激活内置knowledge-baseSkill 后Skills middleware 才会向模型开放这组工具工具作用list_kbs列出当前运行可见的知识库含kb_id、名称与描述query_kb按kb_id检索片段返回kb_id、file_id和内容find_kb_document在指定文件中按关键词或正则定位内容patterns支持列表use_regex、case_sensitive可配open_kb_document按file_id分段读取解析后的文档window_size默认 1800 字符窗口get_mindmap读取知识导图递归把 JSON 导图转为层级文本search_file按文件名搜索可见知识库中的文件offset默认 0limit默认 300、上限 5000download_kb_file把有权限的原始文件下载到当前 Project 的outputs/支持save_as重命名权限在执行处重新校验是这组工具的安全核心每个工具都先调用_resolve_visible_knowledge_bases_for_query(runtime)取得当前会话可见知识库列表来自context._visible_knowledge_bases该字段由prepare_agent_runtime_context在构图前按用户角色与部门过滤后写入再经_find_query_target校验传入的kb_id必须存在于可见列表中否则直接返回不存在或当前会话未启用。因此工具参数中的kb_id、file_id和文件名都会在工具执行处重新检查不能用模型提示词或 Agent 配置绕过知识库权限。download_kb_file在落盘时还会剥离save_as中的目录成分、重名时追加_1/_2后缀防止路径穿越。知识库不会挂载为沙盒目录读取方式见知识库机制详解。需要在 Python 中直接取得知识库工具时from yuxi.agents.toolkits.kbs import get_common_kb_tools kb_tools get_common_kb_tools()get_common_kb_tools()返回 7 个通用工具list_kbs、get_mindmap、query_kb、find_kb_document、open_kb_document、search_file、download_kb_file。返回的具体顺序由函数实现维护不要把顺序当作协议——依赖下标访问不可靠应按工具名引用。工具组装流程内置 Agent 创建 Graph 时执行以下四步实现在 graph.py 与相关服务中prepare_agent_runtime_context按当前用户权限过滤工具、知识库、MCP、Skills 和子智能体。其实现见 context.py读取用户并做资源归一化normalize_agent_context_config、调用resolve_visible_knowledge_bases_for_context填充可见知识库、调用resolve_runtime_skills_for_context生成_skill_runtime_snapshot并将结果缓存到context._runtime_prepared以避免重复构图时重复解析。resolve_configured_runtime_tools(context)注册 Agent 配置和可见 Skill 依赖的可执行本地工具并加载配置的 MCP 工具。实现见 service.py按context.tools从 buildin 分类中取工具用asyncio.gather并发加载各 MCP 服务器的工具避免串行累积 1-2 秒延迟再通过resolve_skill_gated_tools把 Skill 依赖的本地工具一并注册进 ToolNode。注意工具名冲突会直接抛错MCP 工具与本地工具同名、Skill 本地工具与 MCP 工具同名都会触发RuntimeError。SkillsMiddleware根据当前已预加载或已激活的 Skill向模型请求开放相应工具 schema。其门控逻辑见 middlewares/skills.pygated_tool_names可见 Skill 依赖、不属于基础工具集的工具减去当前已激活 Skill 的工具集合后从request.tools中剔除再追加已激活或预加载 Skill 的依赖工具与 MCP 工具。动态激活由读取SKILL.md触发当模型调用read_file读取某个可见 Skill 的SKILL.md时_process_tool_call_result会把该 slug 合并进activated_skills状态middlewares/skills.py。工具执行器再次检查具体文件、知识库、MCP 和用户身份。如前所述present_artifacts、ocr_parse_file、download_kb_file等都在函数体内基于ToolRuntime重新解析thread_id、uid、workdir_relative_path并校验路径范围。整条链路的图示Agent 配置 用户权限 ↓ 运行时资源快照 ↓ 可执行工具注册 ──→ Skill 激活门控 ──→ 模型可见工具 ↓ 执行处的目标授权可执行与模型可见是两件事工具可以先注册到 ToolNode等 Skill 激活后才对模型开放这正是resolve_configured_runtime_tools注册全部 Skill 依赖工具、而SkillsMiddleware只放行已激活依赖的原因反之模型看见某个工具也不代表它可以访问任意资源——真正的资源授权发生在工具执行处。MCP 和 SkillsMCP 工具由已启用的 MCP 服务器提供服务器配置和工具禁用列表由 MCP 管理链路读取。Skills 可以声明本地工具、MCP 和其他 Skill 依赖预加载 Skill从首轮就开放其依赖工具SkillsMiddleware会把预加载 Skill 的完整说明注入系统提示段并直接把其依赖工具加入模型可见列表普通 Skill在模型通过read_file读取其SKILL.md后激活激活后其本地工具与声明的 MCP 依赖才开放deps_bundle由build_dependency_bundle构建包含tools与mcps两部分。职责边界划分工具实现放在toolkits内置与知识库工具或由 MCP 服务器提供Skill 的使用说明和依赖放在 Skill 目录SKILL.mdMCP 的连接和工具发现由 MCP 服务负责Agent 配置只选择资源范围tools、mcps、skills等字段不直接复制工具实现。详细规则见 Skills 管理 和 MCP 集成。新增工具时检查在 Yuxi 中新增一个工具前建议逐条核对以下清单对应 tools-system.md 的新增工具时检查确定归属层级工具属于内置工具、知识库工具、MCP 还是 Skill这决定了注册位置、category 取值与元数据来源。确定可见性策略是否需要在ToolNode注册保证可执行是否需要 Skill 激活后才让模型看见如知识库工具如果走 Skill 门控要确认resolve_skill_gated_tools能解析出该工具并且不在基础工具集context.tools中否则不会进入门控集合。执行处权限校验产生副作用文件、网络、数据库时执行处是否有用户、路径和资源权限校验参考present_artifacts的路径白名单、download_kb_file的可见知识库校验与路径穿越防护。结构化错误返回错误是否以结构化结果返回并保留可排查信息如ocr_parse_file返回{error: ...}、install_skill用ToolMessage返回失败明细避免裸抛异常导致整个 Agent 运行中断。稳定展示元数据前端展示名称是否来自稳定元数据通过display_name而非函数名提供用户可读名称通过tags支持筛选避免前端硬编码。补齐测试是否补充纯逻辑和真实 HTTP/文件链路的相应测试仓库中 test_web_search_provider.py 覆盖 web_search 供应商解析test_agent_stream_close.py 等测试覆盖工具调用与流式场景可作为参考模板。总结Yuxi 的工具系统把注册、可执行、模型可见、目标授权四个环节彻底分离tool装饰器与toolkits包负责注册与元数据resolve_configured_runtime_tools负责把配置范围内工具注册进 ToolNodeSkillsMiddleware负责按 Skill 激活状态门控模型可见性每个工具的执行体则承担最终的资源授权。理解这四层就能在新增工具、接入 MCP 或编写 Skill 时既保证功能可用又不破坏多租户权限边界。【免费下载链接】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),仅供参考