前言
这是一个系统学习LangChain 1.0和LangGraph 1.0的实践仓库,涵盖从基础概念到实战项目的完整学习路径。
前期知识回顾
Java 转 AI 开发必看:LangChain1.0 从入门到精通,一文搞定生产级 AI 应用开发 基础调用LLM
提示词模板 (Prompt Templates)
PromptTemplate 简单文本模板
核心概念
PromptTemplate 用于书写简单的文本文档
优点:可以对格式化补全文字。
缺点:不能携带角色信息,只能生成纯字符
适用场景:摘要、翻译、续写
三种方式:
使用 from_template(最简单)
显式指定变量(更严格)input_variables
使用 invoke(直接生成消息) ,传输一个字典
defexample_2_prompt_template_basics():""" 示例2:PromptTemplate 的基本用法 PromptTemplate 用于简单的文本模板 适合单一提示词的场景 """print("\n"+"="*70)print("示例 2:PromptTemplate 基础用法")print("="*70)# 方法 1:使用 from_template(最简单)print("\n【方法 1:from_template(推荐)】")template1=PromptTemplate.from_template("将以下文本翻译成{language}:\n{text}")prompt1=template1.format(language="法语",text="Hello, how are you?")print(f"生成的提示词:\n{prompt1}\n")response1=model.invoke(prompt1)print(f"AI 回复:{response1.content}\n")# 方法 2:显式指定变量(更严格)print("【方法 2:显式指定变量】")template2=PromptTemplate(input_variables=["product","feature"],template="为{product}写一句广告语,重点突出{feature}特点。")prompt2=template2.format(product="智能手表",feature="超长续航")print(f"生成的提示词:\n{prompt2}\n")response2=model.invoke(prompt2)print(f"AI 回复:{response2.content}\n")# 方法 3:使用 invoke(直接生成消息)print("【方法 3:使用 invoke(更方便)】")template3=PromptTemplate.from_template("写一首关于{theme}的{style}风格的诗,不超过4行。")# invoke 直接返回格式化后的值prompt_value=template3.invoke({"theme":"春天","style":"现代"})print(f"生成的提示词:\n{prompt_value.text}\n")ChatPromptTemplate - 聊天消息模板
核心概念
ChatPromptTemplate 用于构建聊天消息
优点:支持多种角色,创建消息对象列表(
List[BaseMessage])缺点:创建相对复杂
适用场景:多轮对话、聊天机器人、智能代理
三种方式:
使用元组格式(最简单,推荐)
messages=chat_template.format_messages(role="Python 导师",expertise="用简单的方式解释复杂概念",task="解释什么是列表推导式")])
使用字符串简写(最简洁)
messages=simple_template.format_messages(question="什么是机器学习?")
defexample_3_chat_prompt_template():""" 示例3:ChatPromptTemplate 的基本用法 """print("\n"+"="*70)print("示例 3:ChatPromptTemplate - 聊天消息模板")print("="*70)# 方法 1:使用元组格式(最简单,推荐)print("\n【方法 1:元组格式(推荐)】")chat_template=ChatPromptTemplate.from_messages([("system","你是一个{role},擅长{expertise}。"),("user","请帮我{task}")])print(f"模板变量:{chat_template.input_variables}")# 格式化模板messages=chat_template.format_messages(role="Python 导师",expertise="用简单的方式解释复杂概念",task="解释什么是列表推导式")print("\n生成的消息:")formsginmessages:print(f"{msg.type}:{msg.content}")response=model.invoke(messages)print(f"\nAI 回复:{response.content[:150]}...\n")# 方法 2:使用字符串简写(最简洁)print("【方法 2:字符串简写】")simple_template=ChatPromptTemplate.from_messages([("system","你是一个友好的助手"),("user","{question}")])messages=simple_template.format_messages(question="什么是机器学习?")response=model.invoke(messages)print(f"AI 回复:{response.content[:100]}...\n")多轮对话模板
核心概念
构建包含多系统提示词和对话历史的模板
模板的结构:
System: 设定角色和指令
User: 第一个问题
Assistant: 第一个回答
User: 第二个问题(基于上下文)
defexample_4_conversation_template():""" 示例4:构建多轮对话的模板 """print("\n"+"="*70)print("示例 4:多轮对话模板")print("="*70)# 创建包含对话历史的模板template=ChatPromptTemplate.from_messages([("system","你是一个{role}。{instruction}"),("user","{question1}"),("assistant","{answer1}"),("user","{question2}")])print("模板结构:")print(" 1. System: 设定角色和指令")print(" 2. User: 第一个问题")print(" 3. Assistant: 第一个回答")print(" 4. User: 第二个问题(基于上下文)\n")# 填充模板messages=template.format_messages(role="Python 专家",instruction="回答要简洁、准确",question1="什么是列表?",answer1="列表是 Python 中的有序可变集合,用方括号 [] 表示。",question2="它和元组有什么区别?"# 基于上下文的问题)print("生成的完整对话:")fori,msginenumerate(messages,1):content_preview=msg.content[:60]+"..."iflen(msg.content)>60elsemsg.contentprint(f"{i}. [{msg.type}]{content_preview}")response=model.invoke(messages)print(f"\nAI 回复:{response.content}\n")MessagePromptTemplate(高级)
核心概念:
MessagePromptTemplate 可以提供更细的颗粒度的控制
组件:
SystemMessagePromptTemplate:系统提示词组件
HumanMessagePromptTemplate:用户提示词组件
AIMessagePromptTemplate:ai提示返回格式
defexample_5_message_templates():""" 示例5:使用 MessagePromptTemplate 类 提供更细粒度的控制 """print("\n"+"="*70)print("示例 5:MessagePromptTemplate 类(高级用法)")print("="*70)# 分别创建不同类型的消息模板system_template=SystemMessagePromptTemplate.from_template("你是一个{profession},你的特长是{specialty}。")# AI 消息模板(预设 AI 的回复格式)ai_template=AIMessagePromptTemplate.from_template("好的,作为{profession},我来帮你解答关于{topic}的问题。")human_template=HumanMessagePromptTemplate.from_template("关于{topic},我想知道{question}")# 组合成 ChatPromptTemplatechat_template=ChatPromptTemplate.from_messages([system_template,ai_template,human_template])print("模板组件:")print(f" 1. SystemMessagePromptTemplate")print(f" 2. AIMessagePromptTemplate")print(f" 3. HumanMessagePromptTemplate")print(f"\n总变量:{chat_template.input_variables}\n")# 使用模板messages=chat_template.format_messages(profession="数据科学家",specialty="用数据讲故事",topic="数据可视化",question="如何选择合适的图表类型?")response=model.invoke(messages)print(f"AI 回复:{response.content[:200]}...\n")部分变量(Partial Variables)
核心概念
使用partial()进行部分填充数据,可在后续的程序中继续填充其他变量。
适用场景:
某些变量固定不变
需要创建模板变体
defexample_6_partial_variables():""" 示例6:部分变量 - 预填充某些变量 """print("\n"+"="*70)print("示例 6:部分变量(Partial Variables)")print("="*70)# 创建原始模板original_template=ChatPromptTemplate.from_messages([("system","你是一个{role},你的目标用户是{audience}。"),("user","请{task}")])print(f"原始模板变量:{original_template.input_variables}\n")# 部分填充:固定 role 和 audiencepartially_filled=original_template.partial(role="科技博客作者",audience="程序员")print(f"部分填充后的变量:{partially_filled.input_variables}\n")# 现在只需要提供 taskmessages1=partially_filled.format_messages(task="写一篇关于 Python 装饰器的文章开头")response1=model.invoke(messages1)print(f"文章 1:{response1.content[:150]}...\n")# 复用模板,不同的 taskmessages2=partially_filled.format_messages(task="写一篇关于异步编程的文章开头")response2=model.invoke(messages2)print(f"文章 2:{response2.content[:150]}...\n")LCEL 链式调用
核心概念:
模板+模型的链式调用,中间使用|进行连接
链的组成:
模板 | 模型
(Template) | (LLM)
调用方式:链对象直接使用invoke方法传参字典 key值为模板变量命名,value为变量替换内容
使用优势:
代码更简洁
组件可复用
易于调试和监控
chain.invoke({"role":"幽默的程序员","input":"解释什么是bug"})示例:
defexample_9_lcel_chains():""" 示例9:模板 + 模型的链式调用 LangChain Expression Language (LCEL) """print("\n"+"="*70)print("示例 9:LCEL 链式调用(预览)")print("="*70)# 创建模板template=ChatPromptTemplate.from_messages([("system","你是一个{role}"),("user","{input}")])# 使用 | 运算符创建链chain=template|modelprint("链的组成:")print(" 模板 | 模型")print(" (Template) | (LLM)\n")# 直接调用链response=chain.invoke({"role":"幽默的程序员","input":"解释什么是bug"})print(f"AI 回复:{response.content}\n")print("💡 链式调用的优势:")print(" 1. 代码更简洁")print(" 2. 组件可复用")print(" 3. 易于调试和监控")