JIT-Agent:借鉴JIT编译思想动态生成智能体框架

发布时间:2026/8/31 2:56:28
JIT-Agent:借鉴JIT编译思想动态生成智能体框架 在实际的 Agent 系统中最让人头疼的问题不是写好一个固定的智能体而是同一套系统如何面对不断变化的任务。JIT-Agent 是一种借鉴 JIT 编译思想的动态生成智能体框架的模型它不在启动阶段把所有组件写死而是在收到具体任务后根据任务上下文、可用工具和策略规则在运行时动态组装出合适可执行的智能体框架。这个模型适合用来解决多任务、多工具、多策略组合下的 Agent 编排问题也是从“写死流程”走向“按需生成”的一种工程思路。本文会从设计动机、核心抽象、最小实现、运行验证、常见排错和生产落地几个层面展开。阅读前需要你有基本的 Python 概念、熟悉类与装饰器并了解“注册表”“工厂方法”这类常见设计模式。代码示例会保持最小闭环读者可以复制到本地逐行运行也可以在此基础上替换成 Java、Go 等语言实现。1. 先理解“JIT-Agent”解决什么问题JIT-Agent 解决的核心问题是让同一个 Agent 执行引擎能够根据任务描述动态生成不同结构的智能体框架而不是为每一种任务单独维护一套代码。1.1 静态智能体框架的瓶颈很多团队最初的 Agent 实现是“流程图 回调函数”。系统启动时加载一个固定的 Agent 对象内部包含 planner、tool set、memory、policy 等模块。任务进入后流程基本固定先规划再调用工具最后按策略输出。这种模型的优点是简单、直观、故障容易复现。但任务种类增多之后问题会逐渐暴露每个新任务都需要新增分支逻辑if-else 越来越长。工具的绑定关系写在代码里改一个工具的入参要影响所有调用方。不同任务可能需要不同记忆策略但固定 Agent 只能有一个 memory 实例。灰度发布时新策略只能在整段代码里切换无法按任务粒度做动态实验。例如一个系统既要处理“翻译文档”任务也要处理“调研某个技术方案”任务还要处理“根据客服历史生成摘要”任务。如果只用一个固定框架要么把所有工具都注入到同一个 Agent 里导致工具调用混乱要么拆成三个 Agent 类结果三个类有大量重复代码。静态框架不是不能做而是随着任务组合数量升高维护成本会指数级上升。1.2 JIT-Agent 对“动态生成”的定义JIT 是 Just-In-Time 的缩写最典型的应用是 JIT 编译器。JIT 编译器不会在程序启动前把所有代码编译成机器码而是在程序运行到某个方法时根据当前机器状态、热点数据和运行环境再生成、优化并缓存对应的机器码。JIT-Agent 借鉴的是这层“晚绑定”思想。它把“智能体框架”也看作一个可以按需生成的对象集合。收到一个任务后JIT-Agent 会先解析任务描述生成一份“运行时计划”再按计划从组件注册表中选择具体的 planner、tool、memory、policy 并实例化最后组装成一个可执行的 Agent 对象。这里的“动态生成”有两种落地形式动态组装运行时决定实例化哪些组件并把它们装配成对象图。这是更安全、更容易落地的形式。动态代码生成运行时生成新的 Python 类、字节码或 DSL再加载执行。这种形式灵活但对安全、沙箱和运维要求很高。本文下面的示例以“动态组装”为主。它已经能覆盖绝大多数多任务编排场景也更容易调试和监控。1.3 哪些场景真正需要 JIT-Agent适合使用 JIT-Agent 的场景通常具备以下特征任务类型多样且组合方式由运行时参数决定。工具库持续扩充不同任务需要不同工具集合。业务需要按用户、租户或任务级别定制记忆、审批等策略。需要在不重启服务的情况下引入新组件或新策略。不适合使用的场景也有明显特征任务类型长期固定组件不超过五个请求量极高且对延迟极度敏感。这种情况下直接用一个预先组装好的静态 Agent 更高效没必要让每一次请求都经历“解析规格、生成计划、实例化组件”的开销。2. JIT-Agent 的核心模型AgentSpec、组件注册表与运行时计划要让动态生成变得可预测、可控不能靠散乱的 if-else。JIT-Agent 的核心是三个抽象AgentSpec、ComponentRegistry 和 RuntimePlan。2.1 三个核心抽象AgentSpec 是任务的“需求规格”。它描述了一个任务从哪里来、要完成什么目标、可能用到什么能力。一个最小 AgentSpec 至少包含字段含义示例值task_type任务类型用于选择 planner 和整体流程research、general、summarygoal自然语言目标描述调研 JIT-Agent 的落地方式required_tools任务明确要求的工具列表[web_search, summarize]preferences用户级或任务级偏好配置{memory_size: 20, need_human_review: true}ComponentRegistry 是组件注册表用来管理所有可复用的能力组件。注册表里保存的不是组件实例而是组件的元信息和工厂函数。这样 JIT-Agent 才能根据 AgentSpec 查到合适的组件并在需要时才创建实例。RuntimePlan 是动态生成的产物描述“本次任务需要哪些组件、按什么顺序初始化、给它们什么配置”。RuntimePlan 可以看作 JIT 编译过程中的中间表示它不直接执行任务但决定了后续实例化和执行的方式。这三个抽象各司其职AgentSpec 解决“要什么”ComponentRegistry 解决“有什么”RuntimePlan 解决“用哪些、怎么配”。2.2 动态生成的主要流水线JIT-Agent 的完整流水线可以拆成七个步骤解析 AgentSpec校验必填字段和非法参数。提取特征例如 task_type、required_tools、preferences。组件匹配在注册表中查找满足条件的组件。依赖解析确认组件之间的依赖关系。生成 RuntimePlan把选中的组件 key 和配置写入计划。实例化组件按依赖顺序调用工厂函数。验证生成结果组装成 Agent 对象并执行。其中第 3 到第 6 步是 JIT-Agent 和普通 Agent 最大的区别。普通 Agent 在第 1 步之后通常会直接进入“按固定流程调用工具”JIT-Agent 则先在运行时生成一张“组件装配表”再按表创建对象。2.3 为什么说这是“JIT”而不是“AOT”AOTAhead-Of-Time思路也可以用在 Agent 框架上在服务启动前预先定义若干模板运行时按模板复制并填充参数。例如启动时加载“research_agent.yaml”和“general_agent.yaml”请求到达后根据 task_type 选择对应模板。JIT 和 AOT 的核心差异在于“生成时机”和“生成依据”对比维度AOT 预定义模板JIT 动态生成组件选择时机服务启动或发布前任务到达后组件组合依据固定模板当前 AgentSpec 和注册表状态新组件生效速度需要重新发布模板注册后即可按规则选择运行时开销低直接查表相对高需要生成计划灵活性较低组合数受模板限制较高可按任意合法规则组合JIT-Agent 不是要完全取代 AOT。实际生产中可以两者混用对高频、固定的任务模板走 AOT 路径对复杂、多变的动态任务走 JIT 路径。但如果只学习一种实现从 JIT 模型入手更能理解“动态生成”的本质。3. 用 Python 实现一个最小可运行的 JIT-Agent 引擎这一节会实现一个单文件版本的 JIT-Agent 引擎。它不依赖外部框架只使用 Python 标准库适合用来验证动态生成智能体框架的核心机制。3.1 环境准备与项目结构建议使用 Python 3.10 及以上版本因为代码会用到dataclass和类型注解。不需要安装第三方库。项目结构可以保持最小jit_agent_demo/ ├── jit_agent.py # 注册表、Builder、Agent、组件定义 └── run_demo.py # 运行两个不同任务验证动态生成实际项目里可以把组件拆分到不同模块避免单文件过大。但这里先合并到一个文件降低阅读成本。3.2 先定义组件注册表注册表负责保存组件 key 和工厂函数。组件 key 格式统一为分类:名称例如planner:basic_planner、tool:web_search。# jit_agent.py import logging from dataclasses import dataclass, field from typing import Any, Callable, Dict, List logging.basicConfig(levellogging.INFO) class ComponentRegistry: def __init__(self) - None: self._factories: Dict[str, Callable[..., Any]] {} def register( self, category: str, name: str, factory: Callable[..., Any], ) - None: key f{category}:{name} self._factories[key] factory def get(self, key: str) - Callable[..., Any]: if key not in self._factories: raise KeyError(funregistered component: {key}) return self._factories[key] def has(self, key: str) - bool: return key in self._factories这里的关键点是factory收到的是“生成时上下文”而不是直接收到任务文案。后续 Builder 会传入 RuntimePlan 和已创建组件这样组件之间可以互相访问。3.3 定义 AgentSpec 与 RuntimePlandataclass class AgentSpec: task_type: str goal: str required_tools: List[str] field(default_factorylist) needs_web_search: bool False preferences: Dict[str, Any] field(default_factorydict) dataclass class RuntimePlan: components: List[str] field(default_factorylist) config: Dict[str, Any] field(default_factorydict)AgentSpec 的必填字段是task_type和goal。required_tools和preferences是可选的增强信息。RuntimePlan 的components是组件 key 列表config保存本次生成需要传给组件的配置。3.4 实现动态框架生成器生成器是 JIT-Agent 的大脑它负责根据 AgentSpec 生成 RuntimePlan再根据 RuntimePlan 实例化组件。class JITAgentBuilder: def __init__(self, registry: ComponentRegistry) - None: self.registry registry def build_plan(self, spec: AgentSpec) - RuntimePlan: plan RuntimePlan() if spec.task_type research: plan.components.append(planner:research_planner) else: plan.components.append(planner:basic_planner) for tool in spec.required_tools: plan.components.append(ftool:{tool}) if spec.needs_web_search: plan.components.append(tool:web_search) plan.components.append(memory:simple_memory) if spec.preferences.get(need_human_review): plan.components.append(policy:human_review) else: plan.components.append(policy:auto_execute) plan.config[goal] spec.goal plan.config[memory_size] spec.preferences.get(memory_size, 10) return plan def build_agent(self, spec: AgentSpec) - DynamicAgent: plan self.build_plan(spec) logging.info(JIT plan components: %s, plan.components) instances: Dict[str, Any] {} for key in plan.components: factory self.registry.get(key) instance factory(plan, instances) instances[key] instance logging.info(instantiated %s, key) return DynamicAgent(planplan, instancesinstances)build_plan里隐藏了组件决策规则。当前规则很简单research用调研型 planner否则用基础 planner需要的工具逐个追加默认带记忆组件审批策略从 preferences 读取。这个决策规则可以替换成配置中心规则、特征匹配或评分模型。3.5 定义 DynamicAgent 和组件工厂DynamicAgent 是组装完成后的运行对象。class DynamicAgent: def __init__(self, plan: RuntimePlan, instances: Dict[str, Any]) - None: self.plan plan self.instances instances def get_by_prefix(self, prefix: str) - Any: for key, instance in self.instances.items(): if key.startswith(prefix): return instance raise RuntimeError(fno component with prefix: {prefix}) def run(self, query: str) - str: planner self.get_by_prefix(planner:) memory self.get_by_prefix(memory:) policy self.get_by_prefix(policy:) tools { key.split(:, 1)[1]: instance for key, instance in self.instances.items() if key.startswith(tool:) } steps planner.plan(query) outputs [] for step in steps: tool_name step[tool] tool tools.get(tool_name) if tool is None: raise RuntimeError(ftool {tool_name} is not in generated framework) output tool.execute(step[input]) memory.save(tool_name, output) outputs.append(output) return policy.decide(outputs)注意run只依赖组件行为不依赖具体组件类。只要组件实现plan、execute、save、decide这些约定方法JIT-Agent 就能运行。下面定义最小组件class BasicPlanner: def __init__(self, goal: str) - None: self.goal goal def plan(self, query: str): return [{tool: math, input: query}] class ResearchPlanner: def __init__(self, goal: str) - None: self.goal goal def plan(self, query: str): return [ {tool: web_search, input: query}, {tool: summarize, input: query}, ] class MathTool: def execute(self, expr: str) - str: # 演示用生产环境请使用安全的表达式解析器 return fmath_result({expr}) class WebSearchTool: def execute(self, keyword: str) - str: return fweb_result({keyword}) class SummarizeTool: def execute(self, text: str) - str: return fsummary({text}) class SimpleMemory: def __init__(self, size: int 10) - None: self.size size self.items: List[tuple] [] def save(self, key: str, value: str) - None: self.items.append((key, value)) if len(self.items) self.size: self.items.pop(0) class AutoExecutePolicy: def decide(self, outputs: List[str]) - str: return \n.join(outputs) class HumanReviewPolicy: def decide(self, outputs: List[str]) - str: return PENDING_HUMAN_REVIEW: ,.join(outputs)最后把组件注册进注册表def register_default_components(registry: ComponentRegistry) - None: registry.register(planner, basic_planner, lambda plan, deps: BasicPlanner(plan.config[goal])) registry.register(planner, research_planner, lambda plan, deps: ResearchPlanner(plan.config[goal])) registry.register(tool, math, lambda plan, deps: MathTool()) registry.register(tool, web_search, lambda plan, deps: WebSearchTool()) registry.register(tool, summarize, lambda plan, deps: SummarizeTool()) registry.register(memory, simple_memory, lambda plan, deps: SimpleMemory(plan.config.get(memory_size, 10))) registry.register(policy, auto_execute, lambda plan, deps: AutoExecutePolicy()) registry.register(policy, human_review, lambda plan, deps: HumanReviewPolicy())工厂函数接收的参数是(plan, deps)deps是当前已经实例化的组件字典。如果后续需要组件间依赖可以直接从deps中取。3.6 运行两个不同任务在run_demo.py中构造两个完全不同的 AgentSpec# run_demo.py from jit_agent import ( AgentSpec, ComponentRegistry, JITAgentBuilder, register_default_components, ) def main() - None: registry ComponentRegistry() register_default_components(registry) builder JITAgentBuilder(registry) spec1 AgentSpec( task_typegeneral, goal计算表达式的值, required_tools[math], preferences{memory_size: 5}, ) agent1 builder.build_agent(spec1) print(--- agent1 output ---) print(agent1.run(23)) spec2 AgentSpec( task_typeresearch, goal调研 JIT-Agent, required_tools[web_search, summarize], needs_web_searchTrue, preferences{need_human_review: True}, ) agent2 builder.build_agent(spec2) print(--- agent2 output ---) print(agent2.run(JIT-Agent 是什么)) if __name__ __main__: main()执行命令python run_demo.py预期运行结果类似JIT plan components: [planner:basic_planner, tool:math, memory:simple_memory, policy:auto_execute] instantiated planner:basic_planner instantiated tool:math instantiated memory:simple_memory instantiated policy:auto_execute --- agent1 output --- math_result(23) JIT plan components: [planner:research_planner, tool:web_search, tool:summarize, memory:simple_memory, policy:human_review] instantiated planner:research_planner instantiated tool:web_search instantiated tool:summarize instantiated memory:simple_memory instantiated policy:human_review --- agent2 output --- PENDING_HUMAN_REVIEW: web_result(JIT-Agent 是什么),summary(JIT-Agent 是什么)可以看到同一个JITAgentBuilder实例在收到不同 AgentSpec 后生成了完全不同结构的 Agent 框架。这就是 JIT-Agent 的核心能力不是在代码里写死每个任务怎么执行而是在运行时按规格生成。4. 通过两类任务验证“动态生成”的效果运行 demo 只是第一步。要确认动态生成真的生效还需要从三个角度验证组件选择是否不同、执行顺序是否符合预期、异常回退是否可控。4.1 相同引擎生成不同任务框架验证方法是固定同一个 registry 和 builder传入不同 spec对比 RuntimePlan 的components列表。demo 中 agent1 和 agent2 的组件列表明显不同任务plannertoolsmemorypolicygeneral/mathbasic_plannermathsimple_memoryauto_executeresearchresearch_plannerweb_search, summarizesimple_memoryhuman_review这说明 Planner、Tool、Policy 都参与到了动态选择中。如果后续增加新的 task_type只需要在build_plan中增加对应规则并在注册表中注册组件即可。4.2 查看执行日志确认组件选择与排序动态生成最容易出的问题是“组件选对了但执行顺序不对”。当前 DynamicAgent 由planner.plan()推导执行序列也就是说真正的执行顺序由 planner 决定。注册表只负责组装框架不决定工具执行顺序。这一点需要重点关注如果你的 Agent 业务要求“先搜索再总结”那么 ResearchPlanner 返回的 steps 必须先放web_search再放summarize。如果顺序反了结果一定不对。排查时不要只查 JIT-Agent 的生成日志还要看 planner 返回的计划。4.3 验证失败回退逻辑把注册表中某个组件去掉再运行相同 spec会得到 KeyError。例如不注册summarizeregistry.register(tool, web_search, lambda plan, deps: WebSearchTool()) # 不注册 summarize spec AgentSpec( task_typeresearch, goal调研, required_tools[web_search, summarize], ) builder.build_agent(spec)会抛出KeyError: unregistered component: tool:summarize生产环境不应该让这种错误直接暴露给用户。JIT-Agent 的 Builder 应当捕获KeyError记录缺失组件并返回可读错误信息或降级方案。例如缺少summarize时可以降级为只返回搜索结果同时记录一条 warning。5. 动态生成中的常见问题与排查路径JIT-Agent 的常见问题集中在四个方面组件匹配、生成性能、缓存失效和资源生命周期。5.1 组件找不到或匹配不上现象执行build_agent时抛出KeyError: unregistered component。常见原因组件没有注册。注册的分类或名称拼写不一致。依赖的组件注册顺序不对。多个模块重复初始化注册表导致组件被覆盖。检查路径先确认 AgentSpec 期望的组件 key。在注册表对象中打印所有已注册 key。检查是否在register_default_components之后又创建了新的空ComponentRegistry。检查组件模块是否被多个入口重复加载。推荐做法logging.info(registered components: %s, registry._factories.keys())生产环境可以提供一个/health接口返回注册表快照方便排查。5.2 生成耗时过高接口响应变慢现象每秒请求量上来后Agent 接口 P99 延迟明显上升。原因每个任务都重新执行build_plan - 实例化组件的完整流程。组件越多、工厂函数越重生成耗时越高。检查方式在build_plan和每个工厂函数中埋点统计耗时。对比静态 Agent 与动态 Agent 的耗时分布。观察是否SimpleMemory等轻量组件也在重复创建。解决方式对高频、固定 spec 缓存 RuntimePlan 和实例化结果。分离“计划缓存”和“实例缓存”计划缓存可以长期保留实例缓存需要关注线程安全。对低频但耗时高的组件使用懒加载。缓存 key 要包含 AgentSpec 的完整哈希以及注册表版本号。否则组件更新后旧缓存仍会被命中。5.3 缓存命中但组件逻辑已经变化现象修改了某个工具的execute方法重启服务后新逻辑没有生效。原因JIT-Agent 的组件实例被缓存缓存 key 没有包含组件版本或者 Python 的模块缓存导致旧类被复用。检查方式确认缓存中实例的类名和模块名。确认注册组件的 factory 是否被重新加载。确认是否使用了functools.lru_cache或全局 dict 缓存。解决方式给每个组件元信息增加version字段。缓存 key 中加入组件版本。如果有“热更新”需求不要直接覆盖容器中的类使用独立插件加载器并在版本变化时重建缓存。5.4 动态生成对象没有释放导致内存增长现象服务运行几天后内存持续上涨直到 OOM。原因JIT-Agent 每次生成任务都会创建新的组件实例。如果这些实例被全局 map 长期引用或者组件内部持有大对象、文件句柄、数据库连接内存就无法被回收。检查方式使用tracemalloc或内存分析工具观察大对象来源。检查是否有全局agent_pool或instance_cache无限增长。检查工具组件是否创建了连接池但未复用。解决方式为需要释放资源的组件实现close()或上下文管理器。DynamicAgent 增加shutdown()方法统一关闭所有组件。缓存限制最大数量使用 LRU 淘汰。推荐给 DynamicAgent 补一个清理方法class DynamicAgent: def shutdown(self) - None: for instance in self.instances.values(): close getattr(instance, close, None) if callable(close): close()6. 从 Demo 到生产JIT-Agent 落地的工程要素demo 能跑通只是开始。真正上线前还需要从安全、性能、可观测性和运维层面补齐工程能力。6.1 学习环境与生产环境的差异关注点学习环境生产环境组件来源本地代码硬编码配置中心、插件包、自动化注册组件安全只信任本机代码白名单 签名校验 权限隔离生成策略简单 if-else规则引擎、模型打分、AB 实验缓存策略无缓存多级缓存 版本失效异常处理打印堆栈结构化错误码 降级方案日志logging.infotrace_id 审计日志 指标埋点资源回收进程退出自动回收显式 shutdown 连接池管理生产环境里JIT-Agent 的“动态生成”不能做到完全无约束。需要给每个可注册组件设定权限层级例如普通工具谁能注册、内部能力谁能访问、策略类组件是否允许外部上传等。6.2 安全边界动态生成不能变成任意代码执行动态生成最危险的误用是根据用户输入拼接 Python 代码并执行。例如把spec.goal拼进eval或动态 import这是典型的代码注入。动态生成智能体框架时应该遵循以下安全边界组件必须预注册只允许从注册表按 key 查找。AgentSpec 只能影响“选择哪个组件”和“传入什么配置”不能决定“组件内部代码”。任何需要用户提供正则、表达式、DSL 的字段都必须经过 whitelist 校验。如果需要加载插件使用独立的模块隔离机制限制文件访问和网络访问。简单来说JIT-Agent 生成的是对象图和配置不生成可执行的原始代码。如果需要生成代码请单独设计沙箱和权限方案。6.3 缓存策略与热更新动态生成比静态 Agent 多了一部分开销因此缓存是必要的。缓存不能简单用“spec.goal 字符串”做 key因为同一个目标可能对应不同工具权限和审批策略。推荐缓存 key 使用 AgentSpec 的规范化 JSON 哈希。伪代码import hashlib import json def spec_cache_key(spec: AgentSpec, registry_version: str) - str: payload { task_type: spec.task_type, goal: spec.goal, required_tools: sorted(spec.required_tools), needs_web_search: spec.needs_web_search, preferences: spec.preferences, registry_version: registry_version, } raw json.dumps(payload, sort_keysTrue, ensure_asciiFalse) return hashlib.sha256(raw.encode(utf-8)).hexdigest()热更新时需要同时修改注册表版本号并清理对应缓存。不要在更新组件类时直接覆盖旧的缓存对象否则会出现“新旧逻辑混用”的脏数据。6.4 可观测性与监控指标JIT-Agent 需要埋点的关键位置包括build_plan耗时。单个组件工厂函数的实例化耗时。组件选择结果和 RuntimePlan 内容。组件缺失、匹配失败、降级事件的次数。缓存命中率。监控指标建议指标名称类型说明jit_agent_build_plan_duration_msHistogram生成计划耗时jit_agent_component_instantiate_duration_msHistogram组件实例化耗时jit_agent_cache_hit_totalCounter缓存命中次数jit_agent_component_missing_totalCounter组件缺失次数jit_agent_fallback_totalCounter降级总次数每一条生成记录都建议关联同一个 trace_id便于从用户请求串到 AgentSpec、RuntimePlan、组件实例和执行结果。6.5 什么时候不要使用 JIT-Agent如果当前业务满足以下条件不要强行上 JIT-Agent任务类型只有 2 到 3 种长期稳定。工具数量很少且不存在按需组合的需求。请求并发极高增加一次动态生成都不允许。团队刚接触 Agent 开发还没有建立组件抽象和测试基线。JIT-Agent 的价值在组合复杂度高时才明显。组件组合数不足时静态模板反而更简单、更好维护。实际项目应该先在静态框架上沉淀出“组件边界”再逐步引入动态生成。7. 上线前检查清单把 JIT-Agent 放进生产环境前要确认的事最后给出一份可复用的检查清单。这份清单可以在每次新增任务类型或新增组件前执行也可以在版本发布前复核。7.1 每个 Agent 类型上线前要确认的事项AgentSpec 字段是否完整缺少默认值时是否设置了合理兜底。组件是否已在注册表中注册key 是否与 build_plan 中的规则完全一致。组件之间的依赖顺序是否正确是否存在循环依赖。是否验证过两种以上相同 task_type 的不同 preferences 组合。是否验证过组件缺失时的降级路径降级结果是否可被用户接受。是否设置了组件的版本号并纳入缓存 key。是否记录了完整的 RuntimePlan 日志能否回溯到具体某次生成的组件列表。是否测试过 DynamicAgent 的 shutdown避免连接和文件句柄泄漏。是否对 AgentSpec 做了输入校验防止不可信字段影响组件选择。7.2 一次模拟上线巡检的记录模板检查项结果备注注册表组件数量123 planner / 5 tool / 2 memory / 2 policy新增任务类型测试通过general、research、summary 三类缓存命中率86%生产负载模拟下平均生成耗时3.2ms缓存未命中时 18ms组件缺失降级测试通过缺失 summarize 时降级为仅搜索内存清理测试通过agent.shutdown() 后无残留引用检查清单不是一次性写完就结束。每次修改 build_plan 规则、新增组件类别、调整 preferences 含义都要重新走一遍。这样 JIT-Agent 才不会从“动态生成框架”退化成“难以预测的大型 if-else”。JIT-Agent 真正值得借鉴的地方不是“动态”这个词本身而是它把“任务规格”和“组件能力”解耦让 Agent 结构成为可以由运行时推导的产物。实现一个最小引擎不难难的是在动态生成的同时守住安全、性能和可观测性。先从小规模场景验证再逐步扩大到复杂业务是比较稳妥的落地路径。