关于 puda-edge
puda-edge 是用于构建 PUDA 边缘服务的 Python 技能,可封装机器硬件并通过 NATS 暴露类型化命令。它涵盖 SDK/API 与 GUI 实现,以及配置、安全上下文和验证流程。
主要功能
- 01SDK/API 与 GUI 边缘服务指南
- 02类型化且有文档的机器命令
- 03命令安全提示元数据
- 04配置与遥测指南
- 05离线及硬件验证步骤
适用场景
- 01为仪器 SDK 构建 Python 封装
- 02通过 NATS 暴露 GUI 机器工作流
- 03为 Agent 记录安全机器操作
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ pudap/ skills --skill puda-edge安装后在 Claude Code 中输入/puda-edge确认已加载。
附带文件references/gui-edge.md
详细介绍
Puda Edge
帮助编写 Python 边缘服务:连接到 NATS 并公开机器命令的轻量级硬件封装。
构建边缘服务
条件合适时,使用现有的机器 SDK/API。对于通过桌面软件操作的仪器,构建 GUI 边缘服务:AI 使用手册或屏幕截图及任务说明,编写针对特定机器的 Python 工作流,再由 PUDA 通过 NATS 公开这些工作流。
有关 GUI 工作,请阅读 references/gui-edge.md。从 GitHub 克隆 PUDAP/edge-python-gui-template 作为脚手架,并参考 PUDAP/opentrons-gui-edge 作为完整示例。本指南介绍如何将任务说明转换为确定性的 GUI 命令并对其进行验证。有厂商 PDF 手册时,请使用手册。没有手册时,展示点击位置、输入内容和预期结果的屏幕截图也可作为原子命令的有效上下文。如果条件允许,可通过实时截图补充上述任一来源。
对于 SDK/API 和 GUI 边缘服务:
- 在搭建脚手架之前,检查所选模板的依赖项和 SDK 契约。GUI 示例使用
from puda import EdgeNatsClient, EdgeRunner, command。 - 机器命令应具有类型、与 JSON 兼容,并记录参数、单位、默认值、前置条件、返回的证据和失败情况。使用
@command公开预期工作流。对于 GUI 边缘服务,capture_screenshot是唯一的底层远程命令;使用继承的 GUI 助手函数在内部实现高级工作流。 - 通过设置和
.env.example配置机器标识、NATS 服务以及连接/窗口详情。保留模板的生命周期和清理逻辑。不要从其他机器复制凭据或可用的.env。 - 在桌面或硬件验证之前,先离线验证命令。分别报告已实现的内容、使用固定数据测试的内容、在桌面上观察到的情况,以及在硬件上实际运行的内容。
按照 Integrating a New Machine 了解仓库布局、main.py 配置、遥测和多机器 PC。对于 SDK/API 边缘服务,使用 edge-python-template 搭建脚手架;对于 GUI 边缘服务,使用上面的 GUI 模板。仓库命名为 puda-<machine_id>-edge。
仅使用 Python。有关主机/NATS/硬件的调试配置,请使用 puda-deployment。命令正常工作后,使用 puda 安装 CLI。
搭建脚手架
- 从模板创建仓库。解决所有
TODO。 - 在
.env中设置唯一的、小写并以连字符分隔的MACHINE_ID,以及NATS_SERVERS。 - 实现
driver.py,然后在main.py中接入配置和驱动程序。 - 将助手函数设为私有(
_name)。只有@command方法会被公开。
边缘服务连接后,使用 puda machine commands <machine_id> 进行验证。
同一台 PC 上的多台仪器可以共用一个 uv 工作区;每个子目录都应有自己的 MACHINE_ID、driver.py 和 main.py。请参阅文档和 PUDAP/ViPSA。
驱动程序
driver.py 是硬件 API 的轻量封装。方法名、文档字符串、参数和返回注解构成 Agent 看到的命令接口。在 Driver 类的文档字符串中添加一句话摘要;EdgeRunner 会在 puda machine list 和 puda machine ping 中展示第一段内容,这样 Agent 无需运行 puda machine commands 就能了解机器的用途。
- 使用
@command装饰每个可远程调用的方法。未装饰的公共方法不会通过 NATS 发布或调用。没有任何@command方法的驱动程序会在启动时失败。 - 保持命令的原子性:每个方法只执行一项硬件操作。
- 参数必须是基本类型(
str、int、float、bool)或由基本类型组成的简单列表/字典。 - 在每个公共方法的文档字符串中说明参数、返回值和引发的错误;这些内容会为 Agent 提供上下文。
- 失败时抛出异常,并包含命令、目标和硬件响应。返回
False仍会被视为 PUDA 调用成功({"result": false})。 shutdown、home和reset均为可选方法。边缘端停止前会运行shutdown。运行puda machine home会触发home。puda machine reset总会清除活动的run_id,然后在存在reset方法时调用它。
from puda import command, safety
class Driver:
"""Software-only PUDA test machine. Commands are simulated in memory; no hardware is required."""
@command
def shutdown(self) -> bool:
"""Release hardware resources. If defined, called before the edge stops."""
...
@command
def home(self) -> bool:
"""Home the machine. If defined, triggered by `puda machine home <machine_id>`."""
...
@command
def reset(self) -> bool:
"""Software reset. Optional. `puda machine reset` clears the run first, then calls this if present."""
...
@command
def move_to(self, x_mm: float, y_mm: float, z_mm: float) -> bool:
"""
Move the machine head to an absolute position.
Args:
x_mm: Target X position in millimeters.
y_mm: Target Y position in millimeters.
z_mm: Target Z position in millimeters.
Raises:
RuntimeError: If the hardware rejects the move.
"""
result = self._hardware.move_to(x_mm=x_mm, y_mm=y_mm, z_mm=z_mm)
if not result.ok:
raise RuntimeError(
"Failed to move machine head "
f"to x={x_mm}, y={y_mm}, z={z_mm}: {result.error}"
)
return True
@safety
将 @safety 附加到 @command 方法,以便在命令目录中发布提示性上下文。它不会阻止边缘端分发命令。不带 @command 的 @safety 会被忽略。
这五个字段都必须仅作为关键字参数传入。不要添加其他字段。
| 字段 | 必填 | 作用 |
|---|---|---|
summary | 是 | 风险概述 |
hazards | 否 | 简短标签,例如 collision、thermal |
requires | 否 | 前置条件;Agent 会插入前置步骤或先询问 |
forbidden_when | 否 | 不得使用该命令的情形 |
confirm | 否 | 操作者输入 yes 的确认门槛。默认为 false。设为 true 即启用 |
不要在多个字段中重复同一句话。summary 说明风险;requires 指明前置条件;forbidden_when 说明禁止条件;confirm=True 表示需要确认。不要在 summary 中写“confirm…”。
@command
@safety(
summary="Collision risk from unhomed motion or an occupied workspace.",
hazards=["collision"],
requires="Machine must just have been homed.",
forbidden_when="Do not move if the workspace is occupied or human movement is detected.",
confirm=True,
)
def move_to(self, x: float, y: float, z: float) -> dict:
...
对于只读或无害的命令(get_position、echo),不要添加 @safety。对于运动、化学品混合、加热、加压或其他不可逆的硬件操作,请使用 confirm=True。
配置
在 .env 中保留 MACHINE_ID 和 NATS_SERVERS。在 main.py 的 Config 中添加带类型的硬件字段,以便缺少值时能在启动时失败。将这些字段传入 Driver(...)。
遥测数据必须可序列化为 JSON。发布心跳,以及机器实际具备的位置信息、健康状况和状态。字段名应与硬件相符(如关节、柱塞、焦点),不要使用笛卡尔模板。
远程更新
puda machine update
使用前,请运行 puda machine update --help,查看已安装 CLI 的目标指定和更新选项。