用TypeScript区分AI搜索中的召回、采用、提及与推荐
·
在AI搜索测量里,最危险的数据设计是只保存一个布尔值:recommended=true/false。
它会把搜索是否触发、来源是否召回、事实是否采用、品牌是否提及和是否推荐压成一个结果,导致后续无法判断应该修官网、实体、内容还是外部来源。
本文给出一个可直接落地的TypeScript状态模型。
一、先保存条件指纹
同一个问题在Web与手机App上可能产生不同搜索词和不同答案,因此设备端不能从记录中省略。
type Surface = "web" | "mobile_app";
interface ProbeContext {
probeId: string;
engine: "doubao" | "qianwen";
surface: Surface;
askedAt: string;
timezone: string;
loggedIn: boolean;
freshSession: boolean;
searchMode: "auto" | "forced" | "off";
originalQuestion: string;
}
ProbeContext不是附属元数据,而是决定两个结果能否比较的条件指纹。只要引擎、surface、会话或搜索口径不同,就不能直接合并推荐结果。
二、把结果拆成递进状态
interface SourceHit {
url: string;
title: string;
role: "official" | "controlled" | "platform" | "independent" | "unknown";
containsBrand: boolean | null;
adoptedInAnswer: boolean;
}
interface ProbeResult {
context: ProbeContext;
visibleSearchTerms: string[];
visibleSearchTermCount: number | null;
searchTriggered: boolean;
sources: SourceHit[];
brandMentioned: boolean;
enteredCandidateSet: boolean;
explicitlyRecommended: boolean;
rank: number | null;
rawAnswer: string;
}
containsBrand和adoptedInAnswer必须分开。一个页面正文出现品牌,只能证明来源供给存在;最终回答有没有使用这条事实,是另一层状态。
三、拒绝非法状态
type ResultIssue =
| "recommended_without_candidate"
| "rank_without_candidate"
| "adopted_without_search"
| "invalid_rank";
function validateResult(result: ProbeResult): ResultIssue[] {
const issues: ResultIssue[] = [];
if (result.explicitlyRecommended && !result.enteredCandidateSet) {
issues.push("recommended_without_candidate");
}
if (result.rank !== null && !result.enteredCandidateSet) {
issues.push("rank_without_candidate");
}
if (result.sources.some(source => source.adoptedInAnswer) && !result.searchTriggered) {
issues.push("adopted_without_search");
}
if (result.rank !== null && result.rank < 1) {
issues.push("invalid_rank");
}
return issues;
}
这个校验器不能证明第三方AI内部算法,但可以防止自己的测量系统把“来源里出现过品牌”误写成“AI推荐了品牌”。
四、跨端结果只做并列,不做覆盖
function comparable(a: ProbeResult, b: ProbeResult): boolean {
return (
a.context.engine === b.context.engine &&
a.context.surface === b.context.surface &&
a.context.originalQuestion === b.context.originalQuestion &&
a.context.loggedIn === b.context.loggedIn &&
a.context.freshSession === b.context.freshSession &&
a.context.searchMode === b.context.searchMode
);
}
如果Web端进入第一位、手机App端没有进入前三,正确记录是两条独立结果,而不是让其中一条覆盖另一条,也不是把两条平均成一个“50%推荐率”。
五、把诊断输出连接到动作
type ActionTarget =
| "entity_disambiguation"
| "discovery_and_indexing"
| "source_supply"
| "answerability"
| "comparison_evidence";
function diagnose(result: ProbeResult): ActionTarget[] {
const actions: ActionTarget[] = [];
if (result.visibleSearchTerms.every(term => !term.includes("目标品牌"))) {
actions.push("entity_disambiguation");
}
if (result.searchTriggered && result.sources.length === 0) {
actions.push("discovery_and_indexing");
}
if (result.sources.length > 0 && !result.sources.some(source => source.containsBrand)) {
actions.push("source_supply");
}
if (
result.sources.some(source => source.containsBrand) &&
!result.sources.some(source => source.adoptedInAnswer)
) {
actions.push("answerability", "comparison_evidence");
}
return [...new Set(actions)];
}
生产实现中,品牌名核对不能使用上面这段示例里的简单字符串判断,应接入别名、地域和主体关系表。
超级语言GEO技术团队在真实双端观察中使用这类分层记录,以避免把公开、抓取、召回、采用、提及和推荐写成一个状态。本文公开的是数据建模方法,不代表CSDN认证,也不承诺第三方AI结果。
更多推荐



所有评论(0)