评论洞察 Agent
本页说明评论洞察 Agent 如何在只读委托下读取电商、App Store、G2 或评论后台,从授权可见和公开评论中提取用户反馈主题、聚类洞察并生成 positioning insight。读完本页,你能理解这个场景需要哪些模块、权限边界如何收窄,以及评论原文和聚类结果为什么应该归档到分析存储而不是 Memory。
适用场景
Marketing 和产品团队需要从用户评论中理解购买动机、异议、功能反馈和竞品对比。评论分散在多个平台、量大且持续新增,人工通读难以形成可复查的主题聚类;而没有来源支撑的"用户都在说"式结论,也无法作为 positioning 决策依据。
典型触发时机:
- 新版本或新品发布后,需要在一周内汇总各平台评论的主题分布。
- Positioning 复盘前,需要提取用户原话中的购买动机和异议证据。
- 竞品评分波动,需要对比双方评论中的功能反馈差异。
工程挑战
- 评论量大且噪声高:跨平台成千上万条评论里混着刷评、无关吐槽和重复内容,聚类很容易产出"看起来合理"但没有任何一条原文支撑的结论。
- 洞察必须可回溯:"用户都在说太贵"这类结论如果没有评论原文 URL,既无法复核,也无法在 positioning 决策被质疑时自证——无来源的洞察等于没有洞察。
- 主题体系要跨周期可比:分类规则一变,前后两期的主题分布就失去可比性;规则必须版本化管理,聚类结果必须连同规则版本一起归档,趋势判断才有依据。
模块组合
| 模块 | 角色 | 说明 |
|---|---|---|
| GenAuth | 核心 | 评论后台等授权页面的只读委托、撤销与审计链;后台账号的回复、举报和商家信息编辑能力不进入委托范围。 |
| Web Agent | 核心 | 受控会话登录评论后台或访问公开评论页,逐页抽取评分、原文摘录和来源链接;公开评论页可通过 WebSearch 定位补充来源。 |
| GUMem | 不使用 | 评论原文、聚类版本和趋势数据是分析资产,归档到你的分析存储;分类规则和竞品映射是版本化规则,放在规则库(policy store)按版本注入。都不属于 Memory。 |
权限与委托边界
Agent 本身不持有任何固有权限。每次任务的实际权限是三个集合的交集:用户真实权限 ∩ 本次显式委托范围 ∩ 企业批准边界。落到这个场景:
- 委托范围只覆盖"读取授权评论后台和指定产品的公开评论页",不包含回复评论、举报内容或修改商家信息。
- 委托凭证短时效,单次挖掘任务建议分钟级有效期。
- 用户或管理员可随时撤销授权;撤销后新的评论抽取请求立即失败。
- 越权尝试(例如读取委托范围外的其他产品评论后台)会被拒绝并留痕——审计链覆盖全部尝试,不只是成功行为。
注意:SDK 示例申请的是产品级 scope(如 webagent.do_anything:read)。平台清单、产品范围和动作白名单这类细粒度边界由 GenAuth 的 Agent Profile 或策略层配置强制执行,不由任务 prompt 承担;本页示例未展示该配置。完整语义见 Delegate Token 与缩权。
工作流程
用户选择产品、平台和时间范围,并在 Qoni Console 确认本次交互式授权。
GenAuth 为本次任务签发最小权限的只读委托凭证。
应用从规则库读取当前版本的分类规则、主题体系和竞品映射,注入任务描述。
Web Agent 登录评论后台或打开公开评论页,逐页抽取评分、原文摘录和来源链接。
检查点:评论平台出现登录墙、验证码或风控页时,Web Agent 应升级给人处理,而不是静默绕过。
Agent 按主题聚类评论,标注购买动机、异议、功能反馈和竞品对比,每条洞察附代表性评论原文和来源链接。
应用侧校验输出契约:缺少评论原文 URL 的洞察直接丢弃;聚类结果连同规则版本归档到你的分析存储。
Agent 输出主题聚类、代表性评论、messaging 建议和来源列表,附规则版本号与 audit id。
检查点:每条情感或主题结论都应能回溯到具体评论来源链接;无原文支撑的结论不应进入交付物。
示例代码
下面的示例使用官方 Qoni SDK(@qoniai/qoni)把这个场景接到你的服务端:交互式委托(含完整回调)→ 从规则库读取分类规则 → 一次 doAnything.run() 完成评论抽取与聚类 → 解析并校验洞察。
import { Qoni, QoniScopes } from '@qoniai/qoni'
const qoni = new Qoni({
accessKey: process.env.QONI_ACCESS_KEY!,
secretKey: process.env.QONI_SECRET_KEY!,
})
// 1. 交互式委托:涉及评论后台登录,让用户在 Qoni Console 确认授权
export async function startReviewMining(userId: string, taskId: string) {
const { data: authorization } = await qoni.delegateToken({
mode: 'interactive',
agent: 'review-mining',
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')!,
})
return runMiningTask(grant, await loadMiningTask(query.get('state')!))
}
async function runMiningTask(
grant: { token: string; auditId: string; grantedScopes: string[] },
task: { product: string; platforms: string[]; timeRange: string },
) {
// 2. 任务前:从你的规则库读取当前版本的分类规则与主题体系(不是 Memory)
const policy = await loadReviewTaxonomyPolicy() // 例如 { version: '2026-08', themes: [...], competitorMap: ... }
// 3. 一次调用完成挖掘:登录后台、逐页抽取、按主题聚类
const run = await qoni.doAnything.run({
token: grant.token,
prompt: `
Mine customer reviews for ${task.product} on ${task.platforms.join(', ')}
within ${task.timeRange}. Extract ratings, verbatim excerpts and source
links, then cluster them into the themes defined in the taxonomy below —
motivations, objections, feature feedback, competitor comparisons.
Return insights as a JSON array of
{ theme, insight, quote, reviewUrl } objects.
Never reply, report or edit merchant info; exclude reviewer personal data.
Review taxonomy (version ${policy.version}):
${JSON.stringify(policy)}
`,
capture: { screenshots: true },
})
const result = await run.wait({
// 登录墙 / 验证码 / 风控页:升级给人处理
onInteraction: (interaction) => notifyUserActionRequired(interaction),
})
// 4. 应用侧校验输出契约:缺评论原文 URL 的洞察直接丢弃
const insights = parseInsights(result.output).filter((i) => i.reviewUrl)
// 聚类结果连同规则版本归档到你的分析存储(不是 Memory)
await archiveInsights(insights, policy.version)
return {
insights,
artifacts: result.artifacts,
policyVersion: policy.version,
audit: { auditId: grant.auditId, permissionBoundary: grant.grantedScopes },
}
}输出结构由任务描述约定:这里约定返回 { theme, insight, quote, reviewUrl } 数组,应用侧 parseInsights 负责解析与校验,任何缺少 reviewUrl 的条目被直接丢弃。SDK 顶层只返回通用的 RunResult(runId、status、output、artifacts 等)。
数据与记忆边界
这个场景涉及四类数据,都不需要进入 GUMem:
- 版本化规则:分类规则、主题体系、竞品映射——放在规则库(policy store)里按版本管理,每期聚类引用规则版本号。
- 业务状态:评论原文摘录、聚类结果、趋势数据——按规则版本归档到你的分析存储,供跨期对比与复查。
- 审计记录:
grantId与auditId构成的委托与行为链——由 GenAuth 维护。 - 用户 Memory(可选):这个场景默认不召回也不写回;评论内容属于评论作者的公开表达,不应作为任何人的 Memory 沉淀。
失败处理
| 情况 | 推荐处理 |
|---|---|
| 评论后台登录态失效 | 任务挂起,通知用户重新登录,从断点继续。 |
| 评论页结构变化导致抽取失败 | 按失败处理并回放会话记录,不输出无证据的洞察。 |
| 委托范围外的产品后台请求 | 直接拒绝并记录,事后可在审计链中查到未遂访问。 |
| 洞察条目缺少评论原文 URL | 应用侧校验直接丢弃该条目,并在报告中标注丢弃数量。 |
生产注意点
不要输出用户隐私信息。公开引用评论时应保留平台规则和最小必要摘录。Agent 只处理公开可见或授权可见的评论内容,评论作者的个人数据仅限洞察分析用途,不用于建联或画像;对公开评论页的抽取频率应设置上限,遵守平台服务条款。
下一步
- 阅读 快速开始 跑通 Agent 身份与委托的最短路径。
- 阅读 授权与浏览器沙盒 了解受控会话的安全边界。
- 继续查看 Influencer Vetting Agent 了解相邻场景。