木厶笔记存放站木厶笔记存放站
首页
文章
首页
文章
  • Web

    • 网络

      • 01-01 HTTP 基础
      • 01-02 HTTP1.1 首部字段
      • 01-03 HTTP 优化
      • 01-04 HTTPS
      • 01-05 TCP 和 UDP
      • 01-06 URI 和 URL
      • 01-07 Cookie 和 Session
      • 01-08 输入URL_至页面显示的过程
    • 安全

      • CSRF 攻击
      • JSON Web Token
      • sql 注入
      • XSS 攻击
    • 浏览器机制

      • 提升SEO
      • 浏览器内核
      • 浏览器的进程和线程
      • 浏览器缓存机制
      • 跨域
    • 场景实现

      • 优化大量图片加载
      • 扫码登录
    • 性能优化

      • 性能分析
      • 资源请求优化
      • 运行时优化
      • 重排重绘
      • 静态资源优化
  • HTML

    • HTML5基础

      • 01-01 简介
      • 01-02 全局属性
      • 01-03 特殊字符编码
      • 01-04 标签
      • 02-01 图片标签
      • 02-02 a标签
      • 02-03-1 video&audio
      • 02-03-2 AudioContext
      • 02-04 iframe
      • 02-05 表格标签
      • 03-01 form
      • 03-02 fieldset
      • 03-03 label
      • 03-04 input
      • 03-05 select
      • 03-06 datalist
      • 03-07 textarea
      • 03-08 progress
      • 03-09 meter
      • 04-01 dialog
      • 04-02 折叠标签
    • WEBAPI

      • 01-01 Canvas
      • 01-02 Canvas-绘制图形
      • 01-03 Canvas-画布处理
      • 01-04 Canvas-像素滤镜
      • 01-05 OffscreenCanvas
      • 01-06 Canvas-性能优化
      • 02-01 Svg
      • 02-02 Svg-d属性
      • 02-03 Svg-动画
      • 02-04 Svg-foreignObject
      • 03-01 customElements
      • 03-02 shadow-dom
      • 03-03 template
      • 04-01 Drag
  • CSS

    • 基础

      • 01-01 CSS 架构
      • 01-02 At规则
      • 01-03 媒体查询
      • 01-04 @support
      • 02-01 层叠顺序与堆栈上下文
      • 02-02 盒模型
      • 02-03 文档流
      • 02-04 float 浮动
      • 02-05 元素不可见
      • 03-01 视觉格式化模型-基础概念
      • 03-02 视觉格式化模型-格式化上下文(FC)
      • 04-01-显示默认值
      • 05-01 RGB&HSL&HWB&LAB&LCH
      • 05-02 色域和颜色空间
      • 05-03 OKLCH&OKLAB
      • 05-04 相对颜色语法
      • 05-05 color-min()
      • 05-06 线性渐变
      • 05-07 径向渐变
      • 05-08 锥形渐变
      • 06-01 比较函数-min&max&clamp
      • 06-02 三角函数
      • 07-01 文本换行
      • 07-02 自定义字体
      • 08-01 CSS变量
      • 08-02 @property
      • 09-01 相对单位
      • 10-01 CSS 嵌套
      • 11-01 固定宽高比
      • 12-01 clip-path
      • 12-02 mask
      • 12-03 object-view-box
      • 13-01 filter
      • 13-02 backdrop-filter
    • CSS 选择器

      • 01 选择器优先级
      • 02 选择符
      • 03 属性选择器
      • 04 伪类
      • 05 树结构伪类
      • 06 逻辑选择器
      • 07 数学函数
    • 布局

      • flex 布局--实用
      • flex 布局
      • Grid 布局--实用
      • Grid 布局
      • 响应式布局
      • 换肤
      • 移动端布局
      • 锚点定位布局
    • 动画与过渡

      • 01-01 CSS 动画
      • 02-01 view transition
      • 03-01 缓动效果
      • 03-02 逐帧动画
      • 03-03 呼吸&摆钟效果
      • 03-04 打字动画
      • 03-05 沿圆形路径移动动画
      • 03-06 3D翻转卡片
      • 03-08 骨架屏效果
      • 03-09 描边动画
      • 03-10 液态玻璃效果
    • 小寄巧

      • 00-01 初始化 CSS
      • 01-01 半透明边框
      • 01-02 多重边框
      • 01-03 边框内圆角
      • 01-04 连续的图像边框
      • 02-01 自适应的椭圆
      • 02-02 平行四边形
      • 02-03 切角效果
      • 02-04 折角效果
      • 02-05 梯形标签页
      • 02-06 简单的饼图
      • 03-01 单侧投影
      • 03-02 不规则投影
      • 04-01 文字下划线
      • 04-02 渐变色字体
      • 04-03 字体描边
      • 04-04 字体阴影&艺术字体
      • 04-05 任意路径排布文字
      • 04-06 文本省略号
      • 05-01 扩大可点击区域
      • 05-02 交互式的图片对比控件
      • 05-03 简单视差效果
      • 06-01 自适应内部元素
      • 06-02 根据兄弟元素的数量来设置样式
      • 06-03 垂直居中
      • 06-04 消除 inline-block 间隙
      • 07-01 精确控制表格列宽
      • 08-01 修改svg图片颜色
      • 08-02 雪碧图
  • JavaScript

    • 基础

      • 2 script标签
      • 3-1 语法
      • 3-3 var let const
      • 3-4-1 typeof 和 instanceof
      • 3-4-2 Undefined 类型
      • 3-4-3 Null 类型
      • 3-4-4 Boolean 类型
      • 3-4-5 Number 类型
      • 3-4-6 String 类型
      • 3-4-7 Symbol 类型
      • 3-4-8 Object 类型
      • 3-4-9 BigInt 类型
      • 3-5 操作符
      • 3-6 隐式转换
      • 4-1 原始值和引用值
      • 4-2 执行上下文与作用域
      • 4-3 垃圾回收
      • 5-1 Date
      • 5-2 RegExp
      • 5-3 原始值包装类型
      • 5-4-1 Global 单例内置对象
      • 5-4-2 Math 单例内置对象
      • 6-2 Array
      • 6-3 Map
      • 6-4 WeakMap
      • 6-5 Set
      • 6-6 WeakSet
      • 7-1 迭代器与生成器
      • 8-1-1 Object 属性
      • 8-1-2 Object 构造函数方法
      • 8-1-3 Object 语法增强和解构
      • 8-2 Object 创建
      • 8-3 原型和继承
      • 8-4 class 类
      • 8-5 this
      • 8-6 可选链和空值合并运算符
      • 9 proxy 代理与反射
      • 10-1 Function 函数
      • 10-2 apply call bind
      • 10-3 闭包
      • 10-4 私有变量
      • 10-5 扩展运算符和 rest
      • 11-1 event loop 事件循环机制
      • 11-2 Promise 期约
      • 11-3 async await
      • 12-1 BOM
      • 14-1-1 DOM 节点
      • 14-1-2 DOM Document 类型
      • 14-1-3 DOM Element 类型
      • 14-1-4 DOM Text 和 Comment 类型
      • 14-2 动态脚本和动态样式
      • 14-3 MutationObserver 监听节点变化
      • 14-4 Intersection Observer
      • 16-2-1 操控样式
      • 16-2-2 元素尺寸
      • 16-3 DOM 深度优先遍历
      • 17-1 事件流
      • 17-2 事件处理程序
      • 17-3 事件对象
      • 17-4-1 UI 和焦点事件
      • 17-4-2 鼠标和滚轮事件
      • 17-4-3 键盘与输入事件
      • 17-4-4 HTML5 事件
      • 17-4-5 设备和触摸事件
      • 17-6 模拟事件
      • 18-1 requestAnimationFrame&requestIdleCallback
      • 18-2 canvas
      • 19-1 表单基础
      • 19-2 文本框编程
      • 19-3 选择框编程
      • 19-5 富文本编辑器
      • 20-10 Perfromance API
      • 20-11-1 HTML 模板
      • 20-11-2 影子 DOM
      • 20-11-3 自定义元素
      • 20-14 MessageChannel和BroadcastChannel
      • 20-15 AbortController
      • 20-4 File API 与 Blob API
      • 20-7 Notifications API
      • 20-8 Page Visibility API
      • 20-9 Streams API
      • 23 JSON
      • 24-03 Server-Sent-Events
      • 24-04 WebSocket
      • 24-1 XMLHttpRequest
      • 24-5 Fetch API
      • 25-01 cookie
      • 25-02 Web-Storage
      • 26-1 模块语法
      • 26-2 CommonJs 与 ES6 Module 的差异
      • 27-01 WebWorker
    • 设计模式

      • 单例模式
      • 发布订阅模式
      • 工厂模式
      • 策略模式
      • 装饰器模式
      • 观察者模式
      • 适配器模式
    • 手写实现

      • apply call bind
      • flat
      • instanceof
      • JSONP
      • new
      • Promise API
      • trim
      • 数组去重
      • 柯里化
      • 深拷贝
      • 防抖和节流
    • 场景题

      • 映射 URL 参数
      • 模拟红绿灯
      • 请求-丢弃旧时序的请求
      • 请求-并发请求
      • 通过 value 找 key
      • 闭包题
    • 移动端

      • touch 事件
      • visualViewport
      • 像素
      • 移动端布局
      • 视口 Viewport
    • 实用

      • better-scroll 滚动组件
      • Proxy实现英文字母升降序
      • 区别数组和对象
      • 图片懒加载
      • 按首字母排序的列表
      • 控制粘贴板
    • PIXI

      • 1 Application
      • 2 Graphics
      • 3 loader
      • 4 Sprite
      • 5 Spine
      • 6 事件
      • 7 Renderer
  • Node

    • 基础

      • crypto 加密模块
      • fs 模块
      • http 模块
      • mysql 模块
      • redis 模块
    • 框架

      • express
      • koa2
    • 实用

      • @elasticelasticsearch
      • restful Mock 数据
      • 自定义 Mock 数据
    • 错误

      • pm2-watch报错 502
      • spawn 中文乱码
  • Jquery

    • 基础

      • 事件
      • 动画
      • 工具方法
      • 操作 dom
      • 获取元素
  • TypeScript

    • 环境

      • config
      • 环境
    • 基础

      • 01 原始类型和特殊类型
      • 02 字面量和类型拓宽
      • 03 interface 和 type
      • 04 数组和元组
      • 05 class(类)
      • 06 函数和重载
      • 07 联合类型和交叉类型
      • 08 泛型
      • 09 类型推断和类型断言
      • 10 匹配提取
      • 11 重新构造
      • 12 递归循环
      • 13数组长度做计数
      • 14 特殊特性
      • 15 内置高级类型
      • 16 inter extends
      • 17 协变和逆变
  • Vue

    • 环境

      • 安装
      • 自定义环境变量
    • 基础(2.x)

      • data
      • keep-alive
      • nextTick
      • props和sync
      • ref
      • v-for和v-if
      • 事件绑定
      • 动态组件
      • 动画
      • 循环渲染
      • 插槽 slot
      • 条件渲染
      • 样式绑定
      • 模板语法
      • 生命周期
      • 组件通讯
      • 自定义指令
      • 表单绑定
      • 计算属性和监听器
    • 基础(3.x)

      • Composition API
      • Script setup
      • Suspense
      • sync 语法糖
      • Teleport
      • vue3的升级点
      • 常用动画
      • 生命周期
    • router

      • vue-router 3
      • vue-router 4
    • vuex

      • pinia
      • vuex
      • vuex4
      • 刷新不丢失 vuex
    • 底层

      • MVVM
      • 双向绑定
      • 响应式
      • 模板编译
      • 渲染过程
      • 虚拟DOM和diff算法
    • 应用

      • 权限管理
  • React

    • 环境

      • 安装
      • 自定义环境变量
    • 基础

      • JSX
      • ref
      • SCU
      • 不可变数据 setState
      • 事件
      • 动画
      • 异步组件
      • 插槽
      • 条件
      • 生命周期
      • 组件公共逻辑抽离
      • 组件通讯
      • 表单
      • 逃离组件 portals
    • hooks

      • hooks
      • react-query
      • useClickOutSide —— 点击外面
      • useDebounce —— 防抖
      • useURLQueryParam —— 输入框值与search绑定
    • router

      • react-router-com 6
      • react-router-dom hooks
      • react-router-dom
    • redux

      • react-redux
      • redux 与 hooks
      • redux-persist
      • redux-thunk
      • redux-toolkit
      • redux
    • 底层

      • JSX本质
      • setState 原理
      • 合成事件
    • 实用

      • CSS-in-JS
      • 字体库
      • 数组优化为哈希表
      • 组件的子元素只能是规定的元素
  • Echarts

    • 基础

      • 仪表盘
      • 基础
      • 折线图
      • 散点图
      • 柱状图
      • 雷达图
      • 饼图
  • Electron

    • 环境

      • 基本安装
      • 集合 react
    • 基础

      • Dialog
      • 原生菜单
      • 右键菜单
      • 进程
  • 前端工程化

    • babel

      • babel7 实践
      • 工作原理
      • 生态
    • Browserslist

      • 基础
    • npm

      • npm模块安装机制
      • npm脚本
    • qiankun

      • 隔离原理
    • Vite

      • css
      • gzip-打包
      • vite config 常见配置
      • 环境
      • 静态资源
    • webpack

      • css环境
      • js&ts环境
      • loader
      • loader和plugin的区别及编写
      • plugin
      • splitChunks
      • webpack5--模块联邦
      • 代码压缩
      • 优化性能
      • 图片
      • 性能分析工具
      • 提高构建速度
      • 构建性能--并行
      • 构建性能--持久化缓存
      • 热更新
    • 代码提交规范

      • husky&lint-staged
  • Java

    • 环境

      • idea 创建 maven-archetype-webapp
      • spring boot web 的配置参考
      • spring 从初始配置
      • 与 git 集合
    • Web 基础

      • mybatis pager的应用
      • [] 和 List 和 Set
      • 全局 cors 跨域
      • 接口例子——登录
      • 文件接口——图片
      • 有效时间的唯一字符串
      • 自定义类
      • 通用的泛型服务端响应对象
  • Elastic

    • 基础

      • 分词规则
      • 基础概念
      • 基础语法
      • 环境搭建
    • 实用

      • canal——数据库准实时导入
      • logstash——数据库基于时间轴导入
  • Mysql

    • 基础

      • 字段操作
      • 数据库操作
      • 查询操作
      • 表操作
  • Python

    • 基础

      • 1-1-Number
      • 1-2-String
      • 1-3-list和tuple
      • 1-4-序列
      • 1-5-set
      • 1-6-dict
      • 2-1-运算符
      • 2-2-对象比较
      • 3-1-条件判断
      • 3-2-循环
      • 4-1-模块-包
      • 4-2-模块-__init__
      • 4-3-模块-内置变量
      • 4-4-模块-导入
      • 5-1-解包
      • 5-2-函数参数
      • 5-3-作用域
      • 5-4-高阶函数&三元表达式
      • 6-1-类
      • 6-2-类的继承
      • 6-3-枚举
      • 7-1-json
      • 8-1-文件IO
      • 8-2-pathlib
  • Flutter

    • 环境

      • 创建及运行项目
      • 第三方库
      • 运行环境
      • 静态资源
    • Dart

      • dynamic var object
      • List
      • Map
      • Number
      • Set
      • String
      • URI
      • 函数
      • 变量
      • 库
      • 异步
      • 流程控制语句
      • 类
      • 运算符
    • 基础

      • 1 Widget
      • 2 StatelessWidget & StatefulWidget
      • 3 State生命周期
      • 4 状态管理
      • 5 路由
    • 基础组件

      • Button
      • Text
      • 单选开关和复选框
      • 图片及ICON
      • 表单
      • 输入框
      • 进度指示器
    • 布局组件

      • 1 布局约束
      • 2 线性布局(Row & Column)
      • 3 弹性布局(Flex)
      • 4 流式布局(Wrap & Flow)
      • 5 层叠布局(Stack & Positioned)
      • 6 绝对定位(Align)
      • 7 LayoutBuilder & AfterLayout
    • 容器类组件

      • Container
      • Scaffold
      • 变换-Transform
      • 空间适配-FittedBox
      • 裁剪-Clip
      • 装饰-DecoratedBox
    • 可滚动组件

      • SingleChildScrollView
      • 通用属性
  • Git

    • 基础

      • Git commit message 规范
    • 实用

      • cherry-pick
      • stash
      • 分支&修改最近一次commit
      • 撤销
  • 算法

    • 基础

      • leetcode
      • 时间复杂度
    • 收录

      • 阿拉伯数字转中文
    • 数据结构

      • 哈希表、集合
      • 并查集
      • 数组、链表、跳表
      • 栈、队列
      • 树、二叉树、二叉搜索树
    • 算法

      • DFS 和 BFS
      • 二分查找
      • 二叉树路径问题题目
      • 动态规划2--基础题
      • 动态规划2--背包问题
      • 区间类题目
      • 岛屿类题目
      • 排列组合子集类题目
      • 排序算法
      • 摩尔投票
      • 递归
      • 链表
  • 部署

    • centos8

      • bitwarden_rs
      • ElasticSearch
      • git
      • https及http2
      • mac 向 centos 传输文件
      • nginx
      • nvm
    • 其他

      • docker
      • sitemap
      • 重装系统
  • 图形学

    • 基础

      • 1 三角函数
      • 2 斜率k
      • 3 向量
      • 4 矩阵
  • AI

    • Agent

      • 01-01-提示链
    • huggingface

      • 01-01-使用和下载模型
      • 01-02-数据集
      • 01-03-文本分类任务微调
    • langchain

      • 00-01-web用例集合
      • 01-01-Message
      • 01-02-promptTemplate-提示词模版
      • 01-03-outputParser-输出解析器
      • 01-04-fewShot
      • 02-01-LECL&chain
      • 02-02-stream
      • 03-01-debug
      • 04-01-多模态
      • 05-01-tool
      • 06-01-agent
      • 07-01-embedding基础
      • 07-02-向量数据库
      • 08-01-RAG
    • langgraph

      • 1-01-图
      • 1-02-1-状态
      • 1-02-2-消息状态
      • 1-03-节点
      • 1-04-边
      • 1-05-Send
      • 1-06-Command
      • 1-07-配置-configurable
      • 1-08-1-内存持久性
      • 1-08-2-删除持久消息
      • 1-08-3-向量数据库
      • 1-08-4-持久上下文token优化
      • 1-09-1-工具
      • 1-09-2-大量工具优化
      • 1-10-1-人机交互-interrupt
      • 1-10-2-人机交互-interrupt_before
      • 1-11-1-流式输出
      • 1-11-2-自定义流式传输
      • 1-11-3-输出特定的流式消息
      • 1-12-1-子图
      • 1-13-1-ReAct
    • mcp

      • 01-简介
      • MCP Client nodejs
      • MCP Server Python
      • MCP Server TS
    • prompt

      • 提示词策略
      • 输出output

提示链

提示链设计思维

提示链(Prompt Chaining),也称为流水线(Pipeline)模式,是将复杂任务拆解为一系列更小、更易管理的子问题,每个子问题通过专门设计的提示单独处理,并将前一步的输出作为下一步的输入,形成链式依赖。

核心思想:与其让 LLM 一步到位解决复杂问题,提示链采用分而治之策略,每一步的输出作为下一步的输入至关重要,这种信息传递建立了依赖链,使 LLM 能够在前一步基础上不断完善理解,逐步逼近目标解。

  1. 明确每个步骤的目标:每个提示都应该有清晰、单一的目标,避免在一个提示中处理多个不相关的任务
  2. 合理设计上下文传递:前一个步骤的输出应该包含下一个步骤所需的关键信息,但也要避免传递过多冗余信息
  3. 使用角色定位:为每个步骤分配明确的角色,如"市场分析师"、"技术专家"等,提升专业性
  4. 结构化输出:提升下一步提示词拼接的灵活性

为什么需要提示链?

单一提示的局限性 ⚠️

对于多层次任务,单一复杂提示往往效率低下,模型容易出现以下问题:

  • 忽略部分指令:模型可能只完成部分任务,遗漏关键环节
  • 丢失上下文:在长文本处理中,模型可能无法保持完整的上下文理解
  • 错误累积:一步到位的处理方式,错误会直接体现在最终输出中
  • 上下文窗口不足:复杂任务需要大量上下文,可能超出模型的窗口限制
  • 出现幻觉:模型可能生成看似合理但实际错误的信息

示例:要求模型分析市场调研报告、总结发现、提取数据点并撰写邮件,单一提示可能导致模型只完成部分任务,遗漏关键环节。

提示链的优势 ✅

提示链通过将复杂任务拆解为聚焦的顺序流程,显著提升可靠性和可控性:

  1. 模块化设计:将复杂任务拆分为独立的模块,每个模块负责一个特定功能,更容易理解、调试和维护
  2. 提高准确性:每个步骤的输出都经过精心设计的提示进行约束和优化,减少错误传播的可能性
  3. 增强可解释性:每个步骤都会产生中间输出,这些中间结果可以被检查、验证和调试
  4. 灵活组合:可以根据需求动态调整步骤,添加、删除或重新排序

角色分配:为确保每步任务准确,可为模型分配不同角色,如"市场分析师"、"贸易分析师"、"文档专家"等,让每个步骤都有明确的专业定位。

应用场景与流程构建

1. 信息处理流程 📄

场景:许多任务需对原始信息多次转换,如文档摘要、实体提取、用实体查询数据库、生成报告

提示链:

  1. 从指定URL或文档提取文本内容
  2. 摘要清洗后的文本
  3. 从摘要或原文中提取实体(如姓名、日期、地点)
  4. 用实体查询内部知识库
  5. 生成包含摘要、实体和查询结果的最终报告

流程构建:

from typing import TypedDict, List
from pydantic import BaseModel
from langgraph.graph import StateGraph, END
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser, PydanticOutputParser
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(temperature=0)

class Entity(BaseModel):
    name: str
    date: str
    location: str
    organization: str

class AgentState(TypedDict):
    source: str
    text: str
    summary: str
    entities: List[Entity]
    query_results: str
    final_report: str

# 提示 1:提取文本内容
def extract_node(state: AgentState):
    prompt = ChatPromptTemplate.from_template("""你是文档处理专家。请从以下 URL 或文档中提取文本内容:

{source}

输出格式:纯文本内容,去除格式标记。""")
    chain = prompt | llm | StrOutputParser()
    return {"text": chain.invoke({"source": state["source"]})}

# 提示 2:摘要文本
def summarize_node(state: AgentState):
    prompt = ChatPromptTemplate.from_template("""你是内容摘要专家。请对以下文本进行摘要,保留关键信息:
    
{text}

输出格式:200字以内的摘要。""")
    chain = prompt | llm | StrOutputParser()
    return {"summary": chain.invoke({"text": state["text"]})}

# 提示 3:提取实体
def extract_entities_node(state: AgentState):
    summary = state.get('summary', '')
    parser = PydanticOutputParser(pydantic_object=Entity)
    format_instructions = parser.get_format_instructions()
    prompt = ChatPromptTemplate.from_template("""你是信息提取专家。请从以下文本中提取实体信息:
    
{summary}

需要提取的实体类型:
- 人名
- 日期
- 地点
- 组织

{format_instructions}""")
    chain = prompt | llm | parser
    entity = chain.invoke({"summary": state["summary"], "format_instructions": format_instructions})
    return {"entities": [entity]}

# 提示 4:查询知识库
def query_kb_node(state: AgentState):
    entities = state.get('entities', [])
    entities_str = "\n".join([f"- {entity.name} ({entity.date}, {entity.location}, {entity.organization})" for entity in entities])
    prompt = ChatPromptTemplate.from_template("""你是知识库查询专家。根据以下实体信息,查询相关知识:

{entities_str}

输出格式:200字以内的查询结果,不要有任何解释。""")
    chain = prompt | llm | StrOutputParser()
    return {"query_results": chain.invoke({"entities_str": entities_str})}

# 提示 5:生成最终报告
def report_node(state: AgentState):
    summary = state.get('summary', '')
    entities = state.get('entities', [])
    entities_str = "\n".join([f"- {entity.name} ({entity.date}, {entity.location}, {entity.organization})" for entity in entities])
    query_results = state.get('query_results', '')
    prompt = ChatPromptTemplate.from_template("""你是报告撰写专家。请基于以下信息生成综合报告:
    
摘要:{summary}
实体:{entities_str}
查询结果:{query_results}

输出格式:结构化的 Markdown 报告,包含标题、摘要、关键发现、结论等部分。""")
    chain = prompt | llm | StrOutputParser()
    return {"final_report": chain.invoke({"summary": summary, "entities_str": entities_str, "query_results": query_results})}

# 构建图
workflow = StateGraph(AgentState)

# 添加节点
workflow.add_node("extract", extract_node)
workflow.add_node("summarize", summarize_node)
workflow.add_node("entities", extract_entities_node)
workflow.add_node("query", query_kb_node)
workflow.add_node("report", report_node)

# 定义连线
workflow.set_entry_point("extract")
workflow.add_edge("extract", "summarize")
workflow.add_edge("summarize", "entities")
workflow.add_edge("entities", "query")
workflow.add_edge("query", "report")
workflow.add_edge("report", END)

# 编译
app = workflow.compile()

# 运行
inputs = {"source": "http://example.com/data"}
result = app.invoke(inputs)
print(result["final_report"])

2. 复杂问答 💬

场景:回答需要多步推理或信息检索的问题

提示链:

  1. 识别用户问题的核心子问题(崩盘原因、政府应对)
  2. 检索第一个子问题的相关信息
  3. 检索第二个子问题的相关信息
  4. 综合所有信息,形成完整答案

流程构建:

from typing import TypedDict, List
from pydantic import BaseModel
from langgraph.graph import StateGraph, END
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser, JsonOutputParser
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(temperature=0)

class SubQuestion(BaseModel):
    question: str
    type: str  # 原因/应对/影响等

class AgentState(TypedDict):
    question: str
    sub_questions: List[SubQuestion]
    answer_1: str
    answer_2: str
    final_answer: str

# 提示 1:识别子问题
def decompose_node(state: AgentState):
    prompt = ChatPromptTemplate.from_template("""你是问题分析专家。请分析以下问题,识别需要回答的核心子问题:

问题:{question}

输出格式:JSON 格式,包含 sub_questions 数组,每个子问题包含 question 和 type(原因/应对/影响等)。""")
    parser = JsonOutputParser(pydantic_object=List[SubQuestion])
    chain = prompt | llm | parser
    result = chain.invoke({"question": state["question"]})
    return {"sub_questions": result}

# 提示 2:检索第一个子问题
def retrieve_1_node(state: AgentState):
    sub_questions = state.get("sub_questions", [])
    if not sub_questions:
        return {"answer_1": ""}
    sub_q = sub_questions[0]
    prompt = ChatPromptTemplate.from_template("""你是信息检索专家。请检索关于以下问题的相关信息:

子问题:{sub_question}

输出格式:详细的信息摘要,包含关键事实和数据。""")
    chain = prompt | llm | StrOutputParser()
    return {"answer_1": chain.invoke({"sub_question": sub_q.question})}

# 提示 3:检索第二个子问题
def retrieve_2_node(state: AgentState):
    sub_questions = state.get("sub_questions", [])
    if len(sub_questions) < 2:
        return {"answer_2": ""}
    sub_q = sub_questions[1]
    prompt = ChatPromptTemplate.from_template("""你是信息检索专家。请检索关于以下问题的相关信息:

子问题:{sub_question}

输出格式:详细的信息摘要,包含关键事实和数据。""")
    chain = prompt | llm | StrOutputParser()
    return {"answer_2": chain.invoke({"sub_question": sub_q.question})}

# 提示 4:综合答案
def synthesize_node(state: AgentState):
    prompt = ChatPromptTemplate.from_template("""你是答案综合专家。请基于以下信息,形成完整的答案:

原问题:{question}
子问题1的答案:{answer_1}
子问题2的答案:{answer_2}

输出格式:结构化的答案,包含:
1. 问题概述
2. 各子问题的详细回答
3. 综合结论""")
    chain = prompt | llm | StrOutputParser()
    return {"final_answer": chain.invoke({
        "question": state["question"],
        "answer_1": state.get("answer_1", ""),
        "answer_2": state.get("answer_2", "")
    })}

# 构建图
workflow = StateGraph(AgentState)

# 添加节点
workflow.add_node("decompose", decompose_node)
workflow.add_node("retrieve_1", retrieve_1_node)
workflow.add_node("retrieve_2", retrieve_2_node)
workflow.add_node("synthesize", synthesize_node)

# 定义连线
workflow.set_entry_point("decompose")
workflow.add_edge("decompose", "retrieve_1")
workflow.add_edge("retrieve_1", "retrieve_2")
workflow.add_edge("retrieve_2", "synthesize")
workflow.add_edge("synthesize", END)

# 编译
app = workflow.compile()

# 运行
inputs = {"question": "1929 年股市崩盘的主要原因及政府政策应对?"}
result = app.invoke(inputs)
print(result["final_answer"])

3. 数据提取与转换 🔄

场景:从非结构化文本(发票、表单、邮件)中提取结构化数据

提示链:

  1. 尝试从文档中提取指定字段(姓名、地址、金额、日期)
  2. 检查字段是否齐全且格式正确
  3. 若字段缺失或格式错误,重新提示模型查找缺失/错误信息
  4. 再次验证结果,必要时重复步骤3
  5. 格式化输出为标准格式

流程构建:

from typing import TypedDict, Optional
from pydantic import BaseModel
from langgraph.graph import StateGraph, END
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser, JsonOutputParser
from langchain_openai import ChatOpenAI
import json

llm = ChatOpenAI(temperature=0)

class ExtractedData(BaseModel):
    name: Optional[str] = None
    address: Optional[str] = None
    amount: Optional[str] = None
    date: Optional[str] = None

class AgentState(TypedDict):
    document: str
    extracted_data: str
    validation_count: int
    validated_data: str
    formatted_data: str

# 提示 1:初步提取
def extract_node(state: AgentState):
    prompt = ChatPromptTemplate.from_template("""你是数据提取专家。请从以下文档中提取指定字段:

文档内容:{document}

需要提取的字段:
- 姓名
- 地址
- 金额
- 日期

输出格式:JSON 格式,包含所有字段,如果某个字段无法提取,使用 null。""")
    parser = JsonOutputParser()
    chain = prompt | llm | parser
    result = chain.invoke({"document": state["document"]})
    return {"extracted_data": json.dumps(result, ensure_ascii=False), "validation_count": 0}

# 提示 2:验证和补全
def validate_node(state: AgentState):
    extracted_data = state.get("extracted_data", "{}")
    validation_count = state.get("validation_count", 0)
    
    prompt = ChatPromptTemplate.from_template("""你是数据验证专家。请检查以下提取结果,查找缺失或错误的字段:

提取结果:{extracted_data}
原始文档:{document}

如果字段缺失或格式错误,请重新查找并修正。

输出格式:JSON 格式,包含所有字段的完整和正确值。""")
    parser = JsonOutputParser()
    chain = prompt | llm | parser
    result = chain.invoke({
        "extracted_data": extracted_data,
        "document": state["document"]
    })
    
    # 检查是否所有字段都有值
    all_fields_present = all([
        result.get("name"),
        result.get("address"),
        result.get("amount"),
        result.get("date")
    ])
    
    return {
        "validated_data": json.dumps(result, ensure_ascii=False),
        "validation_count": validation_count + 1
    }

# 条件判断:是否需要重新验证
def should_revalidate(state: AgentState) -> str:
    validated_data = json.loads(state.get("validated_data", "{}"))
    validation_count = state.get("validation_count", 0)
    
    # 检查字段完整性
    all_fields_present = all([
        validated_data.get("name"),
        validated_data.get("address"),
        validated_data.get("amount"),
        validated_data.get("date")
    ])
    
    # 如果字段不完整且未超过最大重试次数,继续验证
    if not all_fields_present and validation_count < 3:
        return "validate"
    else:
        return "format"

# 提示 3:格式化输出
def format_node(state: AgentState):
    validated_data = json.loads(state.get("validated_data", "{}"))
    prompt = ChatPromptTemplate.from_template("""你是数据格式化专家。请将以下数据转换为标准格式:

数据:{validated_data}

要求:
- 金额统一为数字格式(如:1050.00)
- 日期统一为 YYYY-MM-DD 格式
- 地址规范化

输出格式:JSON 格式,包含格式化后的所有字段。""")
    parser = JsonOutputParser()
    chain = prompt | llm | parser
    result = chain.invoke({"validated_data": json.dumps(validated_data, ensure_ascii=False)})
    return {"formatted_data": json.dumps(result, ensure_ascii=False)}

# 构建图
workflow = StateGraph(AgentState)

# 添加节点
workflow.add_node("extract", extract_node)
workflow.add_node("validate", validate_node)
workflow.add_node("format", format_node)

# 定义连线
workflow.set_entry_point("extract")
workflow.add_edge("extract", "validate")
workflow.add_conditional_edges(
    "validate",
    should_revalidate,
    {
        "validate": "validate",  # 继续验证
        "format": "format"       # 格式化
    }
)
workflow.add_edge("format", END)

# 编译
app = workflow.compile()

# 运行
inputs = {"document": "发票内容:张三,北京市朝阳区,壹仟零五十元,2024年1月15日"}
result = app.invoke(inputs)
print(result["formatted_data"])

4. 内容生成流程 📝

场景:自动化创意写作、技术文档生成

提示链:

  1. 根据用户兴趣生成 5 个主题创意
  2. 用户选择或自动选定一个主题
  3. 基于选定主题生成详细大纲
  4. 根据大纲第一点撰写草稿
  5. 根据第二点撰写草稿,并提供前一段上下文,依次完成所有大纲点
  6. 整体审阅并优化草稿的连贯性、语气和语法

流程构建:

from typing import TypedDict, List, Dict
from pydantic import BaseModel
from langgraph.graph import StateGraph, END
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser, JsonOutputParser
from langchain_openai import ChatOpenAI
import json

llm = ChatOpenAI(temperature=0)

class Topic(BaseModel):
    title: str
    brief_description: str

class OutlineItem(BaseModel):
    section_title: str
    key_points: List[str]

class AgentState(TypedDict):
    user_interests: str
    content_type: str
    topics: List[Dict]
    selected_topic: str
    outline: List[Dict]
    sections: List[str]
    current_section_index: int
    full_draft: str
    optimized_draft: str

# 提示 1:生成主题创意
def generate_topics_node(state: AgentState):
    prompt = ChatPromptTemplate.from_template("""你是创意策划专家。根据用户的兴趣和需求,生成 5 个主题创意:

用户兴趣:{user_interests}
内容类型:{content_type}

输出格式:JSON 格式,包含 topics 数组,每个主题包含 title 和 brief_description。""")
    parser = JsonOutputParser()
    chain = prompt | llm | parser
    result = chain.invoke({
        "user_interests": state["user_interests"],
        "content_type": state["content_type"]
    })
    return {"topics": result.get("topics", [])}

# 提示 2:选择主题(这里简化为自动选择第一个)
def select_topic_node(state: AgentState):
    topics = state.get("topics", [])
    if topics:
        selected = topics[0]
        return {"selected_topic": json.dumps(selected, ensure_ascii=False)}
    return {"selected_topic": ""}

# 提示 3:生成大纲
def generate_outline_node(state: AgentState):
    prompt = ChatPromptTemplate.from_template("""你是内容结构专家。基于选定的主题,生成详细的内容大纲:

主题:{selected_topic}

输出格式:JSON 格式,包含 outline 数组,每个大纲点包含 section_title 和 key_points。""")
    parser = JsonOutputParser()
    chain = prompt | llm | parser
    result = chain.invoke({"selected_topic": state["selected_topic"]})
    return {
        "outline": result.get("outline", []),
        "sections": [],
        "current_section_index": 0
    }

# 提示 4:分段撰写(循环执行)
def write_section_node(state: AgentState):
    outline = state.get("outline", [])
    current_index = state.get("current_section_index", 0)
    previous_sections = state.get("sections", [])
    
    if current_index >= len(outline):
        # 所有段落已完成,合并为完整草稿
        full_draft = "\n\n".join(previous_sections)
        return {"full_draft": full_draft}
    
    current_section = outline[current_index]
    previous_text = "\n\n".join(previous_sections) if previous_sections else "无"
    
    prompt = ChatPromptTemplate.from_template("""你是内容撰写专家。请根据以下大纲点撰写内容:

大纲点:{section}
前文上下文:{previous_sections}

要求:
- 与前文保持连贯
- 风格一致
- 内容丰富

输出格式:Markdown 格式的完整段落。""")
    chain = prompt | llm | StrOutputParser()
    section_content = chain.invoke({
        "section": json.dumps(current_section, ensure_ascii=False),
        "previous_sections": previous_text
    })
    
    new_sections = previous_sections + [section_content]
    return {
        "sections": new_sections,
        "current_section_index": current_index + 1
    }

# 判断是否继续撰写
def should_continue_writing(state: AgentState) -> str:
    outline = state.get("outline", [])
    current_index = state.get("current_section_index", 0)
    if current_index < len(outline):
        return "write_section"
    else:
        return "optimize"

# 提示 5:整体优化
def optimize_node(state: AgentState):
    prompt = ChatPromptTemplate.from_template("""你是内容优化专家。请审阅并优化以下草稿:

完整草稿:{full_draft}

优化方向:
- 连贯性和流畅度
- 语气和风格统一
- 语法和拼写
- 逻辑结构

输出格式:优化后的完整 Markdown 文档。""")
    chain = prompt | llm | StrOutputParser()
    result = chain.invoke({"full_draft": state["full_draft"]})
    return {"optimized_draft": result}

# 构建图
workflow = StateGraph(AgentState)

# 添加节点
workflow.add_node("generate_topics", generate_topics_node)
workflow.add_node("select_topic", select_topic_node)
workflow.add_node("generate_outline", generate_outline_node)
workflow.add_node("write_section", write_section_node)
workflow.add_node("optimize", optimize_node)

# 定义连线
workflow.set_entry_point("generate_topics")
workflow.add_edge("generate_topics", "select_topic")
workflow.add_edge("select_topic", "generate_outline")
workflow.add_edge("generate_outline", "write_section")
workflow.add_conditional_edges(
    "write_section",
    should_continue_writing,
    {
        "write_section": "write_section",
        "optimize": "optimize"
    }
)
workflow.add_edge("optimize", END)

# 编译
app = workflow.compile()

# 运行
inputs = {
    "user_interests": "人工智能和机器学习",
    "content_type": "技术博客"
}
result = app.invoke(inputs)
print(result["optimized_draft"])

5. 有状态对话智能体 💭

场景:多轮对话,需要维护上下文和状态

提示链:

  1. 处理用户发言,识别意图和实体
  2. 更新对话状态(保存关键信息)
  3. 基于当前状态生成回复或识别下一步所需信息
  4. 后续轮次重复,每次新发言启动链式流程,利用累积的对话历史

流程构建:

from typing import TypedDict, List, Dict
from pydantic import BaseModel
from langgraph.graph import StateGraph, END
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser, JsonOutputParser
from langchain_openai import ChatOpenAI
import json

llm = ChatOpenAI(temperature=0)

class IntentAnalysis(BaseModel):
    intent: str
    entities: Dict[str, str]
    needs_clarification: bool

class AgentState(TypedDict):
    user_message: str
    conversation_history: List[str]
    intent_analysis: Dict
    current_state: Dict
    reply: str

# 提示 1:理解用户意图
def intent_node(state: AgentState):
    prompt = ChatPromptTemplate.from_template("""你是对话理解专家。请分析用户的发言,识别意图和实体:

用户发言:{user_message}
对话历史:{conversation_history}

需要识别:
- 用户意图(询问/请求/确认等)
- 关键实体(人名/地点/时间等)
- 需要澄清的信息

输出格式:JSON 格式,包含 intent、entities 和 needs_clarification。""")
    parser = JsonOutputParser()
    chain = prompt | llm | parser
    history_text = "\n".join(state.get("conversation_history", []))
    result = chain.invoke({
        "user_message": state["user_message"],
        "conversation_history": history_text
    })
    return {"intent_analysis": result}

# 提示 2:更新对话状态
def update_state_node(state: AgentState):
    intent_analysis = state.get("intent_analysis", {})
    current_state = state.get("current_state", {})
    
    # 更新状态:保存关键实体和意图
    updated_state = {
        "last_intent": intent_analysis.get("intent", ""),
        "entities": intent_analysis.get("entities", {}),
        "needs_clarification": intent_analysis.get("needs_clarification", False),
        **current_state  # 保留之前的状态
    }
    
    return {"current_state": updated_state}

# 提示 3:生成回复
def reply_node(state: AgentState):
    prompt = ChatPromptTemplate.from_template("""你是对话助手。基于以下信息生成回复:

用户意图:{intent}
识别实体:{entities}
对话历史:{conversation_history}
当前状态:{current_state}

要求:
- 保持对话连贯性
- 利用历史上下文
- 如果需要更多信息,礼貌地询问

输出格式:自然流畅的回复文本。""")
    chain = prompt | llm | StrOutputParser()
    history_text = "\n".join(state.get("conversation_history", []))
    result = chain.invoke({
        "intent": state["intent_analysis"].get("intent", ""),
        "entities": json.dumps(state["intent_analysis"].get("entities", {}), ensure_ascii=False),
        "conversation_history": history_text,
        "current_state": json.dumps(state["current_state"], ensure_ascii=False)
    })
    
    # 更新对话历史
    new_history = state.get("conversation_history", []) + [
        f"用户:{state['user_message']}",
        f"助手:{result}"
    ]
    
    return {"reply": result, "conversation_history": new_history}

# 构建图
workflow = StateGraph(AgentState)

# 添加节点
workflow.add_node("intent", intent_node)
workflow.add_node("update_state", update_state_node)
workflow.add_node("reply", reply_node)

# 定义连线
workflow.set_entry_point("intent")
workflow.add_edge("intent", "update_state")
workflow.add_edge("update_state", "reply")
workflow.add_edge("reply", END)

# 编译
app = workflow.compile()

# 运行(第一轮)
inputs = {
    "user_message": "我想了解人工智能",
    "conversation_history": [],
    "current_state": {}
}
result = app.invoke(inputs)
print(result["reply"])

# 运行(第二轮,使用第一轮的历史)
inputs2 = {
    "user_message": "它有哪些应用?",
    "conversation_history": result["conversation_history"],
    "current_state": result["current_state"]
}
result2 = app.invoke(inputs2)
print(result2["reply"])

重点:每轮对话都启动链式流程,利用累积的对话历史(状态),使系统能跨多轮对话保持上下文和连贯性。

6. 代码生成与优化 💻

场景:AI 辅助开发,生成和优化代码

提示链:

  1. 理解用户代码需求,生成伪代码或大纲
  2. 根据大纲撰写初稿代码
  3. 识别代码潜在错误或改进点(可用静态分析工具或再次调用 LLM)
  4. 根据问题重写或优化代码
  5. 补充文档或测试用例

流程构建:

from typing import TypedDict, List, Dict
from pydantic import BaseModel
from langgraph.graph import StateGraph, END
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser, JsonOutputParser
from langchain_openai import ChatOpenAI
import json

llm = ChatOpenAI(temperature=0)

class RequirementAnalysis(BaseModel):
    description: str
    tech_stack: List[str]
    pseudocode: str

class CodeIssue(BaseModel):
    type: str
    severity: str
    suggestion: str

class AgentState(TypedDict):
    user_requirement: str
    language: str
    requirement_analysis: Dict
    generated_code: str
    review_issues: List[Dict]
    optimized_code: str
    documentation: str

# 提示 1:理解需求
def understand_node(state: AgentState):
    prompt = ChatPromptTemplate.from_template("""你是需求分析专家。请分析用户的代码需求:

用户需求:{user_requirement}

输出:
- 功能描述
- 技术栈建议
- 伪代码或算法思路

输出格式:JSON 格式,包含 description、tech_stack 和 pseudocode。""")
    parser = JsonOutputParser()
    chain = prompt | llm | parser
    result = chain.invoke({"user_requirement": state["user_requirement"]})
    return {"requirement_analysis": result}

# 提示 2:生成代码
def generate_code_node(state: AgentState):
    prompt = ChatPromptTemplate.from_template("""你是代码生成专家。根据以下需求生成代码:

需求分析:{requirement_analysis}
编程语言:{language}

要求:
- 代码规范
- 包含注释
- 处理边界情况

输出格式:完整的代码文件,包含必要的导入和函数。""")
    chain = prompt | llm | StrOutputParser()
    result = chain.invoke({
        "requirement_analysis": json.dumps(state["requirement_analysis"], ensure_ascii=False),
        "language": state["language"]
    })
    return {"generated_code": result}

# 提示 3:代码审查
def review_code_node(state: AgentState):
    prompt = ChatPromptTemplate.from_template("""你是代码审查专家。请审查以下代码,识别潜在问题:

代码:{generated_code}
原始需求:{user_requirement}

检查项:
- 逻辑错误
- 性能问题
- 代码风格
- 安全性

输出格式:JSON 格式,包含 issues 数组,每个问题包含 type、severity 和 suggestion。""")
    parser = JsonOutputParser()
    chain = prompt | llm | parser
    result = chain.invoke({
        "generated_code": state["generated_code"],
        "user_requirement": state["user_requirement"]
    })
    return {"review_issues": result.get("issues", [])}

# 提示 4:优化代码
def optimize_code_node(state: AgentState):
    prompt = ChatPromptTemplate.from_template("""你是代码优化专家。请根据审查结果优化代码:

原代码:{generated_code}
审查问题:{review_issues}

输出格式:优化后的完整代码。""")
    chain = prompt | llm | StrOutputParser()
    result = chain.invoke({
        "generated_code": state["generated_code"],
        "review_issues": json.dumps(state["review_issues"], ensure_ascii=False)
    })
    return {"optimized_code": result}

# 提示 5:生成文档和测试
def document_node(state: AgentState):
    prompt = ChatPromptTemplate.from_template("""你是文档专家。请为以下代码生成文档和测试用例:

代码:{optimized_code}

要求:
- API 文档
- 使用示例
- 单元测试用例

输出格式:Markdown 格式的文档和测试代码。""")
    chain = prompt | llm | StrOutputParser()
    result = chain.invoke({"optimized_code": state["optimized_code"]})
    return {"documentation": result}

# 构建图
workflow = StateGraph(AgentState)

# 添加节点
workflow.add_node("understand", understand_node)
workflow.add_node("generate_code", generate_code_node)
workflow.add_node("review_code", review_code_node)
workflow.add_node("optimize_code", optimize_code_node)
workflow.add_node("document", document_node)

# 定义连线
workflow.set_entry_point("understand")
workflow.add_edge("understand", "generate_code")
workflow.add_edge("generate_code", "review_code")
workflow.add_edge("review_code", "optimize_code")
workflow.add_edge("optimize_code", "document")
workflow.add_edge("document", END)

# 编译
app = workflow.compile()

# 运行
inputs = {
    "user_requirement": "实现一个快速排序算法",
    "language": "Python"
}
result = app.invoke(inputs)
print("优化后的代码:")
print(result["optimized_code"])
print("\n文档和测试:")
print(result["documentation"])

注意:以上所有示例都使用 LangGraph 的 StateGraph 来构建提示链,这是更推荐的实践方式,因为它提供了:

  • 状态管理:统一管理整个流程的状态
  • 灵活控制流:支持条件分支和循环
  • 可扩展性:易于添加新节点和修改流程
  • 可调试性:每个节点的输入输出都可以清晰追踪

总结

提示链通过将复杂问题拆解为一系列更简单、易管理的子任务,为引导大语言模型提供了稳健框架。分而治之策略让模型每次专注于单一操作,显著提升输出的可靠性和可控性。

关键要点:

  • 明确步骤目标:每个提示都有清晰、单一的目标
  • 结构化输出:使用 JSON/XML 格式确保数据传递的准确性
  • 角色定位:为每个步骤分配明确的专业角色
  • 合理设计流程:根据任务特点设计合适的链式流程

经验法则:当任务过于复杂、包含多阶段处理、需在步骤间调用外部工具,或需构建多步推理、状态管理的智能体时,建议采用提示链模式。

最近更新: 2026/1/11 17:55
Contributors: kingmusi