adapt-parser实战:用Python优雅实现意图识别与实体抽取
做语音控制、对话系统或者规则引擎的同学一定被同一个问题折磨过用户说“帮我把客厅的灯调亮一点”你辛辛苦苦写了十几个if-else去匹配“开灯”“打开灯”“亮一点”结果对方换个说法程序就歇菜。这个把自然语言拆成“意图实体”的过程早期我全用正则硬扛后来换了Python的adapt-parser包语法简洁、参数直观处理这类固定场景的指令解析比我之前自己写的那套模板要省心得多。这篇就以adapt-parser为核心把它的语法、参数和实际应用案例掰开讲清楚。文章适合正在做语音助手、智能家居控制、聊天机器人“指令理解”模块的开发者也适合准备从正则裸奔转向结构化意图解析的朋友。1. 这个包解决什么问题先搞懂意图与实体1.1 从“把客厅的灯调亮一点”说起我们拆一下这句指令。用户真正想表达的信息其实只有三层一是动作“调节亮度”二是对象“客厅的灯”三是程度“调亮一点”。在自然语言处理里这种结构化拆解有个约定俗成的叫法——意图识别与实体抽取。意图就是“用户想干什么”实体就是“操作对象和操作参数”。放到程序里用户输入的是一串文字程序要输出的应该是一个相对干净的结构比如意图调节亮度设备灯房间客厅调节方向调亮如果你用传统正则第一版可能这样写import re text 把客厅的灯调亮一点 if re.search(r调亮, text): device 灯 room 客厅 if 客厅 in text else 未知 brightness 调亮看起来能跑可用户一旦说“把客厅照明调亮点”“客厅灯亮一些”你的正则就要不断加分支加到最后变成一坨无法维护的表达式。adapt-parser做的事情就是把“匹配哪些词”和“匹配后归到哪个实体”抽象成声明式的实体定义再用意图构建器把这些实体组合起来。你不用再关心语言里有多少种同义表达只要把常见说法作为候选值喂给它剩下的匹配交给解析器。1.2 为什么选 adapt 这种轻量方案而不是全部交给正则或重型框架我见过不少团队遇到意图解析问题第一反应是上完整版对话理解平台。那些框架确实很强能做意图分类、槽位填充、多轮对话但代价是模型体积大、需要训练数据、推理延迟高。对智能家居这种“指令集很固定”的场景等于拿大炮打蚊子。也有团队坚持全用正则就像我刚才说的短期可行一旦实体值超过五十个、同义词超过一百种维护成本立刻失控。adapt-parser的思路介于两者之间它不依赖机器学习模型不需要训练所有匹配规则都是显式的但你又不必亲手去拼正则细节。它内部会做归一化、短语匹配、候选排序你只需要给出实体候选值和意图组合方式。这个包最早是从一个开源语音助手项目的内部工具里拆出来的所以它的设计天然适合“离线、轻量、可嵌入”的解析场景。我自己在几个项目里拿它做过智能家居指令解析、日程提醒的语义提取都没有额外引入重型依赖跑起来非常干净。2. 核心语法拆解从注册实体到解析意图2.1 环境准备与安装adapt-parser是纯Python实现安装很简单pip install adapt-parser装完之后导入方式比较固定from adapt.engine import IntentDeterminationEngine from adapt.intent import IntentBuilder from adapt.entity import Entity from adapt.regex import Regex我在 Python 3.8 和 3.11 上都跑过兼容性没什么问题。如果你的项目环境比较乱建议先建一个干净的虚拟环境再装避免和已有的包产生依赖冲突。2.2 三块积木Entity、Regex、IntentBuilderadapt-parser的玩法可以浓缩成三块积木。第一块是实体Entity用来声明一类候选词。比如你想识别“客厅”“卧室”“书房”这类房间实体就注册一个叫 Room 的实体engine IntentDeterminationEngine() engine.register_entity(Entity(Room, [客厅, 主卧, 书房, 厨房])) engine.register_entity(Entity(Device, [灯, 空调, 窗帘])) engine.register_entity(Entity(Action, [打开, 关闭, 调亮, 调暗]))实体名是你在后面意图构建器里引用的唯一标识候选值就是用户口语里最常出现的说法。第二块是正则Regex用来匹配一些实体值无法穷举的动态信息比如时间、温度数值、地点名称。adapt-parser里它不叫正则处理器而是专门封装了一个类关键是正则里的命名分组名会自动变成实体类型。举例来说engine.register_regex_parser(Regex(r设置闹钟在 (?PTime\d{1,2}:\d{2})))这句的意思是只要文本里出现“设置闹钟在 7:30”这种模式Time就会被当作实体提取出来对应的值就是“7:30”。这个设计非常巧妙等于把正则捕获组和实体体系打通了。第三块也是最重要的一块是意图构建器IntentBuilder用来规定一个意图到底需要哪些实体同时出现builder IntentBuilder(SetAlarmIntent) builder.require(Time) parser builder.build() engine.register_intent_parser(parser)上面这段代码的含义是我定义一个叫 SetAlarmIntent 的意图它必须包含 Time 实体才会被触发。2.3 让引擎跑起来determine_intent 的返回结构积木凑齐后真正干活的是engine.determine_intent。拿最常见的闹钟识别示例来看engine.register_entity(Entity(Time, [7:00, 7:30, 8:00])) builder IntentBuilder(SetAlarmIntent) builder.require(Time) engine.register_intent_parser(builder.build()) result next(engine.determine_intent(设置闹钟在 7:30)) print(result)输出大概是这样的结构{ intent: {SetAlarmIntent: 1.0}, entities: [ { type: Time, data: { confidence: 1.0, match: 7:30 } } ] }这里的重点有几个月几个月需要理解清楚intent字段是一个字典key是意图名value是置信度entities是列表里面每个元素包含type和datadata.match是实际匹配到的文本data.confidence是置信度。如果你只需要最可能的那个候选用next()取第一个没问题。但有时候一个句子会同时触发多个意图determine_intent返回的其实是可以迭代的候选列表建议循环遍历或用list()接收全部结果再排序。3. 参数到底有哪些实体、意图与匹配规则的个性化3.1 Entity 参数名称与候选值列表Entity构造函数最核心的两个参数就是name和候选值集合。我先给一个最小示例Entity(City, [beijing, shanghai, guangzhou])name 最好是英文字母组成的标识符因为意图构建器内部要用这个名字做关联引用。候选值可以是单词也可以是带空格的短语adapt支持连续短语匹配。比如“turn on”“switch on”这种多词短语可以整体注册engine.register_entity(Entity(Action, [turn on, switch on, power up]))有人容易犯一个错误把一个整体动作拆成两个实体再设计复杂的组合。比如“打开灯”拆成“打开”和“灯”两个词没问题但“把音乐音量调大一点”这种长短语如果你非要拆成“音乐”“音量”“调大”三个实体又要额外处理它们之间的位置关系。我在实际项目里的经验是当短语的语义足够独立时直接整体注册成单个实体值反而更省事。3.2 IntentBuilder 的 require / optionally / one_of这是adapt-parser参数设计的精华所在。先看一个完整的组合builder IntentBuilder(RoomLightIntent) builder.require(Action) builder.require(Device) builder.optionally(Room) builder.one_of(BrightnessUp, BrightnessDown) parser builder.build() engine.register_intent_parser(parser)其中参数语义可以这样理解require(实体)必须出现的实体缺失则该意图不成立。optionally(实体)可选实体出现了就提取不出现也不影响意图成立。one_of(实体1, 实体2)多个实体中需要至少出现一个。我用一张表整理了一下它们的区别方便后面对比方法是否必须影响置信度方式典型场景require是缺失则意图完全不匹配提取核心动作、核心对象optionally否缺失不扣分出现则补充信息房间信息、时间信息one_of至少一个一个都没有则意图不匹配打开/关闭在语义上偏向某一侧这里还要多说一句参数怪癖one_of的参数并不是百分百确定的“可多个同时出现但无须全部出现”的关系它只是降低了意图成立的门槛。出现多个时多个实体都会被提取到entities列表里。如果你想让多个实体必须同时出现就用两个require。3.3 正则解析器的命名分组与优先级正则参数里最容易踩坑的是“命名分组名必须和已知实体名一致否则会被当成新实体”。我也在这上面翻过车一开始写正则时命名分组写成了time小写而实体注册名是Time结果解析结果里出现了两个不同的实体 key意图构建器怎么也匹配不上。正确写法是让命名分组名与实体名完全保持一致engine.register_entity(Entity(Time, [])) engine.register_regex_parser(Regex(r(?PTime\d{1,2}:\d{2})))注意我上面的实体Time候选值为空列表这听起来很怪但它在实际开发中很有用先用正则兜底提取动态值再保留一个空实体作为类型占位。这样意图构建器依然可以引用Time这个实体类型。关于优先级adapt-parser里的正则解析器和实体解析器是并列的它们各自独立匹配然后把结果合并到候选列表里。因此同一个句子可能同时被正则和实体表匹配到产生两个相似候选。我建议在注册顺序上把更具体的正则放在前面把宽泛的实体表放在后面这样拿到next()时优先得到精确结果。不过如果候选结果太多还是统一做一次置信度排序比较靠谱。4. 实际应用案例智能家居控制指令解析4.1 场景设计与实体定义前面讲的语法、参数比较理论这一节我直接带你搭一个能跑起来的智能家居控制解析模块。假设我们的场景是控制灯光、空调和窗帘指令形式大概是打开客厅的灯关闭主卧空调把书房的窗帘调暗一点先定义实体engine IntentDeterminationEngine() engine.register_entity(Entity(Action, [打开, 关闭, 调亮, 调暗])) engine.register_entity(Entity(Room, [客厅, 主卧, 书房, 厨房])) engine.register_entity(Entity(Device, [灯, 空调, 窗帘])) engine.register_entity(Entity(Brightness, [调亮, 调暗]))这里有个细节Brightness和Action有重叠词“调亮”“调暗”。同一个词同时出现在两个实体里会触发多个匹配候选。这是一种真实情况后面我会专门讲怎么处理。4.2 意图组合与正则补充考虑到中文口语里经常夹带一些“把”“的”“一点”这类无实义词直接靠分词和实体表匹配不太稳定。我习惯再加一个正则解析器做兜底engine.register_regex_parser(Regex(r(?PAction打开|关闭|调亮|调暗).*(?PRoom客厅|主卧|书房|厨房).*(?PDevice灯|空调|窗帘)))然后定义意图builder IntentBuilder(DeviceControlIntent) builder.require(Action) builder.require(Room) builder.require(Device) builder.optionally(Brightness) engine.register_intent_parser(builder.build())这里我把Brightness设成可选因为“打开空调”不需要亮度信息而“调亮”这类指令里亮度又很重要。optional 的意义就在于同一套解析规则输入缺失不报错输入完整也能提取。4.3 解析效果与完整代码下面是完整的可运行代码我把注释也写得详细一点from adapt.engine import IntentDeterminationEngine from adapt.intent import IntentBuilder from adapt.entity import Entity from adapt.regex import Regex engine IntentDeterminationEngine() engine.register_entity(Entity(Action, [打开, 关闭, 调亮, 调暗])) engine.register_entity(Entity(Room, [客厅, 主卧, 书房, 厨房])) engine.register_entity(Entity(Device, [灯, 空调, 窗帘])) engine.register_regex_parser(Regex(r(?PAction打开|关闭|调亮|调暗).*(?PRoom客厅|主卧|书房|厨房).*(?PDevice灯|空调|窗帘))) builder IntentBuilder(DeviceControlIntent) builder.require(Action) builder.require(Room) builder.require(Device) builder.optionally(Brightness) engine.register_intent_parser(builder.build()) def parse_command(text): try: result next(engine.determine_intent(text)) except StopIteration: return {intent: None, entities: []} intent_name list(result[intent].keys())[0] entities { item[type]: item[data][match] for item in result[entities] } return {intent: intent_name, entities: entities} print(parse_command(打开客厅的灯)) print(parse_command(关闭主卧空调)) print(parse_command(把书房的窗帘调暗一点))输出大致如下{intent: DeviceControlIntent, entities: {Action: 打开, Room: 客厅, Device: 灯}} {intent: DeviceControlIntent, entities: {Action: 关闭, Room: 主卧, Device: 空调}} {intent: DeviceControlIntent, entities: {Action: 调暗, Room: 书房, Device: 窗帘, Brightness: 调暗}}这套代码放到真实项目里可以直接接到你的设备控制函数上比如parse_result parse_command(打开客厅的灯) if parse_result[intent] DeviceControlIntent: room parse_result[entities].get(Room) device parse_result[entities].get(Device) action parse_result[entities].get(Action) control_device(room, device, action)4.4 多意图冲突时的处理思路真实场景里用户可能同时说“打开客厅的灯和关闭书房的空调”这种一句多意图的情况adapt-parser默认会按一个意图去解析效果不一定理想。我的做法是在外层先做简单切分比如检测到“和”“同时”就把句子先拆成两条指令再分别解析。这种预处理不算复杂但能把adapt-parser的能力边界保护住避免过度依赖解析器处理所有复杂性。5. 踩过的坑与性能调优心得5.1 实体词重叠时的置信度取舍前面提到Action里注册了“调亮”Brightness里也注册了“调亮”结果解析“把书房的窗帘调暗一点”时entities列表里可能出现多个同类型或跨类型候选。next()取到的第一个结果并不一定是最期望的那个。我的经验是不要只依赖next()而是遍历候选结果用“实体覆盖度”做一次综合排序。所谓覆盖度就是命中的实体数占该意图所需实体数的比例。比如“调暗”同时命中Action和Brightness但一条指令既需要 Action 又需要 DeviceBrightness 只是可选补充那么优先选 Action 命中合理、Brightness 命中也齐全的候选而不是反过来。best_result None best_score 0 for result in engine.determine_intent(把书房的窗帘调暗一点): intent_name list(result[intent].keys())[0] entity_types {item[type] for item in result[entities]} score len(entity_types) if score best_score: best_result result best_score score这段代码逻辑不复杂但能解决大量“候选多个但我想取信息最全那个”的烦恼。5.2 语句归一化大小写、缩写和标点的处理adapt-parser虽然内部有归一化处理比如统一小写、处理常见缩写但中文标点、全角半角问题它不会全包。用户输入“打开客厅的灯”和“打开客厅的灯。”这里的句号如果不做预处理可能影响后续实体提取的精确匹配。我一般会在进入determine_intent之前加一道清洗import re def clean_text(text): text text.lower() text re.sub(r[。、;,.!?], , text) text re.sub(r\s, , text) return text.strip()别小看这一步它至少能让实体匹配的召回率上一个台阶。尤其是用户从手机输入法里经常打出全角符号统一替换成空格后adapt-parser的短语匹配会稳定很多。5.3 调试时一定要开日志adapt-parser内部有日志输出我刚开始用的时候什么日志都不开匹配不上只能干瞪眼。后来开了 DEBUG 日志才发现它能打印出“尝试解析某条语句、匹配到哪个实体、最终选了哪个意图”的详细链路。import logging logging.basicConfig(levellogging.DEBUG)当你的实体表越来越大比如一个协议里注册了几百个实体值你会发现日志里会刷出大量“候选不匹配”的记录。这时不要慌先把日志级别调到 INFO只保留关键结果真正要排查具体某条语句时再开 DEBUG。5.4 实体表维护与性能adapt-parser不是基于深度学习的解析器它的匹配时间复杂度基本和候选实体数量成正比。如果某个实体的候选值加到几千个整体解析速度会明显下降。我的优化思路是分级注册高频常用实体放主引擎低频特殊实体单独建一个备选引擎用了兜底正则时才去查备用引擎。另外有一个非常实用的技巧把实体候选值按场景分类。同一个词在不同场景下语义不同可以设计成两套实体名称再通过两个意图去区分。比如“关闭”在灯光场景是关灯在音乐场景是停止播放虽然候选词一样但实体名不一样意图构建器就能准确区分场景避免所有带“关闭”的指令全部涌向同一个意图。5.5 中英文混合输入的适配经验如果你的系统要同时支持中文和英文指令我建议不要把两种语言放在同一个实体候选列表里硬塞。分开注册实体表比如中文Action实体注册“打开”英文实体注册“turn on”然后分别构建对应语言的意图解析器最后在入口层判断语言类型再分发给不同的IntentDeterminationEngine实例。这种做法代码量略多但后续扩展新语言非常方便也不会因为中英文短语的token化方式不同而互相干扰。6. 结尾我的一点实战心得写完这些我最想给你留个实操层面的建议不要一开始就追求把所有语义都用IntentBuilder表达出来。我最早做设备控制时恨不得一个意图把“时间、地点、人物、动作”全部塞进require结果用户稍微说一句省略主语或宾语的指令整个解析直接失败。后来我改成“必须实体只保留核心动作和核心对象其余全部 optionally”识别率反而高了很多。另外adapt-parser的适配方案其实很灵活不要被它的类名限制住思路。你完全可以用它做协议指令清洗、日志关键信息提取、甚至是文本格式校验只要把“要提取的信息”定义成实体把“触发条件”定义成意图这套解析思路就能迁移过去。如果你在中文场景下遇到匹配不顺先看看是否做了空格和标点归一化再看正则命名分组是否和实体名一致这两个问题解决了大部分匹配问题都能迎刃而解。

相关新闻

open-code-review:基于CLI+git diff+LLM Agent的可插拔代码审查范式

open-code-review:基于CLI+git diff+LLM Agent的可插拔代码审查范式

1. “open-code-review”不是工具名,而是正在发生的协作范式迁移你最近在 GitHub 提交 PR 后,是不是发现评论区里多了一条带 🤖 图标的自动评论?它没用“LGTM”,也没写“请补充测试”,而是逐行指出&#xf…

2026/10/20 10:51:06 阅读更多 →
open-code-review:面向 Git 工作流的开源代码评审协议

open-code-review:面向 Git 工作流的开源代码评审协议

1. 项目概述:这不是一个“代码审查工具”,而是一套可嵌入开发流的开源协作协议你有没有过这样的经历:PR 提交后,等了两小时没人点开看,最后发现是同事在忙别的事,或者压根没注意到通知;又或者&a…

2026/10/20 10:51:07 阅读更多 →
CNN可视化实战:特征图、卷积核与Grad-CAM全解析

CNN可视化实战:特征图、卷积核与Grad-CAM全解析

做视觉或者深度学习这块时间久了,多少都会遇到一种情况:模型跑通了,精度看着还行,但出问题时你根本不知道它到底哪一步出了问题。之前调一个图像分类任务,训练集里某个类别大量出现带特定纹理的背景,结果模…

2026/10/20 10:50:50 阅读更多 →

最新新闻

STM32F030 RTC唤醒与Stop模式低功耗实战:纽扣电池续航数月

STM32F030 RTC唤醒与Stop模式低功耗实战:纽扣电池续航数月

简介:这份资源面向使用STM32F030系列、尤其是STM32F030C8T芯片进行低功耗开发的嵌入式工程师与学习者,聚焦RTC闹钟定时5分钟后从待机模式唤醒这一典型场景。内容围绕LSE时钟源初始化、RTC闹钟寄存器配置、PWR唤醒事件设置以及进入待机模式的完整流程展开…

2026/10/20 10:50:42 阅读更多 →
QualityScaler 使用指南:如何在 Windows 上对图像和视频做 AI 超分与降噪

QualityScaler 使用指南:如何在 Windows 上对图像和视频做 AI 超分与降噪

QualityScaler 使用指南:如何在 Windows 上对图像和视频做 AI 超分与降噪 【免费下载链接】QualityScaler QualityScaler - image/video AI upscaler app 项目地址: https://gitcode.com/GitHub_Trending/qu/QualityScaler 照片随着时间变得模糊、噪点明显&a…

2026/10/20 10:50:42 阅读更多 →
STM32F030 RTC唤醒5分钟:Stop模式待机电流从200μA压到5μA实战

STM32F030 RTC唤醒5分钟:Stop模式待机电流从200μA压到5μA实战

简介:这份资源面向使用STM32F030系列、尤其是STM32F030C8T芯片进行低功耗开发的嵌入式工程师与学习者,聚焦RTC闹钟定时5分钟后从待机模式唤醒这一典型场景。内容围绕RTC时钟源初始化、闹钟寄存器配置、唤醒事件设置、待机模式进入与GPIO唤醒后输出等关键…

2026/10/20 10:50:42 阅读更多 →
如何用regnetx_004.pycls_in1k微调自己的数据集:从ImageNet 1000类到专属分类任务

如何用regnetx_004.pycls_in1k微调自己的数据集:从ImageNet 1000类到专属分类任务

【免费下载链接】regnetx_004.pycls_in1k 项目地址: https://ai.gitcode.com/hf_mirrors/timm/regnetx_004.pycls_in1k 点击查看 免费下载 为什么选 regnetx_004.pycls_in1k 做微调? regnetx_004.pycls_in1k 是 timm 库中 RegNetX 家族的入门级图像分类…

2026/10/20 10:50:42 阅读更多 →
de风——【从零开始学习Linux】Linux基础指令详解(一)

de风——【从零开始学习Linux】Linux基础指令详解(一)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:50:42 阅读更多 →
(Linux与计算机网络)IO模型

(Linux与计算机网络)IO模型

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:49:41 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →