easynet.run · 全部问题场景

这个领域摸索了几年,最后把 Skill 打包卖了 6000 块?

假设你帮跨境商家做了几年商品上架检查:哪些字段容易漏、标题与规格怎么核对、缺少什么资料时必须问供应商,你都整理进了 Skill。有人愿意出 6000 块买走这套文件。这里的 6000 块是一个假设报价,不是客户成交记录。真正要决定的是:这次交付一份方法,还是长期提供检查服务?

买断并不一定吃亏。客户想离线运行、自己修改,你也不打算负责维护,卖文件很合理。但另一类客户只想把今天的商品交过来,明天规则变了也有人更新。他们不想研究怎么装 Skill、选模型、调提示词。对这类客户,你可以卖每次可用的检查结果,而不只是第一次下载。

把场景缩到一只旅行杯:商品 CUP-17 的标题写着 500 ml,规格表却填了 350 ml,材质一栏还是空的。服务返回两条待办:向供应商确认容量后统一标题和规格;补齐材质,不让 AI 猜。客户可以在上架前批量调用检查,也可以让自己的 Agent 在整理商品时调用。本文附件只实现这两个自定义检查,不检查图片,也不代表任何平台的完整审核规则。

已经有网站和 Flask 或 FastAPI 接口,客户也只从网页提交资料?继续用它们就可以。MCP 同样可以把这个检查暴露给兼容的助手。考虑 EasyNet 的理由不是 Flask 不能做生意,而是你还希望同一项检查进入多个 Agent 的工作流,并通过明确的调用入口管理谁能使用。发现范围、MCP 接入和调用权限仍要实际配置,不能把“发布了”当作所有助手都会自动找到。

先运行附件 listing_check.py 看清楚输入输出。然后看 provider.py:在函数上加 @node.register,review_listing 内部仍调用已有检查逻辑。真实 Skill 需要由你已有的 Agent 或模型执行器加载;保留那份执行环境,把函数内部换成受限的检查流程即可。装饰器负责函数级接入,不会把 Markdown 自动变成可靠服务,更不会顺带实现支付。

如果客户从你的网站购买并使用,网站后端先确认登录身份、订阅是否有效和剩余额度,再调用检查函数。后端共用一个 Runtime 服务身份时,Runtime 看到的是这个服务,并不会自动区分每一位付费客户。如果让客户 Agent 直接调用,就需要把它的实际身份接到授权流程,并验证未获准的调用者会被拒绝、撤权后不能再调用。

收费也要落到可核对的一件事:例如“成功交付一份检查报告算一次”,而不是按 HTTP 重试次数收费。给客户请求一个唯一编号,重复提交返回同一份报告;失败释放预占额度;执行结果未知时先查任务,不立刻扣第二次钱。订阅、支付回调验签、额度账本和退款由你的产品与支付系统实现。EasyNet 的调用记录不能直接当结算账单。

这项服务值得续费,靠的是漏检是否减少、规则有没有持续更新、结果是否能接进客户原来的工作。先拿一批获准使用的历史样本,与人工结果对照,再让一个试用客户走完提交、收到报告和取消访问。Skill 留在服务端能避免直接分发原文件,但输出仍可能暴露方法;不要许诺绝对防复制。卖一次文件,还是持续交付一项专业服务——这才是用 EasyNet 尝试新一代 SaaS 时要验证的选择。

  1. 01

    客户提交 CUP-17

    标题 500 ml · 规格 350 ml · 材质缺失

  2. 02

    核对权益,再执行

    产品检查订阅;提供方运行既有方法

  3. 03

    返回两项待办

    确认容量 · 补充材质;成功交付后记账

交付报告,不分发 Skill 文件。下图是服务设计示意,不是成交实录。

先运行一次商品检查

运行 python3 -B listing_check.py。只检查两个自定义条件,不调用模型或网络。

本地示例 · python
"""Local, fictional merchant checklist; not marketplace policy or an AI run."""
import json
import re

def check_listing(listing: dict) -> dict:
    for field in ("sku", "title", "material", "capacity_ml"):
        if field not in listing:
            raise ValueError(f"Missing field: {field}")
    if not all(isinstance(listing[k], str) for k in ("sku", "title", "material")):
        raise ValueError("sku, title and material must be text")
    if not listing["sku"].strip() or len(listing["title"]) > 200:
        raise ValueError("Invalid SKU or title")
    if type(listing["capacity_ml"]) is not int or listing["capacity_ml"] <= 0:
        raise ValueError("capacity_ml must be a positive integer")
    issues = []
    if not listing["material"].strip():
        issues.append({"field": "material", "reason": "Material is missing",
                       "action": "Ask the supplier; do not invent it"})
    # Demo supports one whole-number ml quantity, not packs, decimals or other units.
    capacities = re.findall(r"(?<![\w.,])(\d+)\s*ml\b", listing["title"], re.IGNORECASE)
    if len(capacities) > 1:
        raise ValueError("Multiple title capacities need manual review")
    if capacities and listing["capacity_ml"] != int(capacities[0]):
        issues.append({"field": "capacity_ml", "reason": f"Title says {capacities[0]} ml but specification differs",
                       "action": "Confirm capacity and update both fields"})
    return {"sku": listing["sku"], "rules_version": "demo-1",
            "issues": issues, "needs_review": bool(issues)}

if __name__ == "__main__":
    print(json.dumps(check_listing({"sku": "CUP-17", "title": "500 ml travel cup",
                                   "material": "", "capacity_ml": 350}), indent=2))

预期结果:CUP-17:两项问题;needs_review 为 true,规则版本 demo-1。

用装饰器接入已有函数

接入示例:需另行配置 Runtime 和调用权限,装饰器不处理付款或订阅。

本地示例 · python
"""Integration adapter; configure Runtime and caller authorization before serving."""
from easyremote import ComputeNode
from listing_check import check_listing

node = ComputeNode(namespace="listing_review")

@node.register
def review_listing(listing: dict) -> dict:
    return check_listing(listing)

if __name__ == "__main__":
    node.serve()

预期结果:获准调用返回相同结构;跨调用方验证需在真实环境完成。

把实施说明交给你的 Agent

从本地样例走到真实 Skill、客户授权和测试支付;未验证的环节逐项记录。

阅读完整交接任务
# Build a paid listing-review service, not a downloadable Skill bundle

Start with this page's listing_check.py, test_listing_check.py and provider.py attachments in a new directory.
Do not overwrite an existing project. Ask for the directory and serving environment if unknown.

1. Run python3 -B -m unittest -v test_listing_check.py, then python3 -B listing_check.py.
   CUP-17 must return two issues: missing material and
   conflicting capacity. Confirm a nonempty material with capacity 500 returns no issues.
   Confirm missing fields, invalid types and nonpositive capacity fail.
   These are fictional merchant rules, not marketplace compliance checks.
   Capacity extraction only covers one whole-number ml quantity in the title;
   decimals, other units and pack sizes need a separate reviewed implementation.
2. Ask the owner for their existing Skill, approved examples, model runner and data policy.
   Never pretend a Markdown Skill executes itself. Keep the Skill, credentials and
   runner on the provider. Replace the deterministic checker only with an explicit,
   bounded runner, validated JSON output and a timeout. Do not upload customer data
   or start paid model calls without permission.
3. Inspect installed EasyRemote / EasyNet documentation and CLI help. provider.py shows
   function-level registration, not a complete commercial deployment. Configure the
   Runtime and discover the actual published descriptor and address; never invent them.
   Start serving only with the owner's approval.
4. Choose web access or direct Agent access. For a web backend calling under one
   service identity, Runtime does not automatically know the paying customer.
   The backend must authenticate the customer and enforce their entitlement before
   invoking the provider. For distinct Agent identities, verify the actual caller
   grant and revocation with separate authorized and unauthorized callers.
5. Use a payment provider's test mode. Verify webhook signatures server-side.
   Store subscription state and usage in the product database. Define one billable
   unit as one successfully delivered report; use a unique customer/request key,
   reserve capacity atomically, release it on failure, and reconcile unknown outcomes
   before retrying. A Runtime receipt is not a payment settlement or invoice.
6. Test duplicate requests/webhooks, cancelled subscriptions, quota exhaustion,
   provider timeout and another customer's report URL. None should double-charge
   or leak reports. Do not implement in-memory sample dictionaries as production billing.
7. Deliver the diagram, source, local test output, remaining integration work and
   exact evidence of any real authorized/denied calls separately. Do not claim an
   end-to-end sale based on the local checker. No production payment, deployment,
   customer email, model call or deletion without explicit authorization.

Keep internal rules out of customer responses, but do not promise that prompts or
methods cannot be inferred from outputs. Record report version and human review needs.
接入时的检查项
  • CUP-17 返回材质缺失与容量冲突,修改为非空材质和 500 ml 后返回零问题。
  • 未经授权和撤权后的调用均不能取得报告,客户不能读取他人的产物。
  • 重复请求不重复扣费,未知执行结果先核对,不把模拟检查误称实际成交。
源码与接入资料