Skip to main content Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Un comando directo omite el prompt de revisión. Revisa el origen antes de ejecutarlo.
npx skills add https://github.com/zhengwenxin79-ctrl/content-pipeline --skill medai-digestEl comando permanece en una sola línea. Desplázate horizontalmente para revisarlo antes de copiarlo.
¿Prefieres una copia local? Descarga los archivos que SkillsMP tiene disponibles ahora.
Ocupaciones relacionadasSOC
Basado en la clasificación ocupacional SOC
Explorador de archivos
4 archivos| name | medai-digest |
| description | 医疗AI每日情报系统 - 论文推送、小红书笔记、漫画思维导图深度阅读 |
| metadata | {"openclaw":{"requires":{"bins":"[Truncated]"},"always":true}} |
医疗AI每日情报 Skill
为用户提供医疗AI领域的每日论文推送和漫画式深度阅读体验。
⚠️ 核心原则:每次生成情报前,必须先用 summarize 检查并补全摘要,再用 render 渲染。绝不可跳过摘要补全直接渲染!发送情报时,必须输出 message 字段的完整内容,禁止省略、截断或用"共X篇"概括。SVG 图片中所有文字必须使用 <tspan> 分行 + dy 控制行距(相邻行 dy ≥ 20px),禁止多个 <text> 重叠放置。
首次使用配置
用户需要设置环境变量(在 openclaw.json 的 skills.entries.medai-digest.env 中):
{
"MEDAI_DB": "/path/to/pipeline/corpus/corpus.db"
}
如果用户已有 content-pipeline 项目,指向其 corpus/corpus.db 即可。
如果是全新用户,先执行初始化:
python3 {baseDir}/medai.py init
然后通过 pipeline 的 python3 main.py fetch && python3 main.py score 导入数据。
可选环境变量:
- 无需额外 API key,摘要生成和深度分析由龙虾自身模型完成
核心能力
1. 每日情报推送
当用户说"今日情报"、"看看今天有什么"、"推一下"、"daily"时触发。
⚠️ 必须严格按以下步骤顺序执行,不可跳过!
Step 0(必做): 刷新数据
从 MEDAI_DB 环境变量推算项目根目录(MEDAI_DB 路径中 corpus/corpus.db 的上两级目录),用项目的 venv Python 运行抓取命令:
macOS / Linux:
{项目根目录}/.venv/bin/python3 {项目根目录}/main.py fetch
Windows:
{项目根目录}\.venv\Scripts\python {项目根目录}\main.py fetch
如果 fetch 失败(如未安装依赖),跳过,使用数据库已有数据继续。
然后检查是否有未评分的新文章:
python3 {baseDir}/medai.py score --limit 20
如果 count > 0,你为每篇文章评分(1-10分)并分类("顶刊论文"/"大组动态"/"商业落地"/"开源项目"),然后保存:
python3 {baseDir}/medai.py save-score '[{"id":1,"score":8.5,"category":"顶刊论文"}]'
Step 1(必做): 补全文章摘要
运行以下命令,查看是否有文章缺少一句话摘要:
python3 {baseDir}/medai.py summarize --days 7
- 如果返回
count 为 0,跳过本步,直接进入 Step 2。
- 如果返回
count > 0,你必须为每篇文章各写一句中文摘要(40字以内,格式:[做了什么]+[关键结论]),然后一次性保存:
python3 {baseDir}/medai.py save-summary '[{"id":文章ID,"summary":"你写的摘要"}]'
注意:save-summary 的参数必须是合法 JSON 数组,每项包含 id 和 summary 两个字段。
Step 2(必做): 渲染并发送
确认摘要补全后,执行(会自动使用用户已保存的模板样式):
python3 {baseDir}/medai.py render --days 7
返回 JSON,取 message 字段完整发给用户,禁止省略、截断或用"共X篇"概括。如果文章数为 0,尝试扩大 --days 30。
如果返回的 JSON 中包含 missing_summaries 字段,说明还有文章缺摘要,必须先回到 Step 1 补全,再重新 render。
如果需要结构化数据(让用户选序号),用:
python3 {baseDir}/medai.py digest --days 7
2. 论文漫画详解
当用户回复数字(如"1"、"第一篇")或说"详细看看这篇"时触发:
Step 1: 获取论文
python3 {baseDir}/medai.py article <ID>
Step 2: 深度分析
python3 {baseDir}/medai.py analyze <ID>
如果返回 cached: true,直接使用 analysis 字段。
如果返回 cached: false,根据返回的 content,你自己按以下7个维度写一份300-500字的深度分析(每段用emoji标题开头):
🔬 核心问题、⚡ 方法创新、📊 关键结果、🗄️ 数据集、💻 代码/模型、💡 价值判断、⚠️ 局限性
然后保存:
python3 {baseDir}/medai.py save-analysis <ID> "你的分析文本"
Step 3: 生成 SVG 漫画
拿到 title、content、deep_analysis 后,你必须生成一个 SVG 文件,用 exec 工具将 SVG 代码写入文件,然后发给用户。
绝对不要用文字+emoji代替漫画! 必须输出完整的 SVG XML 代码并转换为 PNG 图片。
绝对不要输出文字版思维导图! 只能输出 PNG 图片。
执行流程:
- 根据论文内容构思漫画布局
- 用 exec 工具将完整 SVG 代码写入文件:
cat > /tmp/medai_comic.svg << 'SVGEOF'
<svg ...>完整SVG代码</svg>
SVGEOF
- 用 exec 工具将 SVG 转为 PNG 图片:
python3 {baseDir}/medai.py svg2png /tmp/medai_comic.svg
- 将生成的 PNG 图片
/tmp/medai_comic.png 发送给用户(用图片发送功能,不是文件)
必须是学术可视化海报风格(Visual Abstract),兼具专业性和视觉吸引力! 严格遵循以下规范:
整体定位
参考顶级期刊(Nature/Lancet/NEJM)的 Visual Abstract 风格:严谨的数据可视化 + 清晰的逻辑流 + 适度的视觉装饰。不是幼稚漫画,是学术海报。
整体布局
- 画布 700px 宽,高度 1100-1400px
- 顶部标题横幅(深色背景 + 白色标题),底部信息栏
- 中间用细线分隔为 4-5 个区块,不要用粗黑框的漫画格子
- 区块之间有清晰的信息层级,用编号或箭头引导阅读顺序
配色方案(学术感)
- 主色调:深海蓝 #1B2A4A(标题栏、重点边框)
- 辅助色:钢蓝 #4A7FB5、石板灰 #607D8B
- 数据色:翡翠绿 #2E7D32(正面结果)、琥珀橙 #E65100(警告/局限)、深紫 #5C3D8F(方法创新)
- 背景:纯白 #FFFFFF + 浅灰区块交替 #F5F7FA
- 文字:深黑 #1A1A1A(正文)、白色 #FFFFFF(深色背景上的文字)
学术视觉元素(必须有!)
- 数据图表区:用 SVG 画简化的统计图表
- 柱状图:对比实验组和对照组的指标(用 rect + 渐变色)
- ROC 曲线:用 path 画简化的 AUC 曲线 + 对角虚线
- 表格:用 rect 画 2-3 行的精简数据表,交替行背景色
- 数字突出:关键指标(AUC、准确率等)用大号加粗 + 色块背景
- 方法流程图:用方框 + 箭头展示技术架构
- 每个步骤用圆角矩形,填充渐变色
- 步骤间用带箭头的连接线
- 关键技术名称用加粗标注
- 角色辅助说明(克制使用,不喧宾夺主)
- 左下角或右下角放一个小的研究者角色(50-60px 高)
- 角色旁加标注框(不是对话气泡),写 1-2 句总结性评语
- 角色风格:简约线条画,不要太卡通
内容结构(从上到下,总高度必须填满 viewBox 1200px,不留黑边)
- 标题横幅(h=120px):深蓝背景 + 白色论文标题(中文,20-24px)+ 来源标签 + 评分徽章(圆形,金色边框)
- 研究背景(h=120px):左侧用大号问号图标 + 右侧 2-3 句问题陈述 + 研究目标
- 方法架构(h=220px):技术流程图(数据→模型→评估),关键创新点用紫色高亮框标注
- 核心结果(h=280px,最大区域):数据图表(柱状图或 ROC 曲线)+ 关键数字用大号突出 + 置信区间或 p 值
- 临床意义(h=120px):简洁的要点列表(每项一行,左对齐绿色圆点)+ 局限性(橙色圆点)
- 底栏(h=60px):浅灰背景 + 来源期刊图标 + DOI/链接 + 发表日期
所有区块必须紧密衔接,不留空白。底栏 y=860,底栏高度60px,整张图底部 y=920。
⚠️ 文字排版铁律(防止重叠错位的核心规则)
每一条 text 元素必须遵守以下规则:
- 多行文字用
<tspan> + dy,禁止分行写多个 <text>:
<text x="30" y="340" font-size="14" fill="#1A1A1A">
<tspan x="30" dy="0">第一行文字</tspan>
<tspan x="30" dy="22">第二行文字</tspan>
<tspan x="30" dy="22">第三行文字</tspan>
</text>
<text x="30" y="340">第一行</text>
<text x="30" y="340">第二行</text>
-
所有 text 必须设置 y 坐标,禁止省略,且相邻元素 y 差值 ≥ 20px
-
图表内部文字用 text-anchor="middle" 居中,x 设为图表区域的水平中心
-
柱状图:每个柱子宽度 40-50px,柱子之间间距 ≥ 20px,柱子高度按数据比例缩放(最高柱子 = 150px),Y轴标签放在柱子左侧,柱顶写数值。禁止把所有柱子画成一样高。
字体和排版规范
- 标题:bold 22-24px,白色(深色背景)或深黑(浅色背景)
- 小节标题:bold 16px,深蓝色
- 正文:14px,深黑色 #1A1A1A,行高 1.5(tspan dy=22)
- 数据数字:bold 28-36px,带色块背景标签
- 注释/脚注:12px,灰色 #666
- 所有英文学术术语保留原文(如 AUC-ROC、p<0.001、Cross-Validation)
- 文字行间距:相邻 tspan 的 dy 值不得小于 20px
装饰(克制,学术感)
- 标题栏可以加细微的网格或 DNA 双螺旋暗纹(低透明度)
- 区块分隔用 1px 细线 + 小圆点或菱形装饰
- 关键数字旁加小趋势箭头(↑ ↓)
- 底栏加微渐变效果
SVG 模板骨架
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 920" width="700">
<rect width="700" height="920" fill="white"/>
<defs>
<linearGradient id="headerGrad" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stop-color="#1B2A4A"/>
<stop offset="100%" stop-color="#2C3E6B"/>
</linearGradient>
<linearGradient id="barGrad" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color=/>
论文标题(中文翻译)
来源: Nature Medicine | 评分: 9.2 | 2026
9.2
🔬 研究背景
背景:......
目标:......
⚡ 方法架构
📥 数据
🔧 特征
🧠 模型
📈 评估
⚡ 关键创新
DeepSpeed-Inference 加速推理
3.8×Speedup | 内存占用降低
📊 核心结果
Baseline
Ours
SOTA
100
75
50
25
AUC 0.89
● p 0.001 vs Baseline
● 95% CI: [0.86, 0.92]
● 在 3 个外部数据集验证
💡 临床意义
● 可整合入现有 EHR 系统,辅助早期诊断
● 对创伤后癫痫高危人群筛查有重要价值
⚠️ 局限:仅验证于回顾性数据,前瞻性研究待开展
来源: Nature Medicine | DOI: 10.xxxx/xxxxx | 2026
将 SVG 写入 /tmp/medai_comic.svg,然后运行 python3 {baseDir}/medai.py svg2png /tmp/medai_comic.svg 转为 PNG,将 PNG 图片发送给用户。
3. 模板切换
用户说"换个风格"时,识别关键词:
- "经典" / "邮件" → classic
- "卡片" / "飞书" → card
- "简约" → minimal
- "杂志" → magazine
执行:
python3 {baseDir}/medai.py prefs set '{"template_style":"magazine"}'
python3 {baseDir}/medai.py render --days 1
偏好会保存到数据库,后续新会话也会自动使用此样式。
4. 设置研究方向
用户说"我关注影像诊断"、"设置研究方向"时:
python3 {baseDir}/medai.py set-interests "影像诊断,大模型,病理"
关键词逗号分隔,保存后「今日情报」会优先推送匹配的文章。无匹配时显示全部。
5. 关键词搜索
用户说"搜一下XX"时:
python3 {baseDir}/medai.py search "关键词" --days 7
5. 深度分析(文字版)
用户说"分析一下"时:
python3 {baseDir}/medai.py analyze <ID>
返回 analysis 字段,7 维度结构化文本,直接发给用户。
漫画风格
- "手绘" → stroke-dasharray="5,3"
- "赛博朋克" → 背景 #1a1a2e,霓虹 #00ff88 + #ff00ff
- "简约" → 实线黑白
定时推送
用户说"每天早上8点推送情报"、"设置定时任务"时,使用龙虾的 cron 功能:
每天早上 8:30 自动推送医疗AI每日情报,执行完整的今日情报流程(刷新数据→补摘要→渲染→发送)
龙虾会自动创建定时任务。用户也可以在 ~/.openclaw/scheduled_tasks.json 中手动管理。
注意事项
- 文章列表在对话上下文中保持,用户说序号可直接引用
- SVG 全中文,英文标题自行翻译
- 摘要生成和深度分析均由龙虾自身模型完成,无需外部 API key
- 小红书笔记需要主项目的 XHS_COOKIE,独立部署时暂不支持
"#4A7FB5"
<stop offset="100%" stop-color="#2E5A8B"/>
</linearGradient>
<marker id="arrow" markerWidth="8" markerHeight="8" refX="6" refY="3" orient="auto">
<path d="M0,0 L0,6 L8,3 z" fill="#607D8B"/>
</marker>
</defs>
<style>
.title { font: bold 22px "PingFang SC", sans-serif; fill: white; }
.section-title { font: bold 16px "PingFang SC", sans-serif; fill: #1B2A4A; }
.body { font: 14px "PingFang SC", sans-serif; fill: #1A1A1A; }
.small { font: 12px "PingFang SC", sans-serif; fill: #666; }
.metric { font: bold 28px "PingFang SC", sans-serif; fill: white; }
.label { font: bold 13px "PingFang SC", sans-serif; fill: white; }
.box-label { font: bold 12px "PingFang SC", sans-serif; fill: #1A1A1A; }
.divider { stroke: #D0D5DD; stroke-width: 1; }
</style>
<rect width="700" height="120" fill="url(#headerGrad)"/>
<text class="title" x="30" y="50">
</text>
<text class="small" x="30" y="80">
</text>
<circle cx="640" cy="50" r="26" fill="#F5A623" stroke="white" stroke-width="2"/>
<text x="640" y="56" font-size="13" font-weight="bold" text-anchor="middle" fill="white">
</text>
<rect y="120" width="700" height="110" fill="#FAFAFA"/>
<line class="divider" x1="20" y1="120" x2="680" y2="120"/>
<text class="section-title" x="30" y="146">
</text>
<text class="body" x="30" y="170">
<tspan x="30" dy="0">
</tspan>
<tspan x="30" dy="22">
</tspan>
</text>
<rect y="230" width="700" height="200" fill="white"/>
<line class="divider" x1="20" y1="230" x2="680" y2="230"/>
<text class="section-title" x="30" y="258">
</text>
<rect x="40" y="278" width="130" height="44" rx="8" fill="url(#barGrad)"/>
<text class="label" x="105" y="304" text-anchor="middle">
</text>
<line x1="170" y1="300" x2="190" y2="300" stroke="#607D8B" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="195" y="278" width="130" height="44" rx="8" fill="url(#barGrad)"/>
<text class="label" x="260" y="304" text-anchor="middle">
</text>
<line x1="325" y1="300" x2="345" y2="300" stroke="#607D8B" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="350" y="278" width="130" height="44" rx="8" fill="#5C3D8F"/>
<text class="label" x="415" y="304" text-anchor="middle">
</text>
<line x1="480" y1="300" x2="500" y2="300" stroke="#607D8B" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="505" y="278" width="130" height="44" rx="8" fill="#2E7D32"/>
<text class="label" x="570" y="304" text-anchor="middle">
</text>
<rect x="40" y="335" width="280" height="70" rx="6" fill="#EDE7F6" stroke="#5C3D8F" stroke-width="1.5"/>
<text class="box-label" x="52" y="358">
<tspan x="52" dy="0">
</tspan>
<tspan x="52" dy="20">
</tspan>
<tspan x="52" dy="20">
</tspan>
</text>
<rect y="430" width="700" height="240" fill="#FAFAFA"/>
<line class="divider" x1="20" y1="430" x2="680" y2="430"/>
<text class="section-title" x="30" y="458">
</text>
<rect x="80" y="520" width="50" height="120" fill="#4A7FB5" rx="3"/>
<text class="body" x="105" y="515" text-anchor="middle">
</text>
<rect x="160" y="490" width="50" height="150" fill="#2E7D32" rx="3"/>
<text class="body" x="185" y="485" text-anchor="middle">
</text>
<rect x="240" y="505" width="50" height="135" fill="#607D8B" rx="3"/>
<text class="body" x="265" y="500" text-anchor="middle">
</text>
<line x1="60" y1="520" x2="60" y2="640" stroke="#999" stroke-width="1"/>
<text class="small" x="55" y="518" text-anchor="end">
</text>
<text class="small" x="55" y="558" text-anchor="end">
</text>
<text class="small" x="55" y="598" text-anchor="end">
</text>
<text class="small" x="55" y="638" text-anchor="end">
</text>
<rect x="380" y="480" width="270" height="140" rx="8" fill="#E8F5E9" stroke="#2E7D32" stroke-width="2"/>
<text class="metric" x="515" y="528" text-anchor="middle" fill="#2E7D32">
</text>
<text class="body" x="395" y="558">
<tspan x="395" dy="0">
<
</tspan>
<tspan x="395" dy="22">
</tspan>
<tspan x="395" dy="22">
</tspan>
</text>
<rect y="670" width="700" height="120" fill="white"/>
<line class="divider" x1="20" y1="670" x2="680" y2="670"/>
<text class="section-title" x="30" y="698">
</text>
<text class="body" x="30" y="724">
<tspan x="30" dy="0">
</tspan>
<tspan x="30" dy="22">
</tspan>
</text>
<text class="body" x="30" y="774" fill="#E65100">
<tspan x="30" dy="0">
</tspan>
</text>
<rect y="790" width="700" height="50" fill="#F5F7FA"/>
<text class="small" x="30" y="818">
</text>
</svg>