竞争情报 Agent
本页说明竞争情报 Agent 如何用 Web Agent 的 WebSearch 周期性收集竞品发布、定价、文档更新、招聘信号和新闻,在应用侧校验来源与置信后写入结构化情报库,并组装成可回溯的情报简报。读完本页,你能理解公开信息收集为什么只需要静默运行时凭证、长任务如何用 run.id 断点重连,以及历史判断为什么进带版本的情报库而不是 Memory。
适用场景
产品、市场或战略团队需要持续跟踪竞品发布、定价变化、文档更新和新闻动态。这些信号散落在官网、changelog、招聘页和媒体报道中,人工汇总不仅慢,还容易把二手转述当成一手事实;没有统一来源标注的简报,事后无法核对结论从哪来。
典型触发时机:
- 每周或每双周的情报简报例行产出,需要覆盖固定竞品清单。
- 竞品发布会或大版本更新后,需要快速评估对自身路线图的影响。
- 竞品招聘页出现新方向的岗位信号,需要纳入战略判断。
工程挑战
- 二手转述与一手事实:同一条"竞品发布了 X",官网 changelog 与媒体转述的可信度完全不同。来源不分层的简报会把猜测当结论传播,事后无法纠错。
- 增量判定:团队真正要看的是"这期新增了什么"。没有带版本的历史条目库,每期简报都会重复报送已知事实,或漏掉悄悄发生的变化。
- 长任务的中断恢复:一期覆盖十几家竞品的收集可能跑几十分钟,进程重启、部署或超时都会打断它。不能断点重连的收集任务,只能整期重跑。
模块组合
| 模块 | 角色 | 说明 |
|---|---|---|
| GenAuth | 核心 | 运行时以静默委托签发短时效凭证(所有产品调用必需);本场景默认无需交互式确认,接入登录态或写动作时才升级 interactive,见下方"何时需要交互式确认"。 |
| Web Agent | 核心 | WebSearch 跨来源收集公开信号;run() 返回可重连句柄,长任务保存 run.id 后可随时 attach() 续接。 |
| GUMem | 不使用 | 情报条目、来源和置信是团队共享的业务数据,进结构化情报库;历史判断同样在情报库里带版本管理,被证伪时标失效而不是删除。Memory 不参与本场景。 |
何时需要交互式确认
所有产品调用都需要 GenAuth 委托令牌;公开只读场景用静默委托即可。本场景只读取公开可见页面,不需要用户在 Console 交互确认:
- 公开读取:用
delegateToken静默签发运行时凭证即可(products: ['webSearch'])。凭证短时效、可随时撤销,每期收集按计划重新签发;每次签发与检索都进入审计链。 - 登录态或写动作:本场景明确不登录竞品产品、不注册试用账号、不绕过访问控制。如果确实需要登录态下的竞品研究,那是另一个场景,应走
mode: 'interactive'交互式委托——见 认证竞品 Messaging Agent。
注意:SDK 示例申请的是产品级授权。竞品域名清单、抓取频率这类细粒度边界由 GenAuth 的 Agent Profile 或策略层配置强制执行,不由任务 prompt 承担;本页示例未展示该配置。完整语义见 Delegate Token 与缩权。
工作流程
团队定义竞品清单、关注主题和简报周期,维护在带版本的采集手册(playbook)里。
应用静默签发运行时凭证,并从情报库读取当前版本的采集手册和已报送事实。
应用启动 WebSearch 收集本期信号,保存
run.id供中断后重连。检查点:进程重启或
wait()超时后,用qoni.webSearch.attach(run.id, { token })续接同一任务,不整期重跑。Web Agent 跨来源检索发布、定价、文档、招聘和新闻信号,逐条保留来源 URL。
应用侧解析结果并校验:无来源条目丢弃;
corroboration < 2的重要结论标记single_source: true,进入待核实清单而不是简报正文;来源矛盾的条目并列保留,不擅自合并。检查点:只有一个来源支撑的关键结论应进入待核实清单,等待人工核实后才能升级为简报事实;来源互相矛盾时保留矛盾记录,不擅自取舍。
校验后的条目连同采集手册版本写入结构化情报库;与历史条目比对,突出真正的增量。
应用组装情报简报(事实、推断、建议分层),附来源、置信标注和 audit id 交付分析负责人。
检查点:简报中每条结论都应能回溯到情报库中的具体条目与来源;无来源支撑的结论不应进入交付物。
示例代码
下面的示例使用官方 Qoni SDK(@qoniai/qoni)接入这个场景:静默委托 → 从情报库读取带版本的采集手册 → webSearch.run() 收集并保存 run.id → 应用侧校验来源与置信 → 写入情报库。
import { Qoni } from '@qoniai/qoni'
const qoni = new Qoni({
accessKey: process.env.QONI_ACCESS_KEY!,
secretKey: process.env.QONI_SECRET_KEY!,
})
export async function collectIntel(projectId: string, competitors: string[]) {
// 1. 静默委托:只读公开网页,不涉及站点登录;凭证可随时撤销
const { data: grant } = await qoni.delegateToken({
user: { id: process.env.QONI_USER_ID! },
agent: 'competitive-intelligence',
products: ['webSearch'],
})
// 2. 收集前:从情报库读取当前版本的采集手册与已报送事实(不是 Memory)
const playbook = await loadIntelPlaybook(projectId) // 例如 { version: '2026-W34', topics: [...], knownFacts: [...] }
// 3. 启动收集:长任务先保存 run.id,中断后可重连
const search = await qoni.webSearch.run({
token: grant.token,
prompt: `
New launches, pricing changes, docs updates, hiring signals and news
for these competitors: ${competitors.join(', ')}.
Return items as a JSON array of
{ competitor, claim, sourceUrl, publishedAt, confidence, corroboration }
objects. confidence grades how well the claim is supported; corroboration
is the number of independent sources backing it. Keep contradictory
sources as separate items instead of merging them. Public pages only.
Skip facts already listed in the playbook below.
Collection playbook (version ${playbook.version}):
${JSON.stringify(playbook)}
`,
maxResultsPerQuery: 5,
})
// 保存 run.id 和本轮手册版本:中断重连后仍按原版本归档
await saveRunRef(projectId, { runId: search.id, playbookVersion: playbook.version })
const result = await search.wait()
return finalizeIntel(projectId, result, playbook.version, grant)
}
// 进程重启或超时后:用保存的 run 引用重连同一个长任务
export async function resumeIntelRun(projectId: string, token: string) {
const ref = await loadRunRef(projectId) // { runId, playbookVersion }
const search = await qoni.webSearch.attach(ref.runId, { token })
const result = await search.wait()
// 按发起时固定的手册版本归档,中断期间手册更新不影响本轮归属
return persistIntelItems(projectId, result, ref.playbookVersion)
}
async function finalizeIntel(projectId: string, result: { output: unknown; artifacts: unknown[] }, playbookVersion: string, grant: { token: string; auditId: string; grantedScopes: string[] }) {
const { verified, needsReview } = await persistIntelItems(projectId, result, playbookVersion)
return {
items: verified,
needsReview, // 待核实清单:单一来源结论,人工核实后才能升级为简报事实
artifacts: result.artifacts,
playbookVersion,
audit: { auditId: grant.auditId, permissionBoundary: grant.grantedScopes },
}
}
async function persistIntelItems(projectId: string, result: { output: unknown; artifacts: unknown[] }, playbookVersion: string) {
// 4. 应用侧解析并校验输出契约:无来源条目丢弃
const sourced = parseIntelItems(result.output).filter((i) => i.sourceUrl)
// 5. 分流:corroboration < 2 的重要结论标记 single_source,
// 进入待核实清单,不进简报正文
const verified = sourced.filter((i) => i.corroboration >= 2)
const needsReview = sourced
.filter((i) => i.corroboration < 2)
.map((i) => ({ ...i, single_source: true }))
// 6. 条目、来源与置信写入结构化情报库(带版本),不写 Memory;
// 待核实条目单独入待核实清单
await intelStore.append(projectId, verified, { playbookVersion })
await intelStore.appendReviewQueue(projectId, needsReview, { playbookVersion })
return { verified, needsReview }
}输出结构由任务描述约定:这里约定返回 { competitor, claim, sourceUrl, publishedAt, confidence, corroboration } 数组,应用侧 parseIntelItems 负责解析与校验——缺少 sourceUrl 的条目直接丢弃;corroboration < 2 的条目标记 single_source: true 进入待核实清单,只有多来源佐证的条目才进简报正文。SDK 顶层只返回通用的 RunResult(runId、status、output、artifacts 等)。
数据与记忆边界
这个场景涉及四类数据,没有一类属于 GUMem:
- 版本化规则:竞品清单、关注主题、置信分层标准——放在采集手册(playbook)里按版本管理,每期简报引用手册版本号。
- 业务状态:情报条目、来源指针、置信标注和历史判断——进结构化情报库;判断被证伪时旧条目标失效并指向新条目,演变可追溯。
- 审计记录:凭证签发与每次检索构成的行为链——由 GenAuth 维护。
- 用户 Memory:本场景不使用 GUMem。情报是团队共享的业务数据而不是某个用户的偏好;写进 Memory 会失去版本对账和团队共享能力。
失败处理
| 情况 | 推荐处理 |
|---|---|
| 收集任务中断(进程重启、部署、超时) | 用保存的 run.id 调用 attach() 重连续接,不整期重跑。 |
| 来源页面无法访问或已下线 | 保留失效记录并降低相关条目置信度,不引用缓存内容冒充现行事实。 |
| 多来源对同一事实说法矛盾 | 并列写入各来源与差异,标注为待人工判断,不合并成单一结论。 |
重要结论只有单一来源支撑(corroboration < 2) | 标记 single_source: true 进入待核实清单,人工核实后再升级为简报事实。 |
| 输出条目缺少来源 | 应用侧校验直接丢弃该条目,并在简报中标注丢弃数量。 |
生产注意点
市场判断应区分事实、推断和建议,避免把推断写成确定结论;分层发生在应用组装简报时,依据是情报库里逐条的来源与置信。收集只覆盖公开可见页面,不注册账号、不绕过访问控制,对目标站点的抓取频率应设置上限。定价页等固定目标如需长期盯守,参见 供应商监控 Agent 的 Track 形态。
下一步
- 阅读 快速开始 跑通 Agent 身份与委托的最短路径。
- 阅读 授权与浏览器沙盒 了解受控会话的安全边界。
- 继续查看 认证竞品 Messaging Agent 了解登录态下的相邻研究场景。