设计与实现解析)
FastGPT 统一工具参数转换与运行时编译Tool Input Runtime设计与实现解析【免费下载链接】FastGPTFastGPT is a knowledge-based platform built on the LLMs, offers a comprehensive suite of out-of-the-box capabilities such as data processing, RAG retrieval, and visual AI workflow orchestration, letting you easily develop and deploy complex question-answering systems without the need for extensive setup or configuration.项目地址: https://gitcode.com/GitHub_Trending/fa/FastGPT导读本文以 .agents/design/app/tool-input-runtime.md 为骨架深入剖析 FastGPT 中工具参数从「原始定义」到「模型可见参数」再到「最终执行参数」的统一编译链路。你将理解ToolInputDefinition / ToolInputConfiguration / CompiledToolRuntime三层数据模型、AgentV2 与工作流 ToolCall 共用的 compiler 与参数合并策略、AJV 运行时校验的边界以及这套设计如何在不迁移存量数据的前提下保持数据库与公开协议兼容。一、背景三类消费方为何需要统一编译 seamFastGPT 的工具定义可能来自两种源头JSON SchemaHTTP 工具OpenAPI 解析、MCP 工具、系统工具System Tool声明输入输出NodeIO工作流节点输入项FlowNodeInputItemType用于插件工作流、普通工具节点和子应用。这些工具定义会被三类运行时消费AgentV2Agent 节点中挂载的工具按{ key, mode } config持久化工作流 ToolCallToolCall 节点挂载的工具按 NodeIO 保存普通工作流执行通过工具节点直接调用的外部工具。设计文档的核心诉求是建立统一编译 seam把「原始定义」「持久化配置」「模型可见参数」「最终执行参数」四层解耦。这样三种消费方共享同一套编译、过滤、合并、校验逻辑同时保持现有数据库结构与公开协议不变。二、数据模型四个核心概念1.ToolInputDefinition参数的原始定义位于 packages/global/core/app/tool/runtime.tsexport type ToolInputDefinition { key: string; // 参数唯一 key对应当前工具定义的 NodeIO key jsonSchema?: JsonSchemaPropertiesItemType; // 原始 JSON Schema property如 HTTP/MCP 工具 nodeInput: FlowNodeInputItemType; // NodeIO 投影视图 allowedModes: AgentToolInputModeEnum[]; // 该参数允许的输入来源 };createToolInputDefinitions通过两个判断决定allowedModescanInputBeAgentGenerated(input)是否允许 Agent 生成与 formEdit/utils.ts 中的agentGeneratedDenyRenderTypes黑名单强相关password、selectLLMModel、selectDataset 等类型被排除canUseFixedBinding是否允许手工绑定。手工控件manualInputRenderTypes存在、或当前类型为reference工作流连线、或根本不允许 Agent 生成时都允许手工模式。2.ToolInputConfiguration持久化的最终选择export type ToolInputConfiguration { key: string; mode: AgentToolInputModeEnum; // agentGenerated | manual binding?: unknown; // 可选手工绑定值 };createToolInputConfigurations读取 NodeIO 的最终输入来源若请求模式不在allowedModes内则回退到第一个允许的模式allowedModes[0] ?? manual这是运行时安全边界的重要一环。3.CompiledToolRuntime编译产物export type CompiledToolRuntime { modelTool: ChatCompletionTool; // 发给 LLM 的 function schema agentGeneratedKeys: string[]; // Agent 参数白名单 fixedInputBindings: Recordstring, unknown; // 固定输入绑定 };4. 两个编译函数compileToolRuntime()从最新工具定义和当前配置生成唯一运行时描述runtime.tsmergeToolRuntimeParams()过滤模型未知字段并与固定绑定合并拒绝两组 key 冲突runtime.ts。三、转换规则七条行为约束文档定义了七条转换规则与源码逐一对应HTTP、MCP 和系统工具保留完整 JSON Schema property并投影为 NodeIO 配置视图。对应 jsonschema.ts 的jsonSchema2NodeInput每个 property 通过canProjectJsonSchemaToNodeInput判断可投影性同时保留customJsonSchema副本与toolDescription。基础类型、对象、同类型数组、枚举和同基础类型 nullable union 支持手工配置。canProjectJsonSchemaToNodeInputjsonschema.ts从type / const / enum / anyOf / oneOf分支归一共同基础类型数组仅当items为单一 schema 且元素类型为基础类型时才允许投影。混合 union、tuple 和无法确定基础类型的 schema 只允许 Agent 生成。无法归一类型时返回WorkflowIOValueTypeEnum.any并在jsonSchema2NodeInput中降级为renderTypeList: [agentGenerated]selectedType: agentGeneratedjsonschema.ts。文件、知识库、模型等 NodeIO 专属输入只允许手工配置不进入模型 schema。对应unsupportedToolInputRenderTypes黑名单formEdit/utils.ts以及canInputBeAgentGenerated中的agentGeneratedDenyRenderTypesformEdit/utils.ts。AgentV2 继续保存{ key, mode } configSimple 与 Workflow ToolCall 继续保存 NodeIO。canonical schema 定义于 packages/global/core/workflow/migration/schema.tsCanonicalAgentToolInputConfigSchema { key, mode }其中mode取AgentToolInputModeEnumagentGenerated/manual定义于 packages/global/core/app/tool/constants.ts。isToolParam只决定首次默认模式显式mode、selectedType和isToolParam: false优先。normalizeFlowNodeInputType与initAgentToolInputTypeformEdit/utils.ts体现该优先级显式 mode 直接决定来源旧版allAgentGenerated/toolDescription推断只在无 mode 时兜底。toolDescription的旧版默认推断只作用于 workflow tool 的原始pluginInput。Agent 运行时在legacyDefaultMode推断中区分 system/commercial 工具allAgentGenerated与pluginModuletoolDescription见 agent/sub/tool/utils.ts。四、编译流程AgentV2 与 ToolCall 如何共用 compilerAgentV2 侧agent/sub/tool/utils.ts 中的getAgentRuntimeTools是 Agent 侧总入口流程如下解析工具 idsplitCombineToolId按 source 区分 systemTool / commercial / mcp / http / 个人 App对 App 类工具执行读权限鉴权authAppByTmbIdReadPermissionVal通过formatSystemToolNode/formatPersonalAppNode/formatMcpToolNode/formatHttpToolNode生成运行时节点关键点toolSet会展开为多个子工具用initAgentToolInputType将持久化的{ key, mode }合并回最新工具定义filterToolConfiguredParams剔除由 Agent 生成的参数JSON Editor值经parseJsonEditorValue归一为原生值getToolConfigStatus检查必填配置是否完整不完整则直接跳过该工具注册避免模型调用后才失败调用compileRuntimeTool封装compileToolRuntime产出agentGeneratedInputKeys、params固定绑定与requestSchema模型 schema。ToolCall 侧useToolCatalog.ts 中createToolSchema直接调用compileToolRuntime(...).modelTool生成 function schemauseToolCatalog同时维护nodeId - 工具节点映射供执行与响应展示复用。注意 datasetSearchNode 不会作为工具暴露给 LLM。普通工作流普通工作流节点的 NodeIO 引用仍由工作流引擎解析reference在编译前已解析为固定值这正是canUseFixedBinding允许 reference 的原因普通工作流不经过模型 compiler仅在外部工具调用前用assertToolRuntimeParams复验参数runtime.ts。五、参数合并与冲突拒绝mergeToolRuntimeParams的合并策略runtime.tsreturn { ...fixedInputBindings, ...Object.fromEntries(Object.entries(aiParams).filter(([key]) generatedKeySet.has(key))) };固定绑定手工配置 默认值始终先展开作为最终参数的底座模型返回的参数只保留白名单 keyagentGeneratedKeys其余字段一律丢弃若发现某 key 同时出现在固定绑定与白名单中直接抛错Tool input X cannot be both generated and fixed。测试 packages/global/test/core/app/tool/runtime.test.ts 覆盖了「过滤未知字段、固定绑定权威」与「冲突拒绝」两种场景。六、模型 schema 的白名单过滤buildModelVisibleToolJsonSchemajsonschema.ts决定模型可见的 JSON Schema可见 key toolParamsAgent 生成输入∪ schema 中显式isToolParam: true且不属于任何 NodeIO key 的字段stripModelSchemaAnnotations递归移除title / default / isToolParam等展示与默认值注解但保留const / enum / examples它们属于数据本身required同步按可见 key 过滤。测试用例「removes NodeIO titles and defaults from model parameters without changing manual bindings」runtime.test.ts验证了该行为queryagentGenerated进入模型 schema 并保留 descriptionlimitmanual defaultValue 5只进入fixedInputBindings。七、JSON Schema 投影与 NodeIO 往返jsonschema.ts 提供双向转换能力Schema → NodeIOjsonSchema2NodeInput/jsonSchema2NodeOutput/jsonSchema2SecretInput。其中jsonSchema2SecretInput处理isSecret字段将密钥配置转成hidden输入绝不进入模型 schema——这与文档「内部 secret/config 字段不进入 schema」的风险条款一致Agent 运行时中 secrets 通过NodeInputKeyEnum.systemInputConfig的 hidden input 承载见 agent/sub/tool/utils.ts。NodeIO → SchemanodeInput2JsonSchemaProperty/nodeInputs2JsonSchema从valueTypeJsonSchemaMap推导基础 schema并回填enum、default、minimum/maximum等约束getJsonSchemaPropertyFromValueType显式处理any / arrayAny / arrayObject / chatHistory / datasetQuote / dynamic等无法无损表达的语义类型避免默认退化误导模型 contract。Schema 严格校验ToolParamJsonSchemaSchemajsonschema.ts递归校验 type 与结构关系如properties仅允许type: object、array必须有items、required引用的 key 必须存在于properties。八、AJV 运行时校验三个校验入口runtime.ts 构建了基于 AJV 的校验体系多版本方言支持同时实例化 AJV draft-07 / 2019-09 / 2020-12根据 schema 的$schema字段自动选择validator 缓存以JSON.stringify(schema)为 key 缓存编译后的校验函数避免重复编译validateToolInputValue用原始 property schema 校验单个手工配置值配置表单提交时调用validateToolRuntimeParams用完整 schema 校验剔除内部字段后的最终执行参数服务端外部调用前调用assertToolRuntimeParams校验失败的抛错版本错误信息保留可定位的字段路径/ 字段名 message。AJV 配置为{ allErrors: true, strict: false, validateFormats: false }——格式校验关闭恰好对应文档风险条款「原始 JSON Schema 可能包含未知 format本期保留结构约束format 不作为阻断项」。测试 runtime.test.ts 覆盖单 property 校验、完整参数校验含additionalProperties: false拦截未知字段、根级 uniononeOf、$ref/$defs、patternProperties以及 draft 2020-12 方言。九、兼容性策略与风险边界文档「风险与注意事项」在源码中逐一得到落实风险条款源码落实不迁移存量记录兼容读取逻辑必须保留initAgentToolInputType的legacyDefaultMode推断、AgentToolInputConfigSchema.safeParse容错非法存量项直接丢弃canonical schema 只约束新写入未知 format 不作为阻断项AJVvalidateFormats: false内部 secret/config 不进入 schemajsonSchema2SecretInput hidden input canInputBeAgentGenerated黑名单内置节点只允许挂载到工作流 ToolCallagentGeneratedDenyRenderTypes中的selectSkill / selectTool等类型天然排除在 Agent 工具之外另外compileToolRuntime在无 Agent 生成参数时省略parameters字段OpenAI function calling 约定避免空 schema 干扰模型判断。十、关键代码位置索引关注点路径统一编译 seam、参数合并、AJV 校验packages/global/core/app/tool/runtime.tsJSON Schema ⇄ NodeIO 双向转换与模型可见过滤packages/global/core/app/jsonschema.ts工具输入模式归一、黑名单、默认模式推断packages/global/core/app/formEdit/utils.tsAgentV2 运行时工具加载与编译调用packages/service/core/workflow/dispatch/ai/agent/sub/tool/utils.tsToolCall 工具目录与模型 schemapackages/service/core/workflow/dispatch/ai/toolcall/hooks/useToolCatalog.tsAgent 工具持久化 canonical schemapackages/global/core/workflow/migration/schema.ts模式枚举与工具来源枚举packages/global/core/app/tool/constants.ts编译器与校验的单元测试packages/global/test/core/app/tool/runtime.test.ts十一、总结FastGPT 的工具参数运行时设计以「一个 compiler、两个持久化格式、三个消费方」为核心所有工具定义先归一为ToolInputDefinition叠加用户配置形成ToolInputConfiguration再由compileToolRuntime编译成模型 schema、Agent 白名单与固定绑定三件套执行前通过mergeToolRuntimeParams过滤合并、通过 AJV 多方言校验兜底。这套 seam 让 AgentV2、ToolCall 与普通工作流共享同一套安全边界同时借助defaultToAgentGenerated迁移语义与 canonical schema 的「只约束新写入」策略实现了对存量数据与公开协议的零迁移兼容。【免费下载链接】FastGPTFastGPT is a knowledge-based platform built on the LLMs, offers a comprehensive suite of out-of-the-box capabilities such as data processing, RAG retrieval, and visual AI workflow orchestration, letting you easily develop and deploy complex question-answering systems without the need for extensive setup or configuration.项目地址: https://gitcode.com/GitHub_Trending/fa/FastGPT创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考