首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Prompt工程进阶:少样本与思维链

Prompt工程进阶:少样本与思维链

原创
作者头像
用户12278826
发布2026-03-18 10:08:26
发布2026-03-18 10:08:26
610
举报

为什么有时候结构化Prompt还是不能达到满意的效果?

在上一篇文章中,我们学习了结构化Prompt的四大要素,能够生成专业级的Vue3组件。但在实际开发中,我们经常遇到更复杂的业务逻辑,比如:权限控制、状态机转换、复杂表单验证等。这时候,仅仅告诉AI“做什么”还不够,我们还需要教AI“怎么做”。

本篇文章将通过一个动态权限菜单的实战案例,带领我们掌握两个强大的Prompt技巧:少样本思维链

  • 少样本提示(Few-shot Prompting) :给AI举例子,让它学会模仿
  • 思维链(Chain of Thought) :让AI展示推理过程,解决复杂逻辑

少样本提示:给AI一个“模仿样本”

什么是少样本提示?

少样本提示的核心思想是:通过提供输入输出的示例,让AI理解任务的模式和规律。就像教小朋友做题一样,先让他们学习几个例题,再让他们做练习题。

适用场景

  • 需要特定输出格式的任务
  • 有明确模式匹配的逻辑
  • 希望AI模仿某种风格或规范

思维链:让AI“说出解题思路”

什么是思维链?

思维链的核心思想是:引导AI展示中间推理步骤,而不是直接给出答案。就像数学老师要求我们必须写出解题过程,而不是仅仅只是写出最终答案。

适用场景

  • 多步骤推理任务
  • 条件判断复杂的逻辑
  • 需要解释决策依据的场景
  • 数学计算
  • 算法设计

实战案例:动态权限菜单的Prompt进化史

需求描述

我们有这样一个需求:能根据用户权限,动态显示菜单,支持至少3种角色:

  • admin:看到所有菜单
  • editor:看到内容管理相关菜单
  • visitor:只能看到仪表盘和公开页面

版本1:直接提问(开放式)

我的Prompt
代码语言:javascript
复制
text
 体验AI代码助手
 代码解读
复制代码
帮我写一个根据权限显示菜单的逻辑
AI输出
代码语言:javascript
复制
javascript
 体验AI代码助手
 代码解读
复制代码
function getMenus(role) {
  if (role === 'admin') {
    return ['仪表盘', '用户管理', '内容管理', '设置']
  } else {
    return ['仪表盘']
  }
}
问题分析
  • 只区分了admin和非admin
  • 没有考虑多角色场景
  • 逻辑过于简单,无法满足真实需求
  • 没有处理嵌套菜单等复杂情况

版本2:少样本提示(让AI学会模式)

我的Prompt
代码语言:javascript
复制
text
 体验AI代码助手
 代码解读
复制代码
我需要一个根据用户权限动态显示菜单的函数。
请参考以下输入输出示例,生成类似的权限判断逻辑:

示例1:
输入:用户角色 = "admin"
输出:["仪表盘", "用户管理", "内容管理", "系统设置"]

示例2:
输入:用户角色 = "editor"  
输出:["仪表盘", "内容管理", "文章审核"]

示例3:
输入:用户角色 = "visitor"
输出:["仪表盘", "公开文档"]

请根据以上模式,生成一个支持更多角色的权限菜单函数,并确保覆盖至少3种角色。
AI输出
代码语言:javascript
复制
javascript
 体验AI代码助手
 代码解读
复制代码
/**
 * 根据用户角色获取可见菜单
 * @param {string} role - 用户角色
 * @returns {string[]} 菜单数组
 */
function getMenusByRole(role) {
  // 权限菜单映射表
  const roleMenus = {
    admin: ['仪表盘', '用户管理', '内容管理', '系统设置', '日志审计', '权限配置'],
    editor: ['仪表盘', '内容管理', '文章审核', '分类管理', '标签管理'],
    visitor: ['仪表盘', '公开文档', '帮助中心'],
    analyst: ['仪表盘', '数据报表', '用户分析', '流量统计'],
    maintainer: ['仪表盘', '系统监控', '性能优化', '错误日志']
  }
  
  // 返回对应角色的菜单,如果角色不存在则返回空数组
  return roleMenus[role] || []
}

// 测试
console.log('admin:', getMenusByRole('admin'))
console.log('editor:', getMenusByRole('editor'))
console.log('visitor:', getMenusByRole('visitor'))
console.log('analyst:', getMenusByRole('analyst'))
进步
  • 通过示例让AI理解了输入输出的映射关系
  • 自动扩展到了5种角色
  • 代码结构清晰,易于维护
不足
  • 菜单是硬编码的扁平数组,无法处理嵌套菜单
  • 没有考虑权限组合的场景(如用户有多个角色)
  • 缺乏对菜单项权限的细粒度控制

版本3:思维链(让AI展示推理过程)

我的Prompt
代码语言:javascript
复制
text
 体验AI代码助手
 代码解读
复制代码
我需要一个复杂的动态权限菜单系统,支持嵌套菜单和细粒度权限控制。
请先列出你的思考步骤,然后生成代码。

需求:
1. 菜单可以有多级嵌套
2. 每个菜单项可以单独配置所需权限
3. 支持用户拥有多个角色
4. 需要根据用户的所有角色计算最终可见菜单

请按照以下步骤思考:
第一步:分析如何设计菜单数据结构
第二步:考虑多角色权限的合并策略(并集?交集?)
第三步:设计递归遍历菜单树的函数
第四步:处理边界情况(空权限、角色不存在等)
第五步:生成最终的TypeScript代码
AI输出
第一步思考:菜单数据结构设计
代码语言:javascript
复制
text
 体验AI代码助手
 代码解读
复制代码
我需要设计一个支持嵌套的菜单结构,每个菜单项包含:
- name: 显示名称
- path: 路由路径
- icon: 图标
- children: 子菜单
- permissions: 所需权限数组(满足任一即可)
第二步思考:多角色权限合并策略
代码语言:javascript
复制
text
 体验AI代码助手
 代码解读
复制代码
用户可能有多个角色,如 ['admin', 'editor']
策略:取所有角色权限的并集
原因:用户拥有多个角色时,应该拥有所有角色的权限总和
第三步思考:递归遍历算法
代码语言:javascript
复制
text
 体验AI代码助手
 代码解读
复制代码
需要深度遍历菜单树
对每个菜单项检查权限
如果某个菜单项没有权限且没有可见的子菜单,则隐藏
第四步思考:边界情况处理
代码语言:javascript
复制
text
 体验AI代码助手
 代码解读
复制代码
- 权限配置为空:表示公开菜单,所有人可见
- 角色不存在:视为无权限
- 空菜单树:返回空数组
最终代码输出
代码语言:javascript
复制
typescript
 体验AI代码助手
 代码解读
复制代码
/**
 * 动态权限菜单系统
 * 支持多级嵌套、多角色、细粒度权限控制
 */

// ==================== 类型定义 ====================

/** 菜单项接口 */
interface MenuItem {
  /** 菜单名称 */
  name: string
  /** 路由路径 */
  path: string
  /** 图标名称(可选) */
  icon?: string
  /** 子菜单 */
  children?: MenuItem[]
  /** 所需权限列表(满足任一即可),为空表示公开 */
  permissions?: string[]
}

/** 用户角色接口 */
interface UserRole {
  /** 角色ID */
  id: string
  /** 角色名称 */
  name: string
  /** 角色拥有的权限列表 */
  permissions: string[]
}

/** 用户信息接口 */
interface User {
  /** 用户ID */
  id: string
  /** 用户名 */
  name: string
  /** 用户拥有的角色ID列表 */
  roleIds: string[]
}

// ==================== 权限计算函数 ====================

/**
 * 第一步:获取用户的所有权限(多角色并集)
 * @param user 用户信息
 * @param roles 所有角色的定义
 * @returns 用户拥有的所有权限数组(去重)
 */
function getUserPermissions(user: User, roles: Map<string, UserRole>): string[] {
  // 边界情况:用户没有角色
  if (!user.roleIds || user.roleIds.length === 0) {
    return []
  }
  
  // 收集用户所有角色的权限
  const permissionsSet = new Set<string>()
  
  user.roleIds.forEach(roleId => {
    const role = roles.get(roleId)
    if (role && role.permissions) {
      role.permissions.forEach(perm => permissionsSet.add(perm))
    }
  })
  
  return Array.from(permissionsSet)
}

/**
 * 第二步:检查菜单项对当前用户是否可见
 * @param menuItem 菜单项
 * @param userPermissions 用户权限列表
 * @returns 是否可见
 */
function isMenuItemVisible(menuItem: MenuItem, userPermissions: string[]): boolean {
  // 情况1:没有权限要求 -> 公开菜单,所有人都可见
  if (!menuItem.permissions || menuItem.permissions.length === 0) {
    return true
  }
  
  // 情况2:有权限要求 -> 检查用户是否拥有任一所需权限
  return menuItem.permissions.some(perm => userPermissions.includes(perm))
}

/**
 * 第三步:递归过滤菜单树
 * @param menus 原始菜单树
 * @param userPermissions 用户权限列表
 * @returns 过滤后的可见菜单树
 */
function filterMenusByPermissions(
  menus: MenuItem[],
  userPermissions: string[]
): MenuItem[] {
  // 边界情况:空菜单
  if (!menus || menus.length === 0) {
    return []
  }
  
  const result: MenuItem[] = []
  
  for (const menu of menus) {
    // 先检查当前菜单项是否可见
    const visible = isMenuItemVisible(menu, userPermissions)
    
    // 如果有子菜单,递归处理子菜单
    let filteredChildren: MenuItem[] | undefined
    if (menu.children && menu.children.length > 0) {
      filteredChildren = filterMenusByPermissions(menu.children, userPermissions)
    }
    
    // 判断当前菜单项是否应该保留:
    // 1. 菜单本身可见
    // 2. 或者有可见的子菜单(即使自身不可见,但子菜单可见时,应该保留作为父级导航)
    const hasVisibleChildren = filteredChildren && filteredChildren.length > 0
    
    if (visible || hasVisibleChildren) {
      // 创建新的菜单项(避免修改原始数据)
      const filteredMenu: MenuItem = {
        name: menu.name,
        path: menu.path,
        icon: menu.icon
      }
      
      // 如果有可见的子菜单,添加到结果中
      if (hasVisibleChildren) {
        filteredMenu.children = filteredChildren
      }
      
      result.push(filteredMenu)
    }
  }
  
  return result
}

/**
 * 第四步:主函数 - 获取用户的可见菜单
 * @param user 用户信息
 * @param allMenus 完整的菜单树
 * @param allRoles 所有角色的定义
 * @returns 该用户可见的菜单树
 */
function getUserMenus(
  user: User,
  allMenus: MenuItem[],
  allRoles: Map<string, UserRole>
): MenuItem[] {
  // 边界情况处理
  if (!user || !allMenus || !allRoles) {
    console.warn('参数不完整,返回空菜单')
    return []
  }
  
  // 第一步:获取用户的所有权限
  const userPermissions = getUserPermissions(user, allRoles)
  
  // 第二步:根据权限过滤菜单
  const visibleMenus = filterMenusByPermissions(allMenus, userPermissions)
  
  return visibleMenus
}

// ==================== 使用示例 ====================

// 定义所有角色
const roles = new Map<string, UserRole>([
  [
    'admin',
    {
      id: 'admin',
      name: '管理员',
      permissions: ['user:view', 'user:edit', 'content:view', 'content:edit', 'system:config']
    }
  ],
  [
    'editor',
    {
      id: 'editor',
      name: '编辑',
      permissions: ['content:view', 'content:edit', 'content:audit']
    }
  ],
  [
    'visitor',
    {
      id: 'visitor',
      name: '访客',
      permissions: ['public:view']
    }
  ]
])

// 定义完整的菜单树
const allMenus: MenuItem[] = [
  {
    name: '仪表盘',
    path: '/dashboard',
    icon: 'dashboard',
    permissions: [] // 公开菜单
  },
  {
    name: '用户管理',
    path: '/users',
    icon: 'user',
    permissions: ['user:view'],
    children: [
      {
        name: '用户列表',
        path: '/users/list',
        permissions: ['user:view']
      },
      {
        name: '新增用户',
        path: '/users/add',
        permissions: ['user:edit']
      },
      {
        name: '权限配置',
        path: '/users/permissions',
        permissions: ['system:config']
      }
    ]
  },
  {
    name: '内容管理',
    path: '/content',
    icon: 'document',
    permissions: ['content:view'],
    children: [
      {
        name: '文章列表',
        path: '/content/articles',
        permissions: ['content:view']
      },
      {
        name: '发布文章',
        path: '/content/publish',
        permissions: ['content:edit']
      },
      {
        name: '文章审核',
        path: '/content/audit',
        permissions: ['content:audit']
      }
    ]
  },
  {
    name: '系统设置',
    path: '/settings',
    icon: 'setting',
    permissions: ['system:config'],
    children: [
      {
        name: '基本设置',
        path: '/settings/basic',
        permissions: ['system:config']
      },
      {
        name: '安全设置',
        path: '/settings/security',
        permissions: ['system:config']
      }
    ]
  }
]

// 测试不同角色的用户
const testUsers: User[] = [
  {
    id: '1',
    name: '管理员',
    roleIds: ['admin']
  },
  {
    id: '2',
    name: '编辑',
    roleIds: ['editor']
  },
  {
    id: '3',
    name: '访客',
    roleIds: ['visitor']
  },
  {
    id: '4',
    name: '编辑兼访客',
    roleIds: ['editor', 'visitor'] // 多角色
  }
]

// 执行测试
testUsers.forEach(user => {
  console.log(`\n========== ${user.name} 的可见菜单 ==========`)
  const visibleMenus = getUserMenus(user, allMenus, roles)
  console.log(JSON.stringify(visibleMenus, null, 2))
})

少样本 vs 思维链:对比与选择

通过这个实战案例,我们可以清晰地看到两种提示技术的适用场景: http://bkssfp.mpmpc.cn/ http://tjkssfp.mpmpc.cn/ http://shkssfp.mpmpc.cn/ http://zqkssfp.mpmpc.cn/ http://tykssfp.mpmpc.cn/ http://sjzkssfp.mpmpc.cn/ http://hhhtkssfp.mpmpc.cn/ http://sykssfp.mpmpc.cn/ http://cckssfp.mpmpc.cn/ http://hebkssfp.mpmpc.cn/ http://njkssfp.mpmpc.cn/ http://szkssfp.mpmpc.cn/ http://hzkssfp.mpmpc.cn/ http://hfksssfp.mpmpc.cn/ http://xmkssfp.mpmpc.cn/ http://fzkssfp.mpmpc.cn/ http://nckssfp.mpmpc.cn/ http://jnkssfp.mpmpc.cn/ http://qdkssfp.mpmpc.cn/ http://zzkssfp.mpmpc.cn/ http://whkssfp.mpmpc.cn/ http://cskssfp.mpmpc.cn/ http://szssfp.mpmpc.cn/ http://gzkssfp.mpmpc.cn/ http://nnkssfp.mpmpc.cn/ http://hnkssfp.mpmpc.cn/ http://cdkssfp.mpmpc.cn/ http://gykssfp.mpmpc.cn/ http://kmkssfp.mpmpc.cn/ http://xakssfp.mpmpc.cn/ http://lzkssfp.mpmpc.cn/ http://xnkssfp.mpmpc.cn/ http://ycskssfp.mpmpc.cn/ http://wlmqkssfp.mpmpc.cn/

少样本提示适合的场景

场景类型

示例

为什么适合

格式转换

JSON转XML,Markdown转HTML

示例能清晰展示映射关系

模式识别

根据几个例子总结规律

AI能快速捕捉共同模式

风格模仿

模仿特定代码风格

示例提供了风格参考

简单分类

将文本分为几类

示例定义了分类标准

思维链适合的场景

场景类型

示例

为什么适合

复杂推理

权限判断的多步骤逻辑

需要逐步分析条件

算法设计

递归遍历菜单树

需要展示算法思路

数学计算

复杂公式推导

需要展示计算过程

决策解释

为什么某个菜单项被隐藏

需要说明判断依据

边界处理

空权限、多角色等特殊情况

需要全面考虑各种情况

组合使用的最佳实践

在实际应用中,少样本提示和思维链不是互斥的,而是可以组合使用的:

组合使用的Prompt模板

代码语言:javascript
复制
text
 体验AI代码助手
 代码解读
复制代码
我需要一个[复杂功能]。

第一步:请参考以下示例理解需求(少样本):
示例1:输入A -> 输出X
示例2:输入B -> 输出Y

第二步:请按照以下步骤思考(思维链):
1. 分析...
2. 设计...
3. 实现...
4. 处理边界...

第三步:生成完整的代码

如何写出高质量的思维链Prompt

技巧1:引导AI分步思考

代码语言:javascript
复制
text
 体验AI代码助手
 代码解读
复制代码
请按以下步骤思考:
1. 先分析数据结构设计
2. 再考虑算法逻辑
3. 然后处理边界情况
4. 最后生成代码

技巧2:要求展示中间结果

代码语言:javascript
复制
text
 体验AI代码助手
 代码解读
复制代码
在每个思考步骤后,输出当前步骤的结论或伪代码

技巧3:指定思考深度

代码语言:javascript
复制
text
 体验AI代码助手
 代码解读
复制代码
请深入思考以下细节:
- 多角色权限冲突如何解决?
- 菜单树深度超过3层怎么办?
- 性能优化考虑?

技巧4:要求对比不同方案

代码语言:javascript
复制
text
 体验AI代码助手
 代码解读
复制代码
请对比两种权限合并策略(并集vs交集)的优缺点,然后选择最优方案

结语

你在实际工作中遇到过哪些适合用思维链解决的复杂问题?有没有尝试过让AI解释它的推理过程?

对于文章中错误的地方或有任何疑问,欢迎在评论区留言讨论!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 为什么有时候结构化Prompt还是不能达到满意的效果?
  • 少样本提示:给AI一个“模仿样本”
    • 什么是少样本提示?
    • 适用场景
  • 思维链:让AI“说出解题思路”
    • 什么是思维链?
    • 适用场景
  • 实战案例:动态权限菜单的Prompt进化史
    • 需求描述
    • 版本1:直接提问(开放式)
      • 我的Prompt
      • AI输出
      • 问题分析
    • 版本2:少样本提示(让AI学会模式)
      • 我的Prompt
      • AI输出
      • 进步
      • 不足
    • 版本3:思维链(让AI展示推理过程)
      • 我的Prompt
      • AI输出
  • 少样本 vs 思维链:对比与选择
    • 少样本提示适合的场景
    • 思维链适合的场景
  • 组合使用的最佳实践
    • 组合使用的Prompt模板
  • 如何写出高质量的思维链Prompt
    • 技巧1:引导AI分步思考
    • 技巧2:要求展示中间结果
    • 技巧3:指定思考深度
    • 技巧4:要求对比不同方案
  • 结语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档