# dsh-newslatest **Repository Path**: violetlength/dsh-newslatest ## Basic Information - **Project Name**: dsh-newslatest - **Description**: 基于deepseek-Harness下的,新闻数据源管理项目; - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-20 - **Last Updated**: 2026-08-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # dsh-news 把 [NewsList](https://github.com/...)(Tauri + Rust 桌面新闻聚合)的**数据能力**移植为 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(DSH)插件。 让 DeepSeek Agent 能拉热榜、抓网页、管理自定义源,**一句话就能得到一份今日要闻简报**。 设计分层:工具负责取数(`news_top`/`news_digest` 聚合 + `news_fetch` 单源), AI 总结交给 Harness 自身 LLM——符合 DSH「工具取数、模型推理」的哲学。 ## 快速上手(5 分钟跑起来) 前置条件:`dsh-harness`(本仓库同级目录)里已带便携版 Node 22,**不需要**手动装 Node。 ```bash # 1. 构建插件 cd deepseekPlugin/dsh-news npm install npm run build # 2. 启动 Web 控制台(自动用便携 Node 22 + 本地插件路径) cd ../dsh-harness ./run-dsh.sh web --patch ../dsh-news/cordis.local.yml # Windows: run-dsh.cmd web --patch ..\dsh-news\cordis.local.yml # 3. 打开 http://127.0.0.1:3080 ,输入: # "给我今天的新闻简报" → 调 news_digest 输出可直接阅读的简报 # "拉一下微博热搜前10条" → 调 news_fetch(source=微博) # "今天有什么热点" → 调 news_top 聚合多源合并榜单 # "配置LLM" → 调 news_config_llm 填写 apiKey/model 等,保存到本地 # "改一下默认源" → 调 news_config 修改默认数据源 ``` 命令行模式(需要 `DEEPSEEK_API_KEY` 环境变量,或通过 `news_config_llm` 工具配置): ```bash cd deepseekPlugin/dsh-harness ./run-dsh.sh --profile headless --patch ../dsh-news/cordis.local.yml "今天有什么热点" ``` > **关于 Node 版本**:harness 需要 Node ≥ 22.19(zstd + `Promise.withResolvers`)。 > `dsh-harness/.node/` 已捆绑便携版 Node 22.19,脚本会自动优先使用它,不依赖系统 Node。 ## 工具(12 个) ### 新闻获取(7 个) | 工具 | 说明 | | --- | --- | | `news_top` | **聚合多源合并榜单**:自动去重、标注来源、按源顺序排列。不传参即用默认源。最适合「今天有什么热点」 | | `news_digest` | **一键今日要闻简报**:抓多个热榜 → 合并去重 → 每条附一句离线摘要,直接输出可读文本 | | `news_fetch` | 按源名拉热榜。支持中文别名(微博/B站/知乎/36氪…)、`all`/`全部`、不传参用默认源 | | `news_list_sources` | 列出全部内置源(含别名/TTL)+ 自定义源 | | `news_scrape` | 抓取任意 URL(json/web/auto 模式,可指定容器选择器,自动补全相对链接) | | `news_summarize` | 本地抽取式摘要(离线,无需 API key) | | `news_clear_cache` | 清空缓存 | ### 配置管理(2 个) | 工具 | 说明 | | --- | --- | | `news_config_llm` | **配置 LLM 服务**(API Key、模型、Base URL、Provider)。保存到插件本地目录 `~/.dsh-news/llm-config.json`,下次启动自动加载。不传参数显示当前配置 | | `news_config` | **查看/修改插件全局配置**(默认数据源、缓存时间、单源最大条目)。保存到 `~/.dsh-news/plugin-config.json`,下次启动自动加载。不传参数显示当前配置 | ### 自定义数据源(3 个) | 工具 | 说明 | | --- | --- | | `news_source_add` | **新增自定义源**(json/web),**自动调用 AI 分析**生成最优选择器/字段映射,持久化到 `user_sources.json` | | `news_source_list` | 列出自定义源(含 AI 分析状态) | | `news_source_remove` | 删除自定义源 | > **AI 分析能力**:添加自定义源时,插件会自动: > - **HTML 源**:抓取页面 → 调用 LLM 分析 DOM 结构 → 生成 CSS 选择器规则 → 保存到 `extraction_rules` > - **JSON 源**:获取 API 响应 → 调用 LLM 分析字段结构 → 生成字段映射规则 → 保存到 `field_mappings` > - 抓取时优先使用保存的 AI 规则,失败则降级到基础规则 > - 需要先通过 `news_config_llm` 配置 API Key,否则使用 fallback 规则 示例对话: ``` 用户:今天有什么热点? 模型:news_top(sources="微博,知乎,B站") → 返回合并去重后的榜单,模型再按热度总结成回答。 用户:给我今天的新闻简报 模型:news_digest(sources="微博,知乎,36氪", limit=15) → 直接输出带摘要的简报文本。 用户:配置一下LLM 模型:news_config_llm(apiKey="sk-xxx", model="deepseek-chat") → 保存到 ~/.dsh-news/llm-config.json,当前会话立即生效,下次启动自动加载。 用户:以后默认看科技类的 模型:news_config(defaultSources="掘金,InfoQ,GitHub,IT之家") → 保存到 ~/.dsh-news/plugin-config.json,下次启动自动加载。 用户:添加一个 Hacker News 数据源 模型:news_source_add(name="hackernews", title="Hacker News", url="https://hacker-news.firebaseio.com/v0/topstories.json", source_type="json") → 插件自动调用 AI 分析 JSON 结构,生成字段映射规则,保存到 user_sources.json → 之后用 news_fetch(source=hackernews) 即可拉取数据 ``` ## 内置源(对应 news_service.rs) bilibili, weibo, zhihu, github, juejin, douyin, 36kr, ithome, infoq, oschina, segmentfault, csdn, stcn, caixin, ruanyifeng 支持中文别名:`B站`/`哔哩哔哩`、`微博`、`知乎`、`掘金`、`36氪`、`IT之家`、`思否`/`SegmentFault`、 `CSDN`、`财新`、`阮一峰` 等,大小写不敏感。 ## 配置文件 插件本地目录 `~/.dsh-news/` 下有三个持久化文件: | 文件 | 内容 | 由哪个工具管理 | | --- | --- | --- | | `llm-config.json` | LLM API Key / 模型 / Base URL / Provider | `news_config_llm` | | `plugin-config.json` | 默认数据源 / 缓存时间 / 单源最大条目 | `news_config` | | `user_sources.json` | 用户自定义数据源列表 | `news_source_add/list/remove` | 首次使用无需手动创建——工具首次保存时自动创建,下次启动自动加载。 ## 测试 ```bash npm test # 冒烟测试(离线):45 项 npm run test:integration # 集成测试(真网络):31 项,12 个工具全部覆盖 npm run probe # 体检 15 个内置源(源站改版后先跑它定位失效源) npm run typecheck # tsc --noEmit ``` ## 结构 ``` src/ index.ts # 入口:name/inject/Config/apply + 自动加载配置 tools.ts # 12 个 defineTool 定义 builtins.ts # 15 个内置源注册表 + 解析器(每源 TTL、中文别名、36kr POST+重试) digest.ts # 多源并发抓取 / 合并去重 / 简报格式化 llmConfig.ts # LLM 配置读写 + 环境变量自动注入 pluginConfig.ts # 插件全局配置读写 userSources.ts # 自定义源 CRUD + 落盘 + AI 分析触发 aiAnalyzer.ts # **AI 分析模块**:HTML→CSS 选择器生成、JSON→字段映射生成 scrape.ts # 通用 web/json 抓取(自动补全相对链接) summarize.ts # 离线抽取式摘要 cache.ts # 内存 TTL 缓存 http.ts # fetch 封装(UA/Referer/超时/重试) types.ts # 领域类型(含 ExtractionRules / FieldMappingRules) ``` ## AI 分析能力(移植自 ai_client.rs) 插件移植了原 Rust 项目的 AI 分析能力,让自定义数据源添加后**立即可用**: | 能力 | 说明 | 对应 Rust 函数 | | --- | --- | --- | | **HTML → CSS 选择器生成** | 分析 HTML 结构,自动生成 root_container / item_list / item_node + 各字段选择器 | `generate_structured_extraction_rules()` | | **JSON → 字段映射生成** | 分析 JSON API 响应,自动生成字段映射规则(source_field → target field + transform) | `generate_field_mapping_rules()` | | **规则持久化** | 分析结果保存到 `user_sources.json`,下次抓取直接使用,无需重复分析 | — | | **降级兜底** | 无 API Key 或 AI 分析失败时,使用基础规则(常见字段名匹配) | — | **工作流程**: 1. 用户添加自定义源 → `news_source_add` 2. 插件自动调用 LLM 分析数据结构 → 生成最优规则 3. 规则持久化到 `user_sources.json` 4. 后续抓取 → `fetchUserSource()` 优先使用保存的 AI 规则 5. 如果规则失效 → 降级到基础规则(可重新分析) **前置条件**:需要先通过 `news_config_llm` 配置 API Key(DeepSeek / OpenAI / Anthropic 等)。 ## 说明 - 端点/选择器随源站变化可能需微调;HTML 源的容器选择器在 `builtins.ts` 中集中维护。 - 已知修复(对照 Rust 原版 / 站点改版):36kr 用 POST+重试、微博 TTL=1 分钟、 阮一峰 `li.module-list-item`、财新 `.topNews/.boxa .txt`、CSDN 新字段、 SegmentFault 走 `__NEXT_DATA__`(站点已全客户端渲染)。 - `news_config_llm` 保存的配置会自动写入 `process.env.DEEPSEEK_API_KEY`, 但 harness 本身的凭证服务仍以环境变量/web Models 页为准——两者不冲突。 - AI 分析使用配置的 LLM 服务,每次分析约消耗 1000-2000 tokens。