有段时间没有关注langchain了,今天一朋友让我帮做个自动批量生成视频,我想用langgraph和langchain来实现(多智能体交互工作流),我说让我先回忆熟悉下,所以今天拿langchain来实现一个youtube摘要的小工具。 于是我用了cursor创建了空的python工程,设置好python环境,使用uv做了工程初始化和环境变量。
以下是原视频和效果:

本次我使用了gpt-5模型,因为前几天gpt-5刚发布,这两天总是推送让我试用。
问题目标
使用langchain来实现一个youtube视频的摘要,并以指定格式输出 1
具体需求
- 通过命令行指定youtube播放地址URL,根据此URL解析出来视频中的字幕,根据字幕通过AI大模型进行摘要总结
- 生成markdown格式,以视频原语言输出摘要
- 以后支持翻译为其他语言输出摘要,设计时需要考虑扩展的方便
实现要求
- 使用python版的langchain实现;工程使用uv管理,并已初始化了环境
- langchain core版本使用0.3.72 , langchain-openai使用0.3.28,其他依赖按需添加并合理指定版本; 2
- 选择合适的命令行lib,支持进度条;
- AI模型使用google gemini模型,请定义.env文件,并从此文件中读取api-key 3; 封装好LLM并初始化; 在发起调用LLM时能够支持网络代理服务器的设置;
- 可以利用youtube相关api , 如 YouTube Transcript API ;或使用yt-dlp库进行处理;
- 使用LLM对字幕文字进行分析并总结为摘要,要求体现关键内容和观点;
- 如果输入的Youtube URL是直播流则忽略并给出提示;
- 请使用context7工具查阅最新的API文档说明4
整个过程大约10分钟不到,花了很长时间在更新README.md上
gpt-5的回答我将先查看现有的
pyproject.toml与main.py,以便在其基础上添加依赖与结构,然后实现 CLI、字幕解析与 Gemini 摘要生成。接着会并行查阅相关库的最新用法与版本兼容信息。我将并行读取现有项目文件列表并再次尝试读取
pyproject.toml与main.py,随后直接编写 CLI、字幕抓取与 Gemini 摘要逻辑,并更新依赖与 README,同时创建.env.example。Terminal window uv sync | catTerminal window uv sync | catTerminal window uv sync --no-install-project | cat进度
- 已实现基于 LangChain + Gemini 的 YouTube 字幕摘要 CLI,支持
.env、代理、进度条与直播检测。- 已完善依赖与打包配置,提供命令
yt-summary;补充了使用文档与示例。使用指南(快速开始)
- 安装依赖
Terminal window uv sync
- 配置 .env
.env GOOGLE_API_KEY=你的key# 可选:Gemini 调用代理# HTTP_PROXY=http://127.0.0.1:7890# HTTPS_PROXY=http://127.0.0.1:7890
- 运行
Terminal window uv run yt-summary "https://www.youtube.com/watch?v=abcdefghijk" --output summary.md
- 常用参数:
--env-file: 指定.env路径--model: Gemini 模型(默认gemini-1.5-pro)--proxy: 调用 Gemini 的 HTTP(S) 代理--yt-proxy: 抓取字幕代理(支持 http/https/socks5)--lang-hint: 语言提示(如 en、ja、zh-CN),默认跟随原字幕语言--output: 输出 Markdown 文件;不传则打印到控制台示例(含代理与语言提示)
Terminal window uv run yt-summary "https://www.youtube.com/watch?v=abcdefghijk" \--lang-hint en \--proxy http://127.0.0.1:7890 \--yt-proxy socks5://127.0.0.1:9050 \--output summary.md已满足的需求
- 使用
youtube-transcript-api抓取字幕;若无字幕或禁用,给出提示。- 直播流检测:调用
yt-dlp -J判断is_live,如为直播则提示并退出。- LangChain 版本与依赖:
langchain-core==0.3.72langchain-openai==0.3.28(为核心生态兼容)langchain-google-genai==2.0.2langchain-text-splitters==0.3.9- 进度条:
rich- CLI:
typer- 代理:
- LLM 调用:
--proxy或.env中的HTTP_PROXY/HTTPS_PROXY- 字幕抓取:
--yt-proxy传给YouTubeTranscriptApi- 摘要输出:
- 使用
RecursiveCharacterTextSplitter分块,分段小结 + 二次融合,输出 Markdown,默认视频原语言;可用--lang-hint指示语言。- 易于扩展翻译:可在现有最终摘要基础上二次调用 Gemini 保持 Markdown 结构翻译为目标语言(预留了
--lang-hint,后续可新增--target-lang)。代码位置
入口与逻辑:
main.py依赖与命令:
pyproject.toml(已配置脚本入口yt-summary=main:app)使用文档:
README.md若本地 IDE 仍提示导入未解析,属于编辑器未联动虚拟环境的提示;实际
uv run可正常执行。参考了 LangChain v0.3 与 Google Gemini 的最新文档要点,确保 API 用法与当前版本匹配。
如需把最终摘要“翻译为其他语言”,我可在此基础上补一个
--target-lang参数与二次调用逻辑,保持原 Markdown 结构不变。修改摘要逻辑或输出格式也可告知我具体风格要求(如必须包含:时间线要点、关键数据表、结论与行动建议等)。
构建脚本入口如未生效,请先执行一次不带
--no-install-project的uv sync(上一步“安装依赖”即满足)。直播流 URL 将被忽略并提示用户使用已存档的视频链接。
如果你希望我现在加上“翻译为指定语言输出”的选项,我可以直接补上。
第一次生成结果存在两个问题:
- 没有生成.env
- 代理服务器给我生成了两个,一个连接llm的,一个连接youtube,想得还比较周到
我执行了以下命令进行验证
uv run yt-summary "https://www.youtube.com/watch?v=UWpt2FWotlY" --lang-hint en --yt-proxy socks5://127.0.0.1:20809 --output summary.md报错:
Built langchain @ file:///D:/lab/ai/langchain ░░░░░░░░░░░░░░░░░░░░ [0/1] Installing wheels… warning: Failed to hardlink files; falling back to full copy. This may lead to degraded performance. If the cache and target directories are on different filesystems, hardlinking may not be supported. If this is intentional, set
export UV_LINK_MODE=copyor use--link-mode=copyto suppress this warning. Installed 1 package in 9ms 抓取字幕… ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 字幕抓取失败: no element found: line 1, column 0 抓取字幕… ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
第二次问题请解决以下两个问题:1 调用报错,见控制台,分析原因并解决;2 代码中实现了两个代理服务器,请合并为一个,并且只在.env中指定,不必在命令行指定
回答我将修复字幕抓取错误并添加 yt-dlp 作为回退方案,同时合并代理为一个仅从 .env 读取的变量,并更新 CLI 接口与文档。接下来会并行修改代码与依赖,然后再次运行以验证。
Terminal window uv run yt-summary "https://www.youtube.com/watch?v=UWpt2FWotlY" --lang-hint en --output summary.md | cat处理结果
问题1(调用报错):
- 你之前的错误“字幕抓取失败: no element found: line 1, column 0”来自
youtube-transcript-api在某些视频下返回异常/空响应。我增加了稳健回退:当官方字幕接口失败或无字幕时,自动用yt-dlp -J拉取字幕轨并下载.vtt再解析为文本,避免该错误。- 运行时又遇到 Gemini 429(配额/速率限制)。我优化了摘要阶段,将字幕分块按组合并后再调用 LLM,大幅减少请求次数以降低配额压力,并对
ResourceExhausted做了明确提示,便于你根据需要更换模型、等待冷却或升级配额。问题2(合并代理配置):
- 已移除 CLI 的
--proxy与--yt-proxy,合并为单一环境变量GLOBAL_PROXY。该代理同时作用于字幕抓取与 LLM 请求。.env示例:GLOBAL_PROXY=http://127.0.0.1:7890,也支持socks5://...。你现在如何使用
- 配置
.env:GOOGLE_API_KEY=你的key# 可选:统一代理(字幕抓取与Gemini调用都会使用)# GLOBAL_PROXY=http://127.0.0.1:7890# 或 socks5://127.0.0.1:9050
- 运行:
uv run yt-summary "https://www.youtube.com/watch?v=UWpt2FWotlY" --lang-hint en --output summary.md
- 若出现 Gemini 429 配额/速率限制:
- 等待一段时间再试或切换模型(如 gemini-1.5-flash 系列)
- 使用付费配额或更换项目
关键变更
main.py
- 统一代理:仅从
.env读取GLOBAL_PROXY,自动映射到HTTP_PROXY/HTTPS_PROXY;移除命令行代理参数。- 字幕抓取:
- 新增
fetch_transcript_with_api(官方接口)- 新增
fetch_transcript_with_ytdlp(回退到yt-dlp抽取字幕URL并下载.vtt,解析成文本)- LLM 调用:
build_llm仅从.env读取GOOGLE_API_KEYsummarize_chunks将多段按组合并,降低请求次数- 捕获
ResourceExhausted并提示
pyproject.toml
- 依赖新增
pysocks以支持 socks5 代理
README.md
- 改为统一
GLOBAL_PROXY,删掉命令行代理用法,更新示例与说明你的控制台示例已印证:
- 之前字幕抓取错误已由回退逻辑覆盖
- LLM 429 报错已转为明确提示,并通过分组请求缓解
如需进一步降低 LLM 调用(更省配额),我可以把二次汇总也并入首次请求策略,或做更小粒度聚合;也可以增加
--max-chunks限制处理规模。
评论
- 第二次能回答后够运行了,也主动增加了api的429报错处理,但没有输出完整,这个还需要优化。
- 我在需求中提到使用视频的原语言输出,直接给我输出中文了,我检查了代码发现是组织提示词时使用的是中文,gemini-2.5-pro会自动根据提问的语言进行回答。这个也可以继续优化, 只需把提示词改为英文,同时给出明确的说明,以视频的speak language 作为输出language.
- 后来又经过了几轮提问,主要是优化代码结构,最初写在了一个main.py中,优化后按职责拆分了多个文件,易于管理,并完善了README.md
- 还可以继续进行优化,还可以支持网页版等
源码放在了github上,安装好依赖,配置好你的api key和代理可以直接运行:
Footnotes
-
很多的实践证明,提示词结构化输入更有利用大模型的理解 ↩
-
如果能指定版本号最好指定,版本号不同可能API不同,一旦使用了不正确的API,跟AI对话调试起来比较花时间,在AI的认知API是正确的,实际上你和AI是建立在不同版本上的理解 ↩
-
把密钥等敏感信息存放在.env是良好的实践,如果写在死代码执行langchain代码会报错 ↩
-
同上,为了解决API版本变化的问题,context7专门提供了最新的各版本的文档API,这是一个MCP,可以访问 context7.com 查看 ↩