乐于分享
好东西不私藏

LangChain 实战(四):智能文档助手,让 AI 帮你写文档、改 PPT、做总结

LangChain 实战(四):智能文档助手,让 AI 帮你写文档、改 PPT、做总结

LangChain 实战(四):智能文档助手,让 AI 帮你写文档、改 PPT、做总结

这是 LangChain 实战系列的第 4 篇。前情提要:实战一[1] | 实战二[2] | 实战三[3]


开篇说个高频场景

你是不是经常遇到这些事:

❌ 会议纪要:1 小时的会议,整理纪要花 2 小时❌ 周报月报:每周憋半天,写的还都是流水账❌ PPT 大纲:要做汇报,对着空白 PPT 发呆 1 小时❌ 文档润色:写好的方案,语言太生硬,反复改❌ 信息提取:100 页的合同,找个条款翻半天

今天这篇,就用 LangChain 构建一个智能文档助手,帮你搞定这些事。

我们解决四个问题:

  1. 怎么让 AI 自动整理会议纪要?
  2. 怎么让 AI 帮你写周报、月报、总结?
  3. 怎么让 AI 生成 PPT 大纲和内容?
  4. 怎么让 AI 润色和改写文档?

一、核心能力设计

功能架构图

┌─────────────────────────────────────────────────┐│              智能文档助手                        │├─────────────────────────────────────────────────┤│  ┌──────────┐ ┌────────── ┌──────────┐ ──────────┐ ││  │会议纪要  │ │周报月报  │ │PPT 生成   │ │文档润色  │ ││  │整理      │ │自动写    │ │大纲内容  │ │改写优化  │ ││  └────┬─────┘ └────┬─────┘ └────┬───── └────┬─────┘ ││       │            │            │            │        ││       └────────────┴────────────────────────┘        ││                        │                               ││                        ▼                               ││  ┌──────────────────────────────────────────────────┐ ││  │              LangChain 核心层                     │ ││  │  • Document Loaders(文档加载)                   │ ││  │  • Text Splitters(文本分块)                     │ ││  │  • Prompt Templates(提示词模板)                 │ ││  │  • Output Parsers(输出解析)                     │ ││  │  • Chains(链式编排)                            │ ││  └──────────────────────────────────────────────────┘ │└─────────────────────────────────────────────────┘

二、功能一:会议纪要自动整理

场景描述

输入:会议录音转文字稿(或会议笔记) 输出:结构化会议纪要(议题、结论、待办)

完整实现

# meeting_notes.pyfrom langchain_openai import ChatOpenAIfrom langchain.prompts import ChatPromptTemplatefrom langchain.output_parsers import JsonOutputParserfrom pydantic import BaseModel, Fieldfrom typing importListOptional# === 1. 定义输出结构 ===classActionItem(BaseModel):"""待办事项"""    task: str = Field(description="具体任务描述")    owner: str = Field(description="负责人")    deadline: Optional[str] = Field(description="截止时间,如有")    priority: str = Field(description="优先级:high/medium/low")classMeetingSummary(BaseModel):"""会议纪要结构"""    meeting_title: str = Field(description="会议标题")    meeting_date: str = Field(description="会议日期")    attendees: List[str] = Field(description="参会人员列表")    key_topics: List[str] = Field(description="主要议题列表")    decisions: List[str] = Field(description="达成的决议/结论")    action_items: List[ActionItem] = Field(description="待办事项列表")    follow_up: str = Field(description="后续跟进计划")# === 2. 创建提示词模板 ===defcreate_meeting_prompt():"""创建会议纪要提示词"""    parser = JsonOutputParser(pydantic_object=MeetingSummary)    prompt = ChatPromptTemplate.from_messages([        ("system""""你是一个专业的会议秘书。        你的任务是从会议记录中提取关键信息,生成结构化的会议纪要。        要求:        1. 准确识别会议议题和结论        2. 明确提取待办事项(任务 + 负责人 + 时间)        3. 用简洁专业的语言总结        4. 如果某些信息不明确,填"未明确"        输出格式:{format_instructions}"""),        ("human""""会议记录如下:{meeting_transcript}{format_instructions}""")    ])return prompt, parser# === 3. 创建处理链 ===defcreate_meeting_chain():"""创建会议纪要处理链"""    llm = ChatOpenAI(model="gpt-4o", temperature=0.3)    prompt, parser = create_meeting_prompt()    chain = prompt | llm | parserreturn chain# === 4. 使用示例 ===if __name__ == "__main__":    chain = create_meeting_chain()# 模拟会议记录    transcript = """    张三:好,咱们开始今天的周会。首先过一下项目进度。    李四:我这边前端开发完成了 80%,预计周五能全部完成。    张三:好。后端呢?    王五:API 接口都写完了,但是在做性能优化,可能要多两天。    张三:行,那前端等后端联调。对了,下周的客户演示准备得怎么样?    李四:PPT 还没做,我周三前搞定。    张三:好,那演示环境谁负责搭一下?    王五:我来吧,周四前弄好。    张三:行。还有个事,老板说下个月要加两个人,李四你负责面试。    李四:好的。    张三:那散会。    """    result = chain.invoke({"meeting_transcript": transcript    })# 输出结果print("=== 会议纪要 ===")print(f"标题:{result['meeting_title']}")print(f"日期:{result['meeting_date']}")print(f"参会人:{', '.join(result['attendees'])}")print(f"\n主要议题:")for topic in result['key_topics']:print(f"  • {topic}")print(f"\n达成的结论:")for decision in result['decisions']:print(f"  ✓ {decision}")print(f"\n待办事项:")for item in result['action_items']:print(f"  □ [{item['priority']}{item['task']} - {item['owner']} ({item['deadline']})")print(f"\n后续跟进:{result['follow_up']}")

输出示例

=== 会议纪要 ===标题:项目周会日期:2026-04-15参会人:张三,李四,王五主要议题:  • 项目进度同步  • 客户演示准备  • 人员招聘达成的结论:  ✓ 前端周五完成开发  ✓ 后端需要额外两天做性能优化  ✓ 李四负责周三前完成 PPT  ✓ 王五负责周四前搭建演示环境  ✓ 李四负责面试新成员待办事项:  □ [high] 完成前端开发 - 李四 (本周五)  □ [high] 后端性能优化 - 王五 (下周一)  □ [medium] 制作客户演示 PPT - 李四 (周三前)  □ [high] 搭建演示环境 - 王五 (周四前)  □ [medium] 负责新成员面试 - 李四 (下个月)后续跟进:等待后端性能优化完成后进行联调

进阶:处理语音转文字稿

from langchain_community.document_loaders import TextLoaderfrom langchain_text_splitters import RecursiveCharacterTextSplitterdefprocess_meeting_audio(transcript_file: str):"""处理会议录音转文字稿"""# 1. 加载文字稿    loader = TextLoader(transcript_file, encoding='utf-8')    transcript = loader.load()[0].page_content# 2. 如果太长,分段处理iflen(transcript) > 10000:        splitter = RecursiveCharacterTextSplitter(            chunk_size=3000,            chunk_overlap=200        )        chunks = splitter.split_text(transcript)# 3. 分段总结再合并        summaries = []for chunk in chunks:            summary = chain.invoke({"meeting_transcript": chunk})            summaries.append(summary)# 4. 合并总结        final_summary = merge_summaries(summaries)return final_summaryelse:return chain.invoke({"meeting_transcript": transcript})

三、功能二:周报月报自动写

场景描述

输入:本周工作记录(零散的 commit、文档、聊天记录) 输出:结构化周报/月报

完整实现

# weekly_report.pyfrom langchain_openai import ChatOpenAIfrom langchain.prompts import ChatPromptTemplatefrom langchain.output_parsers import JsonOutputParserfrom pydantic import BaseModel, Fieldfrom typing importList# === 1. 定义周报结构 ===classWorkItem(BaseModel):"""工作项"""    task: str = Field(description="工作内容")    progress: str = Field(description="进度状态:已完成/进行中/未开始")    result: str = Field(description="产出/成果")    hours: int = Field(description="耗时(小时)")classWeeklyReport(BaseModel):"""周报结构"""    week: str = Field(description="周次,如'2026 年第 16 周'")    completed_work: List[WorkItem] = Field(description="已完成工作")    ongoing_work: List[WorkItem] = Field(description="进行中工作")    highlights: List[str] = Field(description="工作亮点")    issues: List[str] = Field(description="遇到的问题/风险")    next_week_plan: List[str] = Field(description="下周计划")    total_hours: int = Field(description="总工时")# === 2. 创建提示词 ===defcreate_report_prompt():"""创建周报生成提示词"""    parser = JsonOutputParser(pydantic_object=WeeklyReport)    prompt = ChatPromptTemplate.from_messages([        ("system""""你是一个专业的职场助手。        你的任务是根据零散的工作记录,生成结构化的周报。        要求:        1. 归纳整理工作内容,按项目/任务分类        2. 突出工作亮点和成果(用数据说话)        3. 识别风险和问题        4. 制定合理的下周计划        5. 语言专业、简洁、有重点        输出格式:{format_instructions}"""),        ("human""""以下是本周的工作记录:{work_records}当前日期:{current_date}{format_instructions}""")    ])return prompt, parser# === 3. 创建工作链 ===defcreate_report_chain():"""创建周报生成链"""    llm = ChatOpenAI(model="gpt-4o", temperature=0.5)    prompt, parser = create_report_prompt()    chain = prompt | llm | parserreturn chain# === 4. 集成 Git/文档记录 ===import subprocessfrom datetime import datetime, timedeltadefcollect_work_records(days: int = 7) -> str:"""自动收集工作记录"""    records = []# 1. Git commit 记录try:        end_date = datetime.now()        start_date = end_date - timedelta(days=days)        result = subprocess.run(            ["git""log""--since", start_date.strftime('%Y-%m-%d'), "--pretty=format:"%h - %s (%an)""],            capture_output=True, text=True        )if result.stdout:            records.append("## Git 提交记录")            records.append(result.stdout)except Exception as e:        records.append(f"Git 记录获取失败:{e}")# 2. 文档修改记录(假设有文档管理系统)# records.append("## 文档修改")# records.append("• 更新了产品需求文档 v2.3")# records.append("• 编写了 API 接口文档")# 3. 手动补充的工作记录    records.append("## 其他工作")    records.append("• 参加了 3 次项目会议")    records.append("• 面试了 2 位候选人")    records.append("• 协助解决了线上 bug")return"\n\n".join(records)# === 5. 使用示例 ===if __name__ == "__main__":    chain = create_report_chain()# 收集工作记录    work_records = collect_work_records(days=7)# 生成周报    report = chain.invoke({"work_records": work_records,"current_date": datetime.now().strftime('%Y-%m-%d')    })# 格式化输出print(f"# {report['week']} 周报\n")print("## ✅ 已完成工作")for item in report['completed_work']:print(f"- {item['task']}{item['hours']}小时)")print(f"  产出:{item['result']}")print("\n## 🔄 进行中工作")for item in report['ongoing_work']:print(f"- {item['task']} - {item['progress']}")print("\n## ⭐ 工作亮点")for highlight in report['highlights']:print(f"- {highlight}")print("\n## ⚠️ 问题与风险")for issue in report['issues']:print(f"- {issue}")print("\n## 📅 下周计划")for plan in report['next_week_plan']:print(f"- {plan}")print(f"\n**总工时:{report['total_hours']}小时**")

输出示例

# 2026 年第 16 周 周报## ✅ 已完成工作- 用户模块后端开发(15 小时)  产出:完成 5 个 API 接口,通过单元测试- 前端页面重构(12 小时)  产出:首页加载速度提升 40%- 客户演示 PPT 制作(3 小时)  产出:15 页演示文稿## 🔄 进行中工作- 性能优化 - 进行中 (70%)- 代码审查 - 进行中## ⭐ 工作亮点- 首页加载时间从 3s 降至 1.8s- 修复了 3 个线上紧急 bug- 获得客户对演示的积极反馈## ⚠️ 问题与风险- 后端性能优化进度滞后,可能影响联调- 新成员入职时间未确定## 📅 下周计划- 完成后端性能优化- 开始前后端联调- 继续面试后端工程师- 准备项目阶段汇报**总工时:40 小时**

四、功能三:PPT 大纲自动生成

场景描述

输入:主题 + 关键信息 输出:PPT 大纲 + 每页内容要点

完整实现

# ppt_generator.pyfrom langchain_openai import ChatOpenAIfrom langchain.prompts import ChatPromptTemplatefrom langchain.output_parsers import JsonOutputParserfrom pydantic import BaseModel, Fieldfrom typing importList# === 1. 定义 PPT 结构 ===classSlide(BaseModel):"""单页 PPT"""    slide_number: int = Field(description="页码")    title: str = Field(description="页面标题")    content: List[str] = Field(description="内容要点(3-5 条)")    notes: str = Field(description="演讲者备注")    visual_suggestion: str = Field(description="配图/图表建议")classPresentation(BaseModel):"""完整 PPT"""    title: str = Field(description="演示标题")    subtitle: str = Field(description="副标题")    total_slides: int = Field(description="总页数")    slides: List[Slide] = Field(description="所有页面")    estimated_duration: int = Field(description="预计演讲时长(分钟)")# === 2. 创建提示词 ===defcreate_ppt_prompt():"""创建 PPT 生成提示词"""    parser = JsonOutputParser(pydantic_object=Presentation)    prompt = ChatPromptTemplate.from_messages([        ("system""""你是一个专业的 PPT 策划专家。        你的任务是根据主题生成结构清晰、内容完整的 PPT 大纲。        要求:        1. 结构完整(开场→正文→结尾)        2. 每页内容精炼(3-5 个要点)        3. 提供演讲者备注        4. 给出视觉化建议(图表、图片)        5. 控制总页数在合理范围(10-20 页)        输出格式:{format_instructions}"""),        ("human""""请为以下主题生成 PPT 大纲:主题:{topic}目标受众:{audience}演讲时长:{duration}分钟关键信息:{key_points}{format_instructions}""")    ])return prompt, parser# === 3. 创建生成链 ===defcreate_ppt_chain():"""创建 PPT 生成链"""    llm = ChatOpenAI(model="gpt-4o", temperature=0.7)    prompt, parser = create_ppt_prompt()    chain = prompt | llm | parserreturn chain# === 4. 导出为 Markdown/PPTX ===defexport_to_markdown(presentation: dict) -> str:"""导出为 Markdown 格式"""    md = f"# {presentation['title']}\n"    md += f"## {presentation['subtitle']}\n\n"    md += f"**预计时长:{presentation['estimated_duration']}分钟**\n\n"    md += f"**总页数:{presentation['total_slides']}**\n\n"    md += "---\n\n"for slide in presentation['slides']:        md += f"## 第{slide['slide_number']}页:{slide['title']}\n\n"for point in slide['content']:            md += f"- {point}\n"        md += f"\n> 📝 演讲者备注:{slide['notes']}\n"        md += f"\n> 🎨 视觉建议:{slide['visual_suggestion']}\n\n"        md += "---\n\n"return mddefexport_to_pptx(presentation: dict, output_file: str):"""导出为 PowerPoint 文件"""from pptx import Presentationfrom pptx.util import Inches, Pt    prs = Presentation()# 标题页    title_slide = prs.slides.add_slide(prs.slide_layouts[0])    title_slide.shapes.title.text = presentation['title']    title_slide.placeholders[1].text = presentation['subtitle']# 内容页for slide_data in presentation['slides']:        slide = prs.slides.add_slide(prs.slide_layouts[1])        slide.shapes.title.text = slide_data['title']# 添加内容要点        tf = slide.placeholders[1].text_frame        tf.clear()  # 清除默认段落for i, point inenumerate(slide_data['content']):if i == 0:                p = tf.paragraphs[0]else:                p = tf.add_paragraph()            p.text = point            p.font.size = Pt(18)            p.space_after = Pt(10)# 保存    prs.save(output_file)print(f"PPT 已保存到:{output_file}")# === 5. 使用示例 ===if __name__ == "__main__":    chain = create_ppt_chain()# 生成产品发布会 PPT    presentation = chain.invoke({"topic""AI 智能助手产品发布","audience""企业客户和媒体","duration"30,"key_points""""        1. 产品定位:企业级 AI 助手        2. 核心功能:文档处理、数据分析、自动化工作流        3. 技术优势:自研大模型、响应速度快        4. 价格策略:订阅制,按量付费        5. 上市时间:2026 年 5 月 1 日        """    })# 导出为 Markdown    md_content = export_to_markdown(presentation)withopen("product_launch.md""w", encoding='utf-8'as f:        f.write(md_content)# 导出为 PPTX    export_to_pptx(presentation, "product_launch.pptx")print("PPT 生成完成!")

输出示例(Markdown 格式)

# AI 智能助手产品发布## 重新定义企业生产力**预计时长:30 分钟****总页数:12**---## 第 1 页:封面- AI 智能助手产品发布- 重新定义企业生产力- 2026 年 4 月> 📝 演讲者备注:开场问候,感谢到场嘉宾> 🎨 视觉建议:产品 Logo + 科技感背景---## 第 2 页:议程- 市场痛点分析- 产品介绍- 核心功能演示- 技术优势- 价格与上市计划- Q&A> 📝 演讲者备注:简要介绍今天的议程> 🎨 视觉建议:简洁的目录列表---## 第 3 页:市场痛点- 企业员工 30% 时间花在重复性文档工作上- 数据分析门槛高,业务人员难以自助- 现有工具学习成本高,使用率低- 信息孤岛严重,协作效率低> 📝 演讲者备注:用数据说明市场痛点> 🎨 视觉建议:柱状图展示时间浪费情况---## 第 4 页:产品介绍- 定位:企业级 AI 生产力助手- 目标用户:中小企业到大企业- 核心价值:让 AI 帮你工作,而不是替代你- 差异化:专注工作场景,深度集成现有工具> 📝 演讲者备注:强调产品定位和差异化> 🎨 视觉建议:产品界面截图...(后续页面略)

五、功能四:文档润色与改写

场景描述

输入:原始文档 输出:润色后的版本(更专业、更流畅、更符合场景)

完整实现

# document_polisher.pyfrom langchain_openai import ChatOpenAIfrom langchain.prompts import ChatPromptTemplatefrom langchain_text_splitters import RecursiveCharacterTextSplitter# === 1. 创建润色提示词库 ===POLISH_PROMPTS = {"professional""""    你是一位专业的文字编辑。请润色以下文档,使其更加:    1. 专业正式    2. 逻辑清晰    3. 用词准确    4. 语句流畅    保持原意不变,只改进表达方式。    原文:    {text}    润色后:    ""","concise""""    你是一位精简专家。请改写以下文档,使其更加:    1. 简洁明了    2. 去除冗余    3. 重点突出    4. 易于快速阅读    目标:在保持核心信息的前提下,减少 30% 字数。    原文:    {text}    精简后:    ""","persuasive""""    你是一位说服专家。请改写以下文档,使其更加:    1. 有说服力    2. 突出价值和收益    3. 使用积极的语言    4. 增加行动号召    原文:    {text}    改写后:    ""","email""""    你是一位商务沟通专家。请将以下内容改写成专业的商务邮件:    1. 合适的称呼和结尾    2. 清晰的意图表达    3. 礼貌但直接的语气    4. 明确的行动期望    原始内容:    {text}    邮件:    ""","technical""""    你是一位技术文档专家。请润色以下技术文档,使其更加:    1. 术语准确    2. 结构清晰    3. 示例充分    4. 易于理解    原文:    {text}    润色后:    """}# === 2. 创建润色链 ===defcreate_polisher_chain(style: str = "professional"):"""创建文档润色链"""    llm = ChatOpenAI(model="gpt-4o", temperature=0.5)    prompt_text = POLISH_PROMPTS.get(style, POLISH_PROMPTS["professional"])    prompt = ChatPromptTemplate.from_template(prompt_text)    chain = prompt | llmreturn chain# === 3. 处理长文档 ===defpolish_long_document(text: str, style: str = "professional", chunk_size: int = 2000) -> str:"""润色长文档"""# 分割文档    splitter = RecursiveCharacterTextSplitter(        chunk_size=chunk_size,        chunk_overlap=200,        separators=["\n\n""\n""。""!""?"]    )    chunks = splitter.split_text(text)# 创建润色链    chain = create_polisher_chain(style)# 分段润色    polished_chunks = []for i, chunk inenumerate(chunks, 1):print(f"正在润色第 {i}/{len(chunks)} 段...")        polished = chain.invoke({"text": chunk})        polished_chunks.append(polished.content)# 合并return"\n\n".join(polished_chunks)# === 4. 使用示例 ===if __name__ == "__main__":# 原始文档(示例)    original_text = """    我们这个产品挺好的,功能很多,可以用在很多地方。    比如说写文档啊,做表格啊,都可以用。    而且价格也不贵,比别的家便宜。    欢迎大家来试试,用了就知道好了。    """# 专业风格润色    professional_chain = create_polisher_chain("professional")    professional_result = professional_chain.invoke({"text": original_text})print("=== 专业版 ===")print(professional_result.content)# 精简版    concise_chain = create_polisher_chain("concise")    concise_result = concise_chain.invoke({"text": original_text})print("\n=== 精简版 ===")print(concise_result.content)# 说服版    persuasive_chain = create_polisher_chain("persuasive")    persuasive_result = persuasive_chain.invoke({"text": original_text})print("\n=== 说服版 ===")print(persuasive_result.content)

输出示例

=== 专业版 ===本产品具备丰富的功能模块,可广泛应用于多种业务场景。核心功能包括:- 智能文档处理- 电子表格自动化- 数据分析与可视化在定价方面,本产品具有显著的市场竞争力,相比同类产品价格更优。我们诚挚邀请您体验本产品,相信其卓越性能将为您带来实质性的工作效率提升。=== 精简版 ===产品功能丰富,适用场景广泛:• 文档处理• 表格制作• 性价比高欢迎试用,效果显著。=== 说服版 ===想象一下,如果有一个工具能帮你:✓ 自动完成繁琐的文档工作✓ 轻松制作专业表格✓ 节省 50% 的工作时间这就是我们的产品能为你带来的改变!而且,现在体验的价格比市场同类产品低 30%。立即开始免费试用,7 天后你将无法想象没有它的工作生活!

六、整合:一站式文档助手

完整应用

# doc_assistant.pyfrom fastapi import FastAPI, UploadFile, Filefrom fastapi.responses import HTMLResponsefrom pydantic import BaseModelfrom typing importOptionalListimport uvicornfrom meeting_notes import create_meeting_chainfrom weekly_report import create_report_chainfrom ppt_generator import create_ppt_chain, export_to_markdownfrom document_polisher import create_polisher_chain, polish_long_documentapp = FastAPI(title="智能文档助手")classMeetingRequest(BaseModel):    transcript: strclassReportRequest(BaseModel):    work_records: str    current_date: strclassPPTRequest(BaseModel):    topic: str    audience: str    duration: int    key_points: strclassPolishRequest(BaseModel):    text: str    style: str = "professional"@app.post("/api/meeting-notes")asyncdefgenerate_meeting_notes(request: MeetingRequest):"""生成会议纪要"""    chain = create_meeting_chain()    result = chain.invoke({"meeting_transcript": request.transcript})return result@app.post("/api/weekly-report")asyncdefgenerate_weekly_report(request: ReportRequest):"""生成周报"""    chain = create_report_chain()    result = chain.invoke({"work_records": request.work_records,"current_date": request.current_date    })return result@app.post("/api/ppt-outline")asyncdefgenerate_ppt_outline(request: PPTRequest):"""生成 PPT 大纲"""    chain = create_ppt_chain()    result = chain.invoke({"topic": request.topic,"audience": request.audience,"duration": request.duration,"key_points": request.key_points    })return {"presentation": result,"markdown": export_to_markdown(result)    }@app.post("/api/polish")asyncdefpolish_document(request: PolishRequest):"""润色文档"""iflen(request.text) > 5000:# 长文档分段处理        result = polish_long_document(request.text, request.style)else:        chain = create_polisher_chain(request.style)        result = chain.invoke({"text": request.text}).contentreturn {"polished_text": result}@app.get("/", response_class=HTMLResponse)asyncdefhomepage():"""简单的前端页面"""return"""    <!DOCTYPE html>    <html>    <head>        <title>智能文档助手</title>        <style>            body { font-family: Arial; max-width: 800px; margin: 50px auto; }            textarea { width: 100%; height: 200px; }            button { padding: 10px 20px; margin: 10px 0; }            .result { background: #f5f5f5; padding: 20px; margin: 20px 0; }        </style>    </head>    <body>        <h1>📝 智能文档助手</h1>        <h2>会议纪要</h2>        <textarea id="transcript" placeholder="粘贴会议记录..."></textarea>        <button onclick="generateMeetingNotes()">生成纪要</button>        <h2>周报生成</h2>        <textarea id="workRecords" placeholder="粘贴工作记录..."></textarea>        <button onclick="generateReport()">生成周报</button>        <h2>PPT 大纲</h2>        <input type="text" id="pptTopic" placeholder="主题" style="width:100%">        <textarea id="pptPoints" placeholder="关键信息..."></textarea>        <button onclick="generatePPT()">生成 PPT</button>        <h2>文档润色</h2>        <textarea id="docText" placeholder="粘贴要润色的文本..."></textarea>        <select id="style">            <option value="professional">专业正式</option>            <option value="concise">简洁明了</option>            <option value="persuasive">有说服力</option>            <option value="email">商务邮件</option>        </select>        <button onclick="polishDoc()">润色</button>        <div id="result" class="result"></div>        <script>            async function callAPI(endpoint, data) {                const response = await fetch(endpoint, {                    method: 'POST',                    headers: {'Content-Type': 'application/json'},                    body: JSON.stringify(data)                });                return await response.json();            }            async function generateMeetingNotes() {                const transcript = document.getElementById('transcript').value;                const result = await callAPI('/api/meeting-notes', {transcript});                document.getElementById('result').innerHTML =                     '<h3>会议纪要</h3><pre>' + JSON.stringify(result, null, 2) + '</pre>';            }            async function generateReport() {                const workRecords = document.getElementById('workRecords').value;                const result = await callAPI('/api/weekly-report', {                    work_records: workRecords,                    current_date: new Date().toISOString().split('T')[0]                });                document.getElementById('result').innerHTML =                     '<h3>周报</h3><pre>' + JSON.stringify(result, null, 2) + '</pre>';            }            async function generatePPT() {                const topic = document.getElementById('pptTopic').value;                const points = document.getElementById('pptPoints').value;                const result = await callAPI('/api/ppt-outline', {                    topic: topic,                    audience: '通用',                    duration: 20,                    key_points: points                });                document.getElementById('result').innerHTML =                     '<h3>PPT 大纲</h3><pre>' + result.markdown + '</pre>';            }            async function polishDoc() {                const text = document.getElementById('docText').value;                const style = document.getElementById('style').value;                const result = await callAPI('/api/polish', {text, style});                document.getElementById('result').innerHTML =                     '<h3>润色后</h3><pre>' + result.polished_text + '</pre>';            }        </script>    </body>    </html>    """if __name__ == "__main__":    uvicorn.run(app, host="0.0.0.0", port=8000)

七、踩坑记录

坑 1:长文档处理超时

问题:会议记录超过 1 万字,一次性处理超时

解决

# 分段处理 + 合并chunks = split_document(long_text, chunk_size=3000)summaries = [chain.invoke(chunk) for chunk in chunks]final_summary = merge_summaries(summaries)

坑 2:输出格式不稳定

问题:有时输出 JSON,有时输出纯文本

解决

# 强制使用 OutputParserparser = JsonOutputParser(pydantic_object=MeetingSummary)chain = prompt | llm | parser  # 确保输出是 JSON

坑 3:润色后失去原意

问题:过度润色导致关键信息丢失

解决

# 提示词中强调保持原意prompt = """润色以下文档,使其更专业,但**保持原意不变**。只改进表达方式,不要添加或删除关键信息。"""

总结

智能文档助手核心价值

功能
节省时间
适用场景
会议纪要
2 小时 → 5 分钟
所有会议
周报月报
1 小时 → 10 分钟
每周/每月
PPT 大纲
1 小时 → 5 分钟
汇报、演讲
文档润色
30 分钟 → 1 分钟
邮件、方案

关键要点

  1. 结构化输出:用 Pydantic 定义输出格式
  2. 分段处理:长文档分块后合并
  3. 风格可选:提供多种润色风格
  4. 一键导出:支持 Markdown、PPTX 等格式

下一篇预告

实战(五):知识库问答系统——让 AI 基于你的私有数据回答问题,支持 PDF、Word、网页等多种数据源,带引用来源和置信度评估。

敬请期待!🚀


本文是 LangChain 实战系列第 4 篇。完整系列:实战 1-4 篇

作者:小爪 🐾公众号:[你的公众号名称]

系列汇总:关注公众号回复「LangChain」获取全部文章 PDF

引用链接

[1]实战一: #

[2]实战二: #

[3]实战三: #