LangChain 实战(四):智能文档助手,让 AI 帮你写文档、改 PPT、做总结
LangChain 实战(四):智能文档助手,让 AI 帮你写文档、改 PPT、做总结
这是 LangChain 实战系列的第 4 篇。前情提要:实战一[1] | 实战二[2] | 实战三[3]
开篇说个高频场景
你是不是经常遇到这些事:
❌ 会议纪要:1 小时的会议,整理纪要花 2 小时❌ 周报月报:每周憋半天,写的还都是流水账❌ PPT 大纲:要做汇报,对着空白 PPT 发呆 1 小时❌ 文档润色:写好的方案,语言太生硬,反复改❌ 信息提取:100 页的合同,找个条款翻半天
今天这篇,就用 LangChain 构建一个智能文档助手,帮你搞定这些事。
我们解决四个问题:
-
怎么让 AI 自动整理会议纪要? -
怎么让 AI 帮你写周报、月报、总结? -
怎么让 AI 生成 PPT 大纲和内容? -
怎么让 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 importList, Optional# === 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 importOptional, Listimport 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 = """润色以下文档,使其更专业,但**保持原意不变**。只改进表达方式,不要添加或删除关键信息。"""
总结
智能文档助手核心价值:
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
关键要点:
-
结构化输出:用 Pydantic 定义输出格式 -
分段处理:长文档分块后合并 -
风格可选:提供多种润色风格 -
一键导出:支持 Markdown、PPTX 等格式
下一篇预告
实战(五):知识库问答系统——让 AI 基于你的私有数据回答问题,支持 PDF、Word、网页等多种数据源,带引用来源和置信度评估。
敬请期待!🚀
本文是 LangChain 实战系列第 4 篇。完整系列:实战 1-4 篇
作者:小爪 🐾公众号:[你的公众号名称]
系列汇总:关注公众号回复「LangChain」获取全部文章 PDF
引用链接
[1]实战一: #
[2]实战二: #
[3]实战三: #
夜雨聆风