Skip to content

Partner Portal Monitoring Agent

本页说明 Partner Portal Monitoring Agent 如何在负责人交互式委托下登录 partner portal,用 Track 对政策、价格表、返点和公告页面建立长期监控,命中变化时带证据通知负责人。读完本页,你能理解登录态监控为什么必须走交互式委托、Profiles 如何让后续巡检复用登录态,以及政策基线为什么进监控存储而不是 Memory。

适用场景

渠道、品牌或市场团队需要监控 partner portal 中的产品标题、图片、价格、库存、促销和描述是否符合要求,同时关注登录后才可见的政策文档、价格表、返点规则和公告。这类页面没有公开 API,人工逐个登录巡检既慢又容易漏掉更新。

典型触发时机:

  • partner portal 发布新的返点规则或价格表,需要在生效前通知渠道负责人。
  • 促销窗口开启前,需要核对多个 portal 中的产品展示是否符合品牌规则。
  • 渠道协议续签前,需要确认 portal 内政策文档相对上一周期有哪些变化。

工程挑战

  • 登录态维护:portal 内容在登录墙后面,会话过期、MFA 和风控页是常态。无人值守监控的成败取决于登录态能否安全复用、失效时能否升级给人而不是静默中断。
  • 变化定级:portal 每天都有例行更新,真正需要上报的是"返点规则改了""政策生效日期提前了"这类实质变化。没有带版本的政策基线,定级只能靠人重读全文。
  • 多 portal 异构:每家 portal 的页面结构、术语和更新方式都不同,基线口径难以统一;一处结构改版就可能让整条监控链路输出噪音。

模块组合

模块角色说明
GenAuth核心portal 登录态属于高风险委托:交互式授权、短时凭证、可撤销、越权留痕,全部由 GenAuth 承担。
Web Agent核心Profiles 保存并复用已授权的登录态;Track 维护长期 monitor,按 schedule 取数比对并回调通知。
GUMem可选仅保存负责人确认的长期风险偏好(例如"返点类变化一律升级")。政策与价格基线是业务状态,进监控基线存储按版本管理,不进 Memory。

Partner Portal Monitoring Agent 场景架构

权限与委托边界

Agent 本身不持有任何固有权限。每次监控任务的实际权限是三个集合的交集:用户真实权限 ∩ 显式委托范围 ∩ 企业批准边界。落到这个场景:

  • 委托范围只覆盖"读取指定 partner portal 的政策、价格、返点、公告和商品展示页面",不包含下单、改价、修改商品信息或联系 partner。
  • portal 登录属于高风险操作,必须走 mode: 'interactive':负责人在 Qoni Console 确认授权,凭证在服务端回调中兑换,不暴露给浏览器。
  • 委托凭证短时效;长期监控依靠按计划重新签发凭证,而不是一张长期有效的凭证。
  • 越权尝试(例如访问委托范围外的订单管理页面)会被拒绝并留痕——审计链覆盖全部尝试,不只是成功行为。

注意:SDK 示例申请的是产品级 scope(如 webagent.do_anything:read)。portal 域名、页面范围和动作白名单这类细粒度边界由 GenAuth 的 Agent Profile 或策略层配置强制执行,不由任务 prompt 承担;本页示例未展示该配置。完整语义见 Delegate Token 与缩权

工作流程

Partner Portal Monitoring Agent 工作流程

  1. 负责人选择 partner、portal、页面范围和通知渠道。

  2. 应用发起交互式委托;负责人在 Qoni Console 确认授权,服务端回调兑换凭证。

  3. 应用创建 Track monitor;首轮运行打开 portal,负责人在受控会话中完成登录,登录态由 Profiles 保存供后续 tick 复用。

    检查点:登录墙、MFA 或风控页出现时升级给人处理,不静默绕过。

  4. 首轮取数建立政策、价格表、返点和公告页面的基线;基线连同规则版本写入监控基线存储。

  5. 之后每次按 schedule 运行,Track 抓取当前页面并与基线比对;变没变由规则判定,不由模型措辞决定。

  6. 命中变化时,Track 回调你的应用:变化字段、截图证据和来源 URL 构成变化记录。

  7. 应用按政策基线为变化定级(可选:结合负责人确认过的风险偏好),推送异常、证据、建议动作和 audit id 给负责人。

    检查点:每条异常都应能回溯到具体页面截图和来源 URL;无证据支撑的变化判断不应进入通知。

示例代码

下面的示例使用官方 Qoni SDK@qoniai/qoni)接入这个场景:交互式委托(完整 callback)→ 从监控基线存储读取带版本的政策基线 → 创建 Track monitor 建立长期监控。

ts
import { Qoni, QoniScopes } from '@qoniai/qoni'

const qoni = new Qoni({
  accessKey: process.env.QONI_ACCESS_KEY!,
  secretKey: process.env.QONI_SECRET_KEY!,
})

// 1. 入口:发起交互式委托——涉及 portal 登录态,让负责人在 Qoni Console 确认授权
export async function startPortalMonitoring(ownerId: string, portalPages: string[]) {
  // 任务参数存应用存储,state 只放任务 ID,回调时按 ID 取回
  const taskId = await taskStore.save({ portalPages })
  const { data: authorization } = await qoni.delegateToken({
    mode: 'interactive',
    agent: 'partner-portal-monitoring',
    scopes: [QoniScopes.DO_ANYTHING_READ], // 登录巡检所需的产品级只读 scope
    redirectUri: 'https://app.example.com/qoni/callback',
    state: taskId,
    user: { id: ownerId },
    expiresIn: 900, // 秒;长期监控按计划重新签发,而不是延长有效期
  })
  redirectUserTo(authorization.authorizationUrl)
}

// 2. 负责人同意后,在服务端回调中兑换委托令牌,并继续创建监控
export async function handleQoniCallback(request: Request) {
  const query = new URL(request.url).searchParams
  const { data: grant } = await qoni.completeDelegateToken({
    grantId: query.get('grantId')!,
    code: query.get('code')!,
    state: query.get('state')!,
  })
  // 按 state 里的任务 ID 取回 startPortalMonitoring 存下的页面清单
  const { portalPages } = await taskStore.load(query.get('state')!)
  return createPortalMonitor(grant, portalPages) // grant.token 只保存在服务端
}

回调中拿到 grant 后调用 createPortalMonitor 建立监控。登录态由 Profiles 在首轮登录后保存,后续 tick 复用,不需要每轮重新登录。

Draft interface

统一 SDK 的 Track 接口签名尚未定稿,下面的示例只表达集成意图;Track 的产品语义见 Track

ts
// Track 所需 scope 以正式签名为准(Draft interface);此处沿用产品级只读 scope 示意
export async function createPortalMonitor(
  grant: { token: string; auditId: string; grantedScopes: string[] },
  portalPages: string[],
) {
  // 3. 创建前:从监控基线存储读取当前版本的政策基线(不是 Memory)
  const baseline = await loadPortalPolicyBaseline() // 例如 { version: '2026-Q3', watchedPages: [...], escalation: ... }

  // 4. 创建长期 monitor:首轮登录建立基线,之后按 schedule 反复比对
  //    (登录态复用字段以 Track 正式签名为准,此处不展示)
  const { data: monitor } = await qoni.track.create({
    token: grant.token,
    intent: `
      Watch these partner portal pages for policy, price list, rebate and
      announcement changes: ${portalPages.join(', ')}.
      Report only substantive changes with the changed fields, a screenshot
      and the source URL. Read only: never place orders, change prices,
      edit listings or contact partners.

      Policy baseline (version ${baseline.version}):
      ${JSON.stringify(baseline)}
    `,
    schedule: { kind: 'interval', intervalSeconds: 3600 },
    notify: { kind: 'callback_url', url: 'https://app.example.com/hooks/portal-track' },
  })

  await saveMonitorRef(monitor.id, { baselineVersion: baseline.version })

  // 促销冻结期或 portal 维护期间暂停调度,结束后恢复
  await qoni.track.pause(monitor.id, { token: grant.token })
  await qoni.track.resume(monitor.id, { token: grant.token })
}

命中变化时 Track 回调你的应用:解析变化记录,丢弃没有截图或来源 URL 的条目,把新基线连同版本号写入监控基线存储,再按定级规则通知负责人。若团队使用 GUMem 保存负责人确认过的风险偏好,由你的应用在定级时读取注入;偏好写入必须先经负责人确认。

数据与记忆边界

这个场景涉及四类数据,只有最后一类可选地属于 GUMem:

  • 版本化规则:政策基线、监控页面清单、定级与升级规则——放在监控基线存储里按版本管理,每条通知引用基线版本号。
  • 业务状态:页面快照、变化记录、截图证据——由 Track 的 run 记录和你的监控存储承载,可回放。
  • 审计记录:交互式授权、每次取数与越权拒绝构成的行为链——由 GenAuth 维护。
  • 用户 Memory(可选):负责人确认的长期风险偏好(例如"返点类变化一律升级")——这才是 GUMem 的位置;政策与价格基线不进 Memory。

失败处理

情况推荐处理
登录态失效monitor 发出需要人介入的信号(intervene);负责人重新登录后继续,这是无人值守监控闭环的关键。
portal 页面结构改版导致比对失败按失败处理并回放该次 run,人工确认后重建基线,不输出无证据的变化结论。
委托范围外的页面请求直接拒绝并记录,事后可在审计链中查到未遂访问。
回调条目缺少截图或来源应用侧校验直接丢弃该条目并记录丢弃数量;无证据不通知。

生产注意点

Agent 不应下单、改价、修改商品信息或联系 partner;输出应作为 review report,由负责人决定后续动作。监控只读、只通知,不代替人执行任何变更。schedule 间隔应结合 portal 更新频率设置下限,避免对目标站点造成压力;委托撤销后 monitor 的下一次取数会立即失败,这是预期行为而不是故障。

下一步

  • 阅读 Track 了解 monitor 的完整生命周期与事件流。
  • 阅读 快速开始 跑通 Agent 身份与委托的最短路径。
  • 继续查看 供应商监控 Agent 了解公开页监控的相邻场景。