目录CodeAct 工程化科普把多轮 tool calling 折叠成一次 execute_codeHyperlight/.NET 视角先把话说死CodeAct 不是“更聪明”而是“少回合”为什么你会被多轮编排折磨开销不在工具在回合与上下文1延迟链一长就爆2token越做越厚烧得心疼3最痛的你在宿主里写了一套“微型工作流引擎”Hyperlight 这条线怎么工作的沙箱里跑 Python靠 call_tool(...) 回宿主发生了什么最容易搞错的一点call_tool 不是“在沙箱里重写工具”.NET 侧怎么接Provider 自动注入 vs Function 手动接线以及你该选哪个选型规则同事口吻版A想“每次 run 都默认可用 CodeAct” → 用 ProviderB想“把 execute_code 当普通工具手动控制指令与暴露” → 用 Function配置面你迟早会碰到的几个选项最关键的“工具可见性”差异省心的来源适用边界与治理什么时候该用、审批怎么做、哪些坑别踩1什么时候适合上 CodeAct2什么时候不值得折腾3审批粒度一个很现实的限制4安全治理一句话再次强调CodeAct 工程化科普把多轮 tool calling 折叠成一次 execute_codeHyperlight/.NET 视角不换模型、不换工具主要换一件事别让你在宿主里当调度器把“计划”塞进一次 execute_code 里跑完。你是不是也写过那种 agent查一次数据 → 回模型 → 再调一个工具 → 再回模型……说实话最烦的不是工具难写。是编排回合多得离谱。慢、贵、还容易写成一坨 if/else。结论先放这能折叠的就别硬多轮。把控制流/数据处理/工具编排塞进一次execute_code让模型写段短程序在沙箱里跑完。回合数下去延迟和 token 才会真的下去。先把话说死CodeAct 不是“更聪明”而是“少回合”先给一个工程师能听懂的定义。CodeAct 的本质给模型一个execute_code工具。然后让模型别再“一步一步选工具”而是直接写一段短程序把三件事一次写进去•控制流循环/分支/重试你以前写在 orchestrator 里的那堆•数据变换过滤、聚合、排序、格式化那些中间态处理•工具编排连续调用多个工具并把前一步输出喂给下一步你可能会问那工具是不是要重写模型是不是要换不用。工具没变、模型没变主要变的是“计划在哪执行”。以前是什么结构•传统模型每次只决定“下一步调哪个工具”•model → tool → model → tool → ...现在是什么结构•CodeAct模型一次写出“完整小流程”•model → execute_code(一段代码里自己调工具、处理结果) → model(收尾/解释)官方文档里把这件事说得很直白CodeAct 的目的就是把model→tool→model 的循环loop折叠collapse。所以收益从哪来不是什么“模型忽然变聪明”。是你把原来散落在多个回合里的决策与中间态处理集中进一次执行。回合数少了延迟/token 自然更好看。就这么点东西。为什么你会被多轮编排折磨开销不在工具在回合与上下文你写过 function calling 的话八成踩过这三个坑。我也踩过。1延迟链一长就爆每次 tool call本质上都要再请求一次模型。网络来回、队列排队、推理时间……单步看不出来五步十步就开始肉眼可见地慢。2token越做越厚烧得心疼多轮编排的常见形态是•每一轮都要带上对话历史•还要带 tool schema、上一步返回、你额外塞的解释链路越长上下文越肥。token 不是线性增长很多时候是“滚雪球”。3最痛的你在宿主里写了一套“微型工作流引擎”说实话模型经常只是被你当成“下一步选择器”。真正的控制流是你在 host 里写的•if/else•重试•分页拉取•聚合、去重、排序然后你还得在每步之间把状态塞回 prompt。烦不烦烦。这就是 CodeAct 值得折腾的原因它把“下一步怎么走”从多轮对话里挪到一次代码执行里。而且不是空口。官方博客在代表性的 tool-heavy 工作负载里给了量化结果•端到端延迟大约减半~50%•token 使用下降 60%注意这里省下来的不是“工具调用时间”。主要是“少了很多模型回合 少了很多上下文重复”。提醒一句收力这套东西不是让模型更会想。是让你少当调度器。就这样。Hyperlight 这条线怎么工作的沙箱里跑 Python靠 call_tool(...) 回宿主好机制讲清楚不然很容易误解。发生了什么Hyperlight 这条线也是当前文档化的 CodeAct 后端大概是这么跑的1.模型输出一段短 Python 程序•重点是“短”。它是胶水代码不是让模型写一整个系统。2.运行位置在隔离的 sandbox / micro-VM 里执行一次•文档里强调了每次执行是干净的运行环境snapshot/restore / clean state 这类思路。•这点很重要减少“上一次执行留下脏状态”的问题。3. 工具怎么用在沙箱里通过call_tool(name, ...)调用你提供的工具•这里的关键词是provider-owned host tools。最容易搞错的一点call_tool 不是“在沙箱里重写工具”你可能会下意识以为工具也跑进沙箱了所以更安全没关系但这个理解不对。call_tool(...)只是桥。你注册的工具函数仍然是在宿主进程里执行。沙箱里的 Python 只是负责•决定调用顺序•传参数•接回结果•做中间数据处理所以安全与治理要分两层看•沙箱限制AllowedDomains/FileMounts/HostInputDirectory•约束的是“沙箱里那段 Python 能直接访问什么网络/文件”。•host tool 的权限边界•工具仍在宿主进程执行。•宿主进程能访问什么内网、凭据、磁盘、数据库工具就潜在能访问什么。•这部分必须靠你把工具做窄、可审计、可控。工程口径总结一句CodeAct 让模型写胶水代码Hyperlight 把胶水关进笼子里。真正碰敏感资源的仍然应该通过你定义的 host tool 去做。别反过来把沙箱开成“万能脚本机”。就这么回事。.NET 侧怎么接Provider 自动注入 vs Function 手动接线以及你该选哪个到 .NET 这边先把“你到底该怎么接”说清楚。我不写安装教程文档里有一行dotnet add package ... --prerelease但我会把路径讲明白。你需要记住一个包名•Microsoft.Agents.AI.Hyperlightpreview然后你会看到两种典型接法。选型规则同事口吻版判断标准很简单你想让 CodeAct 默认可用还是想自己精确控制暴露面A想“每次 run 都默认可用 CodeAct” → 用 Provider用•HyperlightCodeActProvider•HyperlightCodeActProviderOptions它干的事很明确•每次运行自动注入execute_code•自动注入一段运行时 guidance告诉模型怎么写代码、怎么call_tool(...)•还能把一批工具挂在 provider 上作为“只在沙箱里可用”的工具这对你来说意味着你不需要每次都在 prompt 里手写那段“请用 execute_code”。也不需要让模型在 direct tool surface 上看到一堆小工具。它更容易把链路折叠成“一次执行”。B想“把 execute_code 当普通工具手动控制指令与暴露” → 用 Function用•HyperlightExecuteCodeFunction•以及它的BuildInstructions(...)这个形态适合两种情况•你有一套固定的 sandbox 配置想以 function 的方式直接挂到 agent 上•你想把execute_code只暴露给某些场景/某些路由而不是默认每次都能用但代价也很直白prompt guidance 你得自己拼。也就是你得把BuildInstructions(...)的输出塞进 agent instructions 里。配置面你迟早会碰到的几个选项不管 Provider 还是 Function你基本都会看到这些配置点•Tools挂给 provider 的工具让沙箱里能call_tool(...)•FileMounts给沙箱读写的挂载别乱给能不用就不用•AllowedDomains沙箱允许访问的外网域名 allow list•HostInputDirectory宿主输入目录相关的约束最关键的“工具可见性”差异省心的来源这里是工程上最值钱的一点•工具挂在 Provider 上•模型表面只看到一个execute_code•具体工具在沙箱里用call_tool(...)访问•更容易把 N 次小调用折叠成一次 execute•工具直接挂在 Agent 上•模型把工具当一等公民倾向于逐个调用•每次调用都有单独的 tool message也更适合逐次审批/逐次可见我的建议你可以直接抄先别贪。从 2-3 个只读/纯函数/确定性强的工具开始把最烦的那条链路折叠掉。副作用工具先别塞进去。跑通一条再扩。就这样。适用边界与治理什么时候该用、审批怎么做、哪些坑别踩你读到这儿大概率会问“那我是不是应该把所有工具都塞进 CodeAct”别。说实话这是最容易翻车的地方。1什么时候适合上 CodeAct一句话tool-heavy而且中间态处理多。典型场景•链式查询查 A 再查 B再拼起来•分页/循环拉取要拉多页数据才能收敛•过滤、聚合、排序你以前在 host 里写的那些数据清洗•生成结构化产物一次出表格/JSON/报告骨架这类任务里“前一步的产出是下一步的输入”回合数就是负担。把它折叠进一次execute_code收益最明显。2什么时候不值得折腾•只需要 1-2 次工具调用•回合本来就少CodeAct 可能得不偿失。•强副作用、需要逐次确认•发邮件、付费、写生产库、删数据……•这些你通常希望每一步都可见、可审批。3审批粒度一个很现实的限制文档里明确提到一个当前限制•审批往往是围绕整个execute_code调用做决定•而不是对 code block 里每个call_tool(...)单独审批结论就很朴素•需要逐次审批的工具优先留在 agent 的 direct tool surface•能批量折叠的“安全工具”才放 provider 里给call_tool(...)Hyperlight 文档也给了经验法则把便宜、确定、安全可链式调用的工具放 provider敏感/有副作用的操作要更谨慎必要时保持 direct 调用。4安全治理一句话再次强调•沙箱别乱开网络/文件权限AllowedDomains、FileMounts能少就少•host tools 仍在宿主进程执行权限边界靠你•工具要窄•输入要校验•行为要可审计如果你把一个“万能 HTTP 请求工具”塞给call_tool(...)那你基本等于把宿主权限打包送出去了。别干。收个尾CodeAct 很强但它强在“折叠编排回合数”。不是给你一个更大的自由度去乱跑。就这样。最后回扣主张。CodeAct 真正解决的是“编排回合数”不是“模型会不会”。你不需要换模型也不需要重写工具。你主要是把那条“model→tool→model”的长链折叠成一次execute_code。你接下来最稳的动作我建议你照做一次验证1.挑一条最 tool-heavy 的链路分页/聚合/多次查询那种2.把其中 2-3 个只读/纯工具挂进HyperlightCodeActProvider3.让模型用一次execute_codecall_tool(...)跑完4.副作用工具继续走直连 逐次审批跑通一条你就知道该不该继续扩。就这样下篇文章跟大家详细讲下如何在 MAF 中集成 CodeAct。引入地址