diff --git a/chat-intent-router.mjs b/chat-intent-router.mjs index 81e5d37..51963bf 100644 --- a/chat-intent-router.mjs +++ b/chat-intent-router.mjs @@ -82,6 +82,14 @@ const REALTIME_INFO_AGENT_PATTERNS = [ /(?:实时|最新).{0,8}(?:信息|数据|情况|动态|资讯)/u, ]; +const RICH_PUBLISHABLE_CONTENT_HINT_PATTERNS = [ + /(?:服务号|公众号|H5|h5).{0,24}(?:用户|读者|粉丝|阅读|推送|发布|消息|文章|内容)/u, + /(?:整理|排版|美化|输出).{0,24}(?:给|成|为).{0,12}(?:服务号|公众号|H5|h5)/u, + /(?:服务号|公众号|H5|h5|页面|文章|推文|图文|长文|专题).{0,24}(?:用户|读者|粉丝|客户|阅读|推送|发布|转发|分享|展示|内容)/u, + /(?:整理|排版|美化|输出|生成|制作|做成).{0,24}(?:给|成|为|适合).{0,16}(?:用户|读者|粉丝|客户|服务号|公众号|H5|h5|图文|文章|页面|推文|转发|分享|阅读)/u, + /(?:适合|方便).{0,12}(?:用户|读者|粉丝|客户).{0,12}(?:阅读|转发|分享)/u, +]; + const MEMORY_RECALL_PATTERNS = [ /你(?:还)?记得(?:我)?/u, /(?:有没有|是否).{0,6}记住/u, @@ -103,6 +111,20 @@ export function isRealtimeInfoQuestion(text) { return REALTIME_INFO_AGENT_PATTERNS.some((pattern) => pattern.test(normalized)); } +export function isRichPublishableContentIntent(text) { + const normalized = String(text ?? '').trim(); + if (!normalized || normalized.length < 260) return false; + if (!RICH_PUBLISHABLE_CONTENT_HINT_PATTERNS.some((pattern) => pattern.test(normalized))) return false; + const bulletCount = (normalized.match(/(?:^|\n)\s*(?:[-*•]|[0-9]+[.、]|[🌍🇺🇸⚽🎤📉🌡️📰])\s*/gu) ?? []).length; + const headingCount = (normalized.match(/(?:^|\n)\s*(?:#{1,3}\s+|[🌍🇺🇸⚽🎤📉🌡️📰].{0,24}$)/gmu) ?? []).length; + const sectionLikeCount = (normalized.match(/(?:^|\n)\s*(?:[^\n]{1,24})\n(?:\s*[-*•]\s+)/gu) ?? []).length; + return bulletCount + headingCount + sectionLikeCount >= 5; +} + +export function isRichChannelPageIntent(text) { + return isRichPublishableContentIntent(text); +} + function buildRealtimeInfoClassification() { return normalizeClassification({ route: CHAT_INTENT_ROUTE.AGENT, @@ -750,6 +772,15 @@ export function classifyWithRules({ agent_brief: '生成或更新 MindSpace 公开页面,并返回可访问链接;信息不足时使用合理默认,不要停在追问。', }, { source: 'rule' }), decisionContext); } + if (includeIntentPatterns && normalized && isRichPublishableContentIntent(normalized)) { + return finalizeRouterClassification(normalizeClassification({ + route: CHAT_INTENT_ROUTE.AGENT, + confidence: 0.93, + reason: '结构化长内容适合生成页面承载', + suggested_skill: 'static-page-publish', + agent_brief: '优先将用户提供的结构化长内容整理为 MindSpace 公开 H5 页面,并返回可访问链接;不要只回复文字摘要。', + }, { source: 'rule' }), decisionContext); + } if (includeIntentPatterns && normalized && isRealtimeInfoQuestion(normalized)) { return finalizeRouterClassification(buildRealtimeInfoClassification(), decisionContext); } diff --git a/chat-intent-router.test.mjs b/chat-intent-router.test.mjs index 6942eff..b3118e8 100644 --- a/chat-intent-router.test.mjs +++ b/chat-intent-router.test.mjs @@ -20,6 +20,8 @@ import { ROUTER_DECISION_MODE, ROUTER_DECISION_SESSION_HINT, isRealtimeInfoQuestion, + isRichChannelPageIntent, + isRichPublishableContentIntent, coerceRealtimeWebSkill, resolveChatIntentRouterPolicy, } from './chat-intent-router.mjs'; @@ -94,6 +96,117 @@ test('classifyWithRules routes themed article requests to agent orchestration', assert.equal(result.suggestedSkill, 'static-page-publish'); }); +test('classifyWithRules routes rich service account content to static-page-publish', () => { + const text = `以下是今天(2026年7月7日,星期二)国际上的主要热点新闻: + +🌍 地缘政治与安全 +- 霍尔木兹海峡油轮遇袭。 +- 伊朗最高领袖哈梅内伊葬礼。 +- 中国核潜艇在南太平洋试射远程导弹。 +- 俄罗斯空袭基辅。 + +🇺🇸 美国 +- Charlie Kirk 遇刺案预审听证。 +- 特朗普财务披露。 +- 最高法院允许德州实施应用商店年龄验证法。 + +⚽ 体育 +- 2026世界杯,比利时4-1淘汰美国,西班牙1-0绝杀葡萄牙。 + +🎤 娱乐 +- Taylor Swift 与 Travis Kelce 在麦迪逊广场花园举行婚礼。 + +📉 财经 +- 道指首次突破53,000点,AI 芯片热潮推动股市新高。 +- Samsung Q2 利润飙升1,800%。 + +🌡️ 其他 +- 新泽西高温致至少25人死亡。 +- 古巴全国大停电。 + +请整理给服务号用户阅读。`; + const result = classifyWithRules({ + text, + userMessage: { + role: 'user', + content: [{ type: 'text', text }], + metadata: { displayText: text }, + }, + }); + assert.equal(isRichChannelPageIntent(text), true); + assert.equal(result.route, CHAT_INTENT_ROUTE.AGENT); + assert.equal(result.suggestedSkill, 'static-page-publish'); + assert.match(result.reason, /结构化长内容/); +}); + +test('isRichChannelPageIntent does not route short service account copy to page', () => { + assert.equal(isRichChannelPageIntent('请整理给服务号用户阅读:今天 AI 新闻有哪些?'), false); +}); + +test('classifyWithRules prefers pages for rich structured content meant for readers', () => { + const text = `下面是活动资料,请整理成适合用户阅读和转发的内容: + +活动概览 +- 名称:城市夜跑季 +- 时间:7月12日到7月20日 +- 地点:滨江步道、中央公园、城市广场 + +亮点介绍 +- 三条不同难度路线,适合亲子、入门和进阶跑者 +- 每晚有补给站、音乐打卡点和城市灯光秀 +- 完赛可领取电子证书和联名纪念徽章 + +报名信息 +- 早鸟票 39 元 +- 标准票 59 元 +- 团队票 5 人起享 8 折 + +注意事项 +- 需提前 30 分钟签到 +- 建议穿反光装备 +- 遇强降雨活动顺延 + +传播重点 +- 强调轻松参与、城市夜景和朋友一起完成 +- 内容需要清晰、有层次,适合用户直接阅读。`; + const result = classifyWithRules({ + text, + userMessage: { + role: 'user', + content: [{ type: 'text', text }], + metadata: { displayText: text }, + }, + }); + assert.equal(isRichPublishableContentIntent(text), true); + assert.equal(result.route, CHAT_INTENT_ROUTE.AGENT); + assert.equal(result.suggestedSkill, 'static-page-publish'); +}); + +test('isRichPublishableContentIntent keeps plain long summaries out of page fast path', () => { + const text = `请总结以下会议纪要: + +产品进展 +- 首页完成第一版视觉调整 +- 登录链路还需要补充错误提示 +- 分享页需要统一按钮文案 + +技术进展 +- 后端接口完成基础联调 +- 前端状态管理仍有重复请求 +- 缓存策略需要继续评估 + +风险 +- 设计稿还没有最终确认 +- 部分接口缺少压测数据 +- 发布窗口需要和运营确认 + +下一步 +- 明天上午确认视觉改动 +- 下午完成联调复测 +- 周五前整理发布清单`; + assert.equal(isRichPublishableContentIntent(text), false); +}); + test('classifyWithRules honors forceDeepReasoning bypass', () => { const result = classifyWithRules({ text: '你好',