← 返回信息流
技术博客Hugging Face Blog·1 小时前

Shippy项目教我们如何构建智能体

原标题:What building Shippy taught us about building agents

速览

本文回顾了构建Shippy智能体过程中的经验教训,包括设计决策、常见错误和架构选择。这些经验有助于开发者避免陷阱,提升智能体的可靠性、可扩展性和实用性。项目团队分享了从原型到生产环境的实践总结,对AI agent开发具有直接指导意义。

AI 深度解读

背景

在海洋保护这类高风险的运作领域构建 AI agent,首先面临的是可靠性问题。对于海事分析师而言,一个错误答案可能让巡逻船驶错数海里,消耗本就紧张的资源,甚至危及人员安全。Skylight 团队(一个为政府机构和 NGO 提供实时海上态势感知的平台)在构建其 AI agent Shippy 时发现,真正的工作并不在模型本身,而在于构建一个可信任的系统——它必须正确、能保持在自身能力边界内、并能处理广泛任务。而且,所有验证都必须在 Skylight 的实时数据上进行,这些数据随新卫星和船舶信号不断更新,而非静态快照。

核心内容

Agent 架构:灵魂、技能与配置

Shippy 的架构被拆分为三个部分:

  • 灵魂(Soul):系统提示,定义 Shippy 的人设并设定行为边界。
  • 技能(Skills):告诉 Shippy 如何处理特定类型的请求。
  • 配置(Config):涵盖其他所有内容——运行哪个 agent 框架(目前是 OpenClaw,一个开源 agent 框架)、使用哪个 LLM(目前是 Claude Opus 4.6)、运行时设置等。API 密钥等机密在运行时注入;更换模型或框架只需修改配置,无需重建。

灵魂与技能一起被打包成 Docker 镜像——一个版本化、可部署的制品,定义了 Shippy 的本质。技能遵循与 Claude Code、Codex 等编码工具相同的 agent-skills 规范——即带有结构化 frontmatter 的纯 Markdown 文件,使每个技能易于理解、版本化和修改。

Shippy 当前包含以下技能:

  • 查询 Skylight API 获取 Events(Skylight 识别出的船舶行为,如捕鱼或两船之间的转运)和船舶数据
  • 查找专属经济区(EEZ)和海洋保护区(MPA)边界
  • 解释船舶轨迹数据(船只广播的位置和运动信号),基于 Skylight 模型(包括 Atlantes)已生成的活动分类
  • 生成可交互的地图链接,让分析师从 Shippy 聊天回答直接跳转到 Skylight 地图上的确切位置

例如,Skylight API 查询技能编码了回答特定区域问题的完整工作流。当分析师或用户问“显示上个月巴拿马 EEZ 内的捕鱼活动”时,技能指令引导 Shippy 首先通过 Skylight 的区域 API 将“巴拿马 EEZ”解析为边界多边形(而非猜测或硬编码坐标),然后在该几何体内查询 Fishing Events,将结果格式化为带有返回 Skylight 地图的深层链接,并标注从 Skylight 合作伙伴(如 Global Fishing Watch 或 TMT)获取的任何船舶元数据。

一个问题可能同时调用多个技能。例如“是否有船舶在 Cordillera de Coiba MPA 附近作业?”会使用 Skylight 技能进行数据查询、合作伙伴 ProtectedSeas 的数据库获取 MPA 边界上下文,以及船舶轨迹技能解释船舶行为。所有这些都在一个对话轮次中完成。

灵魂定义了 Shippy 会做什么、不会做什么。它不会对船舶是否违法做出法律判定——这应由人类决策,而非 agent。它也不会在数据支持的范围之外进行推测。这些边界在系统提示中明确写出,而非隐含于微调中,因此可审计且易于修改。

为不确定的 Agent 提供确定性的工具

Agent 是非确定性的。你无法控制模型决定做什么,但可以让它调用的工具变得可预测。为此,Shippy 通过一个专为调用 API 构建的 CLI 与 Skylight “对话”,而不是自己发出原始 API 调用。

Skylight API 有几十种输入类型、嵌套过滤器对象、分页游标和复杂几何输入。早期原型中,团队让 Shippy 从头构造 API 调用,结果产生了大量细微错误:格式错误的分页静默丢弃结果、几何编码错误,以及因误解过滤器类型而返回错误数据的看似正确的查询。

Skylight CLI 将这些复杂性压缩成可预测的接口。Shippy 发出单一命令 skylight events search 并带上类型化的过滤器标志,CLI 则处理认证、分页和结构化输出。CLI 还是自文档化的:详尽的 --help 文本和详细的错误信息为 agent(以及人类开发者)提供了足够上下文,使其无需猜测即可从错误中恢复。其输出始终写入本地 JSON 文件,而非通过 shell 管道传递。早期大结果集会遇到管道缓冲区限制或破坏下游工具(如 jq)。写入磁盘避免了这两个问题,并让 agent 能在后续步骤中程序化访问查询结果。

CLI 之下是标准化的 API:多种资源类型(Skylight Events、船舶、区域、卫星图像、船舶轨迹等)通过一对通用操作(search 和 aggregate)访问。API 的输入和输出被定义为带有字段级描述的 typed schemas。

这种分层——类型化 API、确定性 CLI、引用 CLI 命令的 agent 技能——意味着 Shippy 的每个组件都可以独立测试。API 有自己的测试套件;CLI 可由人类或 agent 使用;agent 技能引用处理烦琐工作的 CLI 命令,这样 Shippy 每次调用 Skylight API 时就不必重新发明轮子。每一层都缩小了下一层可能出错的范围。

沙盒托管与隔离

Skylight 服务于 70 多个国家的数百家政府机构和 NGO。例如菲律宾的一名渔业官员有自己的关注区域、船舶观察列表和告警配置,这些都与他们的 Skylight 账户绑定。当他们向 Shippy 提问时,agent 的 API 调用需要返回他们的数据,且其对话历史绝不能对其他人可见。

每个用户都在自己的临时、隔离会话中与 Shippy 对话。让这个机制在大规模下可靠工作是该项目最重大的工程之一。团队构建了 Mothership,一个 agent 托管平台,为每个用户会话提供专用的 Kubernetes 部署。当用户打开对话时,系统启动一组 Pod,打包 agent 运行时、技能和 Skylight CLI。用户的 Skylight JWT 在预置时注入,这样 agent 的 API 调用就限定在该用户的数据范围内。agent 在多步分析过程中写入的文件仅存在于该会话中,绝不会跨用户共享。沙盒内部,agent 可以编写并运行代码、安装依赖、拉取数据集并完成多步分析。在网络层面,沙盒仅限访问所需的服务。

评估 Agent 而非模型

大多数基准测试用静态问题评估通用 AI。它们无法捕捉 agent 接入真实工作流后的行为:如何选择工具、如何查询实时数据、如何对结果采取行动、以及如何知道何时停止。因此团队围绕 Shippy 的实际工作方式构建了自身的评估系统,对整个 agent(模型、技能和沙盒)在实时数据上进行评分。

在评估框架中,领域专家编写场景和评分规则,选择每个任务适用的标准并设置权重,确保每个任务都根据实际重要的方面进行评分。例如,一个捕鱼事件查询任务将数据准确性作为最高权重,接下来是边界解析和时间范围,最后是来源归因。

(原文在评分细则部分被截断,但其核心思想已完整传达)

关键要点

  • Agent 的三元架构:将 agent 拆分为灵魂(系统提示)、技能(结构化 Markdown 文件)和配置(框架、模型、运行时),使行为可审计、技能可版本化、配置可热更新。
  • 确定性 CLI 作为中介:通过构建专门的 CLI 抽象复杂 API,让 agent 使用简谐、类型化的命令,而非直接构造 API 调用,从而大幅减少细微错误。
  • 分层独立测试:API、CLI、技能三层各司其职,每层都可独立测试,缩小下一层可能出错的范围。
  • 每个用户隔离的沙盒会话:使用 Kubernetes 为每个用户会话启动临时 Pod,注入用户身份令牌(JWT),确保数据隔离和网络限制。
  • Agent 级别的评估体系:不依赖静态基准,而是由领域专家编写真实场景和加权评分规则,在实时数据上评估整个 agent(模型+技能+沙盒)的表现。
  • 行为边界明确写在系统提示中:Shippy 不会做法律判定,不会在数据之外推测,这些边界不是隐含在微调中,而是
查看原文 →huggingface.co