每天早晨打开手机面对几十个新闻APP推送的几百条信息你是不是也感到信息过载的困扰想要快速了解行业动态却要在海量信息中手动筛选这个过程既耗时又低效。更让人头疼的是不同平台的新闻格式各异有些重要信息可能因为排版混乱而被忽略。这正是AI智能体技能Skills能够大显身手的地方。与传统AI只能回答问题不同具备Skills的AI智能体能够主动执行复杂任务。今天我们要实现的自动读取新闻Skill就是让AI学会像专业编辑一样自动抓取、解析和总结新闻内容为你提供精准的信息服务。这个技能的核心价值在于它将繁琐的信息处理流程标准化、自动化。你不再需要手动访问多个新闻网站AI会帮你完成从数据获取到内容提炼的全过程。更重要的是这个Skill可以复用在各种AI平台上一次开发多处使用。1. 这篇文章真正要解决的问题信息过载时代我们面临的核心痛点不是缺少信息而是缺少高效的信息过滤和提炼机制。传统解决方案存在几个明显缺陷手动浏览的低效性即使使用RSS阅读器仍然需要人工判断每条新闻的价值这个过程本身就需要消耗大量时间精力。通用AI的局限性普通对话AI虽然能回答问题但无法主动执行新闻采集任务。每次都需要你手动提供具体指令无法实现真正的自动化。技术门槛的现实障碍虽然Python爬虫等技术可以实现自动化但对非专业开发者来说学习成本高维护难度大。我们的自动读取新闻Skill正是针对这些痛点设计的解决方案。它不是一个简单的工具脚本而是一个可复用的AI能力模块具备以下核心优势零代码使用最终用户只需简单指令即可触发完整工作流跨平台兼容基于标准Skills格式可在Claude、Cursor等多种AI工具中运行智能过滤内置内容优先级判断只推送真正有价值的信息持续优化通过反馈机制不断改进新闻筛选准确性这个方案特别适合需要持续关注行业动态的产品经理、研究人员、投资者以及任何希望提升信息获取效率的知识工作者。2. Skills基础概念与核心原理要理解自动读取新闻Skill的实现首先需要掌握AI Skills的基本架构。Skills的本质是将人类专业知识转化为AI可执行的标准化指令集。2.1 Skills的三大核心组件SKILL.md文件这是Skill的说明书采用Markdown格式编写。它定义了Skill的触发条件、输入参数、执行步骤和预期输出。对于新闻读取Skill这个文件会详细说明如何识别新闻源、解析时间戳、提取关键信息等。脚本文件包含具体的执行逻辑可以是Python、JavaScript或其他语言。新闻读取Skill的脚本主要负责HTTP请求、HTML解析、文本提取等技术操作。资源文件可能包含配置参数、模板、示例数据等。比如新闻源的URL列表、关键词过滤规则、输出格式模板等。2.2 Skills的工作原理流程用户指令 → AI识别Skill需求 → 加载SKILL.md → 执行对应脚本 → 返回结构化结果以新闻读取为例当你说帮我看看今天AI领域的重要新闻AI会识别这是新闻读取任务自动加载对应的Skill然后执行预设的新闻采集流程最后返回整理好的摘要。2.3 Skills与传统脚本的关键差异特性传统脚本AI Skills触发方式手动执行自然语言自动触发使用门槛需要技术背景对话式交互集成度独立运行与AI工作流深度集成适应性固定逻辑可结合AI推理能力这种架构设计使得Skills既保持了代码的精确性又具备了AI的灵活性。我们的新闻读取Skill正是基于这种理念将复杂的网络爬虫和文本分析封装成简单的对话指令。3. 环境准备与前置条件在开始构建新闻读取Skill之前需要确保开发环境配置正确。以下是详细的环境要求和建议配置。3.1 基础开发环境Python环境建议使用Python 3.8及以上版本。这是大多数AI工具和网络库支持的最佳版本范围。# 检查Python版本 python --version # 预期输出Python 3.8.x 或更高 # 创建虚拟环境推荐 python -m venv news_skill_env source news_skill_env/bin/activate # Linux/Mac # 或 news_skill_env\Scripts\activate # Windows必要的Python库新闻读取Skill依赖几个核心库每个都有特定作用pip install requests beautifulsoup4 python-dateutil feedparserrequests用于发送HTTP请求获取网页内容beautifulsoup4HTML解析和内容提取python-dateutil时间格式处理和解析feedparserRSS订阅解析支持3.2 AI平台选择与配置Skills可以在多个AI平台上运行每个平台有细微差异Claude Desktop目前对Skills支持最完善的平台之一配置简单适合初学者。Cursor with Claude开发者的首选集成了代码编辑和AI能力调试方便。VS Code with Continue插件化方案灵活性高适合已有VS Code工作流的用户。配置关键点确保AI工具具有文件系统访问权限这是Skills正常工作的基础。3.3 网络访问权限检查新闻读取Skill需要访问外部网站要确保网络环境允许出站连接# 测试网络连通性 import requests test_sites [ https://news.cnblogs.com, https://segmentfault.com, https://zhihu.com ] for site in test_sites: try: response requests.get(site, timeout5) print(f✓ {site} 可访问) except: print(f✗ {site} 访问失败)如果遇到网络限制可能需要配置代理或选择可访问的新闻源替代方案。3.4 项目目录结构准备规范的目录结构是Skill可复用的关键news_reader_skill/ ├── SKILL.md # Skill描述文件 ├── news_reader.py # 主执行脚本 ├── config.json # 配置文件 ├── templates/ # 输出模板 │ └── report.md └── examples/ # 使用示例 └── example_usage.md现在环境准备就绪我们可以开始构建核心的新闻读取逻辑了。4. 新闻读取Skill的核心设计思路构建一个实用的新闻读取Skill需要解决几个关键技术挑战如何智能识别重要新闻、如何处理不同网站的异构结构、如何保证信息的时效性和准确性。4.1 多源新闻采集策略单一新闻源容易产生信息偏差我们采用多源聚合策略技术社区源CSDN、博客园、SegmentFault等关注技术动态综合资讯源知乎专栏、微信公众号等获取行业观点官方渠道各大厂商技术博客获取第一手信息每个源都需要定制化的解析规则但共享统一的内容评估标准。4.2 内容质量评估体系不是所有被爬取的内容都是有价值的信息。我们建立三级过滤机制基础过滤去除广告、导航栏、页脚等噪音内容时效性过滤优先处理24小时内的内容可配置时间窗口相关性过滤基于关键词和主题模型的内容评分# 内容评分算法示例 def calculate_content_score(article, keywords): score 0 # 时效性评分越新分数越高 hours_old (datetime.now() - article.publish_time).total_seconds() / 3600 timeliness_score max(0, 1 - hours_old / 72) # 3天内有效 # 相关性评分 relevance_score 0 for keyword in keywords: if keyword in article.title.lower(): relevance_score 2 if keyword in article.content.lower(): relevance_score 1 # 来源权威性评分 source_score get_source_credibility(article.source) return timeliness_score * 0.4 relevance_score * 0.4 source_score * 0.24.3 智能摘要生成技术原始新闻内容往往冗长我们需要提取核心信息关键句提取基于TextRank等算法识别重要句子实体识别提取人名、组织名、技术术语等关键实体观点归纳区分事实陈述和观点表达这种设计确保了Skill既具备技术深度又保持用户友好性。5. 完整代码实现与分步解析下面我们进入具体的代码实现环节。我们将分模块构建完整的新闻读取Skill。5.1 SKILL.md文件完整实现SKILL.md是Skill的元数据描述文件决定了AI如何理解和调用这个技能。# 自动新闻读取技能 ## 技能描述 自动从多个技术新闻源采集、解析和总结最新信息提供个性化的新闻摘要服务。 ## 触发关键词 - 今日技术新闻 - AI领域动态 - 帮我看看最新技术消息 - 行业新闻汇总 ## 输入参数 - sources (可选): 指定新闻源如[csdn, cnblogs, zhihu] - keywords (可选): 关注的关键词过滤如[人工智能, 机器学习] - limit (可选): 返回条目数默认10条 - time_range (可选): 时间范围如24h、7d ## 输出格式 结构化新闻摘要包含标题、来源、时间、摘要和原文链接。 ## 使用示例用户: 请给我今天AI领域的重要新闻 AI: [自动调用本技能] 正在从CSDN、博客园等源获取AI相关新闻...## 实现脚本 news_reader.py ## 依赖项 - requests 2.25.1 - beautifulsoup4 4.9.3 - python-dateutil 2.8.1这个描述文件确保了AI能准确理解何时以及如何调用我们的新闻读取功能。5.2 核心新闻读取类实现# news_reader.py import requests from bs4 import BeautifulSoup from datetime import datetime, timedelta import json import time from urllib.parse import urljoin, urlparse import re class NewsReader: def __init__(self, config_fileconfig.json): self.load_config(config_file) self.session requests.Session() self.session.headers.update({ User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 }) def load_config(self, config_file): 加载配置文件 try: with open(config_file, r, encodingutf-8) as f: self.config json.load(f) except FileNotFoundError: # 默认配置 self.config { sources: { csdn: { url: https://blog.csdn.net/news/main.html, selectors: { articles: .main-content .article-list .article-item, title: .title a, link: .title ahref, summary: .content, time: .time } }, cnblogs: { url: https://www.cnblogs.com/news/, selectors: { articles: .post-list .post-item, title: .title a, link: .title ahref, summary: .desc, time: .date } } }, timeout: 10, max_articles_per_source: 20 } def fetch_news(self, sourcesNone, keywordsNone, time_range24h): 主入口获取新闻 if sources is None: sources list(self.config[sources].keys()) all_articles [] for source in sources: if source in self.config[sources]: articles self.fetch_from_source(source) all_articles.extend(articles) # 过滤和排序 filtered_articles self.filter_articles(all_articles, keywords, time_range) sorted_articles sorted(filtered_articles, keylambda x: x[timestamp], reverseTrue) return sorted_articles[:self.config.get(max_articles, 10)] def fetch_from_source(self, source_name): 从特定源获取新闻 source_config self.config[sources][source_name] try: response self.session.get(source_config[url], timeoutself.config[timeout]) response.encoding utf-8 if response.status_code 200: return self.parse_html(response.text, source_config, source_name) else: print(f获取{source_name}新闻失败状态码: {response.status_code}) return [] except Exception as e: print(f获取{source_name}新闻时出错: {str(e)}) return [] def parse_html(self, html, source_config, source_name): 解析HTML提取新闻内容 soup BeautifulSoup(html, html.parser) articles [] article_elements soup.select(source_config[selectors][articles]) for element in article_elements[:source_config.get(max_articles, 20)]: try: article self.extract_article_data(element, source_config, source_name) if article: articles.append(article) except Exception as e: print(f解析文章时出错: {str(e)}) continue return articles def extract_article_data(self, element, source_config, source_name): 从单个元素提取文章数据 # 提取标题 title_elem element.select_one(source_config[selectors][title]) if not title_elem: return None title title_elem.get_text().strip() link title_elem.get(href) if link and not link.startswith(http): link urljoin(source_config[url], link) # 提取摘要 summary if summary in source_config[selectors]: summary_elem element.select_one(source_config[selectors][summary]) if summary_elem: summary summary_elem.get_text().strip()[:200] # 限制长度 # 提取时间 publish_time self.extract_time(element, source_config) return { title: title, link: link, summary: summary, source: source_name, publish_time: publish_time, timestamp: self.parse_timestamp(publish_time) } def extract_time(self, element, source_config): 提取并标准化时间格式 if time in source_config[selectors]: time_elem element.select_one(source_config[selectors][time]) if time_elem: time_text time_elem.get_text().strip() return self.normalize_time(time_text) return datetime.now().strftime(%Y-%m-%d %H:%M:%S) def normalize_time(self, time_text): 标准化不同格式的时间字符串 # 处理2小时前、昨天等相对时间 if 小时前 in time_text: hours int(re.search(r(\d)小时前, time_text).group(1)) return (datetime.now() - timedelta(hourshours)).strftime(%Y-%m-%d %H:%M:%S) elif 天前 in time_text: days int(re.search(r(\d)天前, time_text).group(1)) return (datetime.now() - timedelta(daysdays)).strftime(%Y-%m-%d %H:%M:%S) # 处理绝对时间格式 try: return datetime.strptime(time_text, %Y-%m-%d %H:%M:%S).strftime(%Y-%m-%d %H:%M:%S) except: return time_text # 返回原始文本由后续处理 def parse_timestamp(self, time_str): 将时间字符串转换为时间戳用于排序 try: return datetime.strptime(time_str, %Y-%m-%d %H:%M:%S).timestamp() except: return datetime.now().timestamp() def filter_articles(self, articles, keywordsNone, time_range24h): 根据关键词和时间范围过滤文章 filtered [] # 计算时间边界 if time_range 24h: time_limit datetime.now() - timedelta(hours24) elif time_range 7d: time_limit datetime.now() - timedelta(days7) else: time_limit datetime.now() - timedelta(days30) # 默认30天 for article in articles: # 时间过滤 article_time datetime.fromtimestamp(article[timestamp]) if article_time time_limit: continue # 关键词过滤 if keywords: content article[title] article[summary] if not any(keyword.lower() in content.lower() for keyword in keywords): continue filtered.append(article) return filtered # 使用示例 if __name__ __main__: reader NewsReader() articles reader.fetch_news(sources[csdn], keywords[AI, 人工智能]) for i, article in enumerate(articles, 1): print(f{i}. {article[title]}) print(f 来源: {article[source]} | 时间: {article[publish_time]}) print(f 摘要: {article[summary]}) print(f 链接: {article[link]}) print()这个实现包含了完整的新闻采集、解析、过滤流程是Skill的核心执行逻辑。5.3 配置文件详解{ sources: { csdn: { url: https://blog.csdn.net/news/main.html, selectors: { articles: .main-content .article-list .article-item, title: .title a, link: .title ahref, summary: .content, time: .time }, max_articles: 15 }, cnblogs: { url: https://www.cnblogs.com/news/, selectors: { articles: .post-list .post-item, title: .title a, link: .title ahref, summary: .desc, time: .date }, max_articles: 10 } }, timeout: 10, max_articles: 10, user_agents: [ Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36, Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 ] }配置文件使得Skill可以灵活适配不同的新闻源只需修改选择器即可支持新网站。6. Skill集成与AI平台适配代码实现完成后我们需要让AI能够识别和调用这个Skill。这涉及到平台特定的集成方式。6.1 Claude Desktop集成在Claude Desktop中Skills通常放置在特定目录下# Claude Skills目录Mac ~/Library/Application Support/Claude/Skills/ # 创建技能目录 mkdir -p ~/Library/Application Support/Claude/Skills/NewsReader将我们的SKILL.md和news_reader.py复制到该目录Claude会自动检测并加载这个Skill。6.2 测试Skill的触发效果启动Claude Desktop尝试以下对话用户: 请给我今天技术圈的重要新闻 Claude: [自动识别并调用NewsReader Skill] 正在从配置的新闻源获取最新技术新闻... 发现15篇相关文章以下是精选的5篇 1. 《AI编程助手最新对比评测》 来源: CSDN | 时间: 2024-01-15 10:30:00 摘要: 本文对比了Cursor、Claude、GitHub Copilot等主流AI编程工具... 2. 《深度学习框架性能优化实践》 来源: 博客园 | 时间: 2024-01-15 09:15:00 摘要: 分享PyTorch和TensorFlow在实际项目中的性能调优经验...6.3 参数化调用示例Skill支持灵活的参数传递用户: 帮我看看最近3天人工智能和机器学习方面的新闻只要CSDN的来源 Claude: [调用NewsReader Skill with parameters] 正在从CSDN获取人工智能和机器学习相关新闻时间范围: 3天内...这种交互方式使得非技术用户也能轻松使用复杂的新闻采集功能。7. 高级功能与个性化定制基础功能实现后我们可以进一步扩展Skill的实用性。7.1 智能推荐算法基于用户历史阅读行为优化新闻推荐class PersonalizedNewsReader(NewsReader): def __init__(self, user_profileNone): super().__init__() self.user_profile user_profile or {} self.reading_history self.load_reading_history() def calculate_personalized_score(self, article): 基于用户偏好计算个性化评分 base_score super().calculate_content_score(article, self.user_profile.get(keywords, [])) # 作者偏好 author_preference self.user_profile.get(preferred_authors, {}) if article.author in author_preference: base_score * 1.5 # 主题偏好 for preferred_topic in self.user_profile.get(preferred_topics, []): if preferred_topic in article.title.lower(): base_score * 1.3 return base_score7.2 多格式输出支持除了文本摘要还可以生成结构化数据def generate_output(self, articles, formatmarkdown): 支持多种输出格式 if format markdown: return self._generate_markdown(articles) elif format json: return self._generate_json(articles) elif format html: return self._generate_html(articles) def _generate_markdown(self, articles): 生成Markdown格式报告 output # 技术新闻摘要\n\n output f生成时间: {datetime.now().strftime(%Y-%m-%d %H:%M)}\n\n for i, article in enumerate(articles, 1): output f## {i}. {article[title]}\n output f- **来源**: {article[source]} | **时间**: {article[publish_time]}\n output f- **摘要**: {article[summary]}\n output f- [阅读原文]({article[link]})\n\n return output8. 常见问题与解决方案在实际使用中可能会遇到各种问题以下是典型问题及解决方法。8.1 网络请求问题问题现象获取新闻时超时或返回空数据排查步骤检查网络连接是否正常验证目标网站是否可访问查看是否被反爬虫机制拦截解决方案# 增加重试机制 from requests.adapters import HTTPAdapter from requests.packages.urllib3.util.retry import Retry def create_session_with_retries(): session requests.Session() retry_strategy Retry( total3, backoff_factor1, status_forcelist[429, 500, 502, 503, 504], ) adapter HTTPAdapter(max_retriesretry_strategy) session.mount(http://, adapter) session.mount(https://, adapter) return session8.2 网站结构变化导致解析失败问题现象之前正常的Skill突然无法获取内容解决方案建立选择器验证机制def validate_selectors(self, source_config): 验证选择器是否仍然有效 try: response self.session.get(source_config[url]) soup BeautifulSoup(response.text, html.parser) # 测试每个选择器 for selector_name, selector in source_config[selectors].items(): if selector_name articles: elements soup.select(selector) if len(elements) 0: return False, f选择器 {selector} 未找到元素 return True, 选择器验证通过 except Exception as e: return False, f验证过程中出错: {str(e)}8.3 内容去重与质量过滤问题现象不同源报道同一事件产生重复内容解决方案实现基于内容的去重算法def remove_duplicates(self, articles, similarity_threshold0.8): 基于文本相似度去重 unique_articles [] for article in articles: is_duplicate False for existing in unique_articles: similarity self.calculate_similarity(article[title], existing[title]) if similarity similarity_threshold: is_duplicate True # 保留时间最新的版本 if article[timestamp] existing[timestamp]: unique_articles.remove(existing) unique_articles.append(article) break if not is_duplicate: unique_articles.append(article) return unique_articles9. 生产环境最佳实践将新闻读取Skill投入实际使用需要考虑更多工程化因素。9.1 性能优化策略异步处理对于多个新闻源使用异步请求提升效率import aiohttp import asyncio async def fetch_multiple_sources_async(sources): 异步获取多个新闻源 async with aiohttp.ClientSession() as session: tasks [] for source in sources: task self.fetch_single_source_async(session, source) tasks.append(task) results await asyncio.gather(*tasks, return_exceptionsTrue) return results缓存机制避免重复请求相同内容from datetime import datetime, timedelta import pickle class NewsCache: def __init__(self, cache_duration300): # 5分钟缓存 self.cache_duration cache_duration self.cache {} def get(self, key): if key in self.cache: data, timestamp self.cache[key] if datetime.now() - timestamp timedelta(secondsself.cache_duration): return data return None def set(self, key, data): self.cache[key] (data, datetime.now())9.2 错误处理与监控完善的错误处理确保Skill的稳定性def robust_fetch_news(self, sources, fallback_sourcesNone): 带降级机制的新闻获取 try: return self.fetch_news(sources) except Exception as primary_error: print(f主新闻源获取失败: {primary_error}) # 使用备用源 if fallback_sources: try: return self.fetch_news(fallback_sources) except Exception as fallback_error: print(f备用新闻源也失败: {fallback_error}) # 返回缓存数据或空结果 return self.get_cached_news() or []9.3 安全与合规考虑尊重robots.txt检查目标网站的爬虫政策def check_robots_txt(self, domain): 检查robots.txt限制 try: robots_url fhttps://{domain}/robots.txt response requests.get(robots_url) # 解析robots.txt内容判断是否允许爬取 return self.parse_robots_txt(response.text) except: return True # 默认允许请求频率控制避免给目标网站造成压力import time from collections import defaultdict class RateLimiter: def __init__(self, calls_per_second1): self.calls_per_second calls_per_second self.last_calls defaultdict(lambda: 0) def wait_if_needed(self, domain): now time.time() time_since_last now - self.last_calls[domain] if time_since_last 1.0 / self.calls_per_second: time.sleep(1.0 / self.calls_per_second - time_since_last) self.last_calls[domain] time.time()通过本文的完整实现我们构建了一个功能完善、可投入实际使用的自动新闻读取Skill。这个Skill不仅解决了信息过载的痛点还展示了AI Skills技术的强大潜力。读者可以基于这个基础框架继续扩展更多个性化功能打造真正属于自己的智能信息助手。
AI智能体Skills开发实战:构建自动新闻读取技能解决信息过载
每天早晨打开手机面对几十个新闻APP推送的几百条信息你是不是也感到信息过载的困扰想要快速了解行业动态却要在海量信息中手动筛选这个过程既耗时又低效。更让人头疼的是不同平台的新闻格式各异有些重要信息可能因为排版混乱而被忽略。这正是AI智能体技能Skills能够大显身手的地方。与传统AI只能回答问题不同具备Skills的AI智能体能够主动执行复杂任务。今天我们要实现的自动读取新闻Skill就是让AI学会像专业编辑一样自动抓取、解析和总结新闻内容为你提供精准的信息服务。这个技能的核心价值在于它将繁琐的信息处理流程标准化、自动化。你不再需要手动访问多个新闻网站AI会帮你完成从数据获取到内容提炼的全过程。更重要的是这个Skill可以复用在各种AI平台上一次开发多处使用。1. 这篇文章真正要解决的问题信息过载时代我们面临的核心痛点不是缺少信息而是缺少高效的信息过滤和提炼机制。传统解决方案存在几个明显缺陷手动浏览的低效性即使使用RSS阅读器仍然需要人工判断每条新闻的价值这个过程本身就需要消耗大量时间精力。通用AI的局限性普通对话AI虽然能回答问题但无法主动执行新闻采集任务。每次都需要你手动提供具体指令无法实现真正的自动化。技术门槛的现实障碍虽然Python爬虫等技术可以实现自动化但对非专业开发者来说学习成本高维护难度大。我们的自动读取新闻Skill正是针对这些痛点设计的解决方案。它不是一个简单的工具脚本而是一个可复用的AI能力模块具备以下核心优势零代码使用最终用户只需简单指令即可触发完整工作流跨平台兼容基于标准Skills格式可在Claude、Cursor等多种AI工具中运行智能过滤内置内容优先级判断只推送真正有价值的信息持续优化通过反馈机制不断改进新闻筛选准确性这个方案特别适合需要持续关注行业动态的产品经理、研究人员、投资者以及任何希望提升信息获取效率的知识工作者。2. Skills基础概念与核心原理要理解自动读取新闻Skill的实现首先需要掌握AI Skills的基本架构。Skills的本质是将人类专业知识转化为AI可执行的标准化指令集。2.1 Skills的三大核心组件SKILL.md文件这是Skill的说明书采用Markdown格式编写。它定义了Skill的触发条件、输入参数、执行步骤和预期输出。对于新闻读取Skill这个文件会详细说明如何识别新闻源、解析时间戳、提取关键信息等。脚本文件包含具体的执行逻辑可以是Python、JavaScript或其他语言。新闻读取Skill的脚本主要负责HTTP请求、HTML解析、文本提取等技术操作。资源文件可能包含配置参数、模板、示例数据等。比如新闻源的URL列表、关键词过滤规则、输出格式模板等。2.2 Skills的工作原理流程用户指令 → AI识别Skill需求 → 加载SKILL.md → 执行对应脚本 → 返回结构化结果以新闻读取为例当你说帮我看看今天AI领域的重要新闻AI会识别这是新闻读取任务自动加载对应的Skill然后执行预设的新闻采集流程最后返回整理好的摘要。2.3 Skills与传统脚本的关键差异特性传统脚本AI Skills触发方式手动执行自然语言自动触发使用门槛需要技术背景对话式交互集成度独立运行与AI工作流深度集成适应性固定逻辑可结合AI推理能力这种架构设计使得Skills既保持了代码的精确性又具备了AI的灵活性。我们的新闻读取Skill正是基于这种理念将复杂的网络爬虫和文本分析封装成简单的对话指令。3. 环境准备与前置条件在开始构建新闻读取Skill之前需要确保开发环境配置正确。以下是详细的环境要求和建议配置。3.1 基础开发环境Python环境建议使用Python 3.8及以上版本。这是大多数AI工具和网络库支持的最佳版本范围。# 检查Python版本 python --version # 预期输出Python 3.8.x 或更高 # 创建虚拟环境推荐 python -m venv news_skill_env source news_skill_env/bin/activate # Linux/Mac # 或 news_skill_env\Scripts\activate # Windows必要的Python库新闻读取Skill依赖几个核心库每个都有特定作用pip install requests beautifulsoup4 python-dateutil feedparserrequests用于发送HTTP请求获取网页内容beautifulsoup4HTML解析和内容提取python-dateutil时间格式处理和解析feedparserRSS订阅解析支持3.2 AI平台选择与配置Skills可以在多个AI平台上运行每个平台有细微差异Claude Desktop目前对Skills支持最完善的平台之一配置简单适合初学者。Cursor with Claude开发者的首选集成了代码编辑和AI能力调试方便。VS Code with Continue插件化方案灵活性高适合已有VS Code工作流的用户。配置关键点确保AI工具具有文件系统访问权限这是Skills正常工作的基础。3.3 网络访问权限检查新闻读取Skill需要访问外部网站要确保网络环境允许出站连接# 测试网络连通性 import requests test_sites [ https://news.cnblogs.com, https://segmentfault.com, https://zhihu.com ] for site in test_sites: try: response requests.get(site, timeout5) print(f✓ {site} 可访问) except: print(f✗ {site} 访问失败)如果遇到网络限制可能需要配置代理或选择可访问的新闻源替代方案。3.4 项目目录结构准备规范的目录结构是Skill可复用的关键news_reader_skill/ ├── SKILL.md # Skill描述文件 ├── news_reader.py # 主执行脚本 ├── config.json # 配置文件 ├── templates/ # 输出模板 │ └── report.md └── examples/ # 使用示例 └── example_usage.md现在环境准备就绪我们可以开始构建核心的新闻读取逻辑了。4. 新闻读取Skill的核心设计思路构建一个实用的新闻读取Skill需要解决几个关键技术挑战如何智能识别重要新闻、如何处理不同网站的异构结构、如何保证信息的时效性和准确性。4.1 多源新闻采集策略单一新闻源容易产生信息偏差我们采用多源聚合策略技术社区源CSDN、博客园、SegmentFault等关注技术动态综合资讯源知乎专栏、微信公众号等获取行业观点官方渠道各大厂商技术博客获取第一手信息每个源都需要定制化的解析规则但共享统一的内容评估标准。4.2 内容质量评估体系不是所有被爬取的内容都是有价值的信息。我们建立三级过滤机制基础过滤去除广告、导航栏、页脚等噪音内容时效性过滤优先处理24小时内的内容可配置时间窗口相关性过滤基于关键词和主题模型的内容评分# 内容评分算法示例 def calculate_content_score(article, keywords): score 0 # 时效性评分越新分数越高 hours_old (datetime.now() - article.publish_time).total_seconds() / 3600 timeliness_score max(0, 1 - hours_old / 72) # 3天内有效 # 相关性评分 relevance_score 0 for keyword in keywords: if keyword in article.title.lower(): relevance_score 2 if keyword in article.content.lower(): relevance_score 1 # 来源权威性评分 source_score get_source_credibility(article.source) return timeliness_score * 0.4 relevance_score * 0.4 source_score * 0.24.3 智能摘要生成技术原始新闻内容往往冗长我们需要提取核心信息关键句提取基于TextRank等算法识别重要句子实体识别提取人名、组织名、技术术语等关键实体观点归纳区分事实陈述和观点表达这种设计确保了Skill既具备技术深度又保持用户友好性。5. 完整代码实现与分步解析下面我们进入具体的代码实现环节。我们将分模块构建完整的新闻读取Skill。5.1 SKILL.md文件完整实现SKILL.md是Skill的元数据描述文件决定了AI如何理解和调用这个技能。# 自动新闻读取技能 ## 技能描述 自动从多个技术新闻源采集、解析和总结最新信息提供个性化的新闻摘要服务。 ## 触发关键词 - 今日技术新闻 - AI领域动态 - 帮我看看最新技术消息 - 行业新闻汇总 ## 输入参数 - sources (可选): 指定新闻源如[csdn, cnblogs, zhihu] - keywords (可选): 关注的关键词过滤如[人工智能, 机器学习] - limit (可选): 返回条目数默认10条 - time_range (可选): 时间范围如24h、7d ## 输出格式 结构化新闻摘要包含标题、来源、时间、摘要和原文链接。 ## 使用示例用户: 请给我今天AI领域的重要新闻 AI: [自动调用本技能] 正在从CSDN、博客园等源获取AI相关新闻...## 实现脚本 news_reader.py ## 依赖项 - requests 2.25.1 - beautifulsoup4 4.9.3 - python-dateutil 2.8.1这个描述文件确保了AI能准确理解何时以及如何调用我们的新闻读取功能。5.2 核心新闻读取类实现# news_reader.py import requests from bs4 import BeautifulSoup from datetime import datetime, timedelta import json import time from urllib.parse import urljoin, urlparse import re class NewsReader: def __init__(self, config_fileconfig.json): self.load_config(config_file) self.session requests.Session() self.session.headers.update({ User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 }) def load_config(self, config_file): 加载配置文件 try: with open(config_file, r, encodingutf-8) as f: self.config json.load(f) except FileNotFoundError: # 默认配置 self.config { sources: { csdn: { url: https://blog.csdn.net/news/main.html, selectors: { articles: .main-content .article-list .article-item, title: .title a, link: .title ahref, summary: .content, time: .time } }, cnblogs: { url: https://www.cnblogs.com/news/, selectors: { articles: .post-list .post-item, title: .title a, link: .title ahref, summary: .desc, time: .date } } }, timeout: 10, max_articles_per_source: 20 } def fetch_news(self, sourcesNone, keywordsNone, time_range24h): 主入口获取新闻 if sources is None: sources list(self.config[sources].keys()) all_articles [] for source in sources: if source in self.config[sources]: articles self.fetch_from_source(source) all_articles.extend(articles) # 过滤和排序 filtered_articles self.filter_articles(all_articles, keywords, time_range) sorted_articles sorted(filtered_articles, keylambda x: x[timestamp], reverseTrue) return sorted_articles[:self.config.get(max_articles, 10)] def fetch_from_source(self, source_name): 从特定源获取新闻 source_config self.config[sources][source_name] try: response self.session.get(source_config[url], timeoutself.config[timeout]) response.encoding utf-8 if response.status_code 200: return self.parse_html(response.text, source_config, source_name) else: print(f获取{source_name}新闻失败状态码: {response.status_code}) return [] except Exception as e: print(f获取{source_name}新闻时出错: {str(e)}) return [] def parse_html(self, html, source_config, source_name): 解析HTML提取新闻内容 soup BeautifulSoup(html, html.parser) articles [] article_elements soup.select(source_config[selectors][articles]) for element in article_elements[:source_config.get(max_articles, 20)]: try: article self.extract_article_data(element, source_config, source_name) if article: articles.append(article) except Exception as e: print(f解析文章时出错: {str(e)}) continue return articles def extract_article_data(self, element, source_config, source_name): 从单个元素提取文章数据 # 提取标题 title_elem element.select_one(source_config[selectors][title]) if not title_elem: return None title title_elem.get_text().strip() link title_elem.get(href) if link and not link.startswith(http): link urljoin(source_config[url], link) # 提取摘要 summary if summary in source_config[selectors]: summary_elem element.select_one(source_config[selectors][summary]) if summary_elem: summary summary_elem.get_text().strip()[:200] # 限制长度 # 提取时间 publish_time self.extract_time(element, source_config) return { title: title, link: link, summary: summary, source: source_name, publish_time: publish_time, timestamp: self.parse_timestamp(publish_time) } def extract_time(self, element, source_config): 提取并标准化时间格式 if time in source_config[selectors]: time_elem element.select_one(source_config[selectors][time]) if time_elem: time_text time_elem.get_text().strip() return self.normalize_time(time_text) return datetime.now().strftime(%Y-%m-%d %H:%M:%S) def normalize_time(self, time_text): 标准化不同格式的时间字符串 # 处理2小时前、昨天等相对时间 if 小时前 in time_text: hours int(re.search(r(\d)小时前, time_text).group(1)) return (datetime.now() - timedelta(hourshours)).strftime(%Y-%m-%d %H:%M:%S) elif 天前 in time_text: days int(re.search(r(\d)天前, time_text).group(1)) return (datetime.now() - timedelta(daysdays)).strftime(%Y-%m-%d %H:%M:%S) # 处理绝对时间格式 try: return datetime.strptime(time_text, %Y-%m-%d %H:%M:%S).strftime(%Y-%m-%d %H:%M:%S) except: return time_text # 返回原始文本由后续处理 def parse_timestamp(self, time_str): 将时间字符串转换为时间戳用于排序 try: return datetime.strptime(time_str, %Y-%m-%d %H:%M:%S).timestamp() except: return datetime.now().timestamp() def filter_articles(self, articles, keywordsNone, time_range24h): 根据关键词和时间范围过滤文章 filtered [] # 计算时间边界 if time_range 24h: time_limit datetime.now() - timedelta(hours24) elif time_range 7d: time_limit datetime.now() - timedelta(days7) else: time_limit datetime.now() - timedelta(days30) # 默认30天 for article in articles: # 时间过滤 article_time datetime.fromtimestamp(article[timestamp]) if article_time time_limit: continue # 关键词过滤 if keywords: content article[title] article[summary] if not any(keyword.lower() in content.lower() for keyword in keywords): continue filtered.append(article) return filtered # 使用示例 if __name__ __main__: reader NewsReader() articles reader.fetch_news(sources[csdn], keywords[AI, 人工智能]) for i, article in enumerate(articles, 1): print(f{i}. {article[title]}) print(f 来源: {article[source]} | 时间: {article[publish_time]}) print(f 摘要: {article[summary]}) print(f 链接: {article[link]}) print()这个实现包含了完整的新闻采集、解析、过滤流程是Skill的核心执行逻辑。5.3 配置文件详解{ sources: { csdn: { url: https://blog.csdn.net/news/main.html, selectors: { articles: .main-content .article-list .article-item, title: .title a, link: .title ahref, summary: .content, time: .time }, max_articles: 15 }, cnblogs: { url: https://www.cnblogs.com/news/, selectors: { articles: .post-list .post-item, title: .title a, link: .title ahref, summary: .desc, time: .date }, max_articles: 10 } }, timeout: 10, max_articles: 10, user_agents: [ Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36, Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 ] }配置文件使得Skill可以灵活适配不同的新闻源只需修改选择器即可支持新网站。6. Skill集成与AI平台适配代码实现完成后我们需要让AI能够识别和调用这个Skill。这涉及到平台特定的集成方式。6.1 Claude Desktop集成在Claude Desktop中Skills通常放置在特定目录下# Claude Skills目录Mac ~/Library/Application Support/Claude/Skills/ # 创建技能目录 mkdir -p ~/Library/Application Support/Claude/Skills/NewsReader将我们的SKILL.md和news_reader.py复制到该目录Claude会自动检测并加载这个Skill。6.2 测试Skill的触发效果启动Claude Desktop尝试以下对话用户: 请给我今天技术圈的重要新闻 Claude: [自动识别并调用NewsReader Skill] 正在从配置的新闻源获取最新技术新闻... 发现15篇相关文章以下是精选的5篇 1. 《AI编程助手最新对比评测》 来源: CSDN | 时间: 2024-01-15 10:30:00 摘要: 本文对比了Cursor、Claude、GitHub Copilot等主流AI编程工具... 2. 《深度学习框架性能优化实践》 来源: 博客园 | 时间: 2024-01-15 09:15:00 摘要: 分享PyTorch和TensorFlow在实际项目中的性能调优经验...6.3 参数化调用示例Skill支持灵活的参数传递用户: 帮我看看最近3天人工智能和机器学习方面的新闻只要CSDN的来源 Claude: [调用NewsReader Skill with parameters] 正在从CSDN获取人工智能和机器学习相关新闻时间范围: 3天内...这种交互方式使得非技术用户也能轻松使用复杂的新闻采集功能。7. 高级功能与个性化定制基础功能实现后我们可以进一步扩展Skill的实用性。7.1 智能推荐算法基于用户历史阅读行为优化新闻推荐class PersonalizedNewsReader(NewsReader): def __init__(self, user_profileNone): super().__init__() self.user_profile user_profile or {} self.reading_history self.load_reading_history() def calculate_personalized_score(self, article): 基于用户偏好计算个性化评分 base_score super().calculate_content_score(article, self.user_profile.get(keywords, [])) # 作者偏好 author_preference self.user_profile.get(preferred_authors, {}) if article.author in author_preference: base_score * 1.5 # 主题偏好 for preferred_topic in self.user_profile.get(preferred_topics, []): if preferred_topic in article.title.lower(): base_score * 1.3 return base_score7.2 多格式输出支持除了文本摘要还可以生成结构化数据def generate_output(self, articles, formatmarkdown): 支持多种输出格式 if format markdown: return self._generate_markdown(articles) elif format json: return self._generate_json(articles) elif format html: return self._generate_html(articles) def _generate_markdown(self, articles): 生成Markdown格式报告 output # 技术新闻摘要\n\n output f生成时间: {datetime.now().strftime(%Y-%m-%d %H:%M)}\n\n for i, article in enumerate(articles, 1): output f## {i}. {article[title]}\n output f- **来源**: {article[source]} | **时间**: {article[publish_time]}\n output f- **摘要**: {article[summary]}\n output f- [阅读原文]({article[link]})\n\n return output8. 常见问题与解决方案在实际使用中可能会遇到各种问题以下是典型问题及解决方法。8.1 网络请求问题问题现象获取新闻时超时或返回空数据排查步骤检查网络连接是否正常验证目标网站是否可访问查看是否被反爬虫机制拦截解决方案# 增加重试机制 from requests.adapters import HTTPAdapter from requests.packages.urllib3.util.retry import Retry def create_session_with_retries(): session requests.Session() retry_strategy Retry( total3, backoff_factor1, status_forcelist[429, 500, 502, 503, 504], ) adapter HTTPAdapter(max_retriesretry_strategy) session.mount(http://, adapter) session.mount(https://, adapter) return session8.2 网站结构变化导致解析失败问题现象之前正常的Skill突然无法获取内容解决方案建立选择器验证机制def validate_selectors(self, source_config): 验证选择器是否仍然有效 try: response self.session.get(source_config[url]) soup BeautifulSoup(response.text, html.parser) # 测试每个选择器 for selector_name, selector in source_config[selectors].items(): if selector_name articles: elements soup.select(selector) if len(elements) 0: return False, f选择器 {selector} 未找到元素 return True, 选择器验证通过 except Exception as e: return False, f验证过程中出错: {str(e)}8.3 内容去重与质量过滤问题现象不同源报道同一事件产生重复内容解决方案实现基于内容的去重算法def remove_duplicates(self, articles, similarity_threshold0.8): 基于文本相似度去重 unique_articles [] for article in articles: is_duplicate False for existing in unique_articles: similarity self.calculate_similarity(article[title], existing[title]) if similarity similarity_threshold: is_duplicate True # 保留时间最新的版本 if article[timestamp] existing[timestamp]: unique_articles.remove(existing) unique_articles.append(article) break if not is_duplicate: unique_articles.append(article) return unique_articles9. 生产环境最佳实践将新闻读取Skill投入实际使用需要考虑更多工程化因素。9.1 性能优化策略异步处理对于多个新闻源使用异步请求提升效率import aiohttp import asyncio async def fetch_multiple_sources_async(sources): 异步获取多个新闻源 async with aiohttp.ClientSession() as session: tasks [] for source in sources: task self.fetch_single_source_async(session, source) tasks.append(task) results await asyncio.gather(*tasks, return_exceptionsTrue) return results缓存机制避免重复请求相同内容from datetime import datetime, timedelta import pickle class NewsCache: def __init__(self, cache_duration300): # 5分钟缓存 self.cache_duration cache_duration self.cache {} def get(self, key): if key in self.cache: data, timestamp self.cache[key] if datetime.now() - timestamp timedelta(secondsself.cache_duration): return data return None def set(self, key, data): self.cache[key] (data, datetime.now())9.2 错误处理与监控完善的错误处理确保Skill的稳定性def robust_fetch_news(self, sources, fallback_sourcesNone): 带降级机制的新闻获取 try: return self.fetch_news(sources) except Exception as primary_error: print(f主新闻源获取失败: {primary_error}) # 使用备用源 if fallback_sources: try: return self.fetch_news(fallback_sources) except Exception as fallback_error: print(f备用新闻源也失败: {fallback_error}) # 返回缓存数据或空结果 return self.get_cached_news() or []9.3 安全与合规考虑尊重robots.txt检查目标网站的爬虫政策def check_robots_txt(self, domain): 检查robots.txt限制 try: robots_url fhttps://{domain}/robots.txt response requests.get(robots_url) # 解析robots.txt内容判断是否允许爬取 return self.parse_robots_txt(response.text) except: return True # 默认允许请求频率控制避免给目标网站造成压力import time from collections import defaultdict class RateLimiter: def __init__(self, calls_per_second1): self.calls_per_second calls_per_second self.last_calls defaultdict(lambda: 0) def wait_if_needed(self, domain): now time.time() time_since_last now - self.last_calls[domain] if time_since_last 1.0 / self.calls_per_second: time.sleep(1.0 / self.calls_per_second - time_since_last) self.last_calls[domain] time.time()通过本文的完整实现我们构建了一个功能完善、可投入实际使用的自动新闻读取Skill。这个Skill不仅解决了信息过载的痛点还展示了AI Skills技术的强大潜力。读者可以基于这个基础框架继续扩展更多个性化功能打造真正属于自己的智能信息助手。