ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

AI;DR与Don‘t be a meat proxy:构建自动化技术摘要流水线

AI;DR与Don‘t be a meat proxy:构建自动化技术摘要流水线 如果你每天的工作里有一项固定的动作打开一篇技术文章复制正文贴到 AI 对话框里让它总结再把答案复制回文档或者群里。那么你有没有想过这个“复制 — 粘贴 — 再复制”的循环里真正不可替代的劳动力是你不是 AI。在英文技术社区里这种角色有一个不太好听的名字meat proxy肉代理。意思是一个真人被当作某个系统与人之间的“物理中转层”。AI 需要网页内容你就替它读网页AI 需要一段报错日志你就替它复制日志AI 需要某个文档的结论你就把文档一段段喂进去。看起来你是在用 AI 提效实际上你只是从“人肉阅读”升级成了“人肉 I/O 通道”。这篇文章想讨论一种更合理的状态我把它叫作 AI;DR。它借用了互联网上 TL;DRToo Long; Didnt Read的梗但含义反过来不是“太长没读”而是“AI 替你把该读的都读完了并且把结论整理好交给你”。对应的设计原则就是那句 Dont be a meat proxy凡是 AI 能自己获取、解析和理解的信息都不应该由人先手工搬运一遍。接下来我会从工程实践角度拆解 AI;DR 的完整链路。内容包括核心概念、环境准备、最小可运行代码、结构化输出、多源批量汇总以及常见问题和工程建议。读完你可以直接动手搭一套自己的 AI 摘要流水线也能判断清楚哪些场景适合全自动哪些场景必须保留人工审核。1. 这篇文章真正要解决的问题先还原一个真实场景。假设你是某个中间件团队的负责人每周都要搜集社区动态、竞品发布说明、官方博客更新然后整理成周报。过去你的做法是打开浏览器一个标签页一个标签页看把认为重要的段落复制到笔记软件再打开 AI 聊天窗口把笔记内容粘贴进去请它提炼重点。最后你把 AI 输出重新整理成正式文档。整个过程里真正消耗时间的并不是“思考”而是“搬运”。你搬运网页到笔记搬运笔记到 AI搬运 AI 输出到周报。任何一个环节里原文格式稍微乱一点或者文章长度超过上下文限制你还得手动分段、重贴、修格式。这种情况下AI 并没有帮你省时间它只是把你从“阅读者”变成了“操作员”。AI;DR 要解决的就是这层搬运成本。它把上面这条手工链路变成一条自动化流水线输入 URL、左侧菜单、RSS 地址或者 Issue 编号程序自动抓取正文、清洗噪声、构造 prompt、调用大模型、输出结构化摘要最后归档到本地文件或发送到通知渠道。你不再需要打开几十个网页也不再需要在对话框里来回粘贴。更关键的是它改变了人的位置。传统用法里AI 是“回答问题的人”你是“喂问题的人”。在 AI;DR 流水线里AI 是“替你阅读和处理信息的人”你是“审核结论和做决策的人”。这一步转变才是真正降低信息处理成本的地方。这篇文章适合谁看如果你经常要做技术调研、文档阅读、竞品分析、版本更新跟进或者你本身在做 AI 应用开发、AI Agent、自动化工作流那下面这套实践可以直接迁移。如果你所在的场景涉及合同审查、医疗诊断、金融决策等高风险领域那本文的代码可以作为原型参考但必须增加人工复核和流程审批不能直接全自动上线。2. AI;DR 的核心概念与适用场景2.1 TL;DR 与 AI;DR 的差别TL;DR 是传统互联网社区的常见缩写意思是“太长不读”通常是作者自己给长文写一个摘要方便读者快速判断要不要继续看。AI;DR 是把这个概念往前推了一步。它不是“作者没写摘要所以你不读了”而是“你不想读但事情仍然需要被理解那就让 AI 替你理解”。换句话说AI;DR 的本质不是省略阅读而是把阅读过程外包给模型把阅读结果用结构化方式交还给你。这两者的区别看起来只是“谁来写摘要”实际上是完全不同的使用方式TL;DR 是人写的依赖作者表达能力和诚实程度。AI;DR 是模型生成的依赖输入内容的完整性和提示词设计。TL;DR 是静态文本AI;DR 可以按需生成、定时生成、批量生成。TL;DR 只解决“读完没”的问题AI;DR 还解决“读完以后怎么办”的问题。在实际工程里AI;DR 不是一句“帮我总结一下”的提示词而是一条流水线。流水线的输出也不只是“几百字摘要”还可以是优先级标签、风险清单、结论引用、置信度分数甚至是“这条更新是否需要升级依赖”的操作建议。2.2 AI;DR 与 RAG、Agent 的关系很多读者看到这里会联想到 RAG检索增强生成或者 Agent。这里需要做一个简单的边界划分。RAG 的目标是“让模型在回答问题时能引用外部知识”适合问答系统、客服机器人、知识库检索。AI;DR 的目标是“对一个或多个信息来源做定向阅读和理解”两者有重叠但出发点不同。AI;DR 可以是一件轻量工具不一定需要向量数据库和召回排序。Agent 的目标是“让模型能调用工具、执行动作、完成多步骤任务”。AI;DR 可以成为 Agent 的一个 Action比如 Agent 在回答某个问题时自动抓取官网文档并生成摘要。反过来一个跑批任务的 AI;DR 脚本也可以被视为一种最简形态的 Agent因为它具备了“获取信息 → 分析信息 → 输出结果”的闭环。我的建议是不要一上来就搭一个复杂 Agent。先用脚本把 AI;DR 这条链路跑通等确认输出质量和成本可控之后再把工具调用、任务调度、权限管理加进来。这样每一步的失败点都更清晰。2.3 适用场景与不适用场景场景是否推荐原因技术文章速读推荐成本低输出容易验证官方文档更新跟进推荐内容结构相对规范适合批量处理竞品发布说明分析推荐可以帮助快速沉淀对比素材代码仓库 README / CHANGELOG 总结推荐文本长度可控信息密度高合同、法务条款阅读谨慎模型可能存在遗漏或幻觉必须人工复核医疗、金融等高风险决策依据谨慎不能把最终判断直接交给模型需要逐字理解源码逻辑的深度评审不推荐摘要会丢失细节必须回到原文AI;DR 擅长的是“宽而浅”的信息处理比如从一堆文章里找出值得深入阅读的几篇它不擅长“窄而深”的真相判断比如精确定位某个 Bug 的根因。任何时候摘要都不能替代原文本身。3. 环境准备与前置条件本文的示例代码使用 Python只要你的环境满足以下条件即可运行Python 3.10 或更高版本可以访问 OpenAI 兼容接口的 API Key安装了 requests、beautifulsoup4、openai 等依赖先创建一个项目目录和虚拟环境mkdir aidr cd aidr python -m venv .venv source .venv/bin/activate然后安装依赖。这里不把版本锁死因为不同模型服务的 SDK 版本差异较大建议按你实际使用的服务来定版本pip install requests beautifulsoup4 openai python-dotenv需要说明的是openai这个 SDK 不只是能连 OpenAI 官方服务。目前很多模型服务商都提供 OpenAI 兼容接口你只需要配置base_url和api_key就能切换模型。这样代码可以保持稳定模型可以按需替换。接下来创建环境变量文件.envOPENAI_API_KEYsk-your-key-here OPENAI_BASE_URLhttps://api.example.com/v1 OPENAI_MODELgpt-4o-mini注意永远不要把 API Key 硬编码到 Python 文件里。即使是在本地实验也要养成从环境变量读取的习惯避免代码被分享或提交到 Git 仓库时泄密。4. 核心链路拆解4.1 一条 AI;DR 流水线由哪几段组成无论你最终是做一个命令行工具、一个定时任务还是一个 Agent ActionAI;DR 的链路通常都包含下面这些阶段来源获取输入 URL、RSS 链接、文件路径或 Issue 编号抓取原始内容。正文提取去掉导航、广告、页脚、脚本标签等噪声保留文章主体。内容裁剪控制输入长度避免超过模型上下文窗口。构造 Prompt告诉模型要输出什么格式、遵守什么约束。调用模型得到摘要或结构化结果。结果校验与归档解析模型返回内容写入文件或发送通知。这六个阶段里前两步解决的是“AI 能不能读到原文”中间两步解决的是“AI 会不会认真读”最后两步解决的是“读完之后的结果能不能被直接使用”。4.2 最容易出错的三个环节第一个容易出错的是正文提取。很多网站页面里文章正文只是整个 HTML 的一小部分如果直接把全部标签文本喂给模型模型会被大量导航链接和广告内容干扰。更麻烦的是有些网站的正文是 JavaScript 动态渲染的直接用 requests 抓不到最终内容。第二个容易出错的是上下文截断。一篇文章可能有好几万字但模型的上下文窗口有限。如果简单粗暴地截取前 6000 个字符很可能丢失文章后半部分的实验数据或结论。正确做法是先对正文做结构化切分或者先把长文本分段摘要再做合并摘要。本文为了演示可读性会先做前端截断但在生产环境里你应该加上分块逻辑。第三个容易出错的是模型输出格式。无论你要求“输出 JSON”还是“输出 5 个要点”模型都可能偶尔多输出一段解释、JSON 前后带上反引号、字段名被改写。所以代码里必须对模型输出做一层容错解析而不是直接json.loads后就不管。5. 完整示例代码实现5.1 最小可用版本单链接 AI;DR先写一个最简版本。它做的事情是给定一个 URL自动抓取网页正文调用大模型生成中文摘要打印结果。# aidr/simple_summarizer.py import os import re import sys import requests from bs4 import BeautifulSoup from openai import OpenAI MAX_TEXT_LEN 6000 USER_AGENT ( Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36 ) PROMPT 你是一个技术阅读助手请用中文输出一篇技术文章的 AI;DR 摘要。 要求 1. 用不超过 300 字概括文章核心结论。 2. 列出 3-5 个关键要点。 3. 如果文章出现版本号、数字、命令或配置项请原样保留。 4. 如果原文信息不足以支撑结论请明确说明“原文证据不足”。 文章内容如下 {content} def extract_main_text(url: str) - str: resp requests.get( url, timeout20, headers{User-Agent: USER_AGENT}, ) resp.raise_for_status() soup BeautifulSoup(resp.text, html.parser) for tag in soup([script, style, nav, footer, noscript]): tag.decompose() text soup.get_text( , stripTrue) text re.sub(r\s, , text) return text[:MAX_TEXT_LEN] def generate_ai_dr(text: str, model: str) - str: client OpenAI( api_keyos.environ.get(OPENAI_API_KEY), base_urlos.environ.get(OPENAI_BASE_URL), ) resp client.chat.completions.create( modelmodel, messages[ {role: system, content: You are an expert technical reader.}, {role: user, content: PROMPT.format(contenttext)}, ], temperature0.2, ) return resp.choices[0].message.content if __name__ __main__: if len(sys.argv) 2: print(usage: python simple_summarizer.py url [model]) sys.exit(1) url sys.argv[1] model sys.argv[2] if len(sys.argv) 2 else os.environ.get(OPENAI_MODEL, gpt-4o-mini) main_text extract_main_text(url) result generate_ai_dr(main_text, model) print( URL ) print(url) print( AI;DR ) print(result)运行方式set -a source .env set a python aidr/simple_summarizer.py https://example.com/tech-article gpt-4o-mini这个版本结构很简单但已经跑通了“获取 → 清洗 → 摘要 → 输出”的核心链路。你拿到输出后可以判断这篇摘要是否有价值、是否存在幻觉再决定下一步优化方向。5.2 结构化输出从“总结”到“可执行建议”单纯让模型写一段摘要很多时候还不足以支撑决策。对于技术调研场景我更建议让模型输出 JSON包含标题、摘要、关键点、风险和建议并给出一个置信度分数。# aidr/structured_digest.py import json import os import re import sys import requests from bs4 import BeautifulSoup from openai import OpenAI MAX_TEXT_LEN 8000 USER_AGENT ( Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36 ) SYSTEM_PROMPT 你是一个技术情报分析助手。 请分析用户提供的技术文章并输出一个 JSON 对象字段如下 { title: 文章标题, summary: 200字以内的中文摘要, key_points: [要点1, 要点2, 要点3], risks: [风险或局限], recommendation: 给研发团队的一句话建议, confidence: 0.0 } confidence 取值范围 0-1表示你对分析结果的信心。 如果原文信息不完整confidence 不能超过 0.5。 只输出 JSON不要输出任何解释。 def extract_text(url: str) - str: resp requests.get(url, timeout20, headers{User-Agent: USER_AGENT}) resp.raise_for_status() soup BeautifulSoup(resp.text, html.parser) for tag in soup([script, style, nav, footer, aside]): tag.decompose() text soup.get_text( , stripTrue) return re.sub(r\s, , text)[:MAX_TEXT_LEN] def analyze_article(content: str, model: str) - dict: client OpenAI( api_keyos.environ.get(OPENAI_API_KEY), base_urlos.environ.get(OPENAI_BASE_URL), ) resp client.chat.completions.create( modelmodel, messages[ {role: system, content: SYSTEM_PROMPT}, {role: user, content: f请分析下面这篇文章\n\n{content}}, ], temperature0.1, response_format{type: json_object}, ) raw resp.choices[0].message.content # 兼容模型偶尔输出 Markdown 代码块的情况 raw raw.strip() if raw.startswith(): raw re.sub(r^(json)?, , raw) raw raw.rstrip().strip() return json.loads(raw) if __name__ __main__: url sys.argv[1] model sys.argv[2] if len(sys.argv) 2 else os.environ.get(OPENAI_MODEL, gpt-4o-mini) result analyze_article(extract_text(url), model) print(json.dumps(result, ensure_asciiFalse, indent2))运行方式python aidr/structured_digest.py https://example.com/tech-article输出示例{ title: Example: A New Approach, summary: 文章提出了一种新的中间件方案目标是降低分布式场景下的配置成本。, key_points: [ 新方案把配置管理拆成独立模块, 支持动态刷新和灰度发布, 当前版本仍处于早期阶段 ], risks: [ 生产环境共享配置的迁移成本较高, 文档中对回滚机制的说明不足 ], recommendation: 建议先在测试环境小范围验证并补充回滚演练。, confidence: 0.7 }结构化输出的价值在于摘要可以被程序继续处理。你可以把title写进日志把confidence作为筛选条件把risks推送到告警群。摘要就不再只是给人类看的一段文字而是一个可以被下一步工作流消费的数据对象。5.3 多源批量归并一个准 Agent 工作流单篇文章处理跑通后下一步就是把“单链接工具”变成“多源批量工具”。这里我给你一个多线程版本的示例它会读取sources.txt里的多个 URL并行抓取和摘要最后合成一个 Markdown 报告digest.md。先准备链接文件# aidr/sources.txt # 每行一个 URL井号开头的行为注释 https://example.com/docs/introduction https://example.com/docs/deployment https://example.com/blog/release-notes再写批量处理脚本# aidr/batch_digest.py import concurrent.futures as futures import datetime import os import pathlib import re import requests from bs4 import BeautifulSoup from openai import OpenAI BASE_DIR pathlib.Path(__file__).parent SOURCE_FILE BASE_DIR / sources.txt DIGEST_FILE BASE_DIR / digest.md MAX_TEXT_LEN 6000 USER_AGENT ( Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36 ) SUMMARY_PROMPT 请用中文总结下面的技术内容输出格式 ### 一句话结论 ### 关键要点 - 要尽量具体保留数字和配置项。 ### 风险提醒 内容 {content} def load_urls(path: pathlib.Path): urls [] for line in path.read_text(encodingutf-8).splitlines(): line line.strip() if line and not line.startswith(#): urls.append(line) return urls def fetch_text(url: str) - str: resp requests.get(url, timeout20, headers{User-Agent: USER_AGENT}) resp.raise_for_status() soup BeautifulSoup(resp.text, html.parser) for tag in soup([script, style, nav, footer, aside]): tag.decompose() text soup.get_text( , stripTrue) return re.sub(r\s, , text)[:MAX_TEXT_LEN] def call_llm(text: str, model: str) - str: client OpenAI( api_keyos.environ.get(OPENAI_API_KEY), base_urlos.environ.get(OPENAI_BASE_URL), ) resp client.chat.completions.create( modelmodel, messages[ {role: system, content: You are a technical research assistant.}, {role: user, content: SUMMARY_PROMPT.format(contenttext)}, ], temperature0.2, ) return resp.choices[0].message.content def analyze_one(url: str, model: str) - dict: try: text fetch_text(url) summary call_llm(text, model) return {url: url, ok: True, summary: summary, error: } except Exception as exc: return {url: url, ok: False, summary: , error: str(exc)} def main(): urls load_urls(SOURCE_FILE) model os.environ.get(OPENAI_MODEL, gpt-4o-mini) print(f开始处理 {len(urls)} 个来源...) results [] with futures.ThreadPoolExecutor(max_workers4) as executor: future_map {executor.submit(analyze_one, url, model): url for url in urls} for future in futures.as_completed(future_map): result future.result() results.append(result) status OK if result[ok] else FAIL print(f[{status}] {result[url]}) # 写入 Markdown 报告 lines [ # AI;DR 日报, , f生成时间{datetime.datetime.now().isoformat(timespecseconds)}, f来源数量{len(results)}, , ] for result in results: lines.append(f## {result[url]}) lines.append() if result[ok]: lines.append(result[summary]) else: lines.append( 处理失败 result[error]) lines.append() DIGEST_FILE.write_text(\n.join(lines), encodingutf-8) print(f报告已写入 {DIGEST_FILE}) if __name__ __main__: main()运行方式python aidr/batch_digest.py这里其实已经非常接近一个最简 Agent 了它有输入列表有工具函数有并行执行有结果汇总有落盘输出。你只需要把最前面的 URL 来源换成 RSS、数据库查询或 API 返回把最后的 Markdown 换成企业微信机器人、邮件或内部系统推送它就从一个“摘要脚本”升级成了“信息助理”。6. 运行结果与效果验证运行simple_summarizer.py后正常情况下你应该看到类似这样的输出 URL https://example.com/docs/introduction AI;DR 该文章提出了一种新的配置管理方案核心结论是通过将配置独立化并支持动态刷新 可以减少发布变更时的回滚成本。关键要点包括模块化设计、灰度发布支持、 以及当前版本在权限控制方面的限制。判断成功不能只看“有没有打印文字”还要看三个维度第一摘要是否基于原文。你可以随机抽原文章节和摘要对比如果 AI 写出来的结论在原文里找不到对应依据那就是幻觉需要检查 Prompt 和内容截断逻辑。第二关键数字是否保留。技术文章的摘要最怕把“延迟下降 40%”错写成“性能大幅提升”所以 Prompt 里必须强调数字原样保留。这也是我建议在摘要结果里加入confidence字段的原因。第三失败链路是否可追踪。批量任务里如果某个 URL 返回 403脚本不应该整个人挂掉而应该记录FAIL并继续处理其他来源。只有失败可追踪你才能放心地把它接入定时任务。7. 常见问题与排查思路问题现象可能原因排查方式解决方案请求网站返回 403网站开启了反爬校验或要求登录查看响应状态码和响应头增加合法 User-Agent或改用官方 API / RSS / 你已获授权的数据源抓到的正文包含大量导航和广告清洗逻辑只删除了少量标签打印清洗后的前 500 个字符增加aside、menu、related-articles等标签过滤模型摘要里出现原文没有的信息模型产生幻觉或 Prompt 约束不足对比原文定位幻觉内容降低 temperature要求模型必须引用原文必要时加入置信度校验JSON 解析失败模型输出了额外解释或 Markdown 代码块查看模型原始返回值使用response_format{type: json_object}并做容错解析长文章摘要结果偏前半部分简单截断了前 6000 字符检查输入文本长度对长文先分段摘要再合并或使用按标题切分策略批量任务中某个链接失败导致全部中断异常处理粒度过粗查看循环内是否有 try/except每个 URL 独立捕获异常失败任务记录日志后继续API Key 出现在代码或日志里环境变量使用不规范搜索 Git 历史或日志改用环境变量、密钥管理服务并立即轮换泄漏的 Key这里特别想提醒一点爬取网页前请先确认目标网站的服务条款、robots 文件和访问频率限制。如果你的场景需要大量访问他人站点优先使用官方提供的 RSS、API 或搜索引擎收录接口。技术工具可以用但不能变成滥用访问资源的理由。8. 最佳实践与工程建议8.1 让 AI 直接读但让人做最后决策AI;DR 的核心是“Dont be a meat proxy”意思是不要让人类做机械的搬运工作但这不等于把决策权完全交给模型。对于技术选型、依赖升级、以及可能影响线上系统的高风险变更AI 可以给出候选方案和风险清单但最终确认必须由人完成。一个比较稳妥的做法是AI 输出摘要后所有高风险结论都要附带原文引用。Prompt 里要求模型在输出风险点时同时给出原文中的对应句子摘要这样审核者可以快速回到原文验证。8.2 保留原始来源和版本信息在批量摘要场景里你最后看到的可能是一个汇总报告但如果报告里没有 URL、没有原文标题、没有抓取时间那么这个报告的价值会大打折扣。工程上我建议把每条结果都作为一个不可变记录保存至少包含来源 URL抓取时间使用的模型名称和版本输入文本长度原始输出内容后处理之后的结构化结果这样做有两个好处一是你可以用旧报告回放问题看是输入坏了还是模型输出变了二是当模型版本升级后你可以横向对比同一个来源在不同模型下的摘要质量。8.3 成本与上下文控制调用大模型是按 token 计费的AI;DR 这种“每篇文章都调一次模型”的用法成本会比聊天场景更敏感。控制成本的常见手段包括在进入大模型之前先用规则过滤比如只抓取当天更新的页面、只处理命中关键字的标题。对文章做正文抽取和长度裁剪不要把一个 50000 字的 HTML 页面直接丢进模型。对长文档使用“先分段摘要、再汇总摘要”的分层策略而不是一次性传完整上下文。对于分类、打标签这类低难度任务用便宜的小模型对于生成最终周报这类需要综合判断的任务再使用更强模型。8.4 从脚本走向真正的 Agent如果你已经跑通了上面的批量摘要脚本下一步可以按这四个方向演进。第一接入任务调度。用 cron 或内部调度平台让脚本每天定时运行把输出自动写入周报目录。第二增加工具调用。让 Agent 在读取摘要后能继续打开原文、查询接口、甚至向内部系统提问。这时候 AI;DR 就变成了 Agent 的一个 Action。第三增加权限边界。Agent 读取的内容范围、能调用的接口、能发送的消息渠道都应当遵循最小权限原则。不是所有信息都适合被自动抓取和推送。第四建设可观测性。记录每次任务的耗时、token 消耗、输出长度、失败率。AI 应用不是跑通一次就结束了长期可维护的前提是它能被观察、被评估、被回滚。9. 总结与后续学习方向AI;DR 不是什么神秘的新框架也不是某一家大模型厂商的独家功能。它只是一种把信息处理流程重新组织的思路让 AI 直接读取、理解并输出结构化的结论让工程师从“内容搬运工”变成“结论审核者”。Dont be a meat proxy 这句话本质上是提醒我们AI 时代最浪费时间的不是思考而是那些重复、机械、可以被完全自动化的 I/O 动作。如果你看完这篇文章只想做一件事我建议你选自己每周最头疼的一个信息场景比如“每周汇总官方文档更新”或“每天速读团队订阅的博客”然后照着文中的最小脚本搭一个单链接摘要工具。先不用做批量、不用接通知渠道跑通一次再说。跑通之后再做三件事第一把输出从自由文本改成 JSON方便程序消费第二把单链接改成多来源批量处理第三加上定时调度和对失败来源的可视化记录。等你把这三步做完你手里的就不只是一个摘要脚本而是一个贴着地面起飞的信息助理。下次再看到一篇长文时先别急着复制粘贴到聊天框。先问自己这个动作是不是又当了一次 meat proxy如果是那就把它交给 AI;DR 这条流水线。
返回列表