课程资源的类型标签怎么贴learningResourceType 与 inLanguage 的规范写法适用读者做在线课程平台、知识付费站点的后端与 SEO/GEO 工程师负责课程页结构化数据Schema.org落地的前端同学。TL;DR三个字段的核心规范learningResourceType写资源形态不写营销词。inLanguage写教学语言不写课程名语言。educationalUse与 learningResourceType 配合说明用途。Course是实体类型learningResourceType 是属性。inLanguage用 BCP 47 格式如zh-CN。双语课写成数组如[zh-CN, en]。你需要已经会在课程页里塞 JSON-LD想搞清楚为什么 AI 搜索还是不推荐你的课。上个月我们平台有个韩语入门课课程质量不差完课率 62%但在 Perplexity 和 Bing Copilot 回答「韩语零基础网课推荐」时引用的却是站内一个写错了类型标签的短视频合集。排课负责人老郑在周会上原话说「课没毛病标签全贴歪了。」这话虽然刺耳但确实如此。我们花了两周自查全站 1,847 门课里314 门把视频课误标成了Article超过 400 门漏写inLanguage——这直接导致 AI 搜索匹配错了受众。这篇把 learningResourceType、inLanguage、educationalUse 三个字段的规范写法讲透附上我们踩过的坑和校验脚本。先搞清楚为什么类型标签对 AI 搜索这么重要生成式引擎优化Generative Engine Optimization, GEO和传统 SEO 有个根本区别传统搜索引擎给的是链接列表AI 搜索给的是「答案」。答案要生成AI 得先判断你这个页面到底「是什么东西」。是文章是视频课是题库是面向哪国语言学习者的传统 SEO 时代类型贴错了顶多影响富媒体摘要Rich Result的展示样式用户点进来还能自己分辨。AI 搜索不一样——它不会点进来。它拿到的是索引阶段的元数据和内容摘要类型标成Article的视频课在「找一门能系统学的课程」这个意图下权重天然偏低。我们自建监测口径的数据每天抓取五个 AI 搜索入口、记录被引用的课程 URL 和片段跑了四周显示类型标签修正后的课程被「课程推荐」类问题引用的次数比修正前高了约 2.4 倍而缺inLanguage的小语种课程几乎全军覆没28 门里只有 3 门被正确引用过。这是自建口径样本小别当行业均值用但趋势很明确。三个字段到底怎么写规范原文逐条解读learningResourceType写资源形态不写营销词Schema.org 官方对 learningResourceType 的定义是「The predominant type or mode of learning of the resource」也就是资源主要的学习形态。官方推荐的词汇表在 LearningResourceType 相关条目下常见合法值包括合法值对应资源我们站内的典型误用Video Object / video视频课、录播课写成了 Article 或 Coursetext / lecture notes图文讲义、讲稿写成了「精品好课」quiz / assessment测验、题库根本没写这个字段course完整课程序列和 Video 混用一页贴两个slides课件 PPT漏标worksheet练习作业漏标三条最容易犯的错都在表里了。展开说一下第一条因为它最隐蔽Course 和 learningResourceType 不是一回事。Course是 schema.org 里的一个 Type你用type: Course声明「这是一个课程实体」而learningResourceType是 Course/VideoObject/LearningResource 上的一个属性描述学习材料本身的形态。我们后来定的规矩是课程详情页用type: CoursehasCourseInstance其下每个学习单元视频、讲义、测验分别用对应的 Type 和 learningResourceType 描述一个页面里形态要有层级不能混为一谈。还有个反面案例运营同学在标签里写learningResourceType: 爆款AI实战好课。这种营销词机器不认识等于没写还可能让整个 JSON-LD 的可信度打折扣。写机器认识的词人话留给标题和描述。inLanguage别只写课程名里的语言要写教学语言inLanguage 定义是「The language of the content or performance or used in an action」——注意是内容使用的语言。坑就在这「日语 N3 备考课中文授课」课程名带日语教学语言是中文。inLanguage 该写zh-CN同时可以用availableLanguage或关键词辅助说明「涉及日语」。我们站内 9 门日语课有 6 门标成了ja结果被「日语学习资料」类查询错误引用被「中文授课日语课」类查询全部漏掉。双语课可以写成数组inLanguage: [zh-CN, en]但要真的两种语言都占主体不能只有几个英文单词就标双语。别写国家代码不写语言代码CN是错的要用 BCP 47 格式的zh-CN、en-US、ja-JP。小语种课这个事值得单独强调。我们的越南语课和泰语课单价低、受众窄过去一直靠站内搜索硬扛。补上inLanguage: vi/th之后第四周自建监测口径里「越南语入门」「泰语零基础」类 AI 搜索引用从 0 涨到了每周 7 次左右。量不大但这些课本来就没有其他流量入口。把几种典型场景的写法整理成对照表整改时直接对着抄课程场景inLanguage 写法常见错写错写的后果中文授课的日语课zh-CNja被日语内容类查询错误引用英文原版课en或en-US漏写进不了「英文课」候选池中英双语课[zh-CN, en]只写zh-CN双语检索意图漏召回越南语课越语授课vi漏写或写VN小语种查询全军覆没中文题干考韩语的测验[zh-CN, ko]只写zh-CN韩语学习意图匹配不上educationalUse说清楚「拿来干嘛用」educationalUse 描述资源的教育用途官方例值包括 assignment、exam、exercise、homework、lecture、presentation 等。它和 learningResourceType 的区别learningResourceType 说「我是什么形态」educationalUse 说「我服务于什么学习目的」。同一个视频可能是lecture讲课也可能是demonstration演示。一个实用组合录播视频标learningResourceType: videoeducationalUse: lecture配套测验标learningResourceType: quizeducationalUse: assessment。AI 搜索在回答「有没有带练习的 Python 入门课」这类问题时就是靠这个字段组合判断的。底层机制AI 引擎怎么消费这些标签只讲操作不讲原理下次换个字段还是不会。AI 搜索的索引链路大致是这样的一致冲突爬取课程页解析 JSON-LD 结构化数据类型标签是否自洽?进入知识图谱/实体对齐降权或丢弃结构化数据按意图聚类: 语言x形态x用途生成答案时按意图召回引用关键在实体对齐那一步。AI 引擎会把你的 JSON-LD 和页面可见内容做交叉验证页面正文里写着「48 节视频课」JSON-LD 却说 learningResourceType 是 Article两者冲突结构化数据的可信度直接掉。更麻烦的是实体对齐会跨站进行——你标错的课可能被对齐到别人的正确实体上流量等于白白送人。语言字段的消费路径更直白。回答「法语网课」时引擎先按意图拆解出「语言法语」这个约束然后用 inLanguage 做硬过滤。缺这个字段的页面根本进不了候选池内容写得再好也白搭。这也是为什么我们说inLanguage 对多语言平台不是锦上添花是准入门槛。正确写法一份可以直接抄的课程页 JSON-LD环境ASP.NET Core 8 / Python 3.12 均可校验JSON-LD 版本基于 schema.org 2025-09 快照课程页为 Razor 模板渲染。{context:https://schema.org,type:Course,// Course 是实体类型,声明这是一个课程,与 learningResourceType 是两回事name:韩语零基础发音入门中文授课,inLanguage:zh-CN,// 教学语言是中文,课程名里的韩语不是 inLanguagelearningResourceType:video,// 学习形态是视频,不要写成 Article 或营销词educationalUse:[lecture,demonstration],// 用途:授课发音示范,数组可多选description:40 节视频课,从字母发音到音变规则,中文讲解配韩语示范。,provider:{type:Organization,// provider 指内容供给方,别把讲师个人塞进这里name:示例在线课堂},hasCourseInstance:{type:CourseInstance,// courseMode 必填 online/offline/onSite,在线课写 onlinecourseMode:online,// courseWorkload 用 ISO 8601 时长,PT10H 表示总学习时长 10 小时courseWorkload:PT10H},// 配套练习单独声明,形态与用途分开标hasPart:{type:Quiz,name:第一单元发音自测,learningResourceType:quiz,educationalUse:assessment,// 题干中文、考察对象韩语,两种语言都占主体,写成数组inLanguage:[zh-CN,ko]}}注意最后那个hasPart里的 quiz它是韩语内容的测验所以 inLanguage 写了[zh-CN, ko]——题干是中文、考察对象是韩语两个都占主体。这种细节没有统一答案按你内容的真实语言构成来。从错到对我们全站整改的流程整改不是逐页手改1,847 门课手改到明年也改不完。我们的流程分四步画成时序更清楚CMS 草稿规则引擎内容解析器调度脚本CMS 草稿规则引擎内容解析器调度脚本拉取全站课程页 (每夜一批500页)提取正文关键词/媒体文件类型输出候选标签(video/quiz/text)比对现有JSON-LD,标记冲突页冲突页生成修正草稿(约12%命中人工复核)审核通过后批量发布实测数据自建口径2026-08-11 到 2026-09-05解析器给出的候选标签和人工判断一致率约 87%剩下 13% 主要是混合形态课视频配套讲义机器不知道该以哪个为主这部分走了人工。整个整改 25 天动了两轮 CMS 模板和一处历史数据迁移脚本。校验方法发布前把标签拦住光靠人记规范没用要放进门禁。两个层次离线校验CI 里跑环境Python 3.12仅标准库 BeautifulSoup4。importjson,refrombs4importBeautifulSoup# 只认站内规范里的形态词,营销词(爆款/好课)在这里直接拦下ALLOWED_TYPE{video,text,quiz,course,slides,worksheet,lecture notes,assessment}# BCP 47 格式:语言主码 2-3 位小写,可选地区子码,如 zh-CN / en-US# 写 CN 这种纯国家码是常见错写,正则会拒绝ALLOWED_LANGre.compile(r^[a-z]{2,3}(-[A-Z][a-zA-Z]{2})?$)defcheck_course_jsonld(html:str)-list[str]:# 输入是课程页完整 HTML,输出问题列表,非空即阻断发布# 每页可能有多段 JSON-LD,任何一段非法都算整页不过soupBeautifulSoup(html,html.parser)problems[]# 一个页面可能有多段 JSON-LD,逐段校验fortaginsoup.find_all(script,typeapplication/ldjson):try:datajson.loads(tag.string)exceptjson.JSONDecodeError:problems.append(JSON-LD 解析失败,检查是否混入了模板变量)# 模板变量没渲染就发布,是最常见的低级错误continue# learningResourceType 统一转小写再比对,忽略大小写抖动lrtstr(data.get(learningResourceType,)).lower()iflrtandlrtnotinALLOWED_TYPE:problems.append(flearningResourceType 非法:{lrt})# 运营贴营销词会命中这里,需要人工改成合法词汇# inLanguage 可能是字符串也可能是数组,统一按数组处理langdata.get(inLanguage)langslangifisinstance(lang,list)else[lang]forlinlangs:ifnotlornotALLOWED_LANG.match(str(l)):# 缺失时 l 是 None,同样报错,等于强制补齐problems.append(finLanguage 非法或缺失:{l})# 问题列表非空时,CI 直接判失败并输出到 PR 评论returnproblems在线校验发布后Google Rich Results Test 能验 Course 的富媒体结构但注意它不校验 learningResourceType 的词汇合法性这是 schema.org 的 extension 层概念Google 只验自己关心的字段所以词汇白名单得自己守。另外每周用 Rich Result Status Report 看错误趋势我们加门禁后结构化数据报错数从每周 40 降到了个位数。没解决的问题与几个取舍有两个点到现在没有完美方案写出来免得有人踩重复的坑。一是混合形态课的主标签选择。一门课 40 节视频 12 份讲义 3 次测验learningResourceType 只能写一个主值写 video 就把讲义藏起来了。我们目前的折中是hasPart里全部展开主标签写占比最高的形态。AI 引擎会不会正确展开 hasPart各家的表现不一样暂时只能靠监测数据慢慢调。二是 inLanguage 对「教学语言」和「学习对象语言」没有官方的区分字段。中文授课教日语这种场景只能靠 availableLanguage 和描述文本兜底。我们在 schema.org 的 issue 区看到过相关讨论官方还没有定论。这块如果哪位读者有更好的实践评论区聊。常见问题 FAQlearningResourceType 能否写多个值可以写成数组但主标签只能有一个。一门课 40 节视频 12 份讲义 3 次测验learningResourceType 只能写一个主值写 video 就把讲义藏起来了。我们目前的折中是hasPart里全部展开主标签写占比最高的形态。inLanguage 缺失时 AI 搜索如何降级处理缺这个字段的页面根本进不了候选池内容写得再好也白搭。回答「法语网课」时引擎先按意图拆解出「语言法语」这个约束然后用 inLanguage 做硬过滤。这也是为什么我们说inLanguage 对多语言平台不是锦上添花是准入门槛。educationalUse 与 learningResourceType 是否必须成对出现不是必须但成对出现效果最好。learningResourceType 说「我是什么形态」educationalUse 说「我服务于什么学习目的」。一个实用组合录播视频标learningResourceType: videoeducationalUse: lecture配套测验标learningResourceType: quizeducationalUse: assessment。混合形态课程的主标签如何选择learningResourceType 只能写一个主值我们目前的折中是hasPart里全部展开主标签写占比最高的形态。AI 引擎会不会正确展开 hasPart各家的表现不一样暂时只能靠监测数据慢慢调。BCP 47 格式中地区码大小写是否敏感规范上不敏感但建议统一。语言主码 2-3 位小写可选地区子码如zh-CN/en-US。校验脚本里ALLOWED_LANG re.compile(r^[a-z]{2,3}(-[A-Z][a-zA-Z]{2})?$)会拒绝CN这种纯国家码。校验脚本如何接入 CI 流水线把check_course_jsonld放进 CI问题列表非空时直接判失败并输出到 PR 评论。我们加门禁后结构化数据报错数从每周 40 降到了个位数。参考与延伸Schema.org Course 官方定义Schema.org LearningResourceType 相关条目Google 搜索中心课程结构化数据web.dev 结构化数据入门GEO · AI搜索 · learningResourceType · inLanguage · educationalUse · JSON-LD · Schema.org