不用框架手写Agent Harness:四小时实战拆解

手写纯Python agent harness,揭开框架隐藏的重试、上下文与护栏决策。
文章指出,Agent框架把工具调用、上下文管理、重试逻辑和安全护栏封装成几行配置,便利的代价是行为不透明——一次工具调用被触发三次,你分不清是模型、框架还是工具注册表在重试;上下文溢出、护栏被绕过时同样难以定位层级。作者主张用纯Python手写一个不依赖框架的AI数据分析师harness,重点构建四个模块:工具注册表(动态发现MCP工具、先验证后执行、权限优先)、上下文管理器(硬token预算、摘要、可展开句柄、分层记忆)、分层护栏管线(在工具结果进入上下文前拦截间接prompt注入)、运行监督器(超时、重试、重规划、预算与结构化追踪)。练习用mock模型和本地数据库即可完成,无需GPU或API key,真正价值在于获得重读任何框架源码时的清晰视角。

当Agent框架出问题时,最让人抓狂的往往不是报错本身,而是你根本不知道是哪一层在做重试、哪个工具返回值把上下文撑爆了、又是哪条护栏规则被绕过。Reddit上一位开发者用一句话点破了这个痛点:框架用起来很爽,直到你读不懂它的行为。
框架的"黑箱"代价
Agent框架把工具调用、上下文管理、重试逻辑、安全护栏都封装成几行配置。这种便利有明确代价。
当你看到一次工具调用被触发了三次,可能是模型自己重试的,可能是框架的retry策略,也可能是你的工具注册表在做幂等处理——三层都有嫌疑,但日志里分不清。上下文溢出同样如此:是工具返回的原始JSON太大,还是摘要策略没生效,还是memory tier配置错了?
这种模糊性在生产环境尤其危险。一个间接prompt注入让agent执行了不该执行的SQL,你翻遍框架文档也找不到是哪一层的护栏漏了。
作者的判断很直接:自己用纯Python写一遍harness,之后再读任何框架的源码,你都能一眼看出它在哪一层做了取舍。
手写Harness要解决的四个核心模块
这场工作坊的核心是构建一个不依赖任何Agent框架的AI数据分析师。四个模块直接对应生产环境最容易出问题的地方。
工具注册表:先验证再执行
工具注册表不只是维护一个函数列表。它需要从真实的MCP服务器动态发现工具、在调用前校验参数、并强制执行权限检查。
顺序很关键:权限在验证之前。很多框架把这两步混在一起,导致一个本该被拒绝的调用先执行了参数解析,消耗了token和时间。
MCP(Model Context Protocol) 是Anthropic提出的一套开放协议,用标准化方式让模型与外部工具、数据源通信。它把工具定义、参数schema、调用结果都规范成统一格式,使不同模型和不同工具服务器可以互操作。所谓"从真实的MCP服务器动态发现工具",指的是agent启动时向MCP服务器请求工具清单,而不是把工具硬编码在代码里。这样做的代价是:工具的参数校验和权限检查必须在运行时完成,因为你事先不知道会拿到什么工具。这也是为什么工具注册表要把"验证"和"权限"放在执行之前——一旦工具来自动态发现,任何未校验的调用都可能触发意料之外的外部动作。
上下文管理器:在硬性token预算内工作
上下文不是"尽量塞",而是有硬预算。这个模块要实现摘要、可展开句柄(expandable handles)和分层记忆(tiered memory)。
可展开句柄是个巧妙设计:大块工具返回结果先存成句柄,只在需要时展开具体内容,避免一次性把上下文填满。分层记忆则区分短期对话和长期知识,各自有不同的淘汰策略。
间接prompt注入(indirect prompt injection) 与普通的用户输入注入不同:恶意指令不是用户直接输入的,而是藏在agent会读取的外部内容里——比如网页、PDF、数据库字段、工具返回的JSON。当这些内容被塞进上下文,模型可能把它们当成指令执行。传统做法是在用户输入处做过滤,但这条防线对间接注入完全无效,因为攻击载荷走的是"数据"通道。有效的拦截点是在工具结果进入上下文之前检查,识别其中是否含有伪装成指令的内容。这也是上下文管理器与护栏管线必须协作的原因:上下文管理器决定什么内容能进来,护栏决定进来的内容是否安全。
护栏管线:分层拦截
单一护栏容易被绕过,所以需要分层。这条管线要覆盖间接prompt注入和不安全SQL两类典型威胁。
间接注入指的是恶意内容藏在工具返回的数据里,而不是用户直接输入的prompt里。传统输入过滤对此无效,必须在工具结果进入上下文前做检查。
运行监督器:超时、重试、重规划、预算与追踪
这是最容易被框架隐藏的一层。运行监督器要处理超时、重试策略、失败后的重新规划、预算控制,以及结构化追踪(structured traces)。
结构化追踪是排障的关键。当agent行为异常时,你能从trace里看到每一步的决策依据,而不是靠猜。
结构化追踪(structured traces) 指以机器可读的结构记录agent运行的每一步:每一步的输入、决策、工具调用、返回值、耗时、消耗的token,以及触发该决策的理由。它和普通日志的区别在于,日志是给人读的流水账,trace是有schema的事件流,可以被程序查询、聚合、回放。当一次工具调用被重试三次,trace能明确告诉你重试发生在哪一层、由什么条件触发。没有trace,排障只能靠print和猜测;有了trace,你可以对比正常与异常运行的差异,定位到具体是哪一层的策略出了偏差。
为什么这个练习值得做一次
作者强调练习可以在笔记本上用mock model和本地数据库完成,不需要GPU或API key。这个设定降低了门槛,也更接近真实开发场景——大多数agent逻辑问题跟模型能力无关,而是harness设计问题。
工作坊由Data For Science创始人Bruno Gonçalves带领,时长四小时。但真正的价值不在于这四小时,而在于你带着"我写过harness"的视角,重新审视现有技术栈时的那种清晰感。
框架不会消失,也不该消失。但至少要知道它替你做了什么决定。
相关推荐

投票权失守之后:美国民主的隐性代价
探讨美国民主党未能通过《约翰·刘易斯投票权促进法案》和《自由投票法案》后,各州限制性投票立法、最高法院削弱《投票权法案》以及党派杰利蝾螈对选民参与和公平代表性的影响。

AI编程Agent最难的不是写代码,而是知道何时该动手
一位开发者分享构建AI编程Agent的经验:最难的不是让模型更聪明,而是让它知道何时直接动手、何时询问确认、何时完全不碰,配合自检沙箱与模型路由实现可控行为。

陶哲轩:AI正将优美数学变成训练废料
陶哲轩批评硅谷用AI强攻数学难题,将优美数学降格为原始训练材料,产生大量缺乏结构美感的证明。本文解析其“有毒废料”比喻背后的数学审美与激励冲突。