# Tech News Daily

> 科技新闻日报技能。每日科技新闻热榜整理与报告生成。当用户说"科技新闻日报"、"整理今日科技新闻"、"生成科技新闻热榜"、"tech-news-daily"、"TechNews-Daily-Report"或类似表达时触发。功能包括：(1) 使用 Tavily 搜索引擎近7天科技/AI 新闻进行搜索；(2) 按相关度和推荐度评分整理；(3) 自动写入本地 markdown 文件；(4) 同步创建飞书文档到个人知识库；(5) 只发送飞书文档链接到飞书群（不发完整报告内容）。

- Skill: `lord1egypt/tech-news-daily` (Agent Skill)
- Install (CLI): `npx skillmds@latest add lord1egypt/tech-news-daily`
- Raw SKILL.md: https://api.skillmd.com/api/skills/lord1egypt/tech-news-daily/raw
- Safety review: pending (external: skill-scanner PASS, skillspector CAUTION)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: Lord1Egypt (https://skillmd.com/u/lord1egypt)
- Updated: 2026-09-08
- Page: https://skillmd.com/skills/lord1egypt/tech-news-daily

---


# 科技新闻日报 | Tech News Daily

> **版本：** 0.3.3（飞书文档存入「科技新闻日报」知识库目录，parent_node: `Iv9UwDW5viSJDWk12j7cBazYn8b`，对应链接 `https://qcnu4qzh46f0.feishu.cn/wiki/Iv9UwDW5viSJDWk12j7cBazYn8b`）

**v0.3.3 更新说明：**
- 第5步文档创建方式：从 `docs +create --wiki-node`（会导致中文乱码）改为 `wiki +node-create` + `docs +update --doc-format xml`（两步法，确保正确编码和正确位置）

## 概述

按日收集、整理并生成科技新闻热榜报告，包含相关度评分、推荐度评分、来源链接，自动同步到本地文件和飞书文档。

---

## 工作流程

### 第一步：搜索新闻

使用 `tavily_search` 并行搜索中英文科技新闻：

```
搜索词（英文）: "tech news today April YYYY" + "AI artificial intelligence"
搜索词（中文）: "科技新闻 YYYY年MM月DD日 热榜" + "AI 人工智能 科技 最新消息"
时间范围: time_range="week"  （近7天，过滤掉更早的新闻）
结果数量: max_results=10~15
```

**并行搜索策略：**
- 英文 TechCrunch / The Guardian / Fortune / Ars Technica
- 中文 新华网 / 证券时报 / 行业垂直媒体

### 第二步（插入）：合并去重

**先合并，再去重，最后评分。**

将所有搜索结果（英文 + 中文）合并后，执行两轮去重：

**第一轮：URL 精准去重**
- 同一 URL 只保留一条（不同搜索词可能返回相同链接）
- 保留信息最完整的那条（摘要更长、来源更权威优先）

**第二轮：语义去重（核心事实去重 + 独立价值保留）**

**两步判断，先去重，后判断是否保留独立价值：**

**Step A — 识别「同一核心事实」的重复：**
提取每条新闻的**核心三元组**（主体 + 动作 + 客体），判断两条新闻是否属于同一核心事实：
- 示例：微软(主体) 投资(动作) 日本100亿美元(客体)
- 中文"微软宣布向日本投资100亿美元"和英文"Microsoft to invest $10B in Japan" → 核心三元组相同，判定为「同一核心事实」

**Step B — 判断独立保留价值（同一核心事实的多条报道，是否都保留）：**

同一核心事实的报道，**仅在以下条件同时满足时才都保留**，否则只保留最权威的一条：
1. **来源有独立信息**（记者独立采写，非转载，且有补充事实/数据/背景）
2. **角度/维度不同**（财务分析 vs 技术解读 vs 政策分析）

**去重优先级：来源权威性 > 摘要完整性 > 发布时间更新**

**具体判断规则：**
- 同一核心事实 + 无独立信息 + 无新角度 → **去重**，保留最权威一条
- 同一核心事实 + 有独立信息 + 有新角度 → **保留**，合并摘要精华
- 不同核心事实（哪怕相关）→ **保留**

**具体例子：**
- ✅ 微软投资日本（Reuters）+ 微软投资日本（新华网）→ 同一核心事实，均为转载，无独立信息 → **去重，保留 Reuters**
- ✅ 微软投资日本（Reuters）+ 微软投资日本（36kr独立分析）→ 同一核心事实，但36kr有独立分析视角 → **都保留**
- ✅ OpenAI收购TBPN（确认报道）+ OpenAI收购TBPN（谈判进展）→ 核心事实相同，但阶段不同 → **都保留**
- ✅ OpenAI收购TBPN（中文翻译版）→ 与英文同一核心事实，无独立信息 → **去重**

### 第三步：评估与筛选

对每条新闻评估两个维度：

| 维度 | 说明 | 评分标准 |
|------|------|---------|
| **相关度** | 与科技/AI 领域的关联程度 | ⭐1-5 星 |
| **推荐度** | 对读者的阅读价值 | 0-100 分 |

**评分原则：**
- 相关度 5星：AI 技术、芯片、太空探索、重大产品发布
- 相关度 4星：科技政策、行业趋势、并购融资
- 相关度 3星：间接相关的科技新闻
- 推荐度综合考虑：时效性、重要性、独家性、可操作性

### 第四步：写入本地文件

保存路径：`memory/YYYY-MM-DD-tech-news.md`

**文件格式要求：**
- 文件头包含整理时间和来源
- 按国际/国内分类
- 每条新闻包含：标题、相关度(⭐)、推荐度(分)、摘要、来源、链接
- 底部包含数据总览表格
- 末尾同步记录（本地文件 ✅、飞书文档链接）

### 第五步：同步飞书文档

**必须用两步法：先创建 wiki 节点，再写入内容。不要用 `docs +create --wiki-node`（该方式创建的文档编码有问题且位置可能不对）。**

**正确流程：**

```bash
# 步骤 1：用 wiki +node-create 在「科技新闻日报」节点下创建 wiki 节点（返回 node_token 和 obj_token）
lark-cli wiki +node-create \
  --space-id "7621391289904516315" \
  --parent-node-token "Iv9UwDW5viSJDWk12j7cBazYn8b" \
  --title "科技新闻日报 | YYYY年MM月DD日"

# 返回示例：
# {"ok":true,"data":{"node_token":"OnBrwGTJciHcOjk90w7c1cMhn9c","obj_token":"JUqNdp3uSodBX1xF66fcNhcHnFh",...}}
# → 从返回中提取 obj_token（即 doc_token）

# 步骤 2：将本地 markdown 文件转成 XML 后，用 docs +update 写入文档
# 重要：内容必须用 XML 格式（--doc-format xml），禁止用 --doc-format markdown（会导致中文乱码）
# markdown 中的换行用 <br/>，< 用 &lt;，> 用 &gt;，& 用 &amp;
lark-cli docs +update \
  --api-version v2 \
  --doc "<obj_token>" \
  --command overwrite \
  --doc-format xml \
  --content @memory/YYYY-MM-DD-tech-news.xml

# 步骤 3：授予张公子 full_access 权限
lark-cli drive permission.members create \
  --params '{"token":"<obj_token>","type":"docx"}' \
  --data '{"member_id":"ou_d8ace8a146610ca26bc07d8e68a5620f","member_type":"openid","perm":"full_access","type":"user"}' \
  --yes
```

**内容转 XML 注意事项：**
- markdown 内容中的中文必须正确转义（`<` → `&lt;`，`>` → `&gt;`，`&` → `&amp;`，换行 → `<br/>`）
- 推荐用 Python 做 markdown → Feishu XML 的批量转义，避免手动转义出错
- 文件路径必须用相对路径（如 `@memory/2026-05-15-tech-news.xml`），不能是绝对路径
- **禁止**用 `--doc-format markdown` 写入（会导致中文乱码）

**飞书知识库存档目标（v0.3.3）：**
- space_id：`7621391289904516315`
- parent_node_token：`Iv9UwDW5viSJDWk12j7cBazYn8b`（科技新闻日报目录）
- 节点 token：从 `wiki +node-create` 返回的 `node_token`
- doc token：从 `wiki +node-create` 返回的 `obj_token`

**Fallback（当 lark-cli 不可用时）：**

如果 `wiki +node-create` 调用失败，自动切换到 Feishu Open API 直接调用：
```bash
# 1. 获取 tenant_access_token
ACCESS_TOKEN=$(curl -s -X POST 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal' \
  -H 'Content-Type: application/json' \
  -d '{"app_id": "cli_a94b4a1e43781cc7", "app_secret": "<FEISHU_APP_SECRET>"}' \
  | python3 -c "import sys,json; print(json.load(sys.stdin).get('tenant_access_token',''))")

# 2. 在知识库「科技新闻日报」节点下创建 wiki 节点
curl -s -X POST 'https://open.feishu.cn/open-apis/wiki/v2/spaces/7621391289904516315/nodes' \
  -H 'Authorization: Bearer '$ACCESS_TOKEN \
  -H 'Content-Type: application/json' \
  -d '{"parent_node_token": "Iv9UwDW5viSJDWk12j7cBazYn8b", "node_type": "origin", "obj_type": "docx", "title": "科技新闻日报 | YYYY年MM月DD日"}'
# → 获得 obj_token

# 3. 写入文档内容（batch create blocks，XML 格式）
curl -s -X POST 'https://open.feishu.cn/open-apis/docx/v1/documents/<obj_token>/blocks/<root_block_id>/children' \
  -H 'Authorization: Bearer '$ACCESS_TOKEN \
  -H 'Content-Type: application/json' \
  -d '{"children": [...]}'
```

> ⚠️ Fallback 需要 `app_secret`，优先确保 lark-cli 可用——只有当 lark-cli 不可用时才走 fallback。

### 第六步：发送飞书文档链接

**只发链接，不发完整报告内容。**

发送格式：
```
📰 科技新闻日报 | YYYY年MM月DD日
🔗 飞书文档：https://feishu.cn/docx/xxxxx
💾 本地文件：memory/YYYY-MM-DD-tech-news.md
```

使用 `message(action="send", channel="feishu", target="chat:oc_d591432cedf9a00c01878c24754cb050", message="...")`

### 第七步：更新本地文件同步记录

在本地文件末尾添加：
```
## 📋 同步记录
- ✅ 本地文件：`memory/YYYY-MM-DD-tech-news.md`
- ✅ 飞书文档：`科技新闻日报 | YYYY年MM月DD日`
  - 文档链接：https://feishu.cn/docx/xxxxx
  - 知识库：个人知识库
```

---

## 输出模板

```
# 科技新闻日报 | YYYY年MM月DD日

> 整理时间：YYYY-MM-DD HH:MM GMT+8
> 来源：Tavily 搜索 + 公开新闻聚合

---

## 🌐 国际科技热榜

### 1. [新闻标题]
- 相关度：⭐⭐⭐⭐⭐ | 推荐度：XX/100
- 摘要：[1-2句话描述]
- 来源：[媒体名称]
- 链接：[URL]

[... 7条国际新闻 ...]

---

## 🇨🇳 国内 AI 热榜

### 1. [新闻标题]
- 相关度：⭐⭐⭐⭐⭐ | 推荐度：XX/100
- 摘要：[1-2句话描述]
- 来源：[媒体名称]
- 链接：[URL]

[... 8条国内新闻 ...]

---

## 📊 数据总览

- 国际：X 条，平均推荐度 XX
- 国内：X 条，平均推荐度 XX
- 合计：XX 条，平均推荐度 XX

---

## 🔗 关键来源

- [来源1名称]：URL
- [来源2名称]：URL
[...]

---

整理：牛管家 | 整理工具：Tavily 搜索

## 📋 同步记录

- ✅ 本地文件：`memory/YYYY-MM-DD-tech-news.md`
- ✅ 飞书文档：`科技新闻日报 | YYYY年MM月DD日`
  - 文档链接：https://feishu.cn/docx/xxxxx
  - 知识库：个人知识库
```

---

## 参考资源

- **飞书文档操作：** 见 `references/feishu-doc.md`
- **Tavily 搜索：** 使用 `tavily_search` 工具，topic="news"，search_depth="basic" 或 "advanced"

---

## 注意事项

1. **并行搜索**：中英文搜索同时进行，提高效率
2. **时效过滤**：只收录近7天内的新闻，老旧新闻（超过7天）不再收藏，已过期的新闻不计入报告
3. **链接有效性**：优先使用原始来源链接，避免短链接
4. **评分一致性**：相关度和推荐度应有明显区分，相关度高不等于推荐度高
5. **飞书权限**：创建文档时必须传入 `owner_open_id` 确保用户有编辑权限
6. **文件命名**：使用 `YYYY-MM-DD-tech-news.md` 格式，便于排序检索
7. **去重时机**：去重必须在合并所有搜索结果之后、评分之前进行，先去重再评分，不能边搜边去重

---

## ⚠️ 执行建议（重要）

**使用子会话 + 主会话接管的混合模式：**

```markdown
1. 主会话用 sessions_spawn 启动子会话执行前半段：
   - runtime: "subagent"
   - mode: "run"
   - runTimeoutSeconds: 600
   - task: 完整的科技新闻日报任务描述（步骤1-6，只写到本地文件）

2. 主会话在子会话完成后，接管后半段：
   - feishu_wiki 获取知识库
   - feishu_doc 创建并写入飞书文档
   - message 发送链接到飞书群
```

**为什么这样拆分：**
- 子会话负责搜索/整理（耗时，但不需要飞书工具）
- 主会话负责飞书文档操作（子会话里 feishu_doc/feishu_wiki 不可用）
- 主会话超时窗口足够完成文档创建（只需几分钟）

**子会话执行流程（只做前半段）：**
1. 并行中英文搜索（tavily_search）
2. **合并所有搜索结果**（不评分，不分类，先拢到一起）
3. **两轮去重**：
   a) URL精准去重（同一链接只一条）
   b) 语义去重：提取核心三元组（主体+动作+客体），同一核心事实的报道：无独立信息无新角度 → 只保留最权威那条；有独立信息或新角度 → 保留多条
4. **评分**（去重完成后，才开始评分）
5. 分类（国际/国内）
6. 写入本地文件 `memory/YYYY-MM-DD-tech-news.md`，checkpoint 标记 step=4，**然后子会话结束**

**主会话接管后半段（子会话返回后）：**
7. 读取子会话生成的本地文件
8. 调用 `feishu_wiki(action="spaces")` 获取个人知识库 space_id
9. 调用 `feishu_doc(action="create", title="科技新闻日报 | YYYY年MM月DD日", folder_token="首页节点token", owner_open_id="请求用户open_id")` 创建飞书文档
10. 调用 `feishu_doc(action="write", doc_token="新文档token", content="markdown内容")` 写入完整报告
11. **只发飞书文档链接到群**（不发完整报告）
12. 更新本地文件同步记录，标记 step=done

**进度 Checkpoint（v0.2.5 新增）：每步必须写checkpoint**
子会话在每个关键步骤完成后，立即将进度写入 checkpoint 文件 `memory/YYYY-MM-DD-tech-news-checkpoint.json`：

```json
{
  "step": 6,
  "stepName": "飞书文档创建完成",
  "feishuDocUrl": "https://feishu.cn/docx/xxx",
  "localFile": "memory/2026-04-17-tech-news.md",
  "timestamp": 1776396500000,
  "pendingAction": "发送飞书链接"
}
```

**步骤说明：**
- step 1: 搜索完成 → 写入 checkpoint
- step 2: 去重完成 → 写入 checkpoint（附上去重后条数）
- step 3: 评分完成 → 写入 checkpoint
- step 4: 本地文件写入完成 → 写入 checkpoint（标记 localFile 路径）
- step 5: 飞书文档创建完成 → 写入 checkpoint（标记 feishuDocUrl）
- step 6: **只发飞书文档链接到群** → 最后一步，**必须成功**，完成后写入 step: done

**超时补救机制（v0.2.6 强化版）：**
子会话只负责前半段（step 1-4），主会话接管后半段。如果主会话收到子会话超时事件，按以下顺序检查：

1. 读取 checkpoint 文件 `memory/YYYY-MM-DD-tech-news-checkpoint.json`
2. 如果 `step >= 4`（本地文件已写）→ 主会话继续执行步骤7-12（创建飞书文档+发送链接）
3. 如果 `step == done` → 任务已完成，无需补救
4. 如果 `step < 4` → 任务早期失败，需要重新执行

**⚠️ 重要：子会话无法创建飞书文档（feishu_doc 工具在 subagent sessions 中不可用）。所有飞书文档操作必须在主会话执行。**

**⚠️ Fallback 触发条件（v0.2.7）：**
当 `feishu_wiki` 或 `feishu_doc` 工具调用失败（返回 ToolNotFoundError 或类似错误），自动切换到 direct Feishu Open API 调用（见第五步 fallback 说明）。Fallback 模式下需要自行获取 tenant_access_token，建议将 app_secret 存入环境变量 `FEISHU_APP_SECRET` 供 curl 使用。

**⚠️ 关键修复（v0.2.6）：只发链接不发内容；子会话不创建文档**
- 步骤6（发送飞书链接）是整个流程中**最后一步**，只发文档链接，不发完整报告内容
- 飞书群组 ID（目标）：`oc_d591432cedf9a00c01878c24754cb050`
- 消息格式：`📰 科技新闻日报 | YYYY年MM月DD日\n🔗 飞书文档：https://feishu.cn/docx/xxxxx\n💾 本地文件：memory/YYYY-MM-DD-tech-news.md`
- 必须使用 `message(action="send", channel="feishu", target="chat:oc_d591432cedf9a00c01878c24754cb050", message="...")`
- **禁止**在发送飞书消息之前结束会话——即使所有文件/文档操作都完成了，也要留足时间发送消息
- 飞书消息发送成功后，才更新 checkpoint 为 `step: done`

