Skip to content

本地化 Messaging Agent

本页说明本地化 Messaging Agent 如何在交互式委托下读取源 campaign 和区域市场页面实况,对照版本化的术语表与禁译词逐市场核对 messaging 一致性,并以事件流形式返回巡检进度和差异清单。读完本页,你能理解这个场景需要哪些模块、逐市场巡检的进度如何流式返回,以及术语表这类数据为什么应该放在本地化配置库而不是 Memory。

适用场景

国际化 marketing 团队需要把 campaign、landing page 或广告文案改写成适合目标地区的版本,并核对已上线的多语言页面是否与源 messaging 保持一致。区域页面由本地团队各自维护,术语翻译漂移、禁译词误用和源文案更新后的滞后很难靠人工逐市场发现。

典型触发时机:

  • 源 campaign 文案更新后,需要核对各语言市场页面是否同步。
  • 进入新市场前,需要对照当地竞品和市场惯例校准 messaging。
  • 术语表或禁译词更新后,需要排查各区域页面的存量翻译。

工程挑战

  • 多市场 × 多页面的核对量随市场数线性增长:每个市场都要抽取实况文案、对照术语表逐条比对,串行人工核对在源文案更新后的时间窗口内根本做不完,而巡检进行到哪、卡在哪个市场需要实时可见。
  • 差异判定依赖版本化规则:术语表和禁译词更新频繁,一条差异是"真漂移"还是"依据了旧版术语表"必须可追溯到规则版本,否则当地 reviewer 无法复核。
  • 借用员工账号读取区域 workspace 权限过宽:借来的登录态能看到全部市场的 campaign 资料,而单次核对只需要指定源文案和目标区域的只读访问。

模块组合

模块角色说明
GenAuth核心区域 workspace 与 campaign 资料的只读委托、撤销与审计链;发布译文和修改页面留在委托范围之外。
Web Agent核心受控会话逐市场抽取当地已上线页面的实况文案,保留来源 URL 与截图,并查询当地竞品页面作措辞对照。
GUMem不使用术语表、禁译词属于版本化规则,放在你的本地化配置库里按版本注入;差异清单与 reviewer 决策属于业务状态,归档到你的本地化记录——都不属于 Memory。

本地化 Messaging Agent 场景架构

权限与委托边界

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

  • 委托范围只覆盖"读取指定 campaign 资料、区域 workspace 和当地公开页面",不包含发布译文、修改区域页面或改动术语表。
  • 委托凭证短时效,单次核对任务建议分钟级有效期,过期后需重新委托。
  • 用户或管理员可随时撤销授权;撤销后新的资料读取请求立即失败。
  • 越权尝试(例如读取委托范围外的其他市场 workspace)会被拒绝并留痕——审计链覆盖全部尝试,不只是成功行为。

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

工作流程

本地化 Messaging Agent 工作流程

  1. 用户选择源文案、目标地区和要核对的当地页面清单。

  2. GenAuth 发起交互式委托;用户在 Qoni Console 确认后,服务端回调兑换出最小权限的只读凭证。

  3. 应用从本地化配置库读取当前版本的术语表、禁译词和区域措辞规范,注入任务描述。

  4. Web Agent 逐市场抽取当地已上线页面的实况文案,保留来源 URL 与截图;巡检进度以事件流实时返回。

    检查点:区域 workspace 或当地页面遇到登录墙、验证码或风控页时,Web Agent 应升级给人处理,而不是静默绕过。

  5. Web Agent 查询当地竞品和公开市场资料,补充措辞惯例对照。

  6. Agent 对照源 messaging、术语表和禁译词逐条比对当地页面,标注翻译漂移、禁译词误用和滞后未同步项,每条附页面来源和依据的规则版本。

  7. Agent 输出本地化差异清单、修正建议草稿、改写理由和来源,附 audit id;应用侧校验后交当地 reviewer 确认。

    检查点:每条差异和建议都应能回溯到具体页面来源或术语表条目;无来源支撑的结论不应进入交付物。

示例代码

下面的示例使用官方 Qoni SDK@qoniai/qoni)把这个场景接到你的服务端:交互式委托(完整 callback)→ 从本地化配置库读取术语表 → 一次 doAnything.run() 完成多市场核对,用 run.events() 事件流实时转发逐市场巡检进度 → 解析并校验差异清单。

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

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

export async function startLocaleCheck(userId: string, taskId: string) {
  // 1. 交互式委托:涉及区域 workspace 登录,让用户在 Qoni Console 确认授权
  const { data: authorization } = await qoni.delegateToken({
    mode: 'interactive',
    agent: 'localization-messaging',
    scopes: [QoniScopes.DO_ANYTHING_READ, QoniScopes.DO_ANYTHING_MANAGE],
    redirectUri: 'https://app.example.com/qoni/callback',
    state: taskId,
    user: { id: userId },
    expiresIn: 900, // 单次核对任务给分钟级有效期
  })
  redirectUserTo(authorization.authorizationUrl)
}

// GET /qoni/callback —— 用户同意后在服务端兑换 grant,继续执行任务
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')!,
  })
  const task = await loadLocaleCheckTask(query.get('state')!) // 你的任务存储
  return runLocaleCheck(grant, task)
}

async function runLocaleCheck(
  grant: { token: string; auditId: string; grantedScopes: string[] },
  task: { region: string; localPages: string[]; sourceMessaging: string },
) {
  // 2. 任务前:从你的本地化配置库读取当前版本的术语表与禁译词(不是 Memory)
  const policy = await loadLocalizationPolicy(task.region) // 例如 { version: '2026-08', glossary: [...], forbiddenTranslations: [...] }

  // 3. 一次调用完成核对:抽取当地实况、比对源 messaging,只输出草稿
  const run = await qoni.doAnything.run({
    token: grant.token,
    prompt: `
      Verify the live pages for market ${task.region}:
      ${task.localPages.join(', ')}.
      Capture the live copy, compare it against the source messaging,
      glossary and forbidden translations, then flag drift, misused
      terms and unsynced copy. Return diffs as a JSON array of
      { page, diff, suggestion, sourceUrl, glossaryRef } objects.
      Never publish, edit pages or change the glossary.

      Source messaging: ${task.sourceMessaging}
      Localization policy (version ${policy.version}):
      ${JSON.stringify(policy)}
    `,
    capture: { screenshots: true },
  })

  // 4. 事件流:逐市场巡检的进度、截图和需要人参与的步骤实时转发给前端
  let output: unknown
  for await (const event of run.events()) {
    if (event.type === 'progress') appendTrace(event.data) // 巡检到哪个页面
    if (event.type === 'screenshot') renderScreenshot(event.image) // 每页取证截图
    if (event.type === 'interaction') handleInteraction(event.data) // 登录墙 / 验证码升级给人
    if (event.type === 'done') output = event.data.output
  }

  // 5. 应用侧解析并校验输出契约:缺少来源或术语表条目引用的差异不进交付物
  const diffs = parseLocaleDiffs(output).filter(
    (d) => d.sourceUrl && d.glossaryRef,
  )

  return {
    diffs,
    policyVersion: policy.version,
    audit: { auditId: grant.auditId, permissionBoundary: grant.grantedScopes },
  }
}

输出结构由任务描述约定:这里约定返回 { page, diff, suggestion, sourceUrl, glossaryRef } 数组,应用侧 parseLocaleDiffs 负责解析与校验,缺少 sourceUrlglossaryRef 的条目被直接丢弃。事件流断线时 SDK 使用 Last-Event-ID 自动重连续传;事件类型常量见 QoniEventTypes

数据与记忆边界

这个场景涉及四类数据,本场景不使用 GUMem:

  • 版本化规则:术语表、禁译词、区域措辞规范——放在你的本地化配置库里按版本管理,每条差异引用规则版本号。
  • 业务状态:差异清单、修正建议、页面截图、reviewer 决策——归档到你的本地化记录,供复核与追溯。
  • 审计记录:grantIdauditId 构成的委托与行为链——由 GenAuth 维护。
  • 用户 Memory(可选):只有用户明确确认的长期个人偏好才属于 GUMem;术语表和区域规范是团队级规则,不是个人记忆,本场景默认不召回也不写回。

失败处理

情况推荐处理
区域 workspace 登录态失效任务挂起,通知用户重新登录,从断点继续。
当地页面结构变化导致抽取失败按失败处理并回放会话记录,不输出无证据的差异项。
委托范围外的市场 workspace 请求直接拒绝并记录,事后可在审计链中查到未遂访问。
输出差异缺少页面来源或术语表条目引用应用侧校验直接丢弃该条差异,并标注丢弃数量和依据的规则版本。

生产注意点

不要把本地化建议当作法律、文化或合规最终判断。发布前应由当地 reviewer 确认。Agent 只输出差异清单与修正建议草稿,不直接发布译文或修改区域页面;对当地竞品页面的抽取频率应设置上限。术语表更新后应在配置库中发布新版本,避免旧版规则继续判定新差异。

下一步