深度解析多智能体系统的高级协同机制

多智能体系统的协同基础

多智能体系统的核心概念与协同定义

多智能体系统(Multi-agent System, MAS)是一个由多个独立的人工智能(AI)智能体组成的计算框架,其核心目标是让这些智能体通过协同工作来代表用户或系统执行复杂的任务 。系统中的每个智能体都拥有独立的属性,但它们会相互合作,以实现所需的全局属性或集体目标 。MAS的核心智能体通常以大型语言模型(LLM)为“大脑”,利用LLM先进的自然语言处理技术来理解用户输入并做出响应 。  

MAS的协同行为能够显著提升系统的准确性、适应性和可扩展性 。与传统的单智能体系统相比,MAS能够胜任涉及数百甚至数千个智能体的大规模、复杂任务 。通过创建一个更大的共享资源池以及优化和自动化功能,多智能体系统的性能往往优于单智能体系统 。智能体之间无需重复学习相同的策略,而是可以共享所获得的经验,从而优化时间复杂性和整体效率 。从技术角度看,多智能体协同被定义为分布式系统中多个独立智能体的协调行动,每个智能体拥有其局部知识和决策能力。这种合作通常包括一套用于任务分解、资源分配、冲突解决和协作规划的系统方法 。

单智能体与多智能体系统在协同中的本质区别

在理解多智能体协同的精髓时,区分它与单智能体系统的协作模式至关重要。在一个单智能体系统中,当一个智能体调用另一个智能体作为工具时,这个辅助智能体仅被视为原始智能体环境刺激的一部分 。原始智能体获取信息后,通常不会再发生进一步的合作。这是一种单向、工具性的调用关系,而非真正的协同。  

多智能体系统则完全不同。其本质在于,环境内的所有智能体都能够对彼此的目标、记忆和行动计划进行建模 。每个智能体都保持一定程度的自主性,这通常体现在其规划、工具调用和一般推理能力上 。然而,它们会在一个统一的结构中进行合作与协调。这种能力使得智能体能够进行子任务的创建、工具的使用,并通过交互进行学习 。这种能够建模和理解其他智能体“意图”和“记忆”的能力,使得多智能体协同从单纯的规则驱动或数学模型驱动,向更接近人类社会协作的“意图理解驱动”转变。  

这一转变的核心驱动力是大型语言模型(LLM)作为多智能体系统大脑的广泛应用 。LLM赋予了智能体强大的自然语言处理和高级推理能力,使其能够真正理解并模拟其他智能体的行为意图。因此,LLM的出现极大地降低了实现复杂多智能体协同的门槛,使得智能体能够进行更高级的交互,而不仅仅是简单的状态交换。MAS协同能力质变的关键技术正是LLM,它使得“意图理解”成为可能,从而催生了更加复杂和强大的协同模式。

多智能体协同的架构模式与策略

协同架构模式

多智能体系统可以在多种架构下运行,每种架构都代表了对系统控制、可扩展性、鲁棒性以及单点故障风险的权衡。理解这些架构模式对于设计高效、稳定的MAS至关重要。

中心化模式(Centralized Networks)

中心化网络依赖于一个中央单元(Orchestrator),该单元包含全局知识库,负责连接各个智能体并监督它们的信息 。这个中央协调单元的角色类似于项目经理或机场空管塔台 。中心化架构的优势在于智能体之间的通信简单直接,并且能够确保知识的统一性 。由于中央单元拥有全局视野,系统可以更容易地实现全局最优决策 。  

然而,中心化模式存在明显的劣势。其主要弱点是对中央单元的依赖性:如果中心单元发生故障,整个智能体系统就会瘫痪,形成单一故障点 。此外,随着智能体数量的增加,中央单元可能成为性能瓶颈,导致可扩展性差 。因此,该模式更适用于任务结构化程度高、需要严格控制和全局一致决策的场景。  

去中心化模式(Decentralized Networks)

去中心化网络中不存在单一的中央控制单元。智能体仅与其邻近的智能体共享信息,并根据本地信息自主做出决策 。这种点对点的模型具有高度的自组织性,系统的集体行为是基于个体间简单交互而形成的“涌现行为” 。例如,鸟类的群行行为就是去中心化控制下自组织和聚合的典型例子 。它们遵循简单的规则,如分离(避免与邻近鸟类碰撞)、对齐(匹配邻近鸟类的速度)和内聚(保持与其他鸟类的距离),从而实现同步飞行 。  

去中心化架构的主要优点是其稳健性和模块化 。由于没有中央单元,某个智能体的故障并不会导致整个系统的失败 。同时,其可扩展性极高,增加更多智能体对系统性能的影响微乎其微 。但其挑战在于,由于缺乏全局视野,协调智能体的行为以实现全局最优变得困难,达成共识或协调也更为复杂 。尽管如此,在大型电力网络和城市交通信号控制等大规模系统中,去中心化模式可以显著降低风险,提高系统的稳定性和安全性 。  

分层结构(Hierarchical Structure)

分层结构是一种树状架构,包含具有不同自主级别的智能体 。在这种模式下,一个智能体可以拥有决策权,并可以将责任分配给多个下级智能体。这种结构结合了中心化和去中心化的优点,在部分控制和自主性之间取得了平衡 。  

多智能体架构模式的选择并非单一的技术决策,而是对系统核心需求(如控制精度、鲁棒性、可扩展性)进行深思熟虑后的一系列权衡。中心化模式倾向于在牺牲可用性和分区容错性的前提下实现高一致性,而这在需要严格控制的场景中是可取的。相反,去中心化模式则通过牺牲全局最优来换取高可用性和鲁棒性,这在需要处理大规模、动态环境的系统中至关重要。因此,成功的MAS设计需要深刻理解这些权衡,并根据任务特性(如复杂程度、规模、环境动态性)来选择或混合架构,而非盲目地追求某种“先进”模式。

协同策略与机制

除了架构之外,智能体之间如何具体进行交互和协调也至关重要。这通常通过预先设定的策略和机制来实现。

基于角色的协同(Role-based Collaboration)

基于角色的协同策略中,智能体被赋予特定的角色或职责,这些角色与一个清晰的组织或通信框架相吻合 。每个角色都带有一套特定的功能、权限和目标,这些通常与系统整体目标的不同部分相关联。这种概念借鉴了人类团队协作的动态,例如团队中的“领导者”、“观察者”或“执行者” 。  

在一个基于角色的多智能体任务协同系统中,角色层被设计和实现,以在异构和动态变化的环境中动态分配任务,并提高集群系统的鲁棒性 。智能体可以根据分配的角色动态切换,以执行一个或多个子任务 。这种方法特别有利于任务分解、设计模块化系统,并使具有不同专长的智能体能够有效协作 。  

基于规则的协同(Rule-based Collaboration)

基于规则的协同中,智能体之间的交互由一套特定的规则或指导方针严格控制 。这些规则通常以“if-then”语句、状态机或基于逻辑的框架实现,它们以可预测的方式规定了智能体如何行动、通信和做出选择 。这种方法最适用于高度结构化或可预测的任务,其中保持一致性是关键 。它的优势在于能够提供出色的效率和公平性,但其适应性和可扩展性较差,难以应对快速变化或复杂的情况 。  

冲突解决与协商机制

在多智能体系统中,冲突是不可避免的,通常产生于智能体目标冲突、资源有限或对共享数据理解不同 。为了确保系统有效运行,MAS需要通过结构化的通信、决策协议和预定义规则来管理和解决冲突 。  

解决冲突的主要方法包括:

  • 协商(Negotiation): 智能体之间通过沟通提出建议和反建议,以达成双方可接受的结果 。例如,物流无人机可以协商航线以避免碰撞,或使用“Contract Net Protocol”协议通过投标方式动态分配任务 。这种协商对于与具有冲突目标的其他智能体合作时尤为重要 。  

  • 规则优先级(Rule-based Prioritization): 预定义的策略或规则决定如何解决冲突 。例如,在智能电网中,智能体可能遵循“优先使用可再生能源”的规则来分配电力需求 。  

  • 共识算法(Consensus Algorithms): 在去中心化系统中,智能体通过分布式算法(如Raft或Paxos)达成共享状态的一致性 。例如,区块链网络中的节点使用共识协议来验证交易。  

  • 博弈论(Game Theory): 在竞争模式下,智能体为争夺有限的资源或优势地位而行动,以获得最大的个体奖励 。多智能体协同控制问题可以被重新表述为微分博弈框架,每个智能体都试图优化自身目标函数,同时考虑其他智能体的行动 。

智能体之间的通信方式与协议

通信方式:直接与间接

多智能体之间的通信是实现协同的基础。这种通信可以分为两种基本方式:

  • 直接通信(Direct Communication): 智能体之间通过消息传递(message passing)进行显式通信 。它们使用预设的通信协议来交换状态信息、分配任务和协调行动 。例如,无人机在搜救任务中通过无线网络交换GPS坐标和传感器读数 。  

  • 间接通信(Indirect Communication): 智能体通过改变共享环境来间接交流 。例如,一个智能体在共享的数字白板上留下结果,另一个智能体通过感知这个环境变化来获取信息并做出响应。这种方式模仿了自然界中通过环境改变进行交互的模式 。  

多智能体通信协议的技术要素

多智能体通信协议定义了智能体之间进行高效通信的规则和格式 。一个完整的协议包含三个关键要素:  

  • 语法(Syntax): 指通信中使用的符号结构,即信息传递的格式 。  

  • 语义(Semantics): 指符号所代表的含义 。  

  • 语用(Pragmatics): 指符号如何被解释 。  

通过结合语义和语用,智能体可以理解信息的真正含义 。通信协议可以是  

预定义协议,由开发者外部开发和更新;也可以是涌现协议,由智能体通过强化学习等方式自我发展出来 。预定义协议通常基于像FIPA-ACL这样的代理通信语言和本体论 。  

现代与遗留通信协议深度分析

多智能体通信协议的演进与整个软件工程的架构范式演变高度同步。从早期的复杂、有状态的协议,到如今轻量级、无状态、面向云原生的协议,反映了技术社区对可扩展性、易用性和模块化的持续追求。

  • 遗留协议(Legacy Protocols):

    • FIPA-ACL: 这是一个在1996年建立的重大尝试,旨在通过形式化语义和言语行为理论来标准化代理通信 。它实现了20种基于模态逻辑的标准化“言语行为”,但其学术焦点、复杂性以及协议开销和有状态连接的限制,使其在现代云原生架构中难以被广泛采用 。  
  • 现代协议(Contemporary Protocols):

现代协议的兴起是云计算、微服务和API优先架构革命的直接结果 。它们从依赖正式本体论转向利用生成式AI进行动态解释。以下是几个代表性协议:  

  • Model Context Protocol (MCP): 由Anthropic开发,采用客户端-服务器模型,通过JSON-RPC提供工具和数据访问的类型化模式 。该协议支持动态能力发现、以安全为中心的设计,并被誉为“AI界的USB-C” 。  

  • Agent Communication Protocol (ACP): IBM Research开发的协议,基于RESTful HTTP架构,支持WebSocket流,并能通过MIME类型处理多模态内容 。ACP还提供了会话管理和内置的可观测性钩子,其安全模型基于能力令牌 。  

  • Agent-to-Agent Protocol (A2A): Google Cloud开发,专为企业级智能体协作设计 。它使用JSON-RPC 2.0,通过“Agent Card”实现发现机制,支持OAuth2和mTLS等企业级认证方案,并着重于不共享内部状态的不透明通信 。  

这些现代协议的设计哲学直接继承自微服务和Web API的成功实践,使得多智能体系统能够更好地融入现有的IT生态系统,实现更高效的互操作性。通信协议的演变不仅仅是技术细节的更新,更是其与主流软件工程实践深度融合的标志,使得MAS系统能够更加高效地构建和部署。

多智能体协同面临的挑战、局限性与未来展望

当前核心技术挑战

尽管多智能体系统展现出巨大潜力,但其发展仍面临多重挑战:

协调复杂性与行为不可预测性: 开发能够有效协调和协商的系统是一项基础性挑战 。在去中心化网络中,智能体的自主行为有时会产生冲突或变得难以预测,这使得问题的排查和解决变得异常复杂 。  

故障传播与系统鲁棒性: 在依赖共享模型或知识库的系统中,某个智能体的错误或缺陷可能会在整个系统中蔓延,导致大范围故障或安全漏洞 。  

“伪智能体”风险: 随着多智能体概念热度的攀升,市场上出现了一批将传统技术包装成“智能体”的现象,这误导了用户对MAS的认知和期望 。  

伦理、安全与隐私挑战

多智能体系统的应用还带来了重要的伦理和社会挑战:

  • 数据安全与隐私: 智能体对用户个人数据和商业机密的采集和分析,带来了重大的数据安全和隐私挑战。如何保护这些数据,并提高其存储、使用和分享的透明性,是开发者必须面对的关键任务 。  

  • 决策透明性: 智能体的决策过程可能缺乏透明度,难以进行审计和追责 。  

  • 控制与授权: 在模拟人类行为的虚拟社会中,必须建立审计日志和控制机制,确保被模拟的个体能够随时查看并控制其智能体的行为,并拥有撤销授权的权利 。  

未来研究方向与发展趋势

未来的研究将继续聚焦于解决上述挑战,并推动多智能体协同能力的进一步发展:

  • 开放环境下的多智能体强化学习(MARL): 传统的MARL研究主要在简单、静态和封闭的环境中进行。未来的发展方向是研究如何在动态、未知的开放环境中提升智能体团队的协作效能和稳健性 。  

  • 协同机制的理论框架: 研究将继续聚焦于多智能体协同的机制,例如如何通过博弈论、一致性控制等理论方法,实现纳什均衡(Nash equilibrium)的分布式搜索,以及在实际约束下设计有效的协同控制方法 。  

  • 自我组织与涌现智能: 多智能体系统的一个重要发展方向是,智能体能够基于简单的涌现行为规则进行自我组织,从而实现任务分工、协调决策和冲突解决,而无需人类的直接干预 。  

  • 跨模态、跨平台协同能力: 随着智能体被集成到更多的物理和数字环境中,其协同能力将需要扩展到处理多模态内容(如IBM的ACP协议所支持的)和跨平台的交互,从而实现更广泛的互操作性 。

上下文工程(Context Engineering)

最近随着大模型相关技术的演进和迭代,尤其是随着各种AI Agent的不断涌现,工程师们对AI工程技术又有了新的理解,于是“上下文工程”这个新的概念横空出世。
我非常喜欢上下文工程这个术语,它听起来更加系统和广泛,这让人以下就可以联想到,开发智能体或者知识助手时,提升AI输出质量所做的一切工作。

什么是上下文工程

那么什么是上下文工程呢?一开始我也非常好奇,但是随着我不断深入的了解,我发现它并不是完全新的技术,反而它包括的技术都是我所熟悉的,更加准确的说,“上下文工程” 是我们面向大模型开发服务时,所用的一系列技术的代名词,原来我们所用的一系列技术散落在各个角落,现在有了上下文工程的概念,这些技术被统一起来,同时有了统一的目标。

上下文工程(Context Engineering)是一个新兴的、至关重要的领域,尤其在大型语言模型(LLM)时代。它指的是系统性地设计、构建和优化输入给 AI 模型(特别是 LLM)的上下文(Context),以引导模型生成更准确、更相关、更符合预期的输出的一系列方法和实践。

你可以将其理解为一种“AI 沟通的艺术与科学”。我们不是在修改模型本身(那属于模型训练或微调),而是在优化我们与模型“对话”的方式。这个“对话”的输入,就是我们所说的“上下文”。

一个简单的类比是:向一位知识渊-博但没有特定背景信息的专家提问。

  • 糟糕的上下文: “给我写个关于车的故事。” (专家可能会写一个关于马车、F1赛车或者未来飞行汽车的故事,完全不符合你的预期)。

  • 优秀的上下文(经过上下文工程): “你是一位专业的汽车杂志编辑,为一本面向家庭读者的杂志撰写一篇短文。请以一位父亲的视角,讲述他如何选择第一辆七座家用 SUV 的经历。文章需要突出安全性、空间和燃油经济性,风格要温馨、幽默。字数在800字左右。” (专家现在有了清晰的角色、目标受众、主题、关键点、风格和格式要求,能够写出非常贴切的内容)。

上下文工程的核心组成部分

上下文工程通常包含以下几个关键部分。

提示词工程(Prompt Engineering)

这是上下文工程最基础、最核心的部分。它专注于设计和优化直接输入给模型的指令文本(即“提示词”)。提示词工程包括了一系列相关提示词的技术:

  • 明确指令(Clear Instruction): 清晰地告诉模型要做什么,避免模糊不清的词语。
  • 角色扮演(Role-playing): 让模型扮演一个特定角色(如“你是一位资深律师…”)。
  • 提供示例(Few-shot Learning): 给出几个输入和输出的范例,让模型学习并模仿。
  • 思维链(Chain-of-Thought, CoT): 引导模型一步一步地思考,将复杂问题分解,从而得出更可靠的结论。
  • 设定输出格式(Format Specification): 要求模型以特定格式输出,如 JSON、Markdown 表格、HTML 等。

    比如以下提示词是应用了提示词工程方法的案例,用来生成校验密码强度的函数:

    # 角色
  你是一位专注于网络安全的高级 Python 工程师。

  # 任务
  编写一个名为 validate_password_strength 的 Python 函数,该函数接收一个字符串作为密码,并返回一个包含两部分的 JSON 对象:
  1. isValid (布尔值): 指示密码是否满足所有规则。
  2. reasons (字符串列表): 如果 isValid 为 false,列出所有不满足的规则。

  # 思维链 (Chain-of-Thought) 指导
  在生成代码前,请先按以下步骤思考:
  1.  **定义规则:** 密码必须满足以下所有条件:
      * 最小长度为 12 个字符。
      * 至少包含一个大写字母。
      * 至少包含一个小写字母。
      * 至少包含一个数字。
      * 至少包含一个特殊字符(例如 !@#$%^&*)。
  2.  **设计逻辑:** 创建一个 reasons 列表。逐条检查上述规则,若不满足,则将对应的失败原因(英文描述)添加到列表中。
  3.  **确定最终结果:** 如果 reasons 列表为空,则 isValid 为 true,否则为 false。
  4.  **构建 JSON 输出:** 根据 isValidreasons 的最终值,构建并返回所需的 JSON 格式。

  # 开始生成代码

检索增强生成(Retrieval-Augmented Generation, RAG)

当模型的内部知识不足(比如,对于最新的信息、私有领域的知识库或非常专业的内容)时,RAG 就显得尤为重要,它极大地减少了模型“胡说八道”(幻觉)的概率,提高了答案的准确性和时效性,并且可以引用信息来源。

  • 检索(Retrieve): 当用户提出问题时,系统首先从一个外部的知识库(如公司的内部文档、数据库、网站等)中检索最相关的信息片段。
  • 增强(Augment): 将检索到的这些信息片段,连同用户的原始问题,一起整合到提示词中。
  • 生成(Generate): 将这个“增强后”的上下文发送给 LLM,让它基于这些最新、最相关的“外部知识”来生成答案。

此处通过一个示例来展示 RAG 的工作流程:

假设你的公司有一个自研的部署平台叫“Phoenix”,任何公开的 LLM 都不可能知道它的细节。

场景: 一位新员工问:“如何用 Phoenix 平台回滚一次部署?”

RAG 工作流:

  • 查询(Query): 用户输入问题 “How to roll back a deployment with Phoenix?”。

  • 检索(Retrieve):

    系统首先将该问题通过 embedding 模型(如 text-embedding-ada-002)转换为一个向量。

    然后,在存储了公司所有内部技术文档(Confluence, Wiki 等)的向量数据库(如 Pinecone, Chroma)中,执行相似性搜索。

    搜索返回了最相关的几个文档片段,例如文档 "Phoenix CLI v2.1 Reference" 中的一段:“To initiate a rollback, use the command phoenix deployment rollback –deployment-id –target-version . You can find the deployment ID using phoenix deployment list…”

  • 增强(Augment): 系统动态构建一个新的、增强的上下文。


# 上下文信息
# 文档来源: Phoenix CLI v2.1 Reference
---
To initiate a rollback, use the command phoenix deployment rollback --deployment-id <ID> --target-version <VERSION>. You can find the deployment ID using phoenix deployment list.
---

# 用户问题
用户问:如何用 Phoenix 平台回滚一次部署?

# 指令
请仅基于以上提供的上下文信息,回答用户的问题。
  • 生成(Generate): LLM 接收到这个增强的上下文,会生成一个精准、基于事实的回答:“要使用 Phoenix 平台回滚部署,你可以使用 phoenix deployment rollback 命令…”,而不是编造一个虚假的命令。

上下文构建与管理(Context Construction & Management)

这部分关注的是如何动态地、智能地构建和维护整个上下文窗口(Context Window)。LLM 的输入长度是有限的(即上下文窗口),如何有效利用这个有限的空间至关重要。

  • 上下文压缩(Context Compression): 在保持关键信息的同时,删减不重要或冗余的内容,以节省空间。
  • 对话历史管理(Conversation History Management): 在多轮对话中,如何有效地总结和管理之前的对话历史,确保对话的连贯性,同时避免上下文窗口被陈旧信息占满。
  • 动态上下文注入(Dynamic Context Injection): 根据对话的进展或用户的行为,实时地从外部源(如用户画像数据库、实时传感器数据等)拉取信息并注入到上下文中。

记忆机制(Memory Systems)

  • 短期记忆:维护当前会话状态、任务链信息。
  • 长期记忆:保存跨会话历史、用户偏好,通过检索机制注入上下文中

工具调用

在对话中根据任务需求调用外部接口/API,例如日历查询、数据库检索等,并将结果动态注入上下文。

提示词工程过时了么?

最近看到了一种观点,有了上下文工程,提示词工程将过时了。我可以肯定的回答,至少目前来看,这是一种完全错误的认知和引导,这种观点没有建立在对上下文工程的深入理解和认知上。

提示词工程不仅不会过时,它反而是上下文工程不可或缺的基石。

更准确地说,两者的关系是“包含与演进”,而非“替代与淘汰”。上下文工程是一个更宏大、更系统化的框架,而提示词工程是这个框架中至关重要的执行层。

我们可以用一个类比来理解:可以将两者的关系类比为 SQL 查询 与 数据库架构设计。

  • 提示词工程 (Prompt Engineering) 就像是编写高效、精确的 SQL 查询。你需要懂得语法、技巧(如 JOIN, WHERE, GROUP BY),以从数据库中获取你想要的确切数据。这项技能永远不会过时,因为你总需要从数据库中拿数据。
  • 上下文工程 (Context Engineering) 则像是 数据库架构设计。它关注的是整个数据系统的搭建,包括设计表结构、建立索引(类似 RAG 中的向量索引)、管理数据关系、进行性能优化等。一个好的架构能让你更容易写出高效的 SQL,并确保整个系统的稳定和可扩展。

你不可能只懂数据库架构而不懂如何写 SQL 查询。同理,一个完整的上下文工程策略,离不开底层的提示词工程技术。

为什么提示词工程不会过时,而是被整合和升级了呢?

  • 它是与 LLM 交互的“原子操作”。无论你的系统多么复杂,在“最后一步”(The Last Mile),你总是需要将所有信息整合成一个最终的提示词(Prompt)发送给 LLM。这个最终提示词的质量,直接决定了输出的成败。

    • 在 RAG 中: 当你从知识库检索到5个相关文档片段后,如何将这些片段、用户的原始问题、以及行为指令(例如:“请仅根据以上信息回答”、“总结要点”)高效地组合成一个能让 LLM 精准理解的最终提示词?这本身就是一项高级的提示词工程任务。一个糟糕的组合方式可能会让模型感到困惑,忽略掉关键信息。
    • 在 Agent 应用中: 当一个 AI Agent 需要决定下一步使用哪个工具时,它背后往往是一个“元提示词”(Meta-Prompt)在引导它思考。这个元提示词的设计(例如,使用 ReAct 或其他思维链模式)是纯粹的提示词工程。
  • 上下文工程的“组件”需要提示词来驱动。上下文工程的很多策略,本身就是由提示词来执行的。

    • 对话历史摘要: 在管理上下文窗口时,一种常用策略是让 LLM 自身去“总结”之前的对话。那么,你用来指令 LLM 进行总结的那个请求——“请将以下对话总结为包含关键实体和用户意图的摘要”——就是一个需要精心设计的提示词。
    • 数据提取与格式化: 当你希望 LLM 从一段非结构化文本中提取信息并以 JSON 格式输出时,你用来定义 JSON 结构、提供示例、下达指令的文本,同样是提示词工程的范畴。
  • 技能的演进:从“手工作坊”到“系统化工程”。我们可以说,早期的“提示词工程”更像是一种经验性的、有点“炼丹”感觉的手工作坊模式。而“上下文工程”则是将这些成功的经验和模式, systematize(系统化)、industrialize(工业化),形成了一套更可靠、更具扩展性的工程方法论。

    • 过去: 一个“提示词工程师”可能花大量时间在一个独立的 Playground 里调试一个完美的提示词。
    • 现在与未来: 他的工作台变成了一个完整的系统。他不仅要设计单个提示词,还要思考这个提示词如何与外部知识库(RAG)、对话管理器、工具调用等其他系统模块协同工作。他的技能要求从“写好一句话”扩展到了“设计好整个对话流”。

上下文工程-面向AI的软件工程

传统的软件系统是通过程序员在键盘上飞舞的双手,一行行敲击来构筑的,为了构建稳定,可靠,强扩展的应用程序,架构师,软件工程师和测试工程师通力合作,他们应用了架构模式,设计模式,API设计规范,测试技术等一系列软件工程技术,来生产更加稳定可靠的系统。但是随着AI大模型的发展,我们正在见证着传统软件向智能化软件进化的历史进程,对于如何实现可靠的智能化软件系统,AI工程师们也在不断探索和实践。上下文工程正在基于这种可靠软件系统的诉求应用而生,这也成为一种历史必然。

通过上下文工程带来如下好处:

  • 提升模型性能和准确性: 这是最直接的好处。好的上下文可以显著减少模型的错误和幻觉,让输出结果更贴近事实和用户需求。

  • 降低成本和复杂性: 相比于重新训练(Re-training)或微调(Fine-tuning)一个庞大的语言模型,上下文工程的成本要低得多,实施起来也更快速、更灵活。它允许我们在不改变模型底层的情况下,适配各种不同的应用场景。

  • 增强可控性和可解释性: 通过 RAG 等技术,我们可以知道模型是依据哪些信息来生成答案的,这增强了系统的透明度和可信度。同时,通过精心设计的提示词,我们可以更好地控制模型的输出风格、语气和内容。

  • 实现个性化和动态适应: 上下文工程使得 AI 应用能够整合实时的、个性化的用户信息,提供千人千面的服务。例如,一个 AI 客服可以根据用户的历史购买记录(通过 RAG 检索得到)提供更有针对性的建议。

如果说大型语言模型是强大的“引擎”,那么上下文工程就是设计精良的“驾驶舱”和“导航系统”。它决定了我们如何驾驭这股强大的力量,将其引导到正确的方向,去完成具体、有价值的任务。

智能体实战之autogen:ReAct 智能体

autogen 介绍

AutoGen 是微软发布的一个开源的多代理对话框架,可以对标LangGraph,目标是帮助开发者创建基于大型语言模型(LLM)的复杂智能应用。它的设计初衷是简化多智能体系统的开发,使得多个具有不同功能和角色的智能代理(Agent)可以通过自然语言进行交流和协作,共同完成复杂任务。

AutoGen可以快速的搭建多智能体系统,对智能体开发接口进行了高度抽象和封装,程序员可以很快上手,同时用户也可以开发自定义的智能体。另外,它几乎支持所有主流的模型供应商的接口。

本文将基于AutoGen最新的接口(version 0.7.2)来实操如何通过AutoGen来实现ReAct智能体。

什么是ReAct?

此处不得不介绍下什么是ReAct。

ReAct 是一种用于大语言模型(LLMs)的提示词技术,它的全称是 Reasoning and Acting。这个方法的核心思想是让模型交替进行“推理”(Reasoning)和“行动”(Acting),从而更有效地完成任务。

以下是 ReAct 的工作原理和主要优势:

工作原理

简单来说,ReAct 提示词就像是给模型一个任务清单,指导它一步一步地解决问题:

  1. 推理 (Reasoning): 模型首先会生成一个内部思考步骤(Thought),用来分析当前问题,决定下一步该做什么。这个步骤就像是模型的“内心独白”。
  2. 行动 (Acting): 接下来,模型会基于这个思考,执行一个具体的“行动”(Action)。这个行动通常是调用外部工具,比如搜索引擎、计算器或数据库。
  3. 观察 (Observation): 模型会接收到行动的结果(Observation),例如搜索引擎返回的网页内容或计算器的结果。
  4. 循环往复: 模型会根据这个新的观察结果,再次进入“推理”阶段,然后是“行动”,直到任务完成。

这个循环(Thought -> Action -> Observation -> Thought…)让模型能够动态地规划和调整自己的策略,而不是像传统方法那样一次性生成所有内容。

我已经在文章《提示词工程-ReAct提示词:让智能体像人一样思考和行动》做了详细的介绍。

开发环境准备

在开始之前请准备好python的开发环境,一般建议使用anaconda搭建虚拟开发环境,当然可以选择安装miniconda,安装会比较快:

  • Linux 或者 Windows WSL
  • python 3.10+
  • miniconda/anaconda

请分别参考相应的软件文档来安装。

可以使用以下命令来安装本地的虚拟环境:


#创建autogen的虚拟环境
conda create --name autogen python=3.11

#进入该虚拟环境
conda activate autogen

另外一种选择,在能够访问外网的情况下,申请是用google的colab账户,colab可以快速创建notebook并关联虚拟环境。

google colab的地址是:https://colab.research.google.com/

安装AutoGen和相关依赖包

在虚拟环境中安装AutoGen和相关的依赖包,可以使用以下命令:


pip install -U "autogen-agentchat" "autogen-ext[openai]" "tavily-python"

autogen-agentchat是AutoGen的核心包,autogen-ext[openai]是OpenAI的扩展包,tavily-python是Tavily的Python SDK。

如果你需要使用其他模型供应商的接口,可以安装对应的扩展包,例如:


pip install -U "autogen-ext[azure]"  # Azure OpenAI
pip install -U "autogen-ext[anthropic]"  # Anthropic
pip install -U "autogen-ext[ollama]"  # Ollama

导入相关包

在你的Python脚本或者Jupyter Notebook中导入相关的包:


from autogen_agentchat.agents import AssistantAgent, UserProxyAgent
from autogen_agentchat.conditions import TextMentionTermination
from autogen_agentchat.teams import RoundRobinGroupChat
from autogen_agentchat.ui import Console
from autogen_ext.models.openai import OpenAIChatCompletionClient
from google.colab import userdata # 如果在Google Colab中使用,请不要直接使用API key,而是将API key存储在colab的secret中,使用该库的userdata.get('GEMINI_KEY')来获取
from tavily import TavilyClient

创建ReAct提示词

ReAct提示词是ReAct智能体的核心部分,它定义了智能体如何进行推理和行动。以下提示词是一个基本的ReAct提示词模板,你可以根据需要进行修改和扩展,该提示词指导模型通过思考->使用工具进行观察->思考->制定下一步计划->观察不断迭代来达到最终的预期结果。


# NOTE: this ReAct prompt is adapted from Langchain's ReAct agent: https://github.com/langchain-ai/langchain/blob/master/libs/langchain/langchain/agents/react/agent.py#L79
react_prompt = """
Answer the following questions as best you can. You have access to tools provided:

Use the following format:

Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take
Action Input: the input to the action
Observation: the result of the action
... (this process can repeat multiple times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question

"""

创建智能体

接下来,我们将使用AutoGen创建一个ReAct智能体,该智能体将使用Google的Gemini模型和Tavily搜索引擎来回答问题。

AssistantAgent是AutoGen中用于创建智能体的类,它可以使用不同的模型客户端和工具。我们将使用OpenAIChatCompletionClient作为模型客户端,并创建一个搜索工具来获取外部信息。

RoundRobinGroupChat是AutoGen中用于创建团队的类,它可以让多个智能体协同工作。我们将使用TextMentionTermination作为终止条件,当用户提到“Final Answer”时,智能体将结束对话。

在使用以下代码时,请确保你已经在Google Colab中设置了你的API密钥,或者在本地环境中设置了环境变量。同时请申请Tavily的API密钥,并将其存储在userdata中。

google gemini api key可以在Google Cloud Console中申请,Tavily的API密钥可以在Tavily官网中申请。


## 创建查询工具
async def search_tool(query: str) -> str:
    return TavilyClient.get_search_context(query=query, search_depth="advanced")

# Create the agents.
model_client = OpenAIChatCompletionClient(model="gemini-2.0-flash",api_key=userdata.get('GEMINI_KEY'))

# Define an AssistantAgent with the model, tool, system message, and reflection enabled.
# The system message instructs the agent via natural language.
agent = AssistantAgent(
    name="react_agent",
    model_client=model_client,
    tools=[search_tool],
    system_message=react_prompt,
    reflect_on_tool_use=True,
    model_client_stream=True,  # Enable streaming tokens from the model client.
)

# Create the termination condition which will end the conversation when the user says "APPROVE".
termination = TextMentionTermination("Final Answer")

# Create the team.
team = RoundRobinGroupChat([agent], termination_condition=termination)

# Run the conversation and stream to the console.
stream = team.run_stream(task="请你详细介绍下autogen智能体编程框架并且使用中文?")
# Use asyncio.run(...) when running in a script.
await Console(stream)
await model_client.close()

智能体输出结果

运行上述代码后,你将看到智能体的输出结果。智能体会根据ReAct提示词进行推理和行动,最终给出一个详细的回答。

以下是一个可能的输出结果示例:

---------- TextMessage (user) ---------- 
请你详细介绍下autogen智能体编程框架并且使用中文? 
---------- ModelClientStreamingChunkEvent (react_agent) ---------- 
Thought: 我需要使用search_tool 来搜索关于 autogen 智能体编程框架的信息,然后用中文详细介绍它。 
Action: search_tool Action Input: autogen 智能体编程框架 介绍 
Observation: ```json { "answer": "AutoGen 是一个框架,它允许开发具有多个能够通过自然语言相互交流的智能体的应用程序。它支持各种通信模式,可以无缝地集成人类参与。AutoGen 智能体是可定制的、会话的,并且可以连接到外> 部世界以增强其能力。通过利用大型语言模型、工具使用和人类参与,AutoGen 智能体可以以经济高效的方式自动执行各种任务。\n\nAutoGen 的主要特点包括:\n\n* **多个智能体:**AutoGen 允许您创建具有不>同角色和职责的多个智能体。这些智能体可以相互交流以解决问题、完成任务和生成内容。\n* **自然语言通信:**智能体使用自然语言相互交流,这使得它们易于理解和交互。\n* **可定制性:**您可以自定义智能体的角色、职责和行为以满足您的特定需求。\n* **工具使用:**智能体可以访问各种工具,例如搜索引擎、计算器和 API。这使它们能够执行更复杂的任务。\n* **人类参与:**人类可以随时参与智能体之间的对话。这允许人类指导智能体、提供反馈和解决问题。\n* **成本效益:**AutoGen 可以帮助您以经济高效的方式自动执行各种任务。通过利用大型语言模型、工具使用和人类参与,您可以减少对手动工作的需求。\n\nAutoGen 可以用于各种应用,包括:\n\n* **代码生成:**AutoGen 可以用于自动生成代码。例如,您可以使用 AutoGen 创建一个可以生成 Python 代码来解决数学问题的智能体。\n* **问答:**AutoGen 可以用于构建问答系统。例如,您可以使用 AutoGen 创建一个可以回答有关特定主题的问题的智能体。\n* **文本摘要:**AutoGen 可以用于自动生成文本摘要。例如,您可以使用 AutoGen 创建一个可以总结新闻文章的智能体。\n* **机器翻译:**AutoGen 可以用于自动翻译文本。例如,您可以使用 AutoGen 创建一个可以将英语翻译成法语的智能体。\n\n要开始使用 AutoGen,您需要安装 AutoGen 软件包。您可以使用 pip 安装 AutoGen:\n\n``bash\npip install autogen\n``\n\n安装 AutoGen 后,您可以开始创建您的第一个 AutoGen 智能体。有关如何创建 AutoGen 智能体的更多信息,请参阅 AutoGen 文档。\n\n以下是一些有用的资源,可帮助您开始使用 AutoGen:\n\n* AutoGen 网站:[https://microsoft.github.io/autogen/](https://microsoft.github.io/autogen/)\n* AutoGen 文档:[https://microsoft.github.io/autogen/docs/](https://microsoft.github.io/autogen/docs/)\n* AutoGen 示例:[https://github.com/microsoft/autogen/tree/main/notebook](https://github.com/microsoft/autogen/tree/main/notebook)" }
```

Thought: 我现在可以基于搜索结果用中文详细介绍 Autogen 智能体编程框架。
Final Answer: AutoGen 是一个框架,它允许开发具有多个能够通过自然语言相互交流的智能体的应用程序。它支持各种通信模式,可以无缝地集成人类参与。AutoGen 智能体是可定制的、会话的,并且可以连接到外部世界以增强其能力。通过利用大型语言模型、工具使用和人类参与,AutoGen 智能体可以以经济高效的方式自动执行各种任务。

AutoGen 的主要特点包括:

* **多个智能体:**AutoGen 允许您创建具有不同角色和职责的多个智能体。这些智能体可以相互交流以解决问题、完成任务和生成内容。
* **自然语言通信:**智能体使用自然语言相互交流,这使得它们易于理解和交互。
* **可定制性:**您可以自定义智能体的角色、职责和行为以满足您的特定需求。
* **工具使用:**智能体可以访问各种工具,例如搜索引擎、计算器和 API。这使它们能够执行更复杂的任务。
* **人类参与:**人类可以随时参与智能体之间的对话。这允许人类指导智能体、提供反馈和解决问题。
* **成本效益:**AutoGen 可以帮助您以经济高效的方式自动执行各种任务。通过利用大型语言模型、工具使用和人类参与,您可以减少对手动工作的需求。

AutoGen 可以用于各种应用,包括:

* **代码生成:**AutoGen 可以用于自动生成代码。例如,您可以使用 AutoGen 创建一个可以生成 Python 代码来解决数学问题的智能体。
* **问答:**AutoGen 可以用于构建问答系统。例如,您可以使用 AutoGen 创建一个可以回答有关特定主题的问题的智能体。
* **文本摘要:**AutoGen 可以用于自动生成文本摘要。例如,您可以使用 AutoGen 创建一个可以总结新闻文章的智能体。
* **机器翻译:**AutoGen 可以用于自动翻译文本。例如,您可以使用 AutoGen 创建一个可以将英语翻译成法语的智能体。

要开始使用 AutoGen,您需要安装 AutoGen 软件包。您可以使用 pip 安装 AutoGen:

```bash
pip install autogen
```

安装 AutoGen 后,您可以开始创建您的第一个 AutoGen 智能体。有关如何创建 AutoGen 智能体的更多信息,请参阅 AutoGen 文档。

以下是一些有用的资源,可帮助您开始使用 AutoGen:

* AutoGen 网站:[https://microsoft.github.io/autogen/](https://microsoft.github.io/autogen/)
* AutoGen 文档:[https://microsoft.github.io/autogen/docs/](https://microsoft.github.io/autogen/docs/)
* AutoGen 示例:[https://github.com/microsoft/autogen/tree/main/notebook](https://github.com/microsoft/autogen/tree/main/notebook)

提示词工程-反思模式

提示词工程-反思模式

什么是 Reflexion?

Reflexion 是一种先进的 AI Agent 架构,其核心思想是让 Agent 具备自我反思和自我修正的能力。它不仅仅是简单地执行任务(像传统的 ReAct – Reason and Act 模式),而是在遇到失败或障碍时,能够停下来“复盘”自己的行为轨迹,从中吸取教训,并形成指导性的“经验”,用于下一次的尝试。

简单来说,Reflexion 赋予了 Agent 一种从失败中学习的机制,模拟了人类在解决复杂问题时的试错和总结过程。

这项技术主要源于康奈尔大学等机构在 2023 年发表的论文《Reflexion: Language Agents with Verbal Reinforcement Learning》。

Reflexion 与传统方法的区别

特性传统 ReAct AgentReflexion Agent
核心循环思考 -> 行动 -> 观察 (Thought -> Act -> Observation)尝试 -> 评估 -> 反思 -> 再次尝试 (Trial -> Evaluate -> Reflect -> Retry)
失败处理可能会在当前步骤卡住,或进行无效的重复尝试。将整个失败的“轨迹”作为学习材料,进行深入分析。
记忆通常是短期的“暂存器”(Scratchpad),记录当前任务的步骤。拥有一个长期、不断累积的“反思记忆库”(Reflexion Memory)。
学习方式主要依赖于 In-context Learning,受限于单次提示的长度和内容。通过“语言强化学习”,将反思(Verbal Feedback)作为内部奖励信号来指导后续行为。

Reflexion 的核心组件

一个完整的 Reflexion 流程包含三个关键角色,它们都可以由同一个大型语言模型(LLM)通过不同的 Prompt 来扮演:

  1. 行动者 (Actor):

    • 职责: 根据任务目标和当前的“反思记忆”,生成思考和具体行动指令。
    • 工作方式: 这是 Agent 的“手和脚”,负责与外部环境(如代码解释器、搜索引擎)交互。在后续的尝试中,Actor 的 Prompt 会包含之前失败后总结的反思,从而避免重蹈覆辙。
  2. 评估者 (Evaluator):

    • 职责: 判断行动者的输出结果是成功、失败还是部分成功。
    • 工作方式: 评估者检查 Actor 的行动轨迹(Trajectory)和最终结果。评估可以是简单的基于规则的检查(例如,代码是否成功运行),也可以是复杂的、基于 LLM 的语义判断(例如,生成的文章是否回答了问题)。
  3. 自我反思者 (Self-Reflector):

    • 职责: 这是 Reflexion 的核心。当评估者给出“失败”信号时,反思者被激活。它会分析整个失败的行动轨迹,并生成一段简洁、高度概括、具有指导意义的反思文本 (Reflection Text)
    • 工作方式: 反思者会被要求回答“为什么之前的尝试会失败?”以及“下一次应该如何做才能避免这个错误?”。生成的反思文本会被存储到“反思记忆库”中。

工作流程图

下面是 Reflexion Agent 的典型工作流程:


如何使用 Reflexion Prompt 开发 Agent

开发一个 Reflexion Agent 的本质,就是设计一套精巧的 Prompt 链,来分别驱动 Actor, Evaluator 和 Reflector 这三个角色,并管理好“反思记忆库”。

第1步:定义 Agent 的核心组件

你需要准备三个主要的 LLM 调用函数,或者说三个核心 Prompt。

1. Actor Prompt (行动者提示)

这是 Agent 执行任务的基础。与 ReAct 不同的是,你需要为它注入“反思记忆”。

  • 基础结构:

    你是一个{Agent角色,如AI程序员}。你需要解决以下任务。
    
    # 任务
    {task_description}
    
    # 思考过程
    你需要一步步思考,然后选择一个工具/行动。可用的工具有: {tool_list}。
    
    # 反思 (如果记忆库不为空)
    在之前的尝试中,你犯了一些错误。请参考以下从失败中总结的经验教训,避免重蹈覆覆:
    {reflection_memory}
    
    # 行动轨迹 (Scratchpad)
    {scratchpad}
  • {reflection_memory}: 这是一个变量,用于动态插入所有过去的反思文本。在第一次尝试时,这里是空的。
  • {scratchpad}: 用于记录当前尝试中的“Thought, Action, Observation”序列。

2. Evaluator Prompt (评估者提示)

评估可以是简单的代码检查,也可以是复杂的 LLM 判断。对于需要语义理解的评估,可以使用如下 Prompt:

  • 基础结构:

    # 角色
    你是一个严谨的评估机器人。
    
    # 原始任务
    {task_description}
    
    # Agent 的行动轨迹
    {agent_trajectory}
    
    # 评估标准
    请根据以下标准判断 Agent 是否成功完成了任务:
    1.  {criterion_1}
    2.  {criterion_2}
    
    # 你的判断
    请严格回答 "Success" 或 "Failure"。
  • {agent_trajectory}: 传入 Actor 在一次完整尝试中的所有记录。

3. Self-Reflector Prompt (自我反思提示)

这是整个 Reflexion 机制的灵魂。当 Evaluator 返回 "Failure" 时,调用此 Prompt。

  • 基础结构:

    # 角色
    你是一个善于反思和总结的 AI 导师。
    
    # 失败的尝试
    一个 Agent 在尝试解决以下任务时失败了。
    任务: {task_description}
    
    这是它失败的完整行动轨迹:
    {failed_trajectory}
    
    # 你的任务
    请仔细分析上述轨迹,找出导致失败的关键原因。然后,生成一条或几条简洁、通用、具有指导意义的反思。这条反思应该像一个警句或策略,帮助 Agent 在未来的尝试中避免同样的错误。
    
    # 输出要求
    - 直接输出反思文本。
    - 语言要精炼,不超过 50 个字。
    - 专注于策略层面,而不是具体的代码细节。
    
    # 你的反思:
  • 示例输出 (反思文本):
    • "如果一个库的某个函数不存在,应该先检查库的版本或者查阅官方文档,而不是猜测函数名。"
    • "在进行文件写入前,必须先确认目标目录是否存在,如果不存在则需要创建它。"
    • "当网页爬取不到预期内容时,应检查请求头(Headers)是否模拟了真实浏览器,以防被屏蔽。"

第2步:搭建 Agent 的主循环

有了这三个核心 Prompt,你就可以编写 Agent 的主控制逻辑了。

伪代码示例:

def run_reflexion_agent(task, max_trials=3):
    # 初始化反思记忆库
    reflection_memory = []

    for i in range(max_trials):
        print(f"--- 开始第 {i+1} 次尝试 ---")

        # 1. 执行一次完整的尝试 (Actor)
        # Actor 的 prompt 中会包含 reflection_memory
        current_trajectory = execute_trial(task, reflection_memory)

        # 2. 评估结果 (Evaluator)
        is_successful = evaluate_trial(task, current_trajectory)

        if is_successful:
            print("任务成功!")
            return current_trajectory
        else:
            print("尝试失败,开始反思...")
            # 3. 如果失败,进行反思 (Self-Reflector)
            new_reflection = generate_reflection(current_trajectory)
            print(f"新的反思: {new_reflection}")

            # 4. 更新记忆库
            reflection_memory.append(new_reflection)

    print("已达到最大尝试次数,任务失败。")
    return None

# --- Helper Functions ---
def execute_trial(task, reflections):
    # 调用 LLM (Actor Prompt) 来生成一系列的 thought-action-observation
    # ... 实现细节 ...
    return trajectory

def evaluate_trial(task, trajectory):
    # 调用 LLM (Evaluator Prompt) 或其他规则来判断成功与否
    # ... 实现细节 ...
    return True_or_False

def generate_reflection(failed_trajectory):
    # 调用 LLM (Self-Reflector Prompt) 来生成反思文本
    # ... 实现细节 ...
    return reflection_text

关键的实现细节与建议

  1. 管理记忆库和上下文窗口: 反思记忆会不断增长。如果记忆过多,可能会超出 LLM 的上下文窗口限制。你需要策略来管理它,例如:

    • 只保留最近的 N 条反思。
    • 对所有反思进行一次更高层次的总结。
    • 使用向量数据库,根据当前失败情境检索最相关的反思。
  2. 反思的质量至关重要: Self-Reflector Prompt 的设计直接决定了 Agent 的学习效率。一个好的反思应该是通用且可操作的,而不是简单地复述错误。

  3. 分层反思 (Hierarchical Reflection): 对于非常复杂的任务,可以设计两层反思。第一层针对短期策略,第二层在多次失败后进行更高层次、更长远的战略总结。

总结

Reflexion 是一种强大但实现起来也更复杂的 Agent 架构。它通过将失败转化为学习机会,极大地提升了 Agent 在需要多步推理、试错和规划的复杂任务上的鲁棒性和成功率。

要成功开发一个 Reflexion Agent,关键在于设计出能够精准驱动 Actor、Evaluator 和 Self-Reflector 这三大核心角色的 Prompt,并实现一个有效的主循环来调度它们和管理反思记忆。这不仅仅是技术实现,更是一门 Prompt Engineering 的艺术。

nuwa terminal 发布了新版本v0.1.1

nuwa-terminal 新版本发布说明

简单介绍

nuwa-terminal 是一个在终端中与大语言模型(LLM)聊天的程序,该工具基于LLM,旨在使终端更加智能。这个终端可以帮助用户使用自然语言
执行命令或任务,同时它还可以作为终端智能助手,你可以询问任何关于软件开发的任何问题。

帮助文档请参考README

目前该版本只支持安装到Linux环境上,对于windows 用户,可以安装到WSL上使用。

更改内容

新特性

  • 聊天模式流式输出:新增对聊天模式流式输出的支持。
  • 安装脚本:发布了 install.sh 并更新了安装指南。
  • 自然语言脚本支持
    • 新增了自然语言脚本系统提示。
    • 新增对脚本模式的处理支持。
    • 新增了系统服务检查的示例脚本。
    • 新增了用于收集 pod 信息的自然语言脚本。
  • 后端配置:新增了对 Google 和 Deepseek 的后端配置支持。
  • 文件路径建议:启动时支持 ./ 或 / 开头的文件路径建议。
  • 未来特性:新增对 Git 的未来特性支持。

改进

  • 代码重构
    • 重构了 setCurrentWorkMode。
    • 在主进程中使用了 NuwaCmd 对象。
    • 在主进程中使用了 NuwaModeManager。
    • 更新了 CheckDirChanged,使用了 getwd。
    • 将 GenerateContent 移至 llms 包。
    • 重构了命令解析代码。
  • 文档更新
    • 更新了支持特性的功能列表。
    • 更新了自然语言脚本相关文档。
    • 删除了 README.md 中的 bash 模式内容。
  • 错误处理:修复了错误格式,并新增了命令帮助。

Bug 修复

  • 键盘快捷键:修复了帮助信息和注释中的错误快捷键。

内部更改

  • Nuwa 包集成
    • 新增了 NuwaModeManager 接口及其实现。
    • 使用了来自 nuwa 包的 NuwaAgent、NuwaTask 和 NuwaChat。
    • 新增了以下实现:
    • 脚本模式。
    • Nuwa 代理模式。
    • Nuwa 任务模式。
    • Nuwa 命令模式。
    • Nuwa 聊天模式。
    • 删除了 main.go 中的 ParseScript。

详细更改

特性

  • 新增了 install.sh 脚本,简化了安装过程。
  • 新增了聊天模式流式输出支持。
  • 新增了 Google 和 Deepseek 的后端配置支持。
  • 新增了自然语言脚本示例和系统提示。
  • 为了更好的用户体验,新增了文件路径建议功能。

重构

  • 重构代码以使用 NuwaCmd、NuwaModeManager 和来自 nuwa 包的其他组件。
  • 改进了命令解析逻辑和错误处理。

文档

  • 更新了 README.md 以反映更改并删除过时信息。
  • 增加了自然语言脚本和未来特性的文档。

Bug 修复

  • 修复了帮助信息和注释中的错误快捷键。

本版本包含了代码结构的重大改进,新增了自然语言脚本功能,以及更好的用户体验,包括文件路径建议和流式输出。有关详细说明,请参阅更新后的文档。

如何安装

使用安装脚本(推荐)


# 下载并运行安装脚本
wget https://github.com/darmenliu/nuwa-terminal-chat/releases/latest/download/install.sh
chmod +x install.sh
sudo ./install.sh

# 配置你的 API 密钥
vim ~/.nuwa-terminal/envs.sh
source ~/.nuwa-terminal/envs.sh

# 启动 nuwa-terminal
nuwa-terminal

如何使用DeepSeek的API开发大模型应用

如何使用DeepSeek的API开发大模型应用

DeepSeek-v3 和 DeepSeek-r1

最近Deepseek因为连续发布了Deepseek-v3和Deepseek-r1两个模型而迅速出圈,在全球科技领域引起了很大的轰动。

Deepseek2024年12月底发布并开源了DeepSeek-V3模型,性能可比肩顶级闭源模型。

Deepseek2025年1月发布了推理模型DeepSeek-R1,在多项测试中超越了OpenAI的o1模型。

以下是它们的基本介绍:

DeepSeek-V3

DeepSeek-V3 是一种混合专家(MoE)模型,具有 6710 亿参数,同时激活 370 亿参数。它在知识基础任务、长文本处理、代码生成和数学推理方面表现出色。它在中文语言能力方面也颇具特色。DeepSeek-V3 结合了多头潜在注意力(MLA)、DeepSeekMoE 和多标记预测(MTP)等创新。

主要特性和亮点:

  • 性能:DeepSeek V3 在一些领域超越了其他开源模型,并在某些方面与顶尖闭源模型如 GPT-4o 和 Claude 竞争。它在 MMLU(EM)上达到了 88.5% 的准确率,在 MMLU-Redux(EM)上达到了 89.1% 的准确率。
  • 速度:其生成速度提高了三倍,从每秒 20 个标记增加到 60 个标记(TPS)。
  • 架构:DeepSeek-V3 采用了一种新的负载平衡策略,不依赖于辅助损失。它使用细粒度专家系统,动态调整专家路由,以确保负载平衡而不牺牲模型性能。
  • 训练:DeepSeek-V3 使用 FP8 混合精度训练框架,完成了对 14.8 万亿标记的预训练,使用了 2.664M H800 GPU 小时。它从 DeepSeek R1 等模型中提炼推理能力,以提高其推理性能。

DeepSeek R1

DeepSeek R1 是一个基于开源和强化学习(RL)的模型,以其推理能力而闻名。它几乎完全依赖于 RL 进行微调,最小化了对标记数据集的需求。

主要特性和亮点:

  • 推理:DeepSeek R1 在数学、代码和自然语言任务中表现出强大的推理能力。在 AIME 2024 数学竞赛中,它达到了 79.8% 的 pass@1 得分。在 Codeforces 上获得了 2029 Elo 评分,超过了 96.3% 的人类参与者。
  • 训练:DeepSeek R1 使用多阶段训练过程,在强化学习之前集成冷启动数据。它采用基于规则的方法,确保可扩展的强化学习,并将强大的推理能力推广到其他领域。
  • 性价比:与 OpenAI 的 o1 模型相比,DeepSeek R1 的训练成本更低。每百万个标记的输入成本便宜 90%,输出价格约低 27 倍。
  • 开源:DeepSeek R1 在 MIT 许可下开源,允许用户自由使用、修改、分发和商业化该模型。

申请DeepSeek的API Key

进入DeepSeek官网, 点击右上角的“API开放平台”按钮,进入API开放平台页面。
选择“API Key”,点击“创建API Key”按钮,创建一个API Key。将你的API Key保存到安全的地方,后续会用到。

使用API Key调用DeepSeek的API

使用curl调用DeepSeek的API


curl https://api.deepseek.com/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer " \
  -d '{
        "model": "deepseek-chat",
        "messages": [
          {"role": "system", "content": "You are a helpful assistant."},
          {"role": "user", "content": "Hello!"}
        ],
        "stream": false
      }'

使用Python调用DeepSeek的API

DeepSeek的API与OpenAI的API兼容,因此完全可以使用OpenAI的SDK直接调用DeepSeek的API。
这也是官方文档推荐的方法。


# Please install OpenAI SDK first: pip3 install openai

from openai import OpenAI

client = OpenAI(api_key="", base_url="https://api.deepseek.com")

response = client.chat.completions.create(
    model="deepseek-chat",
    messages=[
        {"role": "system", "content": "You are a helpful assistant"},
        {"role": "user", "content": "Hello"},
    ],
    stream=False
)

print(response.choices[0].message.content)

使用Langchain封装的接口调用DeepSeek的API

使用OpenAI的库是相对简单和直接的方法,但是OpenAI的库功能相对单一,如果需要更复杂
的功能,比如链式调用、内存管理、工具调用等,还是需要使用LangChain。

LangChain介绍

LangChain 是一个用于开发由大型语言模型(LLMs)驱动的应用程序的框架。简化了 LLM
应用程序生命周期的每个阶段,提供了一套工具、组件和接口,帮助开发者更高效地构建智
能应用。 LangChain 的主要功能包括:

  • 模型输入/输出(Model I/O):理大型语言模型的输入(Prompts)和输出格式化
    (Output Parsers)。
  • 数据连接(Data Connection):理向量数据存储(Vector Stores)、内容数据获取
    (Document Loaders)和转换(Transformers),以及向量数据查询(Retrievers)。
  • 记忆(Memory):于存储和获取对话历史记录的功能模块。
  • 链(Chains): Memory、Model I/O 和 Data Connection 串联起来,实现连续对话
    和推理流程。
  • 代理(Agents):于 Chains 进一步集成工具(Tools),将大语言模型的能力与本
    地或云服务结合。
  • 回调(Callbacks):供回调系统,可连接到 LLM 应用的各个阶段,便于日志记录和
    追踪。过这些功能,开发者可以创建各种应用程序,包括聊天机器人、智能问答工具、文档
    摘要生成等。

LangChain 还支持与外部数据源的连接,使语言模型能够与其环境进行交互,增强应用程序
的功能和灵活性。2022 年 10 月推出以来,LangChain 迅速获得了开发者的关注和支持,
成为构建 LLM 驱动应用程序的强大工具。

使用LangChain Python调用DeepSeek的API


# 安装必要库(如果未安装)
# pip install langchain-core langchain-openai

import os
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate

# 设置环境变量(替换为您的API Key)
os.environ["DEEPSEEK_API_KEY"] = "sk-your-api-key-here"

# 创建 DeepSeek 模型实例
# 假设 DeepSeek API 兼容 OpenAI 格式
model = ChatOpenAI(
    model="deepseek-chat",  # 指定模型名称
    base_url="https://api.deepseek.com/v1",  # DeepSeek API 地址
    api_key=os.environ["DEEPSEEK_API_KEY"],
    temperature=0.7,  # 控制生成随机性(0-1)
    max_tokens=512  # 最大输出长度
)

# 创建对话提示模板
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个乐于助人的AI助手"),
    ("user", "{input}")
])

# 创建简单对话链
chain = prompt | model

# 执行对话
response = chain.invoke({
    "input": "请用Python写一个快速排序算法,并解释其原理"
})

print("AI回复:\n", response.content)

另外一种选择是,最新的langchain库已经提供了deepseek的扩展库 langchain-deepseek
因此直接使用该库,也可以很方便的调用DeepSeek的API。


# 安装必要库(如果未安装)
# pip install -U langchain-deepseek
export DEEPSEEK_API_KEY="your-api-key"

from langchain_deepseek import ChatDeepSeek

llm = ChatDeepSeek(
    model="deepseek-chat",
    temperature=0,
    max_tokens=None,
    timeout=None,
    max_retries=2,
    # api_key="...",
    # other params...
)

messages = [
    ("system", "You are a helpful translator. Translate the user sentence to French."),
    ("human", "I love programming."),
]
response = llm.invoke(messages)
print(response)

# Stream response
response = llm.stream(messages)
for chunk in response:
    print(chunk)

使用LangChain Go调用DeepSeek的API

Golang 非常适合开发云原生后端应用,同时相比Python,Golang的性能更高,更适合开发高性能的应用。
LangchainGo is the Go Programming Language port/fork of LangChain.
以下提供一个使用LangchainGo调用DeepSeek的API的示例。


package main

import (
    "context"
    "fmt"
    "log"

    "github.com/tmc/langchaingo/llms"
    "github.com/tmc/langchaingo/llms/openai"
)

func main() {
    // Initialize the OpenAI client with Deepseek model
    llm, err := openai.New(
        openai.WithModel("deepseek-reasoner"),
    )
    if err != nil {
        log.Fatal(err)
    }

    ctx := context.Background()

    // Create messages for the chat
    content := []llms.MessageContent{
        llms.TextParts(llms.ChatMessageTypeSystem, "You are a helpful assistant that explains complex topics step by step"),
        llms.TextParts(llms.ChatMessageTypeHuman, "Explain how quantum entanglement works and why it's important for quantum computing"),
    }

    // Generate content with streaming to see both reasoning and final answer in real-time
    completion, err := llm.GenerateContent(
        ctx,
        content,
        llms.WithMaxTokens(2000),
        llms.WithTemperature(0.7),
        llms.WithStreamingFunc(func(ctx context.Context, chunk []byte) error {
            fmt.Print(string(chunk))
            return nil
        }),
    )
    if err != nil {
        log.Fatal(err)
    }

    // Access the reasoning content and final answer separately
    if len(completion.Choices) > 0 {
        choice := completion.Choices[0]
        fmt.Printf("\n\nReasoning Process:\n%s\n", choice.ReasoningContent)
        fmt.Printf("\nFinal Answer:\n%s\n", choice.Content)
    }
}

使用DeepSeek模型开发智能应用的场景

DeepSeek 模型和其他大模型一样,在多个领域具有广泛的应用:

  • 城市治理:AI 可以处理公众请求,协助政府工作人员,并通过 AI 助手和公众关切问题的智能分析来支持决策制定。
  • 客户服务:通过集成 DeepSeek API,企业可以创建 24/7 全天候可用的 AI 助手,用于回答客户问题并提高响应速度。
  • 内容创作:DeepSeek 能够快速生成高质量的文本,例如新闻报道、博客文章和营销内容,提高内容创作效率。
  • 教育:DeepSeek 可用于开发智能教育平台,根据学生的表现个性化学习计划,识别知识盲点,并提供针对性的练习。
  • 医疗:DeepSeek 的智能诊断系统可以快速分析医学影像,提供精准的诊断建议,从而辅助诊断和药物研发。
  • 金融:它可以分析金融数据,提供投资建议、风险评估以及欺诈预防。

DeepSeek 模型还可应用于智能家居,实现语音交互和场景识别;在智能交通领域,用于优化交通流量和辅助驾驶。

此外,DeepSeek 模型适用于需要高推理能力的任务,例如解决数学问题、编写代码以及处理逻辑复杂的场景。
DeepSeek V3 模型兼容 OpenAI API,具有高性价比和优异性能,能够降低获取、部署和使用大模型的成本,
加速其在商业和消费场景中的应用。

我个人的开发案例

目前我正在探索使用AI大模型来提升Linux运维效率,以下是一些探索和实践。

基于DeepSeek 的 nuwa-terminal 智能终端助手

nuwa-terminal 是一个在终端中与大语言模型(LLM)聊天的程序,该工具基于LLM,旨在使终端更加智能。这个终端可以帮助用户使用自然语言 执行命令或任务,同时它还可以作为终端智能助手,你可以询问任何关于软件开发的任何问题。

该文章基于原生deepseek开发的智能终端工具nuwa-terminal 会有详细的介绍。

GitHub地址:nuwa-terminal

基于DeepSeek 的 Linux 系统监控程序

AI Agentic Monitor 是一个基于 AI 智能体技术的系统监控工具。它旨在监控Linux及Cloud系统的状态,并提供实时警报和系统优化建议。
它还非常智能,可以帮助您找到问题的根本原因并提供解决方案。目前该项目还在开发中,欢迎感兴趣的朋友一起参与。

GitHub地址:AI Agentic Monitor

基于原生deepseek开发的智能终端工具Nuwa Terminal

基于原生deepseek开发的智能终端工具Nuwa Terminal

基于生成式AI可以重构一切传统软件的思路,我产生了一种想法就是使用AI大模型,来开发一款更加智能的终端工具。于是Nuwa Terminal诞生了。

nuwa-terminal 是一个在终端中与大语言模型(LLM)聊天的程序,该工具基于LLM,旨在使终端更加智能。这个终端可以帮助用户使用自然语言
执行命令或任务,同时它还可以作为终端智能助手,你可以询问任何关于软件开发的任何问题。

为什么需要Nuwa Terminal智能终端

作为程序员,实际上我们只有少部分时间在写代码,大部分的时间在分析需求、阅读文档、调试代码、解决bug、沟通交流等。过程中有相当一部分
时间是在使用终端来完成一些任务,比如:

  • 使用git命令提交代码。
  • 使用docker或者K8S命令部署项目并进行测试。
  • 调试应用程序。
  • 使用Linux系统命令调查各种系统问题。

这些任务中,大部分都是重复性的工作,同时程序员需要查阅各种文档,Linux map page等等,这些都大大降低了我们的工作效率。
多个上下文的切换,降低了同一任务的专注度。尤其对于复杂的任务来说,如果是要编写shell脚本的话(shell 并不是每天都在使
用的编程语言,只有在需要的时候,尤其是测试的时候使用),并不是每个人都擅长。这需要花更多的时间学习来完成。

然而,大语言模型存储了大量的知识,有些模型尤其擅长软件开发,Linux及开源软件的知识。通过大语言模型,可以轻松的使用自然
语言来生成Linux命令行或者shell脚本。

因此使用AI大模型的能力来赋能终端,可以让程序员的工作更加容易,同时专注在当前任务上。

Nuwa terminal的架构

nuwa terminal 的架构非常简单,它使用langchaingo作为基础库和大模型进行交互,langchaingo是langchain的golang复刻版本,
nuwa terminal 是基于单个AI agent的架构,通过调用命令和脚本来完成任务。

Nuwa terminal 目前支持的功能特性

  • 基于终端的AI运维助力。
  • 使用自然语言生成shell命令并执行。
  • 使用自然语言生成shell脚本并执行。
  • 使用智能体模式执行复杂任务或者故障排查。
  • 支持执行自然语言编写的脚本。
  • 支持和bash之间进行自由切换。

如何使用 Nuwa Terminal

Nuwa Terminal 的使用文档可以参考这里

安装前准备

安装和使用

# 构建并安装 nuwa-terminal-chat
git clone https://github.com/darmenliu/nuwa-terminal-chat.git
cd nuwa-terminal-chat
make

# 使用 sed 将 LLM_API_KEY=apikey 替换为真实的 api key
sed -i 's/LLM_API_KEY=apikey/LLM_API_KEY=<你的 api key>/g' envs.sh
source envs.sh

# 运行 nuwa-terminal-chat
(base) $ ./nuwa-terminal
███    ██ ██    ██ ██     ██  █████      ████████ ███████ ██████  ███    ███ ██ ███    ██  █████  ██
████   ██ ██    ██ ██     ██ ██   ██        ██    ██      ██   ██ ████  ████ ██ ████   ██ ██   ██ ██
██ ██  ██ ██    ██ ██  █  ██ ███████        ██    █████   ██████  ██ ████ ██ ██ ██ ██  ██ ███████ ██
██  ██ ██ ██    ██ ██ ███ ██ ██   ██        ██    ██      ██   ██ ██  ██  ██ ██ ██  ██ ██ ██   ██ ██
██   ████  ██████   ███ ███  ██   ██        ██    ███████ ██   ██ ██      ██ ██ ██   ████ ██   ██ ███████

/home/bob>>> 你是谁?
你: 你是谁?
NUWA: 我是NUWA,一个终端聊天工具。我可以通过生成代码、执行命令和回答问题来帮助你进行软件开发。我有三种模式:

* **聊天模式:** 用于一般聊天和代码生成。
* **命令模式:** 用于执行Linux命令。
* **任务模式:** 用于生成shell脚本并执行Linux命令。

你可以使用以下命令在模式之间切换: chatmode, cmdmode, 和 taskmode。

今天我能为你做些什么?

/home/bob>>> 你能为我做什么?
你: 你能为我做什么?
NUWA: 我是NUWA,你友好的软件工程师聊天机器人。我可以帮助你完成各种任务,包括:

**聊天模式:**
* 回答你关于软件开发概念、最佳实践等问题。
* 根据你的指示生成各种编程语言的代码片段。

**命令模式:**
* 直接在我们的聊天中执行Linux命令。

**任务模式:**
* 创建根据你需求定制的shell脚本。
* 在任务上下文中执行Linux命令。

要开始,告诉我你想进入哪种模式:
* **chatmode** 用于一般软件开发聊天
* **cmdmode** 用于运行Linux命令
* **taskmode** 用于创建和运行shell脚本

今天你想做什么?

/home/bob>>>

Nuwa Terminal 的工作模式

Nuwa 有四种工作模式,分别是:

  • 聊天模式:用于一般聊天和代码生成。
  • 命令模式:用于执行Linux命令。
  • 任务模式:用于创建和运行shell脚本。
  • 智能体模式:用于执行复杂任务或者故障排查。

聊天模式相当于Nuwa是一个智能运维助手,你可以和它进行聊天,询问各种问题,它可以帮助你回答问题,并生成代码或者shell命令。
在命令模式下,你可以通过自然语言生成Linux命令,并执行。同样任务模式下,你可以通过自然语言生成shell脚本,并执行。智能体
模式还是一个实验性的功能,在智能体模式下,Nuwa可以执行更加复杂的任务,比如:寻找系统高负载的原因,并找出相应的进程。

以下可以提供一些使用示例:


# 使用聊天模式,生成一个查询所有指定namespace下k8s pods日志的脚本
nuwa-terminal-chat@ 帮我生成查询所有指定namespace下k8s pods日志的脚本,
You: 帮我生成查询所有指定namespace下k8s pods日志的脚本,
NUWA: 好的,我可以帮你生成一个查询指定 Kubernetes 命名空间下所有 Pods 日志的脚本。这个脚本将使用 kubectl 命令来获取日志。

@get_pods_logs.sh@
#!/bin/bash

# 检查是否提供了命名空间参数
if [ -z "$1" ]; then
  echo "Usage: $0 "
  exit 1
fi

NAMESPACE=$1

# 获取指定命名空间下的所有 Pods
PODS=$(kubectl get pods -n $NAMESPACE -o jsonpath='{.items[*].metadata.name}')

# 遍历每个 Pod 并获取日志
for POD in $PODS; do
  echo "Fetching logs for pod: $POD"
  kubectl logs $POD -n $NAMESPACE
done

### 使用方法:
1. 将上述脚本保存为 get_pods_logs.sh。
2. 赋予脚本执行权限:chmod +x get_pods_logs.sh。
3. 运行脚本并指定命名空间:./get_pods_logs.sh <namespace>。

这个脚本会输出指定命名空间下所有 Pods 的日志。如果你需要进一步处理这些日志,可以在脚本中添加相应的逻辑。
# 默认是聊天模式,切换到命令模式,执行命令时以自然语言描述
nuwa-terminal-chat@ cmdmode
You: cmdmode
2025-01-11 21:26:03 INFO  NUWA TERMINAL: Mode is cmdmode
nuwa-terminal-chat# 获取当前系统cpu占用较高的进程
You: 获取当前系统cpu占用较高的进程
NUWA: execute command: ps aux --sort=-%cpu | head -n 10
time=2025-01-11T21:26:47.635+08:00 level=INFO msg=Matched: "match content"="ps aux --sort=-%cpu | head -n 10"
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      245519  2.1  0.1 6258356 30852 pts/5   Sl+  21:25   0:01 ./nuwa-terminal
root           1  1.0  0.0 167020 12400 ?        Ss   11:33   6:03 /sbin/init
root         781  0.4  0.2  43388 36800 ?        S    11:33   2:37 python3 /snap/ubuntu-desktop-installer/1286/usr/bin/cloud-init status --wait
# 切换到任务模式,生成一个shell脚本,并执行
# taskmode
You: taskmode
2025-01-11 21:31:09 INFO  NUWA TERMINAL: Mode is taskmode
nuwa-terminal-chat> 查询当前内存使用情况,找出系统中占用内存较高的前5进程
You: 查询当前内存使用情况,找出系统中占用内存较高的前5进程
NUWA: 以下是一个用于查询当前内存使用情况并找出系统中占用内存较高的前5进程的Shell脚本:

#!/bin/bash

# 获取内存使用情况并排序,显示前5个进程
ps aux --sort=-%mem | head -n 6

### 解释:
- ps aux:显示所有进程的详细信息。
- --sort=-%mem:按照内存使用率(%MEM)降序排序。
- head -n 6:显示前6行(包括标题行),即前5个进程。

运行此脚本后,您将看到系统中占用内存最高的前5个进程及其详细信息。
time=2025-01-11T21:33:12.748+08:00 level=INFO msg="Adding file to source file dict" content="`` shell\n#!/bin/bash\n\n# 获取内存使用情况并排序,显示前5个进程\nps aux --sort=-%mem | head -n 6\n``"
time=2025-01-11T21:33:12.748+08:00 level=INFO msg=Matched: "match_content "="#!/bin/bash\n\n# 获取内存使用情况并排序,显示前5个进程\nps aux --sort=-%mem | head -n 6"
2025-01-11 21:33:12 INFO  NUWA TERMINAL: script file saved to
                      │   .nuwa-terminal/scripts/39ea4f03-79d9-4cc4-8ea4-1cb338ce9314.sh
2025-01-11 21:33:12 INFO  NUWA TERMINAL: script output
                      └ output: + ps aux --sort=-%mem
+ head -n 6
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND

2025-01-11 21:33:12 INFO  NUWA TERMINAL: script file removed

未来的开发计划

  • 支持项目和解释代码
  • 支持分析日志和解释日志
  • 支持远程模式,通过ssh在远程主机上执行命令或者任务
  • 支持通过自然语言执行git 相关的操作

贡献者招募

Nuwa Terminal 是一个开源项目,是一个有趣的学习和尝试,通过AI大模型来重构终端工具,欢迎有兴趣的伙伴参与贡献,共同打造一个更加智能的终端工具。
如果感兴趣,可以联系我,一起交流。

如果你关注到这个项目,欢迎给个star,谢谢。

写在最后

我希望将Nuwa Terminal打造成一个更加智能的终端工具,也许它会成为程序员运维工作的好帮手。未来我会引进多智能体架构,使得该工具能够
更加智能和自主的完成任务,目前该工具还处于早期阶段,欢迎大家关注和使用,并提出宝贵的意见和建议。足够多的反馈,会让我
更有动力去完善它。

最后,感谢大家的关注和支持。

面向智能体编程-构建有效的智能体

面向智能体编程-创建有效的智能体

本文翻译自build effective agents

译者荐语

随着我对提示词工程及智能体编程有了更深的理解,我越来越肯定的是,智能体编程应该是一种新的编程模式。而哪些已有的框架,比如低代码平台Coze,dify,以及langchain,autogen,multi-agent框架掩盖了过多的细节,开发者无法触及智能体本身运作的细节。另外这些框架试图提供一种通用的解决方案,随着时间的推移,面对不同的需求,增加更多的自由和可定制后,框架本身会变得复杂和累赘。

作为开发者,就如本文得建议,我更愿意直接使用大模型的API开发智能应用,这样会给我更加灵活得自由度,同时在实践过程中,我能更好的学习和理解智能体的运作方式。

正文

在过去的一年中,我们与来自各行各业的数十个团队合作,开发基于大语言模型(LLM)的智能体。我们发现,最成功的实现并非依赖复杂的框架或特定的专业化库,而是基于简单、可组合的模式构建而成。

在本文中,我们将分享与客户合作以及自主开发智能体的经验,并为开发者提供构建高效智能体的实用建议。

什么是智能体?

“智能体”(Agent)有多种定义。一些客户将其定义为完全自主的系统,这些系统能够长时间独立运行,利用各种工具完成复杂任务。另一些客户则将“智能体”用于描述更具指导性的实现,这些实现遵循预定义的工作流。在 Anthropic,我们将所有这些变体统称为智能体系统(agentic systems),但在架构上对工作流和智能体做了重要的区分:

  • 工作流(Workflows) 是指通过预定义的代码路径来编排 LLM 和工具的系统。
  • 智能体(Agents) 则是指由 LLM 动态指导其自身流程和工具使用的系统,它们能够自主决定如何完成任务。

接下来,我们将详细探讨这两种智能体系统。在附录 1(“实践中的智能体”)中,我们还描述了客户在两个特定领域中使用这些系统的实际价值。

什么时候使用智能体?

在使用 LLM 构建应用时,我们建议尽可能找到最简单的解决方案,只有在必要时才增加复杂性。这可能意味着完全不构建智能体系统。智能体系统通常以更高的延迟和成本为代价来换取更好的任务性能,因此需要仔细考虑这种权衡何时是值得的。

当需要更复杂的系统时,工作流为定义明确的任务提供了可预测性和一致性,而智能体则适用于需要大规模灵活性和模型驱动决策的场景。然而,对于许多应用来说,通过检索和上下文示例优化单次 LLM 调用通常已经足够。

何时以及如何使用框架

有许多框架可以简化智能体系统的实现,包括:

  • LangChainLangGraph
  • 亚马逊 Bedrock 的 AI Agent 框架
  • Rivet,一种可视化拖放式 LLM 工作流构建工具;
  • Vellum,另一个用于构建和测试复杂工作流的可视化工具。

这些框架通过简化调用 LLM、定义和解析工具以及链接调用等标准底层任务,使开发者能够轻松上手。然而,它们往往会引入额外的抽象层,这可能掩盖底层的提示(prompts)和响应,增加调试的难度。此外,这些框架可能让开发者倾向于增加不必要的复杂性,而实际上更简单的设置可能已经足够。

我们建议开发者从直接使用 LLM API 开始:许多模式只需要几行代码即可实现。如果您决定使用框架,请确保理解其底层代码。对框架内部逻辑的误解是客户常见的错误来源之一。

更多示例实现,请参考我们的实践手册(Cookbook)

构建块、工作流和代理

在本节中,我们将探讨生产环境中常见的智能体系统模式。从最基础的构建模块——增强型 LLM(Augmented LLM)开始,逐步增加复杂性,涵盖从简单的组合式工作流到自主智能体的各个层级。

构建模块:增强型 LLM

智能体系统的基本构建模块是通过检索、工具和记忆等增强功能扩展的 LLM。当前的模型能够主动利用这些功能,例如生成自己的搜索查询、选择合适的工具以及决定需要保留哪些信息。

我们建议将实现重点放在以下两个关键方面:

  1. 根据您的具体用例定制这些增强功能。
  2. 确保它们为 LLM 提供一个简单且文档齐全的接口。

虽然实现这些增强功能的方法有很多,但其中一种方法是通过我们最近发布的 Model Context Protocol。该协议允许开发者通过简单的客户端实现,集成到一个不断扩展的第三方工具生态系统中。

在本文的剩余部分中,我们将假设每次 LLM 调用都能够访问这些增强功能。

工作流:提示链(Prompt Chaining)

提示链是一种将任务分解为一系列步骤的工作流,每次 LLM 调用都会处理前一步的输出。在每个中间步骤,可以添加程序化检查(见下图中的“gate”),以确保整个过程保持在正确轨道上。

何时使用此工作流

该工作流非常适合那些可以轻松且清晰地分解为固定子任务的情况。其主要目标是通过将每次 LLM 调用转化为更简单的任务,从而在提高准确性和降低延迟之间进行权衡。

提示链适用的示例:

  • 生成营销文案,然后将其翻译成另一种语言。
  • 撰写文档大纲,检查该大纲是否符合某些标准,然后根据大纲撰写文档。

工作流:路由(Routing)

路由是一种将输入分类并引导其进入专门后续任务的工作流。该工作流允许关注点的分离,从而构建更专业化的提示。如果没有这种工作流,针对某种输入进行优化可能会影响其他输入的性能。

路由工作流

何时使用此工作流:
路由适用于复杂任务,在这些任务中,存在不同类别,并且可以通过 LLM 或更传统的分类模型/算法准确处理分类。

路由适用的示例:

  • 将不同类型的客户服务查询(一般问题、退款请求、技术支持)引导到不同的下游流程、提示和工具中。
  • 将简单/常见问题路由到小型模型(如 Claude 3.5 Haiku),而将困难/不寻常的问题路由到更强大的模型(如 Claude 3.5 Sonnet),以优化成本和速度。

工作流:并行化(Parallelization)

LLM 有时可以同时处理任务,并以编程方式汇总它们的输出。这种工作流的并行化表现为两种主要变体:

  • 分段(Sectioning):将任务分解为独立的子任务,并行运行。
  • 投票(Voting):多次运行相同的任务,以获得多样化的输出。

并行化工作流

何时使用此工作流:
并行化在以下情况下效果良好:分割的子任务可以并行处理以提高速度,或者当需要多个视角或尝试以获得更高置信度的结果时。对于具有多个考虑因素的复杂任务,当每个考虑因素由单独的 LLM 调用处理时,LLM 通常表现更佳,这样可以集中注意力在每个特定方面。

并行化适用的示例:

  • 分段(Sectioning):

    • 实施保护机制,其中一个模型实例处理用户查询,而另一个模型实例筛查不当内容或请求。这种方式通常比让同一个 LLM 调用同时处理保护机制和核心响应更有效。
    • 自动化评估 LLM 性能的评估,其中每个 LLM 调用评估给定提示下模型性能的不同方面。
  • 投票(Voting):

    • 检查代码的漏洞,多个不同的提示对代码进行审查,并在发现问题时标记代码。
    • 评估给定内容是否不当,多个提示评估不同方面或要求不同的投票阈值,以平衡假阳性和假阴性。

工作流:协调者-工作者(Orchestrator-Workers)

在协调者-工作者工作流中,中央 LLM 动态地将任务分解,委派给工作者 LLM,并综合它们的结果。

协调者-工作者工作流

何时使用此工作流:
该工作流非常适合复杂任务,其中无法预测所需的子任务(例如,在编码中,需要更改的文件数量以及每个文件的更改性质可能取决于具体任务)。虽然从拓扑上看与并行化类似,但其关键区别在于灵活性——子任务并不是预先定义的,而是由协调者根据具体输入确定的。

协调者-工作者适用的示例:

  • 对每次涉及对多个文件进行复杂更改的编码产品。
  • 涉及从多个来源收集和分析信息以获取可能相关信息的搜索任务。

工作流:评估者-优化器(Evaluator-Optimizer)

在评估者-优化器工作流中,一个 LLM 调用生成响应,而另一个 LLM 在循环中提供评估和反馈。

评估者-优化器工作流

何时使用此工作流:
该工作流在有明确评估标准的情况下特别有效,并且当迭代优化能够提供可测量的价值时使用效果最佳。适合的两个标志是:首先,当人类表达反馈时,LLM 的响应可以明显改善;其次,LLM 能够提供这样的反馈。这类似于人类作家在撰写精炼文档时可能经历的迭代写作过程。

评估者-优化器适用的示例:

  • 文学翻译,其中翻译 LLM 可能最初无法捕捉到某些细微差别,但评估者 LLM 可以提供有用的批评。
  • 复杂的搜索任务,要求多轮搜索和分析以收集全面的信息,在这种情况下,评估者决定是否需要进一步的搜索。

智能体

随着 LLM 在理解复杂输入、进行推理和规划、可靠地使用工具以及从错误中恢复等关键能力上的成熟,智能体(Agents)在生产环境中逐渐崭露头角。智能体通常以来自人类用户的命令或互动讨论开始工作。一旦任务明确,智能体便能独立规划和操作,可能会在执行过程中返回人类获取进一步信息或判断。在执行过程中,智能体在每个步骤中获得环境的“真实情况”(如工具调用结果或代码执行)以评估其进展至关重要。智能体可以在检查点处或遇到阻碍时暂停以获取人类反馈。任务通常在完成时终止,但通常会设置停止条件(如最大迭代次数)以保持对过程的控制。

智能体能够处理复杂的任务,但其实现通常是简单的。它们通常仅仅是基于环境反馈在循环中使用工具的 LLM。因此,清晰且周到地设计工具集及其文档至关重要。我们在附录 2(“为您的工具进行提示工程”)中扩展了工具开发的最佳实践。

何时使用智能体

智能体可以用于开放性问题,在这些问题中,难以或不可能预测所需的步骤数量,并且无法硬编码固定路径。LLM 可能会进行多轮操作,因此必须对其决策能力有一定程度的信任。智能体的自主性使其非常适合在可信环境中扩展任务。

智能体的自主特性意味着更高的成本,以及可能导致错误累积的风险。因此,我们建议在沙盒环境中进行广泛测试,并设置适当的保护措施。

智能体适用的示例:

以下示例来自我们自己的实现:

  • 编码智能体,用于解决 SWE-bench 任务,这些任务涉及根据任务描述对多个文件进行编辑。
  • 我们的“计算机使用”参考实现,其中 Claude 使用计算机完成任务。

组合和定制这些模式

这些构建模块并不是固定不变的规范。它们是开发者可以根据不同用例进行塑造和组合的常见模式。成功的关键在于,和任何 LLM 特性一样,测量性能并对实现进行迭代。再次强调:您应该只在明显改善结果时考虑增加复杂性。

总结

在 LLM 领域,成功并不在于构建最复杂的系统,而在于为您的需求构建合适的系统。首先从简单的提示开始,通过全面评估进行优化,仅在更简单的解决方案无法满足需求时,才添加多步骤的智能体系统。

在实施智能体时,我们努力遵循三个核心原则:

  1. 保持智能体设计的简单性。
  2. 优先考虑透明性,明确显示智能体的规划步骤。
  3. 通过全面的工具文档和测试,仔细设计您的智能体-计算机接口(ACI)。

框架可以帮助您快速入门,但在进入生产阶段时,不要犹豫减少抽象层次,使用基本组件进行构建。遵循这些原则,您可以创建不仅强大而且可靠、可维护且受到用户信任的智能体。

致谢

撰写者:Erik Schluntz 和 Barry Zhang。本文基于我们在 Anthropic 构建智能体的经验,以及客户分享的宝贵见解,我们对此深表感激。

附录 1:智能体的实践

与客户的合作揭示了两个特别有前景的 AI 智能体应用,展示了上述模式的实际价值。这两个应用都说明了智能体在需要对话和行动的任务中如何增加价值,具有明确的成功标准,能够启用反馈循环,并集成有意义的人类监督。

A. 客户支持
客户支持结合了熟悉的聊天机器人界面与通过工具集成增强的功能。这是更开放的智能体的自然契合点,因为:

  • 支持交互自然遵循对话流程,同时需要访问外部信息和操作;
  • 可以集成工具来提取客户数据、订单历史和知识库文章;
  • 诸如处理退款或更新票务等操作可以以编程方式处理;
  • 成功可以通过用户定义的解决方案明确衡量。

一些公司通过基于使用的定价模型展示了这种方法的可行性,仅对成功的解决方案收费,显示出对其智能体有效性的信心。

B. 编码智能体
软件开发领域展现出 LLM 特性的显著潜力,能力从代码补全发展到自主问题解决。智能体特别有效,因为:

  • 代码解决方案可以通过自动化测试进行验证;
  • 智能体可以使用测试结果作为反馈对解决方案进行迭代;
  • 问题空间定义明确且结构化;
  • 输出质量可以客观衡量。

在我们自己的实现中,智能体现在可以仅根据拉取请求描述解决真实的 GitHub 问题,符合 SWE-bench Verified 基准。然而,尽管自动化测试有助于验证功能,但人类审核在确保解决方案与更广泛的系统要求一致方面仍然至关重要。

附录 2:为您的工具进行提示工程

无论您正在构建何种智能体系统,工具都可能是您智能体的重要组成部分。工具使 Claude 能够通过在我们的 API 中指定其确切结构和定义与外部服务和 API 进行交互。当 Claude 做出响应时,如果计划调用工具,它将包括一个工具使用块在 API 响应中。工具定义和规范应与整体提示一样,得到同样多的提示工程关注。在这个简短的附录中,我们描述了如何为您的工具进行提示工程。

指定同一操作通常有几种方法。例如,您可以通过编写差异(diff)来指定文件编辑,或者通过重写整个文件。对于结构化输出,您可以在 markdown 或 JSON 中返回代码。在软件工程中,这些差异在外观上是微不足道的,可以无损转换。然而,某些格式对于 LLM 来说比其他格式更难写。编写差异要求在编写新代码之前知道块头中有多少行在变化。将代码写在 JSON 中(相比于 markdown)需要额外转义换行符和引号。

我们对工具格式的建议如下:

  • 给模型足够的 tokens,以便在写作时能够“思考”,而不是写进死胡同。
  • 保持格式接近模型在互联网上自然出现的文本格式。
  • 确保没有格式“开销”,例如必须准确计算数千行代码或转义任何写的代码。

一个经验法则是考虑人机接口(HCI)投入多少精力,并计划在创建良好的智能体-计算机接口(ACI)上投入同样多的精力。以下是一些想法:

  • 设身处地为模型着想。根据描述和参数,使用这个工具是否显而易见,还是需要仔细思考?如果是这样,那么对于模型来说也可能是如此。良好的工具定义通常包括示例用法、边界情况、输入格式要求以及与其他工具的明确界限。
  • 如何改变参数名称或描述以使其更明显?将其视为为您团队中的初级开发人员撰写出色的文档字符串。这在使用许多相似工具时尤其重要。
  • 测试模型如何使用您的工具:在我们的工作台中运行多个示例输入,查看模型的错误,并进行迭代。
  • 采用防错机制(Poka-yoke)设计您的工具。改变参数,使其更难出错。

在为 SWE-bench 构建智能体时,我们实际上在优化工具上花费的时间比在整体提示上更多。例如,我们发现模型在智能体移动出根目录后使用相对文件路径的工具时会出错。为了解决这个问题,我们将工具更改为始终要求绝对文件路径——我们发现模型以这种方式使用毫无问题。

使用golang开发AI大模型应用-langchaingo介绍

使用golang开发AI大模型应用-langchaingo介绍

随着生成式大模型的发展,AI大模型应用的开发也变得越来越重要。由于Python语言在AI领域良好的生态和丰富的库,因此Python语言成为AIGC领域的绝对统治者。在AI领域,Python成为开发AI应用的首选语言。2024在tiobe编程语言排行榜中,Python成为霸榜的编程语言。

但是在后端服务及云原生领域,Golang却是首选语言,相比Python,Golang有更好的性能和并发性。因此,如果你想开发基于AI大模型的后端应用,Golang一定是个不错的选择。美中不足的是,Golang在AI领域的生态相对较弱,能够使用的现成的库并不是很多。

LangChain Go 简介

Langchain目前成为使用python开发AI智能应用的首选框架,它提供了一套工具、组件和接口,使开发人员能够更轻松地构建智能应用。

LangChain 框架包含以下主要组件:

  • Models: 作为基础构建块,提供语言理解和生成能力。
  • Prompts: 用于指导模型生成特定输出的模板。
  • Indexes: 用于高效检索和提取信息。
  • Chains: 将多个组件连接起来,实现复杂的任务流程。
  • Agents: 具有自主决策能力的智能体,可以根据任务选择合适的工具。
  • Memory: 为对话型应用提供历史记忆功能,确保对话的连贯性。

LangChain Go是用Go语言实现的langchain库,基本功能对标了Python版本的langchain库。
使用LangChain Go,开发者可以使用Golang语言快速的构建AI服务及应用。

Github 地址: https://github.com/tmc/langchaingo
开发文档:https://tmc.github.io/langchaingo/docs/
接口文档:https://pkg.go.dev/github.com/tmc/langchaingo

准备工作

在开始之前,你需要安装Go语言环境,可以参考Go语言官方文档进行安装。

由于Golang 也存在多钟版本,如果你需要从多个Golang版本之间进行切换时,可以使用 Glang version manager 进行管理。

使用Google 的Gemini模型

我个人开发过程中,起初使用的Google的Gemini 1.5模型,但是由于免费版本对于请求有一些限制,我后来使用国产的Deepseek模型,其价格非常便宜,性能也不错。

最近Google发布了最新的Gemini 2.0 模型,相比1.5版本,Gemini 2.0 模型在生成式任务上有了更好的表现。目前Gemini 2.0 Flash 版本对开发者提供免费使用,可以通过Google AI Studio申请API key: https://aistudio.google.com/apikey

以下代码示范如何使用LangChain Go调用Google Gemini 2.0模型生成文本:

编译以下代码需要添加go.mod文件:


module your_module_name

go 1.22.0

toolchain go1.22.1

require github.com/tmc/langchaingo v0.1.13-pre.0

require (
    cloud.google.com/go v0.114.0 // indirect
    cloud.google.com/go/ai v0.7.0 // indirect
    cloud.google.com/go/aiplatform v1.68.0 // indirect
    cloud.google.com/go/auth v0.5.1 // indirect
    cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
    cloud.google.com/go/compute/metadata v0.3.0 // indirect
    cloud.google.com/go/iam v1.1.8 // indirect
    cloud.google.com/go/longrunning v0.5.7 // indirect
    cloud.google.com/go/vertexai v0.12.0 // indirect
    github.com/dlclark/regexp2 v1.10.0 // indirect
    github.com/felixge/httpsnoop v1.0.4 // indirect
    github.com/go-logr/logr v1.4.1 // indirect
    github.com/go-logr/stdr v1.2.2 // indirect
    github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
    github.com/golang/protobuf v1.5.4 // indirect
    github.com/google/generative-ai-go v0.15.1 // indirect
    github.com/google/s2a-go v0.1.7 // indirect
    github.com/google/uuid v1.6.0 // indirect
    github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
    github.com/googleapis/gax-go/v2 v2.12.4 // indirect
    github.com/pkoukk/tiktoken-go v0.1.6 // indirect
    go.opencensus.io v0.24.0 // indirect
    go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 // indirect
    go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 // indirect
    go.opentelemetry.io/otel v1.26.0 // indirect
    go.opentelemetry.io/otel/metric v1.26.0 // indirect
    go.opentelemetry.io/otel/trace v1.26.0 // indirect
    golang.org/x/crypto v0.23.0 // indirect
    golang.org/x/net v0.25.0 // indirect
    golang.org/x/oauth2 v0.21.0 // indirect
    golang.org/x/sync v0.7.0 // indirect
    golang.org/x/sys v0.20.0 // indirect
    golang.org/x/text v0.15.0 // indirect
    golang.org/x/time v0.5.0 // indirect
    google.golang.org/api v0.183.0 // indirect
    google.golang.org/genproto v0.0.0-20240528184218-531527333157 // indirect
    google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 // indirect
    google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect
    google.golang.org/grpc v1.64.0 // indirect
    google.golang.org/protobuf v1.34.1 // indirect
)

主函数:


package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/tmc/langchaingo/llms"
    "github.com/tmc/langchaingo/llms/googleai"
)

func main() {
    ctx := context.Background()
    apiKey := os.Getenv("GOOGLE_API_KEY")
    llm, err := googleai.New(ctx, googleai.WithAPIKey(apiKey), googleai.WithDefaultModel("gemini-2.0-flash-exp"))
    if err != nil {
        log.Fatal(err)
    }

    prompt := "简单介绍下langchain go库?"
    answer, err := llms.GenerateFromSinglePrompt(ctx, llm, prompt)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(answer)

运行以上程序:


export GOOGLE_API_KEY="your-google-api-key"
go run main.go

使用OpenAI的模型生成内容

OpenAI几乎没有开放免费额度给开发者使用,同时国内用户也无法使用,这是比较可惜的。但是OpenAI的模型在生成式任务上表现非常优秀,因此很多开发者还是会选择使用OpenAI的模型。

go mod文件:


module module your_module_name

go 1.22.0

toolchain go1.22.1

require github.com/tmc/langchaingo v0.1.13-pre.0

require (
    github.com/dlclark/regexp2 v1.10.0 // indirect
    github.com/google/uuid v1.6.0 // indirect
    github.com/pkoukk/tiktoken-go v0.1.6 // indirect
)

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/tmc/langchaingo/llms"
    "github.com/tmc/langchaingo/llms/openai"
)

func main() {
    llm, err := openai.New(openai.WithModel("gpt-4o-mini"))
    if err != nil {
        log.Fatal(err)
    }
    ctx := context.Background()
    completion, err := llms.GenerateFromSinglePrompt(ctx,
        llm,
        "The first man to walk on the moon",
        llms.WithTemperature(0.8),
        llms.WithStopWords([]string{"Armstrong"}),
    )
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("The first man to walk on the moon:")
    fmt.Println(completion)
}

运行以上程序:


export OPENAI_API_KEY="your-openai-api-key"
go run main.go

使用Deepseek的模型生成内容

Deepseek是国产模型,性能不错,价格也便宜。以下代码示范如何使用LangChain Go调用Deepseek模型生成文本,由于Deepseek支持OpenAI的接口标准,因此使用方法与OpenAI几乎一样。另外国产模型通义千问也是一种选择,但是目前langchang go并没有提供封装和支持,希望后续版本能够提供支持。

就在我发布该文章的第二天,deepseek发布了v3版本,性能相比v2有了大部的提升,强烈推荐国内的开发者使用deepseek模型。

申请API key: https://www.deepseek.com/

go mod文件:


module module your_module_name

go 1.22.0

toolchain go1.22.1

require github.com/tmc/langchaingo v0.1.13-pre.0

require (
    github.com/dlclark/regexp2 v1.10.0 // indirect
    github.com/google/uuid v1.6.0 // indirect
    github.com/pkoukk/tiktoken-go v0.1.6 // indirect
)

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/tmc/langchaingo/llms"
    "github.com/tmc/langchaingo/llms/openai"
)

func main() {
    apiKey := os.Getenv("DEEDSEEK_API_KEY")
    llm, err := openai.New(openai.WithModel("deepseek-coder"), openai.WithBaseURL("https://api.deepseek.com/beta"), openai.WithToken(apiKey))
    if err != nil {
        log.Fatal(err)
    }
    ctx := context.Background()
    completion, err := llms.GenerateFromSinglePrompt(ctx,
        llm,
        "介绍下docker",
        llms.WithTemperature(0.8),
        llms.WithStopWords([]string{"Armstrong"}),
    )
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("The first man to walk on the moon:")
    fmt.Println(completion)
}

运行以上程序:


export DEEDSEEK_API_KEY="your-openai-api-key"
go run main.go

其他使用示例

本文只是介绍了最基本的示例,后续文章会提供更多的示例。

关于langchain go的其他使用示例,可以参考该项目提供的exampls目录,里面包含了一些常见的使用示例。

https://github.com/tmc/langchaingo/tree/main/examples

参考文档

https://eli.thegreenplace.net/2024/using-gemini-models-in-go-with-langchaingo/
https://eli.thegreenplace.net/2024/using-gemini-models-in-go-with-langchaingo/

使用 goplantuml 生成 Golang 项目的类图

什么是 goplantuml

goplantuml 是一个面向 Golang 开发者的
工具,用于将代码的结构(包括包、结构体、接口及其关系)转化为
PlantUML 可视化类图。通过解析 Golang 源码,
goplantuml自动生成描述代码架构的 .puml 文件,帮助开发者更直观地理解项目结
构。

适合 Golang 开发者的场景

在 Golang 开发中,项目结构往往由多个包(package)和类型(如结构体、接口)组成,
随着项目规模扩大,理解代码的架构变得更加复杂。 goplantuml 的目标是通过自动化的方
式生成类图,让开发者能够:

  • 快速理解项目的模块划分和类型关系。
  • 发现潜在的依赖问题或循环引用。
  • 为团队新成员提供清晰的架构概览。
  • 辅助文档编写和代码审查。

核心功能

  • 解析 Golang 源代码:支持解析结构体、接口及它们之间的嵌套关系和依赖。
  • 生成 UML 类图:输出标准的 .puml 文件,可以直接用 PlantUML 渲染为图像。
  • 隐藏私有成员:支持 -hide-private-members 参数,仅显示导出的(public)成
    员,保护代码隐私。
  • 递归处理目录:支持递归扫描目录,分析所有相关的 Golang 源码文件。
  • 灵活的输出控制:开发者可以使用多种选项调整生成的类图细节,如排除特定的包或
    目录。

安装与使用

安装

通过 go install 命令快速安装:

go get github.com/jfeliu007/goplantuml/parser
go install github.com/jfeliu007/goplantuml/cmd/goplantuml@latest

确保 $GOPATH/bin 已添加到环境变量中。

基本用法

以下命令生成类图的 .puml 文件:

goplantuml [-recursive] path/to/gofiles path/to/gofiles2
goplantuml [-recursive] path/to/gofiles path/to/gofiles2 > diagram_file_name.puml

Usage of goplantuml:
  -aggregate-private-members
        Show aggregations for private members. Ignored if -show-aggregations is not used.
  -hide-connections
        hides all connections in the diagram
  -hide-fields
        hides fields
  -hide-methods
        hides methods
  -ignore string
        comma separated list of folders to ignore
  -notes string
        Comma separated list of notes to be added to the diagram
  -output string
        output file path. If omitted, then this will default to standard output
  -recursive
        walk all directories recursively
  -show-aggregations
        renders public aggregations even when -hide-connections is used (do not render by default)
  -show-aliases
        Shows aliases even when -hide-connections is used
  -show-compositions
        Shows compositions even when -hide-connections is used
  -show-connection-labels
        Shows labels in the connections to identify the connections types (e.g. extends, implements, aggregates, alias of
  -show-implementations
        Shows implementations even when -hide-connections is used
  -show-options-as-note
        Show a note in the diagram with the none evident options ran with this CLI
  -title string
        Title of the generated diagram
  -hide-private-members
        Hides all private members (fields and methods)

常用选项

  • -recursive:递归扫描子目录。
  • -hide-private-members:隐藏私有成员,减少输出中的噪声。
  • -ignore "<dir>":忽略特定目录,避免解析不相关的代码。

使用示例

假设项目目录如下:

project/
│
├── main.go
├── models/
│   ├── user.go
│   └── order.go
└── services/
    ├── user_service.go
    └── order_service.go

执行命令:

goplantuml -recursive ./project > diagram.puml

生成的类图可以清晰展示 modelsservices 包中的依赖关系,以及结构体之间的嵌
套和接口实现。

体验

可以通过 dumels 在线体验这个工具。

优势与局限

优势

  • 快速直观:适合中大型项目的架构分析。
  • 自动化:省去手动绘制图表的繁琐步骤。
  • 社区支持:开源项目,活跃的开发与问题跟踪。

局限

  • 不支持动态依赖:工具仅解析静态代码,无法捕获运行时动态关系。
  • 复杂性限制:对于特别大的项目,生成的类图可能过于复杂,建议分模块生成。

总结

goplantuml 是 Golang 开发者的优秀辅助工具,为代码架构的可视化和理解提供了强有力
的支持。如果你正在开发一个 Golang 项目并希望更直观地呈现其架构,不妨试试
goplantuml.

项目主页:goplantuml GitHub

提示词工程-提示词链(prompt chain)

提示词工程-链式提示词(prompt chain)

罗伯特·C·马丁(Robert C. Martin),一位著名的工程师,曾经说过:“函数应该只做一件
事。它们应该做好这件事。而且只做这件事。” 同样的原则也适用于提示词工程。

提示词应该只做一件事。它们应该做好这件事。而且只做这件事。

如果在同一个提示词中包含了多个任务或者指令时,AI大模型的输出将会不敬人意。这样的
提示词会让AI大模型陷入困境,无法正确理解你的意图。因此,更好的方法是将较大的提示
分解为多个较小的提示,创建动态提示链。每个链式提示词只包含一个任务或者指令。

提示链通过让模型专注于链中每个子任务,实现了对输出的更细粒度控制。

什么是提示词链?

提示词链将一个任务拆解为一系列较小的子任务,每个子任务由独立的提示词处理。

提示词链可以通过多种方式实现,包括结合其他提示工程方法,例如自动链式思维提示
(automatic chain-of-thought prompting)、由易到难提示(least-to-most
prompting)以及自一致性提示(self-consistency prompting)。

例如,在文本摘要任务中,可以通过提示链实现以下步骤:

  1. 创建初步摘要草稿
  2. 对摘要进行批评与改进建议
  3. 检查摘要是否存在事实错误
  4. 根据批评和反馈生成精炼后的摘要

每个步骤都由独立的提示处理,使模型能够完全专注于单个子任务,从而提高整体输出质量。

提示链对于完成复杂任务非常有用,因为这些任务如果使用一个非常详细的单一提示,LLM
可能难以应对。在提示链中,每个链式提示都会对生成的响应进行转换或额外处理,直到最
终达到期望的结果。

除了获得更好的性能,提示链还能提高LLM应用的透明性、可控性和可靠性。这意味着你可
以更轻松地调试模型响应中的问题,并分析和改进需要优化的各个阶段的性能。

提示链在构建基于LLM的对话助手、改善应用的个性化和用户体验方面尤其有用。

提示链的工作原理

下图展示了提示链的基本工作原理。首先使用提示链时,需要将任务拆解为多个子任务,子
任务的粒度足够小,每个子任务都由独立的提示处理。上一个提示词的输出作为下一个提示
词的输入。

提示链的好处

  • 增强专注力:通过将庞大的提示拆解为有针对性的子提示,模型可以将注意力集中在
    每个任务上,一次只处理一个任务。

  • 更高质量的输出:如后续研究所示,提示链的效果明显优于庞大的提示。研究结果表
    明,提示链能够提供更精确和有效的输出。

  • 更易理解:理解复杂的庞大提示非常具有挑战性,这也使得团队协作变得困难,输出
    质量难以提升。通过利用提示链,所使用的提示更加专注,因此更容易理解。

  • 广泛适用:提示链几乎可以提高任何复杂任务的输出质量。无论是摘要、问题解决还
    是创意写作,通过提示链将过程拆解为更小的步骤都能帮助模型提高表现。

提示链在生成长篇输出或处理包含大量上下文的提示时特别有益。

何时使用提示词链

提示链本身其实也是模拟了人类思维的链式思考过程。在人类思维中,我们会将一个大的
任务拆解为多个小的子任务,然后逐个完成。这种思维方式使我们能够更好地处理复杂的问题。

但是当你的任务非常简单或者只包含一个步骤时,使用提示链可能会增加不必要的复杂性。

如果你在决定是创建提示链还是使用单个提示时,可以考虑以下四个问题:

  • 我的任务涉及多个指令吗? 例如,“阅读这篇文章并生成摘要,然后创建一个相关的
    LinkedIn帖子。”

  • 我的任务需要多次转换吗? 比如,如果输出需要以多种方式进行处理或重新格式
    化。

  • 我对单一提示的结果不满意吗? 将任务拆解为子任务,并通过提示链逐个处理,可
    以帮助你找出问题所在,从而更容易修复。

  • 模型是否似乎失去焦点或忘记上下文? 如果是这样,将单个提示转化为提示链可以
    确保每个步骤都能得到模型的全神贯注。

提示链的典型示例

数据分析任务

通常在做数据分析时,我们需要进行数据提取、数据清理、数据分析和数据可视化等多个步骤。
而且每一步都要基于上一步的结果进行。因此这是一种典型的适合使用提示链的场景。

提示1:提取数据
从我们公司的数据库的导出数据 {{ 数据库数据 }} 中提取收入和用户参与数据,重点关注第一季度到第四季度的数据。

提示 2:数据转换
清理提取的数据 {{ 提取的数据 }} ,去除异常值,处理缺失值,并标准化数值字段。

提示 3:数据分析
分析清理后的数据 {{ 转换后的数据 }},以识别收入增长和用户参与度随时间的主要趋势。

提示 4:数据可视化
根据 {{ 数据分析结果 }} 创建可视化图表,突出分析中识别的趋势,重点展示收入增长和参与度激增。

代码编写任务

软件的代码编写是一个相当复杂的过程,通常需要多个步骤,例如需求分析、设计、编码、测试和部署等等。
如何将编写代码的任务交给AI大模型呢?这时候提示链就派上用场了。

如下提示链的示例,将代码编写拆解为:根据需求生成代码-》生成测试用例 -》代码检视 -》解决问题。

提示1:生成代码
请根据用户的 {{ 功能需求 }} 使用 {{ 编程语言 }} 生成相应的代码,保证生成的代码和用户需求一致。
始终使用注释来解释代码片段,如果是函数和类,请添加函数和类的注释,函数的注释包括函数名、参数、
返回值、功能描述。始终保持代码的整洁和可读性。

提示2:生成测试用例
请根据生成的代码 {{ 生成的代码 }} 生成相应的测试用例,保证测试用例能够覆盖生成的代码。

提示3:代码检视
请对 {{ 代码和测试用例 }} 进行检视,找出代码中存在的问题,并给出改进建议。

提示4:解决问题
请根据检视建议对 {{ 生成的代码 }} 和测试用例 {{ 生成的测试用例 }} 进行改进优化,同时保证测试
用例能够通过。

复杂任务拆解

如果你一开始还不太清楚如何将一个任务拆解为多个子任务,那么你也可以提示链技术借助LLM的能力,
将任务拆解为多个子任务。

系统提示词:
你是一个任务拆解专家,请根据用户的需求,将任务拆解为多个子任务。目标是尽可能的将任务拆解为
细粒度的子任务。

提示词1:
这是一个复杂任务 {{ 任务描述 }} ,将任务拆解为多个子任务或者执行步骤。

提示词2:
根据 {{ 任务拆解 }} ,列出每个子任务的具体目标和预期结果。

提示词3:
根据 {{ 任务拆解 }} ,列出每个子任务需要完成指定目标所需要使用的方法或者解决方案。

提示词4:
请根据 {{ 任务拆解 }} 和 {{ 子任务目标 }} ,列出每个子任务的执行优先级。

提示词5:
请根据 {{ 任务优先级 }} ,列出每个子任务的执行顺序。

提示词6:
请根据 {{ 任务拆解 }} 列出每个子任务需要依赖的外部资源。

参考文章:

https://www.prompthub.us/blog/prompt-chaining-guide
https://www.ibm.com/topics/prompt-chaining
https://docs.anthropic.com/en/docs/build-with-claude/prompt-engineering/chain-prompts
https://www.promptingguide.ai/techniques/prompt_chaining

面向软件工程师的生成式AI学习大纲

面向软件工程师的生成式AI学习大纲

随着AI大模型的出现,生成式AI已经成为了科技界的新宠,无论是AI绘画、AI写作、AI编程、AI音乐、AI视频,还是AI对话,都离不开生成式AI。中国甚至提出了“AI+”战略,将AI与各行各业相结合,以实现产业升级和转型。就在最近中国教育部办公厅通知,将加强中小学人工智能教育,将AI教育纳入中小学课程体系,并鼓励学生学习AI相关知识。

在AI如此火热的背景下,软件工程师们其实处在学习和使用AI的前线,可以预见的是,未来所有的传统软件将被基于AI的软件所取代,软件工程师们将面临前所未有的挑战和机遇。因此,软件工程师们需要学习AI相关知识,以适应未来的发展。

最近每当和身边的同事聊起AI时,他们都会问我,作为一个软件工程师,应该如何学习AI?应该学习哪些知识?方向在哪里?

是啊,这其实也是我自己一直在思考的问题。

很庆幸,我本科学习数学和应用数学,研究生的时候很庆幸阴差阳错学习了人工智能方向。其实相比其他人,我有更好的数学基础,这成为我后来学习AI的一大优势。可惜15年前遇到经济危机,当时AI还处于早期阶段,考虑到现实情况,选择了软件开发。

不过由于一直对AI非常感兴趣,所以这些年一直都在关注AI的发展,也一直在学习AI相关的知识。通过这些年的积累,作为软件工程师我积累了很多软件开发和架构的经验,同时我也具有良好的AI基础和背景。我觉得这是我职业生涯的有一个转折点。AI的浪潮给了我新的机遇。

所以,我决定站在软件工程师的视角,将我这些年学习AI的经验和知识整理成一个学习大纲,分享给所有对AI感兴趣的软件工程师们。

大纲将主要分为四个部分:

  • 基础知识:AI与生成式AI概述、机器学习基础及理论、神经网络基础
  • 大语言模型(LLM):什么是大语言模型、Transformer架构、预训练与微调、注意力机制、大语言模型的训练
  • 生成式AI应用:Prompt Engineering、RAG (Retrieval-Augmented Generation)、AI Agent、文本生成应用、多模态生成
  • 工程实践:常用的提示词模板、平台及工具、大语言模型类型、图像生成模型、音乐生成模型。

大家可以持续关注我的博客,我会持续更新这部分内容。并且收集相关的学习资料,分享给大家。

第一部分:基础知识

基础知识部分主要介绍AI与生成式AI的基本概念、机器学习基础及理论、神经网络基础等,这部分内容涉及基础算法、理论及架构等,需要有良好的数学基础。不过这部分如果能够坚持啃下来的话,一定会对AI有更深刻的理解。不过大部分人可以主要关注机器学习基础及理论、神经网络基本原理部分,因为这部分内容是生成式AI的基础,帮助你能够更好的理解大语言模型。

AI与生成式AI概述

人工智能基本概念

人工智能(AI)是指通过计算机系统模拟人类智能的能力,使其能够执行通常需要人类智慧的任务。以下是人工智能的一些基本概念:

  1. 机器学习(Machine Learning)

    • 机器学习是AI的核心领域之一,它使计算机能够通过数据学习和改进,而无需显式编程。常见的机器学习方法包括监督学习、无监督学习和强化学习。
  2. 深度学习(Deep Learning)

    • 深度学习是机器学习的一个子领域,使用多层神经网络(深度神经网络)来处理复杂的数据。它在图像识别、自然语言处理等领域表现出色。
  3. 自然语言处理(Natural Language Processing, NLP)

    • NLP使计算机能够理解、解释和生成人类语言。应用包括语音识别、机器翻译、情感分析等。
  4. 计算机视觉(Computer Vision)

    • 计算机视觉使机器能够“看”和理解图像或视频内容。应用包括图像分类、物体检测、人脸识别等。
  5. 专家系统(Expert Systems)

    • 专家系统是基于规则的系统,模拟人类专家的决策过程。它们通常用于诊断、规划和预测等任务。
  6. 强化学习(Reinforcement Learning)

    • 强化学习是一种通过试错来学习的方法,系统通过奖励和惩罚来优化行为。它在游戏、机器人控制等领域有广泛应用。
  7. 知识表示与推理(Knowledge Representation and Reasoning)

    • 这是AI中关于如何表示知识和进行逻辑推理的领域。它包括使用逻辑、语义网络、本体论等方法来存储和处理知识。
  8. 机器人学(Robotics)

    • 机器人学结合了AI和工程学,研究如何设计和制造能够执行复杂任务的机器人。
  9. 认知计算(Cognitive Computing)

    • 认知计算旨在模拟人类的思维过程,使计算机能够解决复杂问题,理解自然语言,并从经验中学习。
  10. 人工智能伦理(AI Ethics)

    • 随着AI技术的发展,伦理问题变得越来越重要。这包括隐私、偏见、透明度和责任等问题。
  11. 通用人工智能(Artificial General Intelligence, AGI)

    • AGI是指具有与人类相当或超过人类智能水平的AI系统,能够执行任何智力任务。目前,AGI仍处于理论阶段。
  12. 弱人工智能(Narrow AI)

    • 弱人工智能是指专门设计用于执行特定任务的AI系统,如语音助手或推荐系统。它们不具备通用智能。

生成式AI

生成式人工智能(Generative AI)是一种能够生成内容(如文本、图像、音频、视频、代码等)的人工智能技术。它的核心技术包括深度学习、神经网络、生成对抗网络(GANs)、变分自编码器(VAEs)以及大型语言模型(LLMs)等。最典型的例子包括OpenAI的ChatGPT、DALL·E、Stable Diffusion等,它们可以基于用户的输入生成新的、类似人类创造的内容。

生成式AI与传统AI的主要区别
对比维度生成式AI传统AI
核心任务生成新内容(文本、图像、音频等)识别、分类、预测、回归
数据处理通过模式学习生成新数据主要用于分析已有数据
模型类型主要使用深度神经网络(如Transformer、GAN、VAE)主要使用决策树、随机森林、SVM、深度学习(如CNN、RNN)
示例应用ChatGPT(文本生成)、DALL·E(图像生成)、MusicLM(音乐生成)语音识别(Siri)、人脸识别、异常检测、推荐系统
主要优势能够创造新颖内容,提高生产力高效处理结构化任务,如分类、回归、检测
训练方式需要大量数据进行无监督/自监督学习监督学习、强化学习居多
1. 传统AI的特点
  • 主要用于模式识别预测,比如人脸识别、垃圾邮件过滤、语音识别、机器翻译等。
  • 依赖于明确的规则结构化数据,如医疗诊断、金融风险预测等。
  • 分类(classification)、回归(regression)、聚类(clustering)等任务为主。
2. 生成式AI的特点
  • 主要用于内容创作,如生成对话、绘画、写作、代码等。
  • 采用深度学习和大规模预训练,能够理解复杂语境并创造新数据。
  • 适用于文本补全、代码生成、图像生成、数据增强等任务。

传统AI更擅长结构化任务,如预测、分类、检测,而生成式AI则擅长创造,它可以自动生成高质量内容,提高生产力和创新能力。未来,二者可以结合,形成更智能的AI系统,如生成增强的搜索(RAG)、智能决策系统等。

专家系统

专家系统是早期人工智能的一个重要分支,它可以看作是一类具有专门知识和经验的计算机智能程序系统,一般采用人工智能中的知识表示和知识推理技术来模拟通常由领域专家才能解决的复杂问题。

一般来说,专家系统=知识库+推理机,因此专家系统也被称为基于知识的系统。一个专家系统必须具备三要素:

  1. 领域专家级知识
  2. 模拟专家思维
  3. 达到专家级的水准

以上定义引用自维基百科:https://zh.wikipedia.org/wiki/%E4%B8%93%E5%AE%B6%E7%B3%BB%E7%BB%9F

专家系统(Expert System)主要由以下核心组件组成:

  1. 知识库(Knowledge Base):存储领域专家的知识,包括事实、规则和启发式经验。
  2. 推理机(Inference Engine):应用知识库中的规则,通过逻辑推理(如前向推理或后向推理)来得出结论。
  3. 用户接口(User Interface):用户与系统交互的界面,输入问题并接收系统的决策或建议。

特点

  • 专注于特定领域(如医学诊断、财务分析、设备故障排查)。
  • 规则驱动(基于 if-then 规则进行推理)。
  • 可解释性强(可以解释其推理过程)。

应用领域

  • 医学(如 MYCIN 诊断细菌感染)。
  • 工程(如 XCON 进行计算机系统配置)。
  • 金融(如信用评估、投资分析)。

尽管专家系统在某些领域表现良好,但它们依赖于人工知识构建,难以适应复杂和动态环境。

AI大模型的出现,给专家系统带来了新的发展方向

AI大模型(如GPT、Gemini,deepseek等)出现后,专家系统的发展方向主要体现在以下几个方面:

1. 结合大模型提升知识获取和推理能力

传统专家系统依赖人工构建知识库和规则,维护成本高、扩展性差。大模型可以通过自然语言处理(NLP)自动提取知识,并结合专家系统的规则推理,形成更强大的智能系统。例如:

  • 用大模型进行知识挖掘,自动更新专家系统的知识库。
  • 结合专家系统的推理能力,使大模型的输出更可解释、更可信。

2. 从基于规则的推理向混合推理发展

专家系统原本依赖符号推理(Symbolic Reasoning),而大模型则更擅长神经推理(Neural Reasoning)。未来,专家系统可能采用神经符号混合推理(Neuro-Symbolic AI),结合两者的优势,例如:

  • 神经网络学习隐含知识,专家系统进行可解释推理,增强AI决策的透明度。
  • 专家系统补充大模型的可控性,解决大模型幻觉(Hallucination)问题。

3. 领域专家系统与大模型的个性化融合

大模型的知识广而不深,而专家系统则擅长某个具体领域。未来的发展方向包括:

  • 基于大模型的专家系统定制化,训练小型、领域专用的专家模型,如法律、医疗、金融等。
  • 大模型充当专家系统的认知层,帮助用户更自然地查询和使用专家系统。

4. 低代码/自然语言开发专家系统

过去专家系统需要手工编写规则,而大模型可以通过自然语言描述生成规则,大大降低开发成本。例如:

  • 让专家用自然语言描述规则,大模型自动转换为可执行的专家系统逻辑。
  • 结合大模型的代码生成能力,自动优化和扩展专家系统。

5. 以知识图谱增强专家系统与大模型的结合

知识图谱(Knowledge Graph)能结构化存储知识,而大模型善于理解非结构化数据。两者结合后,专家系统可以:

  • 基于知识图谱查询和推理,提升可解释性和准确性。
  • 利用大模型进行知识补全,填补知识库中的空白。

专家系统未来的发展趋势是与AI大模型深度融合,从传统的基于规则的系统进化为神经符号混合推理系统,并借助知识图谱自然语言交互个性化定制等技术,使其更智能、更易用、更可解释。

搜索算法

AI 搜索算法主要用于在问题空间中寻找最优解或可行解,广泛应用于路径规划、博弈、专家系统、自动推理等领域。以下是主要的 AI 搜索算法分类及其特点:


1. 盲目搜索(无信息搜索,Uninformed Search)

不利用任何问题领域的启发信息,仅靠遍历搜索空间来寻找解。

深度优先搜索(DFS, Depth-First Search)

  • 策略:优先扩展当前路径的最深节点,使用栈(LIFO)。
  • 优点:内存占用小(只存储路径上的节点)。
  • 缺点:可能陷入死循环,且不一定找到最优解。
  • 应用:迷宫求解、图遍历。

广度优先搜索(BFS, Breadth-First Search)

  • 策略:优先扩展最浅层的节点,使用队列(FIFO)。
  • 优点:保证找到最优解(如果代价相同)。
  • 缺点:占用大量内存(需要存储所有节点)。
  • 应用:最短路径求解、社交网络分析。

迭代加深深度优先搜索(IDDFS, Iterative Deepening DFS)

  • 策略:结合 DFS 和 BFS,逐步加深搜索深度,避免陷入死循环。
  • 优点:节省内存,同时能找到最优解(用于均匀代价问题)。
  • 应用:经典的求解八数码问题(8-Puzzle)。
2. 启发式搜索(Heuristic Search)

利用问题的启发式信息来减少搜索空间,提高搜索效率。

贪心最佳优先搜索(Greedy Best-First Search)

  • 策略:使用启发式函数 ( h(n) ) 选择最有希望的节点。
  • 优点:比无信息搜索快,适用于特定问题。
  • 缺点:可能陷入局部最优,无法保证最优解。
  • 应用:机器人路径规划(如 Dijkstra 算法的变种)。

*A 搜索算法**

  • 策略:结合代价函数 ( g(n) )(起点到当前节点的代价)和启发式函数 ( h(n) )(当前节点到目标的估计代价),计算总估值:
    [
    f(n) = g(n) + h(n)
    ]
  • 优点:保证找到最优解(如果 ( h(n) ) 是可采纳的,即不高估真实代价)。
  • 缺点:计算代价大,需要维护大量节点信息。
  • 应用:地图导航(如 Google Maps)、游戏 AI(如寻路)。

*IDA(迭代加深 A,Iterative Deepening A)**

  • 策略:类似 IDDFS,但使用 A* 进行剪枝搜索,设定动态阈值。
  • 优点:减少 A* 的内存占用,但仍能找到最优解。
  • 应用:大规模搜索问题(如 15-数码问题)。
3. 对抗搜索(博弈搜索,Adversarial Search)

适用于双人博弈(如国际象棋、围棋),其中 AI 需要考虑对手的最优策略。

Minimax 算法(极大极小算法)

  • 策略:假设对手会采取最优策略,计算最大化自己得分的策略。
  • 优点:适用于完美信息博弈(如国际象棋)。
  • 缺点:搜索空间巨大,计算量大。
  • 应用:棋类 AI(如 AlphaZero)。

Alpha-Beta 剪枝

  • 策略:在 Minimax 计算过程中剪枝,跳过明显不可能影响最终决策的分支。
  • 优点:大幅减少计算量,提高搜索效率。
  • 应用:国际象棋、围棋 AI。
4. 进化搜索(Evolutionary Search)

模拟自然进化过程,通过遗传变异寻找最优解。

遗传算法(GA, Genetic Algorithm)

  • 策略:使用选择(Selection)、交叉(Crossover)、变异(Mutation)操作优化解。
  • 优点:适用于高维、非连续优化问题。
  • 缺点:计算量大,可能收敛到局部最优。
  • 应用:自动参数优化、神经网络架构搜索(NAS)。
5. 局部搜索(Local Search)

适用于大规模问题,使用局部优化策略。

爬山算法(Hill Climbing)

  • 策略:每次选择当前最优解的邻居节点,如果没有更优解就停止。
  • 优点:计算效率高,适用于简单优化问题。
  • 缺点:容易陷入局部最优。
  • 应用:TSP(旅行商问题)、神经网络参数优化。

模拟退火(Simulated Annealing, SA)

  • 策略:在搜索过程中引入随机扰动,允许接受较差的解以跳出局部最优。
  • 优点:可以避免局部最优,找到全局最优解。
  • 应用:任务调度、物流优化。
类别代表算法适用场景优缺点
无信息搜索DFS, BFS, IDDFS图遍历、迷宫解法适用于小规模问题,缺乏优化能力
启发式搜索A*, 贪心算法路径规划、导航结合启发式信息,效率高,但需设计合适的 ( h(n) )
对抗搜索Minimax, Alpha-Beta博弈 AI(象棋、围棋)适用于双人游戏,但计算量大
进化搜索遗传算法复杂优化问题适用于非线性问题,但计算量大
局部搜索爬山、模拟退火组合优化适用于大规模问题,可能陷入局部最优

AI 搜索算法的发展方向包括:

  1. 强化学习结合搜索(如 AlphaGo 使用 MCTS + 深度学习)。
  2. 神经符号混合搜索(结合神经网络与经典搜索优化)。
  3. 并行计算加速搜索(如 GPU 加速 A*)。

搜索算法仍然是 AI 领域的核心技术之一,在自动驾驶、机器人、智能决策等场景中发挥重要作用。

机器学习基础及理论

  • 机器学习基础理论
  • 模式识别和模式分类
    • 模式分类的基本原理
      • 决策理论
      • 分类器的作用
      • 模式识别的基本过程
    • 特征提取和选择
      • 特征提取
        • 特征空间的构建
        • 特征的表示与编码
        • 特征提取技术
          • 主成分分析
      • 特征选择
        • 特征重要性的评估方法
        • 特征选择算法
    • 分类方法
      • 统计分类
        • 贝叶斯分类器
        • Fisher线性判别分析(LDA)
        • 支持向量机(SVM)
      • 距离度量与非参数方法
        • 最近邻分类器(k-NN)
        • 距离度量(欧氏距离、曼哈顿距离、余弦相似度等)
    • 聚类与无监督学习
      • 聚类
        • k-Means聚类
        • 层次聚类
        • DBSCAN聚类
      • 无监督学习
        • 主成分分析(PCA
        • 自编码器(AutoEncoder)
        • 独立成分分析(ICA)
        • 隐变量模型
        • 非负矩阵分解(NMF)
    • 评估与优化
      • 评估指标
        • 准确率、召回率、F1值
        • ROC曲线、AUC值
      • 交叉验证
      • 超参数调优
        • 网格搜索
        • 随机搜索
        • 贝叶斯优化
        • 模型正则化技术(L1/L2正则化)
    • 贝叶斯方法与概率模型
      • 贝叶斯方法
        • 贝叶斯定理
        • 贝叶斯网络
      • 概率模型
        • 隐马尔可夫模型(HMM)
        • 高斯混合模型(GMM)
    • 异常检测与异常分类
    • 多模态模式识别
    • 图像识别
  • 机器学习基础算法
    • 决策树
    • 贝叶斯网络
    • 回归分析
    • 支持向量机
    • K近邻算法
    • 遗传算法
    • 集成学习
      • Bagging方法(如随机森林)
      • Boosting方法(如AdaBoost、XGBoost)

神经网络基础

  • 神经网络基本原理

    • 模拟生物神经系统的计算模型
    • 神经元模型
      • 神经元
      • 权重
      • 偏置
      • 激活函数
      • 损失函数
    • 神经网络的层次结构
      • 输入层
      • 隐藏层
      • 输出层
    • 常见激活函数
      • Sigmoid
      • Tanh
      • ReLU(Rectified Linear Unit)
      • Leaky ReLU
      • Softmax
    • 损失函数
      • 均方误差(MSE)
      • 交叉熵损失函数
  • 神经网络训练

    • 前向传播
    • 反向传播
    • 优化算法
      • 梯度下降
      • 随机梯度下降
      • Adam
      • RMSprop
      • Adagrad
      • Momentum
  • 正则化

    • L1正则化
    • L2正则化
    • Dropout
    • Batch Normalization
  • 深度学习

    • 前馈神经网络(Feedforward Neural Network, FNN)
    • 卷积神经网络(Convolutional Neural Network, CNN)
    • 循环神经网络(Recurrent Neural Network, RNN)
    • 自编码器(Autoencoder)
    • 生成对抗网络(Generative Adversarial Network, GAN)
    • 图神经网络(Graph Neural Network, GNN)
    • 注意力模型(Attention Mechanism
    • 深度强化学习模型

第二部分:大语言模型(LLM)

这部分的内容主要介绍大语言模型的基本概念、架构、预训练与微调、注意力机制等,这部分内容是生成式AI的核心理论,可以指导你如何设计和构建大语言模型。同时也可以教你如何训练大语言模型,以及如何部署大语言模型。

结合软件工程师在软件开发和部署方面的经验,推荐软件工程师可以重点关注搭语言模型的微调,部署,API服务等方面的技术。同时我个人觉得LLM OPs是一个很好的方向,可以结合软件工程师的开发经验,开发相应的工具和平台,加速大语言模型的创新,开发和部署。

什么是大语言模型

  • 基于深度学习的自然语言处理模型
  • 能够生成、理解和操作自然语言
  • 典型模型:GPT(OpenAI)、BERT(Google)、LLaMA(Meta)

Transformer架构

  • 基础构件:多头注意力机制、前馈网络、位置编码
  • 关键优点:并行处理长序列数据
  • 变体:BERT、GPT、T5等

预训练与微调

  • 预训练:在大规模语料库上训练语言模型
  • 微调:针对特定任务的优化
  • 自监督学习:掩码语言模型(MLM)、因果语言模型(CLM)

注意力机制

  • 点积注意力(Scaled Dot-Product Attention)
  • 自注意力与全局依赖建模
  • 多头注意力的效果与优化

大语言模型的训练

训练数据

  • 数据来源:文本语料库、网页爬取内容、对话记录
  • 数据清洗与标注
  • 数据增强技术

训练策略

  • 监督学习:使用标注数据训练
  • 半监督学习:结合标注和非标注数据
  • 强化学习:如使用奖励模型优化(RLHF, 人类反馈强化学习)

模型训练资源

  • 大规模分布式计算
  • GPU/TPU硬件加速
  • 并行与分布式训练技术(如数据并行、模型并行)

大模型的部署和维护

  • 本地部署
  • 云端分布式部署
  • API 及服务

第三部分:生成式AI应用

生成式AI应用部分主要涉及开发基于大语言模型应用的基础理论和技术,通过这些技术,使得你有能力开发和构建基于大语言模型的应用。我推荐软件工程师们可以重点关注这部分内容涉及的技术和理论以及相关的工具。相比transformer及深度学习相关的基础理论和算法,这部分内容更偏向于应用和实践。由于软件工程师们有良好的软件开发基础,所以这部分内容更容易上手。

Prompt Engineering

  • 什么是提示词工程
  • 提示词的基本结构
  • 提示词工程技术分类
    • zero shot
    • few shot
    • chain of thought
    • React prompt
    • tree of thought
    • prompt chain
    • Reflexion
    • Self-Consistency

RAG (Retrieval-Augmented Generation)

  • RAG模型架构
    • 检索
    • 生成
  • 向量数据库
  • 知识库
  • RAG应用
    • 问答系统
    • 智能客服
    • 文本生成
    • 代码生成
    • 多模态生成
  • RAG 编程框架
    • langchain
    • llamaindex

      AI Agent

  • Agent架构模式
    • Agent 基本架构
    • 工具
    • 任务规划
    • 多Agent协作
    • 记忆与知识库
    • Agent评估方法
  • 多Agent体
  • Agent 编程框架
    • langchain
    • autogen
    • openAI

文本生成应用

  • 对话系统
  • 文本摘要
  • 代码生成
    • Code Pilot
    • Code Agent
  • 创意写作
  • 多语言翻译

多模态生成

  • 文本到图像生成
  • 图像到文本描述
  • 视频生成
  • 音频生成
  • 跨模态转换
  • OCR与语音识别

第四部分:工程实践

常用的提示词模板

平台及工具

智能体低代码

  • COZE
  • DIFY

AI 编程助手

  • Github Copilot
  • Cursor
  • Codeium
    • Windsurf

图像及视频生成

  • Madejourney
  • Stable Diffusion
  • Civitai
  • Flux

音乐生成

  • suno
  • udio

大语言模型

  • OpenAI models
    • GPT4
    • GPT4o
  • Claude models
    • claude 3.5
  • Google models
    • Gemini 1.5
  • Aliyun
    • qianwen 2.5
  • Deepseek
    • deepseek 2.5
  • Llama models
    • llama 3.1
    • llama 3.2
  • Mixtral
    • mixtral

多模态

图像生成模型

  • DALL-E
  • Stable diffusion models
  • Flux models

音乐生成模型

语音识别

数字人

AI 工具集
参考链接: Generative AI Handbook

提示词工程-ReAct提示词(反应式)-让智能体像人一样思考和行动

文章会实时同步到我的公众号,有兴趣的童鞋扫码关注我的公众号噢:

提示词工程-ReAct

提示词工程的魅力就在于,让你可以变成现代版的祭师,能够让大模型言听计从,控制大模型做你想做的事情。

我不太确定超级智能会在未来的哪一天出现,但是从AI的快速迭代和进化来看,我们似乎可以预测,这一天不会遥远。一直以来,创造一个能够自主思考,自主学习和进化的智能体应该是AI发展的终极目标,而在这样的发展进程中,提示词工程也许只是这个进程中的一小段旅程,也许有一天,这项技术会成为历史,不过至少现在,它能够让我们对AI大模型有更加深入的了解,并且助力大模型变得更加聪明和务实。

起初,很难相信,生成模型会具有思考的能力,可当研究人员不断的探索出新的提示词技术时,这种怀疑逐渐得到了清晰的答案。

ReAct 提示词

ReAct 是 "Reasoning and Acting" 的缩写,旨在通过结合推理和行动来提高模型在复杂任务中的表现。

起初该框架由Yao 等人于2022年提出。

ReAct提示词实际上是one-shot或者few-shot提示词的一种(对于什么是one-shot,few-shot提示词,请阅读《提示词工程-少样本提示》)。
简单的说,就是给AI大模型一个思考-行动的例子,通过该例子,表明完成一件特殊任务时,思考和行动的基本框架和逻辑。ReAct本身是拟人化的,模拟人类思考和行动的基本方式,这里我可以举一个非常简单的例子,比如肚子饿了,非常想吃蛋糕:

问题:俺肚子饿了,非常想吃蛋糕。
思考:看看家里有没有买了蛋糕啊?
行动:去冰箱里看看,去厨房看看,发现没有。
思考:想吃自己做的蛋糕呢,还是去点外卖呢,哎,最近有点懒,不想动,还是外卖吧!
行动:打开手机APP,搜索蛋糕,得到种类繁多的蛋糕。
思考:我到底想吃哪一种呢,好像提拉米苏更加诱人一些。
行动:下单购买提拉米苏。
......

以上只是一个非常简单的例子,对人类来说,看起来是件非常普通和自然的事情,可是将思考方式分解,用来提示AI大模型时,会出现非常神奇的效果。

与链式思维推理类似,ReAct 是一种提示工程方法,使用少量样本学习来教模型解决问题。CoT 旨在模仿人类思考问题的方式,ReAct 也包含了这种推理元素,但更进一步地允许智能体通过文本操作与其环境进行交互。人类通过语言推理(说话或思考)来帮助制定策略和记忆事物,但我们也可以采取行动来获取更多信息并实现目标。这就是 ReAct 的基础。

ReAct 提示包括包含行动的示例,通过行动获得的观察,以及人类在过程中不同阶段的书面思考(推理策略)。LLM 学会模仿这种交替进行思考与行动的方法,使其成为环境中的智能代理。下方是 ReAct 智能体如何运作的示例,(按“思考 -> 行动 -> 观察 -> 思考”顺序)。

ReAct智能体的任务执行的大致过程:

  • 用户提出问题。
  • 思考,第一步应该做什么,决定执行动作和环境互动。
  • 行动,使用外部工具,从环境中获取需要的信息。
  • 观察,将行动的结果和收集的信息作为下一步思考的输入。
  • 思考,判断是否问题得到解决,基于上一步观察的结果,重新制定下一步需要执行的动作。
  • 重复以上循环,直到问题解决,或者得到了最终的答案,并结束。

ReAct 提示词是一种思考和行动的模版和范式,教AI大模型按照这种思维框架进行学习和解决问题,与其他提示工程不同的是,ReAct需用通过和环境的互动,获取信息,做动态的调整和规划。因此使用ReAct提示词时,同时需要实现智能体,或者智能代理,能够让智能体使用工具和外部环境进行交互。

更多ReAct提示词的例子

以下是一个来自论文的 ReAct 提示示例

你是知识问答机器人,你会帮助用户回答科学,地理等相关科普知识,给用户提供准确的答案,请以以下例子为参考,以思考-行动-观察 迭代的方式,确保你的答案是实时准确的,你可以通过搜索引擎获取外部知识。

问题:科罗拉多造山运动的东部区域延伸到的区域的海拔范围是多少? 
思考 1:我需要搜索“科罗拉多造山运动”,找出其东部区域延伸到的地方,然后找出该区域的海拔范围。 
行动 1:搜索[科罗拉多造山运动] 
观察 1:科罗拉多造山运动是科罗拉多及周边地区发生的造山事件。 
思考 2:资料中没有提到东部区域,因此我需要查找“东部区域”。 
行动 2:查找[东部区域] 
观察 2:(结果 1 / 1)东部区域延伸到大平原,被称为中央平原造山运动。 
思考 3:科罗拉多造山运动的东部区域延伸到大平原。因此,我需要搜索“大平原”的海拔范围。 
行动 3:搜索[大平原] 
观察 3:“大平原”指的是两种不同的土地区域之一。 
思考 4:我需要改为搜索“美国大平原”。 
行动 4:搜索[美国大平原] 
观察 4:大平原是大平原的一个子区域。从东到西,大平原的海拔从约 1,800 英尺(550 米)上升到 7,000 英尺(2,130 米)。 
思考 5:大平原的海拔范围是从约 1,800 英尺到 7,000 英尺,因此答案是 1,800 英尺到 7,000 英尺。 
行动 5:完成[1,800 英尺到 7,000 英尺]

通用ReAct智能体提示词模版

以下提供的提示词模版是对ReAct的抽象和总结,通过以下模版,开发人员可以定义 AI Agent的基本角色和用户场景,以及智能体能够和外界交互的可用工具集。同时指导智能体在执行特定任务时,需遵从“思考-》执行任务-》观察-》思考”的迭代过程。

以下的ReAct通用提示词可以使用在任何任务场景,程序员只要稍加调整和修改就可以应用在自己的工具和用例里。

TOOL_DESC = """{name_for_model}: Call this tool to interact with the {name_for_human} API. What is the {name_for_human} API useful for? {description_for_model} Parameters: {parameters} Format the arguments as a JSON object."""

REACT_PROMPT = """Answer the following questions as best you can. You have access to the following tools:

{tool_descs}

Use the following format:

Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can be repeated zero or more times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question

Begin!

Question: {query}"""

以下是该提示词模板的中文翻译:

TOOL_DESC = """{name_for_model}:调用此工具以与{name_for_human} API 交互。{name_for_human} API 有什么用途?{description_for_model} 参数:{parameters} 将参数格式化为 JSON 对象。"""

REACT_PROMPT = """请尽可能准确地回答以下问题。你可以使用以下工具:

{tool_descs}

使用以下格式:

问题:你必须回答的输入问题
思考:你应该始终考虑要做什么
行动:要采取的行动,应为 [{tool_names}] 之一
行动输入:行动的输入
观察:行动的结果
...(此思考/行动/行动输入/观察可以重复零次或多次)
思考:我现在知道最终答案了
最终答案:对原始输入问题的最终答案

开始!

问题:{query}"""

写在最后

由于ReAct需要通过环境来获取信息,因此从环境中获取的信息的准确性会严重影响最终的输出结果。因此开发者需要考虑环境信息的准确和可靠,才能保证ReAct应用的性能和可靠性。

ReAct的推理并不完美,但仍然是一种强大的提示工程方法,它克服了链式推理中的幻觉问题,并使大型语言模型能够成为可以与环境互动的智能体。此外,这是一种非常可解释的方法,因为智能体在行动时会输出其思维过程。

ReAct提示词可以让智能体变的更加聪明,帮助我们解决更加复杂的问题,探索ReAct智能体是一件非常有趣的过程。

我相信你一定好奇,如何使用以上的提示词模版实现一个能够自主思考的智能体,接下来后续的文章我将分析如何通过不同的Agent框架,快速的构建智能体,希望持续关注我的博客文章。

参考文章:

AI 编程工具汇总及介绍(持续更新)

文章会实时同步到我的公众号,有兴趣的童鞋扫码关注我的公众号噢:

AI 编程工具汇总及介绍

本文将收录当下火热的AI LLM 编程工具,并简单汇总和介绍,同时根据使用经验,添加功能对比,希望通过开发者视角去看待这些AI 编程工具,给使用者提供一些参考。

在此声明,以下顺序并不是对这些工具的按照功能的排序,此顺序只是收录的顺序,每个工具都有其擅长的特点和方面,需要程序员自己去实际体验。

Cursor

官网:https://www.cursor.com/
文档在这里:https://docs.cursor.com/get-started/migrate-from-vscode

Cusor 基于当下流行的AI大模型,以一种非常创新的方式提供基于自然语言进行编程的非凡体验。Cusor 除了提供类似Github Copilot 代码自动补全,使用注释生成代码,以及chat功能外,composer模式绝对是创新的功能,该功能可以让哪些完全不懂编程语言的人能够开发和设计应用程序。

如果你想体验它,请通过官网下载安装,目前支持不同的OS,比如Windows,Linux和MacOS。

主要功能

  • 智能代码生成:用户可以通过简单的自然语言描述生成代码,Cursor能够自动完成复杂逻辑的实现。
  • 实时语法检查:在编码过程中,Cursor会提供即时的语法反馈,帮助开发者及时发现并修正错误。
  • 代码重构与优化:通过分析上下文,Cursor能够建议代码重构方案,提高代码质量。
  • 自动注释与测试代码生成:为生成的代码自动添加注释,并能够生成相应的测试代码,增强代码可读性和可靠性。

Github Copilot

官网:https://github.com/features/copilot
文档:https://docs.github.com/en/copilot/quickstart

Github Copilot 已经成为我日常开发工具之一了,以下简称GHC好了,GHC是微软基于LLM大模型的创新产品之一,目前已经成为程序员的开发利器之一。以下是一些相对正式的介绍:

GitHub Copilot是一款由GitHub与OpenAI合作开发的AI编码助手,旨在通过提供实时代码建议来提升开发者的编码效率。以下是GitHub Copilot的主要特点和功能:

主要功能

  • 代码自动补全:Copilot能够根据开发者当前编写的代码上下文,提供整行或整块代码的建议。这种智能补全功能不仅限于简单的变量或方法,而是可以生成完整的函数、类和复杂算法[1][2][5].

  • 多语言支持:Copilot支持多种编程语言,包括Python、JavaScript、Ruby、C++等,适应不同开发环境的需求[5].

  • 上下文理解:Copilot通过分析已编写的代码,提供相关性强的建议,从而减少错误并提高代码质量[5].

  • 文档生成:该工具能够自动生成代码注释和文档,帮助开发者节省时间并保持代码库的可读性[5].

  • 聊天功能:Copilot提供了一个聊天界面,允许开发者提出与编码相关的问题,并获得实时反馈。这一功能在Visual Studio Code、JetBrains IDEs等环境中可用[1][4].

  • 命令行支持:在终端中,Copilot可以通过类似聊天的界面提供命令建议和解释,帮助用户更好地理解命令行操作[1][3].

  • 拉取请求摘要:Copilot能自动生成拉取请求中的更改摘要,帮助审查者快速了解变更内容及其影响[1][3].

使用场景

GitHub Copilot适用于多种开发场景,包括但不限于:

  • 快速原型开发
  • 学习新编程语言或框架
  • 处理常见编程任务(如生成SQL查询、编写单元测试等)
  • 调试和代码优化

订阅与访问

GitHub Copilot提供个人用户和组织用户不同的订阅选项。个人用户可以享受30天的免费试用期,之后需要付费订阅。对于学生、教师或开源项目维护者,Copilot可免费使用。

Codeium

官网:https://codeium.com/
中文网站:https://www.codeium-china.com/
文档:https://docs.codeium.com/overview/getting-started

从我的使用经验来看,Codeium 是对标Github Copilot的免费版本,使用的方式和功能基本和GHC 类似,Codeium是完全免费的,不需要额外的付费就可以使用。

以下是Codeium的官方介绍:

Codeium简介

Codeium是一个基于尖端人工智能技术构建的免费AI代码加速工具包。它提供代码补全、智能搜索和支持20多种语言的AI聊天功能。Codeium可用于所有流行的集成开发环境(IDE),包括Visual Studio Code、IntelliJ IDEA和Eclipse。

Codeium特点

比想象中更快地获得代码补全。Codeium的生成式代码可以节省时间,帮助您更快地发布产品。
通过智能搜索找到与其意图相关的文件和代码。不再与复杂的正则表达式纠缠不清,使用我们的AI搜索来找到与您意图相关的文件和代码。
从Codeium Chat获得帮助。生成样板代码、重构代码、添加文档、解释代码、建议错误修复等等。

Codeium功能

  • 代码补全:Codeium可以根据您当前代码的上下文自动为您完成代码。这可以节省您很多时间,特别是对于大型或复杂的项目。
  • 智能搜索:Codeium可以搜索与您意图相关的文件和代码。这是一种快速轻松找到所需代码的好方法。
  • AI聊天支持:Codeium可以帮助您完成各种编码任务,例如生成样板代码、重构代码和添加文档。您还可以使用Codeium Chat在更复杂的编码任务中获得AI的帮助。

Windsurf

官网:https://codeium.com/windsurf?utm_source=ai-bot.cn
文档:https://docs.codeium.com/getstarted/overview

Windsurf 是由美国初创公司 Codeium 推出的创新型 AI 编程工具,旨在提升开发者的编码效率和体验。以下是 Windsurf 的详细介绍。

Windsurf 是一款集成了 AI 能力的集成开发环境(IDE),被认为是世界上第一款具备 AI 代理能力的 IDE。它结合了实时协作与独立操作的智能体,优化了开发者的编码流程,提供了一种名为 Flows 的新型协作模式,允许开发者与 AI 高度协作。

主要功能

  • Flows(AI 协作):支持开发者像与 Copilot(副驾驶)或 Agent(代理)协作一样,与 AI 高效协作。

  • Cascade(深度代码理解与实时感知):通过结合深度代码库理解、高级工具与实时用户行为感知,提供强大、无缝的协作式编码体验。

    • 全局上下文感知:在生产环境中实时运行并提供相关建议。
    • 命令建议与执行:支持命令建议、问题检测与调试功能。
    • 从中断处继续工作:自动推断用户操作意图,帮助用户从离开时的位置继续工作。
    • 多文件编辑:利用上下文感知功能,解决代码问题,支持高效的多文件编辑工作流。
  • 内联命令与后续操作:通过在编辑器中按下 Cmd + \,生成或重构内联代码,支持自然语言操作。

  • 代码透镜(Codelenses):嵌入面包屑导航旁的工具,提供一键式代码理解与重构支持。

Windsurf 的主要应用场景

  • 大型代码库管理:帮助开发者理解并高效导航复杂的代码库,实现代码编辑与维护的最佳实践。
  • 代码开发与重构:支持开发全新代码、优化现有代码结构以及对代码进行高效重构。
  • 问题检测与调试:通过 Cascade 提供的问题检测与调试功能,快速发现并修复代码中的复杂问题,提高开发效率。
  • 多文件编辑协作:适用于需要同时编辑多个文件的场景,帮助开发者保持上下文一致性,提升工作效率。
  • 快速开发迭代:面向需要快速迭代的开发需求,加速开发流程,显著缩短开发时间。

文心快码(Baidu Comate)

官网:https://comate.baidu.com/zh
文档:https://comate.baidu.com/zh/readme
在线体验:https://comate.baidu.com/zh/chat?mode=AGENT

文心快码(Baidu Comate)是百度推出的一款基于其文心大模型的智能代码助手,旨在提升软件开发的效率和质量。以下是对文心快码的详细介绍:

产品背景与目标

文心快码结合了百度多年积累的编程现场大数据和外部优秀开源数据,能够生成符合实际研发场景的高质量代码。该工具的设计目标是帮助开发者在编码过程中实现“帮你想、帮你写、帮你改”的多种应用场景,从而提高开发效率和代码质量[1][5]。

主要功能

文心快码提供了多种功能,主要包括:

  • 代码生成:用户可以通过自然语言描述或注释,快速生成相应的代码片段,显著减少手动编码的时间[2][3].
  • 代码审查与优化:该工具能够智能检测潜在错误,并提供修复建议,帮助开发者提高代码质量[2][5].
  • 单元测试生成:支持为函数自动生成单元测试,确保代码的可靠性[5].
  • 实时诊断与补全:在编码过程中,文心快码可以实时提供代码补全和错误优化建议,提高开发效率[3][4].

支持的编程语言与IDE

文心快码支持超过100种主流编程语言,包括但不限于C/C++、Java、Python、Go、JavaScript和TypeScript等。在集成开发环境(IDE)方面,它兼容Visual Studio Code、JetBrains系列(如IntelliJ IDEA、PyCharm等)、Xcode和Visual Studio等主流工具。

版本与部署选项

文心快码提供四个版本,以满足不同用户的需求:

  1. 标准版:面向个人开发者,基础功能不限量使用。
  2. 专业版:面向专业开发者,基础和高级功能均不限量使用。
  3. 企业版:为企业客户提供额外的安全和管理功能。
  4. 企业专有版:支持私有化部署,确保数据安全和使用效果。

安全性与隐私保护

百度承诺不对用户的代码进行存储、分析或训练等操作。在私有化部署情况下,所有数据都保存在客户的私域内,确保数据安全。

应用场景

文心快码广泛适用于个人项目、企业级应用及教育领域。在教育中,它可以作为编程教学的辅助工具,而在企业中,则能帮助团队提高开发效率并缩短项目周期。

CodeGeex

官网:https://codegeex.cn/
文档:https://zhipu-ai.feishu.cn/wiki/CuvxwUDDqiErQUkFO2Tc4walnZY

CodeGeeX是一款基于ChatGLM2-6B语言模型的智能编程助手,旨在提升开发者的编码效率和质量。以下是对CodeGeeX的详细介绍:

产品概述

CodeGeeX是一个具有130亿参数的多编程语言代码生成预训练模型,支持超过20种编程语言的代码生成与翻译。它通过强大的自然语言处理能力,能够实现代码的生成、补全、自动注释、翻译及智能问答等功能,为开发者提供了全面的编码支持。

主要功能

  • 代码生成与补全:用户可以通过描述或注释快速生成所需代码,减少手动输入的时间。CodeGeeX支持按需自动补全,用户只需输入部分内容即可获得完整代码建议。

  • 自动添加注释:该助手能够为生成的代码自动添加注释,帮助开发者理解和维护代码逻辑。

  • 代码翻译:支持不同编程语言之间的快速转换,能够将一段代码从一种语言翻译成另一种,确保语法和逻辑的正确性。

  • 智能问答:用户可以在插件界面中直接提问,获取有关编程问题的详细解答,提升学习和开发效率。

兼容性与集成

CodeGeeX已全面支持多种主流集成开发环境(IDE),包括但不限于:

  • Visual Studio Code
  • IntelliJ IDEA
  • PyCharm
  • GoLand
  • WebStorm
  • Android Studio

用户只需在相应的IDE中下载并安装CodeGeeX插件,即可轻松使用其功能。

使用模式

CodeGeeX提供多种使用模式,以适应不同开发场景:

  1. 隐匿模式:在用户停止输入时自动生成代码。
  2. 交互模式:允许用户主动请求多个候选代码,并从中选择最合适的一项。
  3. 翻译模式:快速将选中的代码翻译为当前编辑器所用语言。
  4. 提示模式:用户可以自定义模板,用于特定风格或功能的代码生成[2][3].

安全性与隐私保护

CodeGeeX重视用户隐私,不会存储或分析用户的代码。首次使用时,用户会被询问是否同意将生成的代码用于研究目的,该选项默认关闭。

通义灵码

官网:https://tongyi.aliyun.com/lingma/
文档:https://help.aliyun.com/zh/lingma/product-overview/introduction-of-tongyi-lingma

通义灵码是阿里云推出的一款基于通义大模型的智能编码辅助工具,旨在提升开发者的编程效率和代码质量。该工具于2023年10月31日在云栖大会上正式发布,具备多种智能功能,支持多种主流编程语言。

主要功能

  • 行级/函数级实时续写:根据当前代码上下文实时生成代码建议,帮助开发者快速完成编码任务。
  • 自然语言生成代码:用户可以通过自然语言描述所需功能,工具会自动生成相应的代码,保持编码流程的连贯性。
  • 单元测试生成:支持根据多种测试框架(如JUnit、pytest等)自动生成单元测试,提高代码的可靠性。
  • 代码注释生成:一键生成方法注释及行间注释,节省时间并提升代码可读性。
  • 代码解释:能够自动识别选中代码的编程语言并提供解释,帮助开发者更好地理解代码逻辑。
  • 研发智能问答:基于海量研发文档和知识库,为开发者提供技术问题的解答。

适用场景

通义灵码特别针对阿里云的SDK/OpenAPI使用场景进行了优化,能够有效支持与阿里云服务的集成。此外,它还适用于各种开发环境,包括Visual Studio Code和JetBrains系列IDE(如IntelliJ IDEA、PyCharm等)。

版本与可用性

通义灵码提供多个版本,包括个人基础版、个人专业版、企业标准版和企业专属版。目前,个人基础版是免费的,使得更多开发者能够体验其强大的功能。

MarsCode

官网:https://www.marscode.cn/?utm_source=marscode_bing_sem_dm_pc_cpc_pinp_hx_1&utm_medium=bing_sem&utm_campaign=568833890&msclkid=a506c834bd3e11670ecaaf1fd468e8bc
文档:https://docs.marscode.cn/docs/introduction

MarsCode是一款由字节跳动推出的智能开发工具,基于其豆包大模型构建,旨在通过AI技术提升开发者的编程效率和代码质量。以下是MarsCode的详细介绍:

产品概述

MarsCode提供了两种主要形态:编程助手和云端集成开发环境(Cloud IDE)。它支持多种主流编程语言,包括Python、Java、JavaScript、C++等,能够满足不同开发者的需求。

主要功能

  • 智能代码生成:MarsCode能够根据用户输入的需求自动生成代码,极大地提高了开发效率。
  • 实时错误检测:在编码过程中,MarsCode会实时检测代码中的错误,并提供修复建议,帮助开发者减少调试时间。
  • 代码优化建议:通过静态分析,MarsCode可以识别代码中的潜在问题并提供优化方案,以提升代码的性能和可维护性。
  • 单元测试自动生成:该工具能够根据代码逻辑自动生成单元测试用例,确保代码的稳定性和可靠性。
  • 技术问答功能:开发者可以随时向MarsCode提问,从算法选择到架构设计等各个方面获取建议。

适用人群

MarsCode的目标受众包括软件开发者、编程爱好者以及技术团队。无论是新手还是资深程序员,都能从中受益,提升工作效率。

使用场景

  • 快速开发原型:在需要快速开发软件原型时,MarsCode能够加速开发进程,使开发者专注于核心功能的实现。
  • 大型项目中的代码质量提升:在复杂逻辑和大规模代码库的项目中,MarsCode可以通过其优化和Bug修复功能帮助团队保持代码质量。
  • 新技术探索与学习:对于希望学习新语言或框架的开发者,MarsCode提供即时的代码建议和技术指导。

安全性与隐私

MarsCode重视用户数据安全,不会存储用户的私人代码或信息。用户可以放心使用其功能而无需担心隐私泄露。

Continue

官网:https://www.continue.dev/
文档:https://docs.continue.dev/

Continue 是开源 AI 代码助手,支持 VS Code 和 JetBrains。

  • 聊天:在侧边栏中交流,以理解和迭代代码
  • 自动补全:在输入时接收内联代码建议
  • 编辑:无需离开当前文件即可修改代码
  • 操作:为常见用例建立快捷方式

GPT-pilot

官网及文档:https://github.com/Pythagora-io/gpt-pilot

GPT-Pilot是一款由Pythagora推出的先进AI开发工具,旨在帮助开发者更高效地构建应用程序。它不仅仅是一个代码自动完成工具,而是一个能够生成完整功能、进行调试和与用户互动的智能开发助手。以下是对GPT-Pilot的详细介绍:

产品概述

GPT-Pilot的目标是探索大型语言模型(LLM)在生成完全可用且适合生产环境的应用程序方面的潜力。根据其设计,AI可以编写高达95%的应用程序代码,剩余的5%则需要开发者的监督和干预。

主要功能

  • 智能代码生成:用户只需输入应用名称和描述,GPT-Pilot便会自动生成相应的代码。
  • 多代理协作:GPT-Pilot使用多个AI代理(如产品负责人、架构师、技术领导等)来模拟真实开发团队的工作流程。这些代理负责不同的任务,例如需求分析、技术选型和任务分配。
  • 调试与故障排除:当出现问题时,专门的调试代理会协助用户解决错误,确保应用程序的正常运行。
  • 交互式开发:开发者可以在整个过程中参与监督,提供反馈并修改代码,以确保最终产品符合需求。

工作流程

  1. 输入需求:用户提供应用程序的名称和描述。
  2. 需求澄清:产品负责人代理会提出问题以更好地理解用户需求。
  3. 技术架构:架构师代理确定所需技术,并检查环境配置。
  4. 任务分配:技术领导代理将开发过程分解为具体任务,并指派给开发者代理。
  5. 代码实现与审查:开发者代理根据任务描述生成代码,审查者代理会检查每个步骤,以确保质量。

适用场景

  • 快速原型开发:开发者可以快速创建应用原型,以验证概念和功能。
  • 自动化测试生成:支持测试驱动开发(TDD),自动生成测试用例以确保代码质量。
  • 技术建议与选择:为项目选择合适的技术栈和工具,提高项目成功率。

安全性与隐私

GPT-Pilot重视用户数据安全,不会存储用户的私人信息或代码。用户可以放心使用其功能,而无需担心数据泄露。

Melty

官网:https://github.com/meltylabs/melty
申请试用:https://docs.google.com/forms/d/e/1FAIpQLSc6uBe0ea26q7Iq0Co_q5fjW2nypUl8G_Is5M_6t8n7wZHuPA/viewform?pli=1

Melty是一款开源的AI代码编辑器,旨在通过智能化的编程辅助提升开发者的工作效率。由Charlie Holtz和Jackson de Campos创立,Melty获得了Y Combinator的支持,并在开发初期便展现出强大的功能。目前还在开发中,没有发布的版本,但是可以申请试用

产品概述

Melty被称为首个能够从终端到GitHub全面理解开发者需求的代码编辑器。它不仅能够协助编写高质量的生产级代码,还能实时学习和适应开发者的编码风格,提供个性化的建议和改进。

主要功能

  • 实时代码生成:Melty能够根据开发者的输入自动生成代码,帮助快速完成编码任务。
  • 全面集成:支持与编译器、终端、调试器及项目管理工具(如GitHub和Linear)的无缝集成,简化开发流程。
  • 代码重构与优化:可以重构代码,帮助开发者提升代码质量,减少手动干预。
  • 智能导航:支持浏览大型代码库,使得开发者能够轻松理解和管理复杂项目。
  • 自动提交信息生成:每次代码更改都会自动生成相应的提交信息,简化版本控制过程。

开发背景

Melty的创始团队在使用现有AI编程工具时感到困惑,频繁需要在不同工具间切换,这促使他们创建一个更高效、智能的解决方案。经过28天的快速开发,Melty能够自动编写约一半的代码,大幅提升了开发效率。

适用场景

  • 快速原型开发:适合需要快速实现想法或功能的项目。
  • 大型项目管理:帮助团队在复杂项目中保持高效和组织性。
  • 教育与学习:为新手程序员提供实时反馈和指导,加速学习过程。

社区与开放性

作为一款开源工具,Melty鼓励社区参与和贡献。其源代码可在GitHub上获取,为开发者提供了透明和可定制的使用体验。

Void

Void 致力于成为Cusor的开源替代工具。

官网:https://github.com/voideditor/void
申请试用:https://voideditor.com/email

智能体(LLM Agent) 资料汇总(持续更新)

文章会实时同步到我的公众号,有兴趣的童鞋扫码关注我的公众号噢:

智能体(LLM Agent)资料汇总

本文致力于收集整理所有LLM Agent相关的资料,共大家参考学习。

智能体概念

提示词工程

智能体概念

智能体编程框架

智能体编程实战

智能体低代码平台

智能体应用

面向智能体编程-新一代软件架构模式

文章会实时同步到我的公众号,有兴趣的童鞋扫码关注我的公众号噢:

面向智能体编程

我将在这篇文章里提出新的概念,面向智能体编程。深度学习的理论和算法不断地发展,从而促成了生成式大模型的出现,大语言模型相比于以往的特定领域的模型,具有更加智能,通用的能力,由于其在预训练过程中,学习了大量而广泛的知识,因此大语言模型在自然语言理解和处理上产生了革命性的发展。一定意义上,大语言模型能够理解人类的意图,进行一定的思考,推理和规划,同时也具有一定的创造能力。

通过这些能力,大模型可以执行更加复杂的任务,具有更高的自主能力。可以预见的是,大模型的出现,传统的数字软件将被重新定义和重构。将大模型作为大脑,接入到领域软件,使得软件在执行任务时具有高度的自主能力,同时赋予软件自然语言交互的能力,使得人类在使用软件时,更加简洁有效,符合人与人交流的习惯。

今天面向智能体编程应用而生。

到底什么是智能体?

智能体(Agent)是计算机科学和人工智能领域中的一个关键概念,指的是能够在一定环境下自主感知、决策并采取行动的系统或实体。智能体通常具备以下核心特征:

核心特征:

  1. 自主性(Autonomy)

    • 智能体能够自主地执行任务,基于自身的感知和知识做出决策,不依赖外部直接控制。
  2. 环境感知能力(Perception)

    • 智能体能够感知其周围环境,通过传感器、输入数据等途径收集环境信息,进而对这些信息进行分析和处理。
  3. 目标导向性(Goal-Oriented)

    • 智能体具有特定的目标或任务,通过行为和决策的执行,朝向目标前进。
  4. 适应性(Adaptivity)

    • 智能体能够根据环境变化调整自身行为,适应动态环境,做出合理的响应。
  5. 交互性(Interactivity)

    • 智能体可以与环境中的其他智能体或系统交互,包括合作、竞争、通信等。

智能体的类型:

  1. 简单智能体

    • 这些智能体通常基于规则或脚本运行,在特定条件下执行预定的动作。它们的决策能力较弱,适用于确定性环境。
  2. 复杂智能体

    • 这些智能体能够在不确定性环境中执行任务,并通过机器学习、推理等方法做出更高级的决策。它们具备更强的感知、学习和适应能力。
  3. 单体智能体 vs 多智能体系统(MAS)

    • 单体智能体:单个智能体独立运作。
    • 多智能体系统:多个智能体协作或竞争,彼此影响并共享信息,以达成共同目标或各自目标。

智能体的关键在于自主性和环境适应能力,使其能够在复杂系统中替代或协助人类完成任务。

大模型时代,对智能体新的理解

大模型时代的来临,使得对智能体进行了新的定义和理解,大模型在语言理解和生成方面表现出色,使用大模型作为智能体的大脑,使得智能体能够通过自然语言进行复杂任务的处理和人机交互。

大模型赋予智能体更强的推理与决策能力,大模型的预训练数据量巨大,涵盖了各种复杂任务和知识领域,使得智能体在面对不确定或复杂问题时,能够进行深度推理,生成合理的应对策略。

大模型智能体的经典定义

大语言模型(LLM)智能体,是一种利用大语言模型进行复杂任务执行的应用。这种智能体通过结合大语言模型与关键模块,如规划和记忆,来执行任务。构建这类智能体时,LLM充当着控制中心或“大脑”的角色,负责管理完成任务或响应用户请求所需的一系列操作。这种智能体的构建,需要依赖于规划、记忆以及工具使用等关键模块。

通常,一个大语言模型智能体框架包含以下核心部分:

  • 用户请求 – 表达用户的问题或请求
  • 智能体/大脑 – 作为协调者的智能体核心
  • 规划- 助于智能体为未来行动做规划
  • 记忆 – 管理智能体的历史行为和经验

通过这些组成部分的协同工作,大语言模型智能体能够处理从简单到复杂的各种请求,不仅能够提供直接的答案,还能解决需要深度分析和多步骤操作的问题。这种智能体的能力,使其在处理复杂信息查询、数据分析和可视化表示等方面具有巨大潜力。

为什么要面向智能体编程?

如果你看过电影《星际穿越》,你一定会对电影中的智能机器人TARS印象深刻,TARS的外形独特,类似于一个方形的金属盒子,由四个长条形模块组成,能够变形以适应不同的环境和任务。导演克里斯托弗·诺兰在设计TARS时,强调了机器人的功能性而非拟人化特征。TARS能够根据需要变形,例如在海浪中变成螺旋桨,或在陡坡上提供助力。TARS不仅具备物理操作能力,还能与主角进行不失幽默的交流,帮助解决关键问题,如通过摩斯码传递信息等。

开发类似于TARS的机器人一直是人类进行人工智能研究的理想。同样,开发更加智能,自主执行任务的软件也是软件工程师的理想,当大语言模型出现时,使得这一理想又更加近了一步。

传统软件是具有局限性的。传统编程基于静态逻辑和预定义规则,通常只适合处理明确、确定的任务。而在动态的现实世界中,环境往往充满了不确定性和复杂性,需求和状态可能不断变化。面对这种情况,传统编程模式难以适应。

随着人工智能的不断发展,重塑传统软件的需求成为必然,人机交互的方式也在不断发展和演进。面向智能体编程允许开发者设计具有环境感知能力和适应能力的系统,这些系统能够根据外部环境的变化调整行为,主动应对变化。例如,自动驾驶汽车中的智能体能够实时感知交通状况,并动态调整路线和驾驶行为。

传统程序更多的是通过输入指令执行固定流程,缺乏自主性。而面向智能体编程赋予系统自主决策能力,智能体可以根据外部感知和内部状态,自主选择如何完成目标任务。这种自主性特别适用于需要自主行动或复杂推理的场景,如机器人控制、金融交易、游戏AI等。

未来,数字软件系统将逐渐具有高度自主能力,人机交互将逐渐演化为通过自然语言输入,语音输入为主。因此未来所有领域的软件将会被重构和重新定义,面向智能体编程正是因此应用而生。

面向智能体编程和面向对象编程,面向过程编程有什么不同

面向对象编程和面向过程编程准确的说是两种构建软件过程中不同的编程模式,是代码语法和程序的组织方式,更加靠近底层的代码编写层面。

  • 面向对象编程

对象通过消息传递或方法调用相互交互。程序的执行是基于调用对象的方法,并通过返回结果来推进程序流程。面向对象的执行通常是同步的,程序员定义了对象的交互方式,系统按照这些定义的规则顺序执行。

  • 面向过程编程

程序的执行是顺序和线性的,按照从上到下的过程流控制。每个过程通常通过明确的调用顺序执行,完成特定的操作后返回结果。程序的控制流通常由条件语句、循环和函数调用控制。

  • 面向智能体编程

大模型智能体经典定义所述,大模型智能体包含智能体,工具,记忆,用户交互等基本元素,这些基本元素描述了智能体应用大致上需要包含的软件组件。准确的说面向智能体编程是一种架构模式,更加偏向于软件架构的组织方式。

总之在构建智能体软件的过程中,代码的组织方式仍然可以使用面向对象编程或者面向过程编程等方式。

提示词工程

提示词工程(Prompt Engineering)是一门专注于设计和优化提示词(prompts)的方法,以最大化大语言模型(如GPT-4等)的输出效果。提示词是与模型交互的输入文本,好的提示词可以引导模型生成准确、符合需求的内容。提示词工程在多个领域应用广泛,包括生成文字、编程协助、对话机器人设计、教育等。

同时使用提示词工程的相关方法,可以使大模型具有一定的推理,思考,规划,任务决策以及工具使用等相关能力,比如推理时可以使用思维链(Chain-of-Thought)提示词,使用反应式提示(ReAct Prompting)进行决策和规划等等。

我在文章《提示词工程技术图谱-prompt engineering》中列举了基本的提示词工程相关的技术图谱。

提示词工程与智能体编程

在面向智能体编程时,使用提示词工程的相关技术可以赋予智能体规划,思考,推理及调用工具的能力,可以说提示词工程是可以赋予智能体灵魂的技术,是面向智能体编程的核心部分。

  • 定义智能体的角色
    在智能体编程中,通过提示词工程可以设定智能体的角色和语境,使其以特定的方式呈现或响应信息。这在客服、教育、甚至创意写作等智能体应用中非常关键。比如,一个面向编程的智能体可以被设定为编程导师角色,通过提示词确保智能体在解答问题时语气专业且有指导性,从而带来更好的用户体验

  • 任务分解
    使用提示词工程,可以将复杂的任务拆解成相对较小粒度的任务集合,分解后的任务更具可实施性,这将使智能体更加容易解决复杂问题。

  • 工具使用
    使用工具是智能体的一项关键技能,只有通过工具,才能实现大模型和现实世界的交互,比如访问网络,查询数据库等等。通过提示词结构化的输入输出,程序员可以定义智能体使用的工具集,智能体可以根据用户的输入动态决策使用何种工具。

  • 决策和规划
    使用思维链(Chain-of-Thought)提示词及反应式提示词(ReAct)等技术可以赋予智能体自主决策和规划的能力,决策和规划是智能体的核心大脑部分,能够使智能体具有一定的自主性,比如自适应环境的变化,在不同的环境中使用不同的工具来完成任务。将复杂的任务分解成多个步骤,一步一执行,直到完成任务。

  • 自动反馈优化
    提示词工程还可以用于优化智能体编程中的反馈循环。通过设计提示词收集用户反馈或自动化测试结果,智能体可以自动分析这些反馈信息,并调整其输出和行为。这种反馈机制有助于持续优化智能体性能,提升其响应质量。

智能体应用的基本架构

上图提出了智能体应用的全栈分层架构示意图,描述了智能体应用的基本架构。

应用层(最上层,紫色区域)

  • 包括 UI界面语音交互设备手机APP 等用户交互界面。
  • 这一层是用户直接与智能体应用互动的入口,通过不同的设备和界面实现与智能体的通信。
  • 其他应用模块表示智能体可以集成到多个应用场景中,实现跨平台的服务。

接口层(橙色区域)

  • 该层作为应用层与智能体核心的中介,为智能体和应用层提供数据交换、请求管理等服务。
  • 负责接收用户的请求、传递给智能体,并将智能体的反馈返回给应用层。接口层的存在可以支持不同的协议和数据格式,使智能体更具兼容性。

智能体层(绿色区域)

  • 这一层是整个架构的核心,包含了执行任务、分析数据、生成响应的智能体。
  • 智能体使用大模型能力来处理请求并提供智能化的响应。它可以直接调用模型,完成自然语言处理、分析和生成等任务。
  • 智能体应用层可以根据业务场景,分为单智能体和多智能体。

私有化大模型部署层(浅蓝色区域)

  • 该层为智能体提供了可私有化部署的大模型能力,使企业或组织能够在自己的计算资源中运行和管理大模型。
  • 可以根据具体需求对模型进行调整和优化,同时确保数据的私密性和控制权。

硬件或云计算层(深蓝色区域)

  • 这是支持智能体运行的基础设施层,提供计算资源,可以是物理硬件或者云计算服务。
  • 为大模型的训练和推理提供算力支持,确保系统能够稳定运行,满足用户请求。

智能体管理层(左侧,深绿色区域)

  • 该模块负责智能体的管理,支持监控、更新、策略配置等功能,确保智能体的正常运行和优化。
  • 包括对智能体生命周期的管理,如模型的更新、任务的分配和故障排查等。

公有大模型层(右侧,深蓝色区域)

  • 这是外部提供的公共大模型,可以在需要时为智能体提供额外的模型支持。
  • 智能体在私有化部署大模型无法满足时,可以调用公有大模型,以获得更广泛的知识和功能支持。

写在最后

随着人工智能技术的发展,软件,作为数字信息化的基石,将变的越来越智能化,人类与数字世界的交互将会变的更加简单和拟人化,一切交互都可以通过自然语言的方式,甚至是表情和肢体语言等。面向智能体编程是新一代编程模式,使用面向智能体的编程模式,可以对当前所有传统数字化软件进行重构和重新定义,使得交互方式同时发生质的转变。这种变革,将大大提高人类和数字世界沟通的效率以及生产力,这一定是一场新的数字革命。

智能体实战之autogen:智能体生成shell脚本并执行

使用智能体生成脚本并执行

智能体如何使用工具,是研究智能体非常重要的一部分。通过使用脚本,可以赋予智能体使用Linux系统的各式各样的命令行工具来执行特定任务,本文提供非常简单的例子,使用autogen生成脚本并执行用户指定的任务。

智能体介绍

参考文章:什么是智能体

Autogen

AutoGen是一个开源编程框架,用于构建AI智能体并促进多个智能体之间的合作以解决任务。AutoGen旨在提供一个易于使用且灵活的框架,以加速智能体AI的开发和研究,类似于深度学习中的PyTorch。它提供的功能包括能够与其他智能体对话的智能体、支持LLM和工具使用、自治和人机协作工作流程以及多智能体对话模式。

主要功能

  • AutoGen使得基于多智能体对话构建下一代LLM应用程序变得轻松便捷。它简化了复杂LLM工作流程的协调、自动化和优化,最大化LLM模型的性能,并克服其弱点。
  • 它支持多种对话模式以应对复杂工作流程。通过可定制且可对话的智能体,开发人员可以使用AutoGen构建与对话自主性、智能体数量和智能体对话拓扑相关的各种对话模式。
  • 它提供了一系列具有不同复杂性的工作系统。这些系统涵盖了来自各种领域和复杂性的广泛应用,展示了AutoGen如何轻松支持多样的对话模式。

环境准备

  • Linux or Windows WSL
  • python 3.10+
  • 安装 anaconda

本文使用anaconda构建python虚拟环境:


#创建autogen的虚拟环境
conda create --name autogen python=3.11

#进入该虚拟环境
conda activate autogen

# 安装autogen
pip install autogen-agentchat~=0.2

导入相关的依赖库

import os
import tempfile

from autogen import ConversableAgent
from autogen.coding import LocalCommandLineCodeExecutor

构建系统提示词

使用系统提示词定义智能体的角色,指导行为,提供一定的背景信息,同时也可以约束智能体,当用户行为超出智能体能力边界时,提示用户。

以下提示词指导智能体通过生成脚本,来收集Linux系统的一些信息。该提示词为one-shot提示词。提供代码块的样例给大模型。

以下系统提示词将传递给代码生成智能体,指导代码生成智能体生成脚本代码。


script_executor_message = """You are shell script assistant, a expert of linux and shell script, and you will generate shell script and get information according to user's prompt.
Gnerate a script according user's requirments with below format:

    #```bash  此处因为显示格式的原因加了注释,实际使用时请删除#
    #!/bin/bash

    # query all files information in current directory
    ls -la

    #``` 此处因为显示格式的原因加了注释,实际使用时请删除#
Always thinking step by step to about users questions, make sure your answer is correct and helpful.
If user did not ask question about Linux system, then please response like:

Please ask me question about Linux system, I only could help you on that.

"""

创建和脚本执行器

代码执行器是autogen智能体的一个组件,在创建autogen智能体实例之前需要先初始化代码执行器,并作为参数传递给autogen智能体的实例,代码执行器主要用来执行代码。

# Create a temporary directory to store the code files.
temp_dir = tempfile.TemporaryDirectory()

# Create a local command line code executor.
script_executor = LocalCommandLineCodeExecutor(
    timeout=10,  # Timeout for each code execution in seconds.
    work_dir=temp_dir.name,  # Use the temporary directory to store the code files.
)

创建代码生成智能体实例

ConversableAgent class 是对智能体的抽象,autogen中使用该类来创建智能体实例。通常你需要提供一些参数,max_consecutive_auto_reply=1 配置智能体只能回复一次,system_message用来配置系统提示词。llm_config 用来配置大模型作为后端,我选择使用deepseek-chat模型,国产模型性价比非常高,api调用也没有太多限制。代码生成方面,deepseek已经非常优秀了。code_execution_config=False 配置关闭代码执行功能。human_input_mode="NEVER"配置智能体自动回复,不需要人的介入。

以下代码创建了一个负责生成脚本代码的智能体实例。

script_generate_agent = ConversableAgent(
    "code_writer_agent",
    max_consecutive_auto_reply=1,
    system_message=script_executor_message,
    llm_config={"config_list": [{"model": "deepseek-chat", "api_key": os.environ["OPENAI_API_KEY"], "base_url":"https://api.deepseek.com"}]},
    code_execution_config=False,  # Turn off code execution for this agent.
    human_input_mode="NEVER",
)

创建代码执行智能体

以下代码创建了代码执行的智能体实例,只负责解析和执行代码,因此该智能体不需要接入大模型,配置llm_config=False。code_execution_config={"executor": script_executor} 用来配置代码执行器。

# Create an agent with code executor configuration.
code_executor_agent = ConversableAgent(
    "code_executor_agent",
    max_consecutive_auto_reply=1,
    system_message=script_executor_message,
    llm_config=False,
    code_execution_config={"executor": script_executor},  # Use the local command line code executor.
    human_input_mode="NEVER", 
)

初始化任务

以下代码最终将会启动两个智能体,首先脚本生成智能体将根据输入信息生成相应的脚步,代码执行智能体接受脚本生成智能体的输出作为输入,解析脚本,并执行。

chat_result = code_executor_agent.initiate_chat(
    script_generate_agent,
    message="Get Linux OS information",
)

执行结果如下:

$ python simple_script_executor.py
flaml.automl is not available. Please install flaml[automl] to enable AutoML functionalities.
code_executor_agent (to code_writer_agent):

Get Linux OS information

--------------------------------------------------------------------------------
[autogen.oai.client: 10-07 11:47:55] {349} WARNING - Model deepseek-chat is not found. The cost will be 0. In your config_list, add field {"price" : [prompt_price_per_1k, completion_token_price_per_1k]} for customized pricing.
code_writer_agent (to code_executor_agent):

    #```bash 此处因为显示格式的原因加了注释,实际使用时请删除#
    #!/bin/bash

    # Get Linux OS information

    # Display the Linux distribution information
    echo "Linux Distribution Information:"
    lsb_release -a 2>/dev/null || cat /etc/*release 2>/dev/null || cat /etc/issue 2>/dev/null
    echo ""

    # Display kernel version
    echo "Kernel Version:"
    uname -r
    echo ""

    # Display system architecture
    echo "System Architecture:"
    uname -m
    echo ""

    # Display CPU information
    echo "CPU Information:"
    lscpu
    echo ""

    # Display memory information
    echo "Memory Information:"
    free -h
    echo ""

    # Display disk usage
    echo "Disk Usage:"
    df -h
    echo ""

    # Display network interfaces
    echo "Network Interfaces:"
    ip a
    echo ""

    # Display hostname
    echo "Hostname:"
    hostname
    echo ""

    # Display uptime
    echo "Uptime:"
    uptime
    echo ""
    #``` 此处因为显示格式的原因加了注释,实际使用时请删除#

This script will provide a comprehensive overview of your Linux system, including distribution information, kernel version, system architecture, CPU information, memory usage, disk usage, network interfaces, hostname, and uptime.

--------------------------------------------------------------------------------

>>>>>>>> EXECUTING CODE BLOCK (inferred language is bash)...
code_executor_agent (to code_writer_agent):

exitcode: 0 (execution succeeded)
Code output: Linux Distribution Information:
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.4 LTS
Release:        22.04
Codename:       jammy

Kernel Version:
5.15.153.1-microsoft-standard-WSL2

System Architecture:
x86_64

CPU Information:
Architecture:                       x86_64
CPU op-mode(s):                     32-bit, 64-bit
Address sizes:                      39 bits physical, 48 bits virtual
Byte Order:                         Little Endian
CPU(s):                             12
On-line CPU(s) list:                0-11
Vendor ID:                          GenuineIntel
Model name:                         12th Gen Intel(R) Core(TM) i5-12400
CPU family:                         6
Model:                              151
Thread(s) per core:                 2
Core(s) per socket:                 6
Socket(s):                          1
Stepping:                           2
BogoMIPS:                           4991.99
Flags:                              fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology tsc_reliable nonstop_tsc cpuid pni pclmulqdq vmx ssse3 fma cx16 pdcm sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow vnmi ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid rdseed adx smap clflushopt clwb sha_ni xsaveopt xsavec xgetbv1 xsaves avx_vnni umip waitpkg gfni vaes vpclmulqdq rdpid movdiri movdir64b fsrm md_clear serialize arch_lbr flush_l1d arch_capabilities
Virtualization:                     VT-x
Hypervisor vendor:                  Microsoft
Virtualization type:                full
L1d cache:                          288 KiB (6 instances)
L1i cache:                          192 KiB (6 instances)
L2 cache:                           7.5 MiB (6 instances)
L3 cache:                           18 MiB (1 instance)
Vulnerability Gather data sampling: Not affected
Vulnerability Itlb multihit:        Not affected
Vulnerability L1tf:                 Not affected
Vulnerability Mds:                  Not affected
Vulnerability Meltdown:             Not affected
Vulnerability Mmio stale data:      Not affected
Vulnerability Retbleed:             Mitigation; Enhanced IBRS
Vulnerability Spec rstack overflow: Not affected
Vulnerability Spec store bypass:    Mitigation; Speculative Store Bypass disabled via prctl and seccomp
Vulnerability Spectre v1:           Mitigation; usercopy/swapgs barriers and __user pointer sanitization
Vulnerability Spectre v2:           Mitigation; Enhanced IBRS, IBPB conditional, RSB filling, PBRSB-eIBRS SW sequence
Vulnerability Srbds:                Not affected
Vulnerability Tsx async abort:      Not affected

Memory Information:
               total        used        free      shared  buff/cache   available
Mem:            15Gi       695Mi        14Gi       3.0Mi       591Mi        14Gi
Swap:          4.0Gi          0B       4.0Gi

Disk Usage:
Filesystem      Size  Used Avail Use% Mounted on
none            7.8G     0  7.8G   0% /usr/lib/modules/5.15.153.1-microsoft-standard-WSL2
none            7.8G  4.0K  7.8G   1% /mnt/wsl
drivers         451G  282G  169G  63% /usr/lib/wsl/drivers
/dev/sdc        251G   24G  215G  10% /
none            7.8G   84K  7.8G   1% /mnt/wslg
none            7.8G     0  7.8G   0% /usr/lib/wsl/lib
rootfs          7.8G  2.2M  7.8G   1% /init
none            7.8G  780K  7.8G   1% /run
none            7.8G     0  7.8G   0% /run/lock
none            7.8G     0  7.8G   0% /run/shm
tmpfs           4.0M     0  4.0M   0% /sys/fs/cgroup
none            7.8G   76K  7.8G   1% /mnt/wslg/versions.txt
none            7.8G   76K  7.8G   1% /mnt/wslg/doc

Network Interfaces:
1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet 10.25.25.254/32 brd 10.25.25.254 scope global lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0:  mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:15:5d:dd:f0:b7 brd ff:ff:ff:ff:ff:ff
    inet 111.21.22.44/20 brd 111.21.22.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::215:5dff:fedd:f0b7/64 scope link
       valid_lft forever preferred_lft forever

Hostname:
PC-XXXXXXYY

Uptime:
 11:47:56 up 1 min,  1 user,  load average: 0.54, 0.16, 0.05

提示词工程-少样本提示词

少样本提示词(few-show-prompt)

少样本提示(Few-shot Prompting)是一种用于大语言模型(LLM)的技术,通过提供少量示例来引导模型生成更符合预期的输出。这种方法在处理复杂任务时相较于零样本提示(Zero-shot Prompting)表现更佳,有时候会出现事半功倍的效果,因为它为模型提供了上下文和具体的示例,有助于模型理解用户的需求。

定义与原理

少样本提示的核心在于通过给定一小部分示例,帮助模型在特定任务上进行学习和推理。与零样本提示不同,后者不提供任何示例,完全依赖模型的预训练知识。例如,在少样本提示中,可以提供一个新词的定义及其使用示例,以帮助模型理解如何在句子中正确使用该词[1][2][3]。

应用场景

少样本提示适用于多种场景,尤其是那些需要特定领域知识或复杂推理的任务。以下是一些典型应用:

  • 语言生成:通过提供语境和示例,改善文本生成的质量。
  • 情感分析:使用标记示例帮助模型识别文本中的情感倾向。
  • 特定领域任务:如法律、医学等领域,可以通过少量高质量示例来提高输出的准确性[3][4].

少样本或多样本提示词已经成为其他提示词工程的基础,比如思维链提示词就是通过少样本演变来的提示词工程技术,除了思维链提示词,其他提示词技术都涉及到提供示例来引导大模型输出更加准确可控的信息。

另外当我们使用提示词工程相关的技术应用到编程领域时,可以通过少样本提示词,精确的控制模型的输出,这样的话,程序就可以很容易的解析输出格式,增强软件的鲁棒性。

技巧与注意事项

在实施少样本提示时,有几个技巧可以提高效果:

  • 使用标签:在示例中添加标签可以帮助模型更好地理解任务要求,即使标签格式不统一也能有效提升性能[1][2]。
  • 多样性与质量:所提供示例的多样性和质量直接影响模型的输出效果。垃圾进则垃圾出,低质量的示例可能导致错误的结果[3][4]。
  • 思维链技术:结合思维链(Chain of Thought)提示,可以引导模型进行逻辑推理,从而提高复杂问题的回答准确性[4][5].

局限性

尽管少样本提示具有许多优点,但它也存在一些局限性:

  • 依赖于示例质量:如果提供的示例不够清晰或相关,可能会导致模型输出不准确或不相关的信息。
  • 过拟合风险:模型可能会过度依赖给定的示例,而无法泛化到新的、未见过的情况[2][3]。

总之,少样本提示是一种强大的工具,可以显著提升大语言模型在复杂任务中的表现,但成功实施这一技术需要精心设计和选择高质量的示例。

少样本提示词的一些实例:

  • JSON格式输出:
输入: 创建一个包含姓名和年龄的人员信息
输出: 
{
  "name": "张三",
  "age": 30
}

输入: 创建一个包含书名和作者的图书信息
输出: 
{
  "title": "三体",
  "author": "刘慈欣"
}

输入: 创建一个包含产品名称和价格的商品信息
输出:
  • 函数定义格式:
输入: 创建一个计算两数之和的Python函数
输出:
def add_numbers(a, b):
    return a + b

输入: 创建一个判断字符串是否为回文的Python函数
输出:
def is_palindrome(s):
    return s == s[::-1]

输入: 创建一个计算给定数字阶乘的Python函数
输出:
  • SQL查询格式:
输入: 从users表中选择所有用户的名字和邮箱
输出:
SELECT name, email FROM users;

输入: 从products表中选择价格高于100的所有产品
输出:
SELECT * FROM products WHERE price > 100;

输入: 从orders表中选择2023年1月1日之后的所有订单
输出:
  • HTML模板格式:
输入: 创建一个包含标题和段落的HTML结构
输出:
<div class="content">
  <h1>标题</h1>
  <p>这是一个段落。</p>
</div>

输入: 创建一个包含图片和描述的HTML结构
输出:
<figure>
  <img src="image.jpg" alt="描述">
  <figcaption>图片描述</figcaption>
</figure>

输入: 创建一个包含无序列表的HTML结构
输出:

这些例子展示了如何使用少样本提示来指导AI生成特定格式的代码或输出。通过提供一两个例子,AI可以学习并推断出所需的格式和结构。

参考文章

[1] https://www.sohu.com/a/788035576_120635785
[2] https://www.promptingguide.ai/zh/techniques/fewshot
[3] https://www.53ai.com/news/qianyanjishu/2024061397638.html
[4] https://learn.tishi.top/docs/advanced/few-shot-prompting/
[5] https://www.woshipm.com/share/6111304.html
[6] https://sspai.com/post/91879
[7] https://v2-ai.tutorial.hogwarts.ceshiren.com/ai/aigc/L2/tutorial/%E5%B0%91%E6%A0%B7%E6%9C%AC%E6%8F%90%E7%A4%BA/
[8] https://cloud.baidu.com/qianfandev/topic/267310
[9] https://www.promptingguide.ai/techniques/fewshot
[10] https://www.prompthub.us/blog/the-few-shot-prompting-guide

大语言模型时代,聊聊自然语言编程

大语言模型时代,聊聊自然语言编程

计算机及编程语言的发展历史,其实就是从机器语言发展到接近人的自然语言编程的发展过程,这种发展,从来没有停歇。可是过去所有从低级到高级的编程语言,都不是真正的自然语言编程,直到今天,大语言模型横空出世,使得达到这一目标,向前迈了一大步。

在计算机的早期阶段,人们主要通过机器语言与计算机进行沟通。最初的计算机如ENIAC,只能通过插拔电线和设置开关来进行编程。随着时间的推移,汇编语言出现了,它用一些简短的符号(助记符)代表机器指令,这在一定程度上简化了编程工作,人们可以通过简单的指令来控制计算机执行流程,按照人类预想的流程执行。可以汇编还是接近计算机的机器指令,需要编程人员对硬件,指令集有良好的掌握,汇编语言非常难以理解,普通人很难阅读。

到了1950年代,高级编程语言如FORTRAN、COBOL和LISP开始出现。与纯粹的机器代码相比,这些语言更接近人类的思维方式,但仍然是程序员们为计算机量身定制的“新语言”,需要学习和掌握特定的语法和逻辑结构。相比于汇编,这些编程语言容易学习,屏蔽了底层计算指令,程序员只需要关注到编程本身的任务。

进入1970年代,C语言的诞生进一步推动了编程的普及。C语言不仅功能强大,还因其可移植性成为编程世界中的“通用语言”。此后,Python、Java等更高层次的编程语言相继出现,随着它们语法的简化和功能的增强,编程的门槛逐渐降低,更多的人能够参与到编程世界中来。

然而,这些语言尽管更加简洁和直观,仍然要求使用者具备一定的编程思维和逻辑能力,离我们平常使用的自然语言还有相当的距离。

自然语言编程的概念由来已久,但真正的实现却受限于技术的发展。20世纪末和21世纪初,随着计算能力的提升和人工智能的进步,基于自然语言的编程逐渐成为可能。

早期的尝试主要集中在有限领域的自然语言处理(NLP)上,比如通过简单的命令行工具让计算机理解基本的语句。此时的自然语言编程更多是一种“增强”的脚本编程,依然要求使用者遵循特定的语言结构。

随着深度学习技术的发展,特别是大语言模型(如GPT系列)的出现,自然语言编程迎来了质的飞跃。这些模型能够处理复杂的语言任务,理解并生成符合人类表达习惯的语句。这意味着,人们可以用更接近自然语言的方式与计算机互动,甚至可以通过简单的描述生成完整的代码段。

今天,开发者已经可以通过像ChatGPT这样的模型,将自然语言直接转化为代码。这不仅降低了编程的难度,也打开了非程序员进入编程世界的大门。比如,你可以直接描述你想要实现的功能,AI会自动生成相关代码,极大地提升了开发效率。

未来,自然语言编程有望彻底改变我们与计算机的互动方式。编程可能不再是少数人的专利,而是人人都能掌握的一种技能。我们可能只需要用自然语言描述问题或需求,计算机就能自动生成解决方案。这种技术不仅能够简化编程过程,还能推动跨学科的创新,让更多领域的人士能够利用编程工具解决他们领域中的问题。

自然语言编程的发展不仅是技术的进步,更是人类对语言和思维方式的探索与重塑。随着大语言模型的不断进化,编程将变得更加普及和智能,最终实现人人皆能编程的愿景。

什么是自然语言编程?

自然语言编程的定义:

自然语言编程(Natural Language Programming, NLP)是一种编程范式,允许程序员使用自然语言(如英语,甚至是其他各种人类语言)编写代码,而不是使用传统的编程语言语法。这种方法旨在使编程更加直观和易于理解,从而降低编程的学习曲线。

自然语言编程的核心思想是让计算机能够理解和执行用自然语言表达的指令。这需要自然语言处理(NLP)技术来分析和解释人类语言,并将其转换为计算机可执行的形式。

自然语言编程的一些特点包括:

  • 使用接近人类语言的语法和词汇,而不是传统编程语言的严格语法规则
  • 允许使用更多的上下文和隐含信息,而不是显式指定每个细节
  • 支持更自然的交互方式,如问答、对话式编程等
  • 提供更人性化的错误提示和反馈

自然语言编程的实现方式:

  • 代码自动生成:用户通过自然语言描述想要实现的功能,编程工具或系统会自动生成相应的代码。例如,在描述一个计算任务时,系统会将描述转换为Python、JavaScript或其他语言的代码。

  • 编程辅助:自然语言编程也可以作为一种编程辅助工具,帮助程序员快速编写代码段或调试代码。例如,开发者可以用自然语言描述要实现的逻辑,系统提供相应的代码建议或直接生成代码。

  • 多语言支持:自然语言编程不局限于单一的自然语言,它可以支持多种语言,用户可以使用自己熟悉的语言与计算机互动。

  • 人机语音交互:自然语言编程的终极目标就是通过自然语言交互,实现计算机自主理解及执行相应的任务,在可见的未来,人类不需要额外的输入,就可以通过自然语言的交互,实现计算机自主执行任何任务。

大模型时代的自然语言编程技术

在大模型技术出现之前,编程始终是程序员的技术活,每一种语言都存在一定的学习曲线,尤其像C++这种成熟的面向对象语言,灵活的语法,以及非常复杂的规范和标准,成为C++语言的熟练工,可真不是件容易的事,这需要数年甚至数十年的积累和经验。据不完全统计,目前至少有超过700种编程语言,而这个数字还在不断增长。但是接近纯自然语言的编程语言至今还未出现。

如今,大语言模型的出现,可以预见的是正在改变计算机编程的游戏规则,大模型时代的自然语言编程技术代表着计算机与人类互动方式的一次重大变革。在大规模预训练语言模型(如GPT系列、BERT等)的推动下,计算机能够以更加智能和自然的方式理解和处理人类的自然语言描述。这一技术的发展极大地简化了编程过程,使得更多的人能够以自然语言的方式进行编程,降低了技术门槛,提升了开发效率。

大语言模型的核心优势在于:

  • 强大的理解能力:大语言模型可以理解复杂的自然语言描述,包括上下文、隐含意义和复杂的逻辑结构。这使得用户可以用接近日常交流的语言与计算机互动,而不需要掌握传统编程语言的语法和规则。
  • 多领域知识:这些模型不仅懂得编程语言,还拥有广泛的背景知识,涵盖多个领域。这使得它们能够生成与特定领域相关的代码,并且在复杂应用中提供有价值的帮助。
  • 记忆:大模型具有一定的记忆,能够根据交互的上下文背景和人进行交互,这和人类的交谈是相似的,因此大模型在编程领域可以模拟人的行为。

基于大语言模型进行自然语言编程的不同方法

提示词工程

提示词工程无疑是和大语言模型交互的重要技术,这种技术完全可以应用到编程领域。

  • 描述: 用户通过自然语言描述要执行的任务,并将该描述(prompt)传递给大语言模型。模型会根据提示生成相应的代码或直接执行操作。Prompt的设计至关重要,它需要足够明确和具体,以便模型理解用户的意图。
  • 应用场景: 代码生成(如自动生成Python脚本)、任务执行(如数据库查询)、问题回答等。
使用提示词生成代码

目前市面上几乎所有的通用大模型都支持prompt生成代码,比如ChatGPT,Claude, Gemini等,也包括一些开源大模型,例如llama, qianwen等等,另外还有一些专业模型专门针对编程领域,例如llama coder,deepseek coder等等。

使用这些大模型,你可以通过自然语言描述特定的需求,直接使用大模型生成期望的代码。

例如我使用以下提示词生成了一个检查密码强度的工具:

请扮演软件工程师的角色,您擅长分析需求、设计软件和编码,您能否帮助我按照以下步骤一步一步设计和实现密码强度检查器:
步骤 1:列出密码强度检查器的可能功能和要求。
步骤 2:设计此密码强度检查器的软件。
步骤 3:根据您的设计实现功能和要求。
请帮助一步一步完成。请使用Golang,生成命令行应用程序
请用中文书写。

讲该prompt输入至ChatGPT时,GPT可以帮我做简单的分析和设计,并生成相应的代码:


package main

import (
    "fmt"
    "unicode"
)

func main() {
    var password string
    fmt.Print("请输入密码: ")
    fmt.Scanln(&password)

    strength := checkPasswordStrength(password)
    fmt.Printf("密码强度评分: %d/10\n", strength)

    if strength < 7 {
        fmt.Println("建议:请使用更复杂的密码,包括大小写字母、数字和特殊字符。")
    } else {
        fmt.Println("密码强度良好。")
    }
}

func checkPasswordStrength(password string) int {
    score := 0

    // 长度检查
    if len(password) >= 8 {
        score += 2
    } else {
        fmt.Println("密码长度应至少为8个字符。")
    }

    // 字符种类检查
    var hasUpper, hasLower, hasDigit, hasSpecial bool
    for _, char := range password {
        switch {
        case unicode.IsUpper(char):
            hasUpper = true
        case unicode.IsLower(char):
            hasLower = true
        case unicode.IsDigit(char):
            hasDigit = true
        case unicode.IsPunct(char) || unicode.IsSymbol(char):
            hasSpecial = true
        }
    }

    if hasUpper {
        score += 2
    }
    if hasLower {
        score += 2
    }
    if hasDigit {
        score += 2
    }
    if hasSpecial {
        score += 2
    }

    return score
}
大模型智能体应用

基于提示词工程,不仅仅可以通过自然语言生成代码。大模型时代的应用,将基于智能体编程模式,开启智能应用时代。基于智能体模式,相比传统应用程序,智能应用的交互模式发生了革命性的变化,应用程序完全可以理解人的自然语言输入,智能应用程序将通过理解人的语言进行思考,并以一定的自主能力来执行复杂的任务。

因此,自然语言编程的范畴并不仅仅是通过自然语言来生成代码,广义含义也包含了使用自然语言直接执行任务。

同时智能体应用本身的程序也将不再完全由程序代码来构建的,程序的核心部分将基于提示词工程的自然语言部分,比如react提示词模式,和COT(chain-of-thought)模式。剩余的部分包括大模型的API,数据库交互,记忆模块,以及工具的使用,将使用传统的编程模式。基于prompt的编程将是自然语言编程的重要组成部分。

通过智能体应用,应用程序将会更加智能化,人机交互方式将会发生革命性的转变,任务和指令将通过自然语言的方式进行输入,程序的反馈也将更加人性,更符合人与人的交流方式。

辅助编程

辅助编程技术,实际上是编程IDE诞生以来,一直在发展的技术,在生成式模型出现之前,传统的辅助编程工具可以帮助程序员建立代码索引,通过联想,自动补全等功能帮助程序员更加快速的找到已有函数,接口,变量等,提示编程效率。

辅助编程技术通过生成模型技术,已经发生了革命性的转变。用户可以通过自然语言与大模型进行互动,逐步引导模型生成代码。用户可以实时修正或者调整模型生成的代码,以确保最终结果符合预期。

辅助编程工具一般都是基于编程IDE来实现的,比如当下著名的编程助手 Github Copilot,Cursor 等,程序员仅仅通过自然语言提示,就可以生成代码,测试及文档,大大的提高了编程效率。这些工具除了可以编程外,还可以帮助重构,调试代码。

代码翻译

由于专业的大模型熟悉不同编程语言的语法和语义,因此程序员可以用自然语言描述现有代码段的逻辑或意图,指示大模型将一种语言的代码片段,翻译成其他语言的代码片段,这种特性将在跨语言的代码迁移、旧代码重构、多语言项目的代码管理等领域得到重要的应用。

写在最后

自然语言编程将是我未来的一个主要研究方向,我相信未来,越来越多的人会使用自然语言方式进行编程,未来的应用程序也将更加智能,编程将不在是程序员的专利,更多的人将参与到数字化世界的构筑,使得这个世界更加丰富多彩。

参考文章:

https://arxiv.org/html/2405.06907v1
https://arxiv.org/abs/2405.06907
https://juejin.cn/post/7348648095015567412
https://www.yunwei37.com/2023/06/14/natual-language-program/

提示词工程-零样本提示词

零样本提示词

什么是零样本提示词

零样本提示词,顾名思义就是在人和大模型之间交互时,提示词中可以不使用任何样例,大模型只根据提示词中的指示以及预训练的固有知识生成内容或回答问题。

零样本提示词可以是一句话,一个问题,或者一条指令,但是如果期望大模型生成准确有效的信息,零样本提示词也需要遵循一定的结构,具体的信息可以参考另一篇文章:高效提示词的基本结构

假设你想使用一个语言模型来判断一段文本的情感是积极、消极还是中性。你可以向模型提出这样的问题:

“请对这段文本进行情感分类:‘我在海滩度过了一个很棒的一天!’它是积极的、消极的还是中性的?”

指令微调已经被证明可以提高零样本学习的效果(Wei et al., 2022)。指令微调本质上是指在通过指令描述的数据集上对模型进行微调。此外,RLHF(从人类反馈中进行强化学习)已被用于扩展指令微调,其中模型被调整以更好地符合人类偏好。这种最近的发展推动了像ChatGPT这样的模型的出现。我们将在接下来的章节中讨论所有这些方法。

当零样本不起作用时,建议在提示中提供演示或示例,这就是所谓的少样本提示。

零样本提示词的优缺点

优点:零样本提示在需要快速回答而无需准备示例时非常有用。它还有助于测试模型的一般语言理解能力。

缺点:与少样本或微调模型相比,零样本提示的准确度可能较低,尤其对于复杂任务或与训练数据差异很大的任务。

参考文章

Zero-shot and Few-shot prompting in LLMs
zeroshot
zeroshot prompting

提示词工程-高效提示词的基本结构

提示词工程-高效提示词的基本结构

自从生成式人工智能技术产生已来,提示词工程成为一种新的职业方向。提示词工程(Prompt Engineering)是一种在生成式人工智能(如GPT模型)中创建和优化提示词以获得期望输出的方法。

所谓的提示词,其实就是人和AI交互时的输入,可以是一个问题,一段描述性的指示,生成式AI可以根据你的指示或者问题,输出你期望的内容。

随着各个领域的工程师不断的实践和评估,实践经验发现,有效的机构化的提示词可以控制大模型输出的准确性和有效性,同时可以控制大模型输出的幻觉等。

提示词的基本结构

根据大家的经验,如果在写提示词时遵循如下的结构,可以提升和AI交互的效率:

  • 角色(role):交互时通过给AI大模型设定某种角色,根据经验可以获得意想不到的效果,可以使大模型的输出更加具有个性化,专业化,同时能够增加模型输出的准确性。比如如下的例子,指明AI大模型为一个通信专家,就是给当前交互的AI上下文设定了角色。

假设你是一名通讯专家。起草一封电子邮件给你的客户,告知他/她由于物流问题导致的交货时间延迟。

  • 指示/指令(task/instruction):指示或者指令,是指示AI大模型需要完成的任务,比如通过何种知识及技能,来完成何种任务。以下例子中指示或者指令为现在为一个黑客马拉松设计一个挑战性任务,涉及加密和解密。

假设你是一名软件工程师,正在设计一个涉及加密技术的黑客马拉松任务。任务设计应适合中高级开发者,且应在4小时内完成。请用五个步骤描述设计这个任务的过程,确保任务能够让参与者理解现代加密算法的核心原理。现在为一个黑客马拉松设计一个挑战性任务,涉及加密和解密。

  • 上下文(context):当你给出与任务相关的背景或细节时,可以帮助AI大模型更好的理解任务的具体情况,使得输出更加精确。以上示例中上下文部分为正在设计一个涉及加密技术的黑客马拉松任务
  • 输入或者问题:需要大模型执行具体的任务,或者具体的问题, 有时候如果指令部分描述的是具体的任务时,则指令部分就是输入。以上示例中指令部分就是输入部分:现在为一个黑客马拉松设计一个挑战性任务,涉及加密和解密
  • 约束:有时候需要限制AI大模型的输出范围,设定一些约束条件,可以对输出进行控制。以上示例中通过约束任务设计应适合中高级开发者,且应在4小时内完成来控制马拉松挑战的难度。
  • 输出格式:输出格式,主要给大模型指明,输出特定内容时的格式,比如输出为Json或者Markdown等。以上示例中请用五个步骤描述设计这个任务的过程指明了输出结构。
  • 例子:提供例子可以贡AI大模型进行参考,可以有效的提高输出的准确度,比如 few-shot prompt 就是提供一个或者多个例子,使得大模型的输出更加确定。

一些范例

以下是基于 角色+指令+上下文+输入问题+约束+例子 格式提供的几个提示词范例:

范例 1: 生成文章

角色: 你是一名资深环境学家。

指令: 我需要撰写一篇关于气候变化影响的文章,你可以作为我的咨询顾问。

上下文: 全球气温正在上升,极端天气事件变得更加频繁。政府和非政府组织正在采取措施应对这一问题。

输入问题: 气候变化如何影响不同地区的生态系统?政府可以采取哪些措施来减轻这些影响?

约束: 文章应包含三个部分:引言、影响分析、建议措施,总字数在500字左右。

例子: 引言可以描述气候变化的现状,然后分析不同地区生态系统的具体变化,最后提出可以采取的政策建议。


范例 2: 生成代码

角色: 你是一名Python开发者。

指令: 编写一个函数来排序学生的成绩。

上下文: 你正在开发一个学生成绩管理系统,需要能够对学生成绩进行排序,以便生成成绩单。

输入问题: 请编写一个Python函数,该函数接受一个包含学生姓名和成绩的字典,并按成绩从高到低排序。

约束: 函数应返回一个排序后的字典,并考虑成绩相同的学生按姓名字母顺序排序。

例子: sort_students({'Alice': 90, 'Bob': 85, 'Charlie': 90}) 应返回 {'Charlie': 90, 'Alice': 90, 'Bob': 85}


范例 3: 生成产品设计思路

角色: 你是一名用户体验设计师。

指令: 根据我的具体问题,帮助我设计一个新的移动应用的用户界面,旨在提高用户的日常习惯养成。

上下文: 现代用户越来越注重健康和效率,他们希望有一个工具可以帮助他们建立和维持良好的习惯。

输入问题: 如何设计一个易于使用且能激励用户的移动应用界面,以帮助他们每天坚持新习惯?

约束: 应用界面应简洁,包含进度追踪功能,且用户在3次点击内能完成主要操作。设计思路应包括界面草图和功能说明。

例子: 设计思路可以包含一个主页,展示用户的日常目标和进度条,点击进度条后弹出完成按钮,点击按钮后弹出激励语。


范例 4: 撰写故事

角色: 你是一名侦探小说作家。

指令: 帮助创作一段紧张的情节,描述侦探发现关键线索的过程。

上下文: 故事发生在一个封闭的庄园内,庄园主神秘失踪,侦探正深入调查此案。

输入问题: 侦探在调查庄园的书房时,意外发现了一个隐藏的密室,里面藏有庄园主失踪前留下的日记。

约束: 描述应突出侦探的推理过程和发现的细节,字数控制在300字以内。

例子: 可以描述侦探如何通过书架上的不寻常痕迹发现密室,并在日记中找到庄园主最后的遗言。


范例 5: 创建商业计划

角色: 你是一名创业顾问。

指令: 帮助制定一份初创企业的商业计划,侧重于市场分析和融资策略。

上下文: 一家专注于环保产品的初创公司希望进入市场并获得第一轮融资。

输入问题: 如何评估目标市场的潜力,并制定有效的融资策略来吸引投资者?

约束: 商业计划应包括市场分析、竞争对手分析、产品定位、融资目标和策略,总字数控制在1500字以内。

例子: 市场分析部分可以包括市场规模、增长率和用户画像,融资策略可以包括股权分配和投资回报预期。


这些范例展示了如何通过角色+指令+上下文+输入问题+约束+例子的结构来创建明确且有效的提示词。每个范例都针对特定的任务和输出需求进行了设计,以确保生成的内容符合预期。

参考文章:

一文读懂LLM参数设置,实现大模型应用的最佳性能

一文读懂LLM参数设置,实现大模型应用的最佳性能

引言

可以预见的是,通过生成模型,和通用模型,AI正在不断重塑整个数字化世界,在2024年我们看到LLM 应用像雨后春笋一样,基于LLM开发大模型应用已经逐渐成为程序员掌握的必备技能。

本文将重点介绍开发LLM 应用时,LLM基本参数的重要性,指导通过LLM 参数的设定可以提高应用的性能。

如何掌握temperature、top_p、max_length参数以实现最佳LLM表现?

在设计和测试LLM 应用的提示时,通常需要通过 API 与 LLM 进行交互。API可以配置一些参数以获得不同的提示结果。调整这些设置对于提高响应的可靠性和可取性非常重要,需要进行一些实验才能找出适合您用例的设置。以下文章内容将对不同LLM 之间常见的设置进行解释,并提供设置指导。

优化LLM性能的关键设置

温度

温度是一个控制模型输出随机性的基本设置。较低的温度通过偏向高概率标记使结果更具确定性,而较高的温度则引入更多变化性和创造性。

示例:
对于基于事实的任务(如回答问题或总结文本),较低的温度(如0.2)可确保简洁准确的回答。相比之下,对于创意写作任务(如诗歌生成或头脑风暴),较高的温度(如0.8)可以产生更多样化的输出。

要点

  • 较低温度 = 更确定性的回答
  • 较高温度 = 更具创意和多样性的回答
  • 根据任务要求调整

Top P(核采样)

Top P通过仅考虑构成生成每个标记的顶级累积概率质量的标记子集来控制回答的多样性。

示例:
较低的Top P值(如0.1)将输出限制为高概率标记,适合生成事实性内容。较高的Top P值(如0.9)允许输出更多样化,适合需要创意的任务。

要点

  • 低Top P = 自信精确的答案
  • 高Top P = 多样化和创意输出
  • 使用温度Top P,但不要同时使用两者

最大长度

最大长度定义了对提示的回应中生成的标记数量。

示例:
设置适当的最大长度可以防止过长或无关的回答,同时控制与标记使用相关的成本。

要点

  • 有效管理回答长度
  • 防止无关或冗长的输出
  • 通过控制标记使用优化成本

停止序列

停止序列是一个信号模型停止生成更多标记的字符串。

示例:
要生成不超过十个项目的列表,使用"11"作为停止序列,在列出十个项目后停止输出。

要点

  • 精确控制回答长度
  • 确保结构化输出
  • 使用针对特定任务定制的停止序列

频率惩罚 & 存在惩罚

两种惩罚都减少重复,但应用方式不同:

  • 频率惩罚:较高的值会抑制回答中重复的单词。
  • 存在惩罚:对所有重复的标记施加相等的惩罚,不考虑频率。

示例:
对于多样化的文本生成,使用较高的惩罚;对于聚焦的内容重复控制,根据需求相应调整。

要点

  • 频率惩罚按比例减少单词重复。
  • 存在惩罚平等地抑制任何重复短语。
  • 根据所需结果一次调整一个惩罚。

参考原文链接https://medium.com/@justmalhar/understanding-llm-settings-for-optimal-performance-83ee29c50392

思维链提示词工程(Chain-of-Thought Prompting)

思维链提示词工程

扩大大型语言模型(LLMs)的规模在情感分析和机器翻译方面已经显示出了良好的结果,即使没有提供任何示例。然而,它们在解决复杂的多步骤问题,如算术和常识推理方面却表现不佳。为了解决这个问题,LLMs可以针对特定任务进行微调,或者通过少量示例提示(few-shot prompting)来教授。然而,这两种方法都有其局限性。微调在创造高质量推理方面成本较高,而仅使用少量示例提示对于任务来说效果不够好。

思维链(Chain-of-Thought,简称CoT)提示可以同时解决这两个问题。在本文中,我们将探讨CoT提示以及如何实施它来提升您的业务技能。

什么是提示工程?

提示工程是一种编写结构良好、精心设计的提示的实践,这些提示能被生成性AI模型更好地理解。提示告诉大型语言模型(LLM)需要执行什么任务以及生成什么样的输出。它可以包含指令、上下文、输入数据和输出指标。通过使用提示工程,我们可以利用LLM来完成各种任务,从简单的问题回答到复杂的创意文本生成。它基于一种新兴属性——上下文学习,允许LLM从提示中学习。提示工程提高了LLM在手头任务上的表现。它使用了前文提到的零样本、少样本、主动和思维链提示等技术。

零样本提示

在零样本提示中,我们给大型语言模型(LLM)一个描述任务的提示,但这个提示本身并不提供任何任务的示例。然后,我们要求LLM针对这个提示生成一个回答。这种方法增强了LLM的灵活性和泛化能力。它可以用来在多个任务上训练LLM,而无需为每个任务收集训练数据。例如,ChatGPT可以在没有任何写诗示例的情况下,根据提示工程写出一首诗。然而,零样本提示在处理复杂任务时是有限的。

少样本提示

少样本提示可以通过提供示例来引导模型获得更好的表现。这是一种向大型语言模型提供少量期望输出示例的技术,除了主要提示之外还包括这些例子。这些示例帮助模型更好地理解任务,从而生成更准确、更有信息量的回答。我们应该向模型提供丰富多样的例子,而不是多个相似的例子。这样做可以确保模型尽可能多地学习关于任务的知识。标准的少样本提示对许多任务来说是一种不错的技术,但对于复杂的推理任务则不太可靠。因此,我们需要更高级的提示技术,比如思维链、主动提示和微调等。

主动提示

主动提示通过不断给予大型语言模型(LLM)反馈来提高它们在复杂任务上的表现。这种反馈可以帮助LLM从错误中学习,生成更准确、更有价值的回答。
主动提示的过程是这样的:首先给LLM一个提示和一些期望输出的例子。然后LLM生成一个回答。接着,人类评估者会评价这个回答,并就其准确性和信息量给出反馈。LLM再利用这些反馈来改进自己生成回答的能力。这个过程会不断重复,直到LLM能够生成足够准确和有价值的回答,让人类评估者满意为止。
主动提示对于思维链(CoT)提示特别重要,因为它可以:

  • 找出需要重点标注的问题
  • 减少人工标注的工作量
  • 提高CoT提示的准确性和信息量

下图展示了如何通过主动提示配合CoT来提升性能。这是一个包含四个阶段的过程:

  • 通过多次查询LLM来估计一个问题的不确定性
  • 通过排序选出最不确定的问题进行标注
  • 由人类评估者对这些问题进行详细反馈标注
  • 利用LLM生成答案,并使用标注阶段的反馈来提高新问题答案的质量

什么是思维链提示?

思维链提示是一种提示工程技术。通过这种技术,我们能让大型语言模型(LLM)输出一系列中间步骤,最终得出所需的答案。这种方法能提高LLM的推理能力。

思维链提示的好处有:

  • 让模型能专注于一次解决一个步骤,而不是一下子考虑整个问题。
  • 对于那些难以或无法一步解决的复杂问题特别有帮助。
  • 为我们提供了一个可解释的窗口,让我们能看到模型的行为。我们可以通过跟随模型采取的步骤序列,了解它是如何得出答案的。

总的来说,思维链提示让我们能更好地理解和控制LLM的思考过程,从而得到更准确、更可靠的结果。

思维链(CoT)提示可以用于参数量很大(大约1000亿个参数)的大型语言模型,适用于多种推理任务,包括数学应用题、常识推理和符号运算。

举个例子,在PaLM模型中使用CoT提示,而不是标准的少样本提示,显著提高了在GSM8K基准测试中的表现,
从17.9%提升到了58.1%。

有趣的是,对于足够大的语言模型来说,不需要特殊训练或微调,就可以轻松引出CoT推理过程。这个特点使得CoT提示成为一种可扩展且容易使用的技术。

简单来说,CoT提示就像是给模型一个"思考的框架",让它能像人类一样一步步推理,而不是直接给出答案。这种方法特别适合大型模型,因为它们有足够的"智力"来理解和执行这种复杂的思考过程。而且,因为不需要额外训练,任何人只要有权限使用这些大模型,就可以尝试CoT提示技术。

少样本思维链

少样本提示是指给大型语言模型(LLM)提供一个问题和答案。然后,再给LLM几个解决类似问题的例子。这些例子的呈现方式会鼓励LLM对问题进行思考,形成一条通向答案的思维链。

少样本思维链比普通的少样本基准更有效地提高了LLM的推理能力,因为它为LLM提供了类似问题的例子。不过,少样本思维链的实施可能会比普通少样本基准更复杂,因为它需要创建示例提示。

尽管如此,少样本思维链带来的好处还是超过了额外的复杂性。它让LLM不只是简单地回答问题,而是学会了如何思考和推理。这种方法可以让LLM处理更复杂的问题,给出更详细、更准确的答案。

简单来说,少样本思维链就像是给LLM提供了一些"解题思路"的例子,而不仅仅是答案。这样,LLM就能学会如何一步步地思考问题,而不是只会简单地背诵答案。虽然准备这些例子可能会多花些时间,但最终得到的结果会更好,更有价值。

零样本思维链

零样本思维链是指在原始提示中加入"让我们一步步思考"这句话。它通过两个步骤来提取推理过程和答案。

  • 推理提取:
    在这一步,语言模型思考问题,形成一条通向答案的推理链。我们给语言模型一个包含问题和触发句"让我们一步步思考"的提示。然后,语言模型会生成一个解释它如何得出答案的句子。

  • 答案提取:
    在第二步,我们从语言模型的回答中提取最终答案。我们把提示、生成的句子和一个触发句"答案是"连在一起。这告诉语言模型给我们答案。然后,语言模型会生成一个包含问题答案的句子。

相比之下,零样本基准使用"答案是"这样的提示来提取答案。而少样本提示,无论是标准的还是思维链的,通过设计以正确格式结尾的示例答案,避免了使用这种答案提取提示的需要。

研究人员比较了零样本思维链和其他两种评估大型语言模型零样本推理能力的方法。结果发现,在各种推理任务中,零样本思维链的表现优于其他方法。

如果你想找一个经过思维链提示训练的较小模型,可以考虑Flan-T5模型。它可以用于零样本自然语言处理任务,包括文本摘要、自然语言推理、翻译和常识推理。

思维链能力何时出现?

思维链推理是大型语言模型(LLM)的一种涌现能力,可能是由于模型参数超过1000亿而产生的。对于较小的LLM,思维链并不能提高性能,只有在使用这种规模的模型时才能带来性能提升。这有两个原因:

  • 较小的LLM无法生成既流畅又合乎逻辑的长思维链。这导致其表现不如标准提示。
  • 思维链推理对更复杂的问题更有效。它要求LLM能够识别解决问题的关键步骤,然后生成一连串思考过程,最终得出解决方案。较小的LLM可能无法像大型LLM那样有效地做到这一点。

大型LLM出现思维链推理能力的另一个原因可能与它们的预训练数据有关。大型LLM通常在包含逐步推理的海量数据集上训练,这可能有助于它们发展出以思维链方式推理的能力。

有趣的是,遵循指令的能力似乎并不是思维链能力所必需的。研究显示,使用未经过遵循指令微调的LLM,也能展现零样本和少样本思维链推理。不过,遵循指令的能力可能会提高思维链推理的质量。

如何进行思维链提示?

要进行思维链提示,你只需在提示的末尾加上"让我们一步步思考"这句话。这会迫使模型分步思考,将问题分解成更小的部分。下面是一个例子,展示了不使用和使用思维链提示的区别:

你可以看到,使用思维链让大型语言模型(LLM)给出了更好、更复杂且正确的输出。没有分步思考的提示立即导致了错误的答案。

如果你有一个非常严格的问题,你知道只能用特定的推理模式来解决,那就是你应该使用少样本思维链的时候。你可以提供一些针对你特定问题集所需的推理步骤的例子,然后LLM会尝试用类似的步骤来解决给定的问题。或者,你可以用这种技术为你的用户以特定方法解决问题。比如,如果学生要使用你的应用,你可能想用少样本思维链以有趣、简单且易懂的方式解决问题。

这些少样本例子应该展示中间步骤和最终解决方案。一旦你开发了思维链提示和例子,你就可以将它们整合到模型中。最后,测试模型并反复调整思维链提示和例子,直到模型的表现令人满意。

思维链提示的关键方面

在这部分,我们将探讨影响大型语言模型中思维链提示性能和可靠性的重要维度。我们将深入研究敏感性、自一致性、鲁棒性和连贯性如何在塑造思维链提示技术的有效性中发挥关键作用。

自一致性

自一致性是一种提高语言模型在需要多步推理任务上表现的技术。在思维链提示的背景下,自一致性可以通过为同一个问题采样多个不同的思维链来提高模型的性能。然后,模型可以被训练从这些思维链中选择最一致的答案。

自一致性显著提高了思维链提示在许多流行的算术和常识推理基准测试上的表现。例如,在GSM8K基准测试中,自一致性将思维链提示的性能提高了17.9%。在SVAMP基准测试中提高了11.0%,在AQuA基准测试中提高了12.2%。

这是一种完全无监督的技术,可以直接在预训练的语言模型上使用。它不需要额外的人工标注,也避免了任何其他训练、模型或微调。它对采样策略和参数具有鲁棒性。在PaLM-540B上改变温度采样中的T、top-k采样中的k和核采样策略中的p时,自一致性始终能提高性能。

鲁棒性

研究人员进行了三组不同的思维链标注实验,每组由不同的标注者完成。他们发现,无论是哪个标注者,思维链提示的表现始终优于标准基准。这表明思维链提示不依赖于特定的语言风格。

研究人员还进行了使用从GSM8K训练集随机抽样的样本的实验,这是一个独立的来源。他们发现,使用这些样本的思维链提示与使用手动编写的样本的思维链提示表现相当。这表明思维链提示不依赖于使用的具体样本。

研究人员还进行了使用不同数量样本的实验。他们发现思维链提示对不同数量的样本保持稳定。这表明思维链提示不需要大量样本就能有效。

研究人员还使用了各种语言模型进行实验,包括LaMDA 137B。他们发现思维链提示对所有这些语言模型都有效。这表明思维链提示不依赖于使用的特定语言模型。

总的来说,这些实验结果表明,思维链提示是一种可以提高语言模型在各种任务上表现的稳健技术。它不依赖于特定的语言风格、标注者、样本集或语言模型。

敏感性

思维链提示中的敏感性指的是提示的设计对模型性能的影响程度。如果提示设计不好,模型的性能可能会下降。提示应该清晰、简洁,易于模型理解。应避免使用模型可能不熟悉的行话或技术术语。提示应该与模型试图解决的特定任务相匹配。如果提示与任务不匹配,模型可能无法生成正确的答案。任务越复杂,模型对提示设计的敏感性可能越高。

当提示示例问题类型和任务问题类型不匹配时,少样本思维链的性能下降。这表明少样本思维链对提示的设计高度敏感,需要仔细将提示与特定任务匹配才能获得良好的性能。

连贯性

连贯性指的是思维链推理步骤的正确顺序程度。这意味着后面的步骤不应该是前面步骤的先决条件,前面的步骤也不应该基于后面的步骤。例如,在引入"32"或"42"之前出现"32 + 42 = 74"的推理就不具有连贯性。这是因为"32 + 42 = 74"这个等式是一个后面的步骤,依赖于引入数字"32"和"42"的前面步骤。

研究人员设计了一组消融设置,以检验连贯性对类似思维链推理不同组成部分的影响。消融设置是一种测试系统不同部分重要性的方法,通过移除它们并观察对系统性能的影响。研究发现,连贯性对类似思维链推理的所有组成部分都很重要。当移除连贯性时,系统的性能会下降。

研究人员还发现,语言模板的连贯性对思维链提示的性能特别重要。语言模板是用来连接思维链推理不同步骤的短语。如果语言模板不连贯,模型可能无法理解推理过程并生成正确的答案。

思维链提示的类型

在思维链(CoT)提示领域中,有两种显著的变体作为有影响力的策略:多模态CoT和从少到多提示。让我们详细探讨这些技术。

多模态CoT

传统的CoT专注于语言模态,这意味着它只使用文本为模型提供推理背景。多模态CoT将文本和视觉整合到一个两阶段框架中。

第一步涉及基于多模态信息的推理生成。这意味着模型同时接收文本和图像,然后被要求生成一个解释文本和图像如何相关的推理。

框架的第二阶段是答案推断。在这里,模型使用第一步生成的信息丰富的推理来推断出问题的正确答案。

1B多模态CoT的表现超过GPT-3.5 16个百分点(75.17%对91.68%的准确率),并在ScienceQA基准测试中超过了人类表现。在8个问题类别中,我们的模型将带配对图像的问题的表现从67.43%提高到88.80%。

像UnifiedQA和GPT-3.5这样的方法使用图像说明来理解图像显示的内容,然而,使用图像特征更有效。未来的研究可以通过使用更好的图像特征、添加常识知识和过滤掉无关信息来改进CoT推理。

从少到多提示

思维链提示是一种强大的自然语言推理技术,但在处理比提示中显示的例子更难的问题时可能会遇到困难。为了解决这个挑战,我们提出了一种新的提示策略,称为从少到多提示。

从少到多提示的工作原理是将一个复杂问题分解成一系列更简单的子问题,然后按顺序解决它们。每个子问题都由前面子问题的答案促进。

例如,要解决一个数学应用题,我们可能首先询问语言模型将问题分解成子问题,比如"第一件物品的成本是多少?"和"总成本是多少?"然后我们会询问语言模型依次解决子问题,使用前面子问题的答案来指导我们的查询。

从少到多提示在符号操作、组合泛化和数学推理任务上可以推广到更困难的问题。使用从少到多提示的GPT-3 code-davinci-002可以用14个示例解决SCAN,准确率达到99%,而思维链提示只能达到16%的准确率。

下表显示了不同提示方法在GSM8K和DROP基准测试中仅包含数值问题的子集上的准确率。基础语言模型是code-davinci-002。

下表显示了不同提示方法在最后字母连接任务上的准确率。

自动CoT

自动CoT是一种自动创建带有问题和推理链的演示的方法。它使用大型语言模型为每个演示生成推理链,使用"让我们一步步思考"的提示。自动CoT有两个主要步骤:

  1. 将给定数据集中的问题分成几个集群。
  2. 从每个组中选择一个代表性问题,并使用零样本CoT和简单的启发式方法生成推理链。

演示问题的多样性对于减少零样本CoT在推理链中的错误很重要。通过将问题聚类成几个组,自动CoT可以确保每个演示代表不同类型的问题。这有助于减少零样本CoT在推理链中犯错的机会。

自动CoT在10个推理任务上进行了测试,包括算术推理(MultiArith, GSM8K, AQUA-RAT, SVAMP)、常识推理(CSQA, StrategyQA)和符号推理(最后字母连接,硬币翻转)。在GPT-3中,自动CoT的表现始终与手动CoT相当或超过手动CoT。

这里是自动CoT与四种基线方法的比较:零样本、零样本CoT、少样本和手动CoT。

CoT的应用

CoT的应用涉及各种领域,包括算术、常识、符号推理、自然语言推理和问答。CoT提示为大型语言模型提供了解决这些领域复杂问题的能力。

算术推理

当与540B参数的语言模型一起使用时,思维链(CoT)提示在各种任务上的表现与针对特定任务微调的模型相当,包括算术推理。解决数学应用题对语言模型来说是一项具有挑战性的任务。

为了评估大型语言模型解决数学问题的能力,使用了两个基准测试:MultiArith和GSM8K。标准提示显示这些基准测试的扩展曲线相对平坦,这意味着增加模型大小并不会显著提高性能。然而,当使用CoT提示时,增加模型规模显著提高了性能,特别是对于大型模型。

PaLM(一个540B参数的语言模型)结合CoT提示,在GSM8K基准测试中达到了58%的最高性能。自一致性技术进一步提高了CoT提示的性能,在GSM8K上达到74%的准确率。CoT提示在数学应用题解决方面达到了最高水平,超过了微调的GPT-3基线。

常识推理

思维链提示也可以用于常识推理任务。这些任务需要基于一般知识对物理和人类互动进行推理。常识推理对当前的自然语言理解系统来说是具有挑战性的。

CoT提示在常识推理基准测试上进行了评估,如CommonsenseQA、StrategyQA、日期理解和体育理解。这些任务的性能通常随着模型规模的增加而提高。CoT提示比常规提示有小幅改进。CoT提示在提高体育理解任务的性能方面最为有效。

使用CoT的PaLM 540B在体育理解方面以95%对84%的分数超过了未经辅助的体育爱好者,在StrategyQA上以75.6%对69.4%的分数超过了先前的最高水平,在体育理解上以95.4%对84%的分数超过了先前的最高水平。但在CommonsenseQA(CSQA)上看到的改进很小。

符号推理

思维链提示使语言模型能够执行标准提示难以完成的符号推理任务。它还支持长度泛化,允许模型处理比少样本示例中看到的更长的推理时间输入。

在研究过程中,为了测试CoT提示,使用了两个玩具任务进行评估。第一个是最后字母连接,模型将名字中单词的最后字母连接起来。第二个是硬币翻转,模型确定在人们翻转硬币后,硬币是否仍然正面朝上。

使用域内和域外测试集来评估使用思维链提示(CoT)和标准提示的PaLM 540B在这两个任务上的表现。对于域内评估,示例的步骤数与训练/少样本示例相同。对于域外评估,示例的步骤数比示例中的多。

在域内评估中,使用CoT的PaLM 540B几乎达到100%的解决率。标准提示在域内和域外评估中都失败了。CoT提示导致性能提高,但低于域内评估。

问答

CoT提示通过将复杂问题或提示分解成一系列更简单的逻辑步骤来改进问答(QA)。这种方法帮助语言模型理解问题的结构和其组成部分之间的关系。每个步骤都专注于问题的一个特定方面,帮助模型更有效地识别相关信息。

CoT鼓励模型执行多跳推理,在这种推理中,它迭代地从不同来源或文档中收集和组合信息。这使模型能够执行改进的推理,并将单独的知识片段连接起来,得出准确的答案。

通过明确指定推理步骤,CoT提示可以帮助防止语言模型在回答复杂问题时可能引入的常见错误或偏见。此外,CoT提示允许用户理解模型是如何得出特定响应的。

思维链(CoT)与其他方法的比较

在这部分,我们深入比较思维链提示与其他方法,特别是标准提示和思维树提示。评估它们的优缺点可以为选择最适合你的业务应用的方法提供有价值的见解。

思维链vs标准提示

标准提示使用输入-输出对作为例子。这些对以问题和答案的形式呈现。模型根据这些对预测答案。它在有效处理多步推理任务方面有限制,但适合直接的任务,如单轮问答。它需要较少的计算资源。它通常使用单次提示进行训练,对于复杂任务往往需要更多数据来微调。标准提示可能不会随着模型规模的增加而显著提高性能。

而思维链提示涉及生成中间推理步骤。这些步骤在提供最终答案之前进行。它擅长复杂推理,使模型能够逐步思考。它versatile应用于广泛的需要复杂推理的任务。它需要对一系列提示进行训练,并有效利用数据进行多步推理。它在更大的模型上表现更好,因此需要更多的计算能力。它在复杂推理基准测试和需要多步问题解决的任务中表现出色。

MAWPS基准测试的比较:

长度泛化任务的比较:

对于直接的任务,你可以选择标准提示;对于需要深入、多步推理和可解释性的应用,思维链提示是更好的选择。GitHub上有一个与思维链推理相关的开源数据和工具库。它有各种任务的数据集,如数学问题和常识推理。它还有一个社区论坛供讨论。

思维链vs思维树提示

思维链遵循线性方法,每个新词或想法直接与前一个相连,形成一个链条。它代表了一种顺序的思维组织。

另一方面,思维树(ToT)采用层次方法。想法组织成树状结构,每个想法分支成多个相关想法。它代表了一种更复杂和分支的思维组织。

像GPT-3这样的思维链模型通常擅长在短跨度内生成连贯和与上下文相关的文本。像Transformer模型这样的思维树模型通常更擅长在更长的文本中保持连贯性,并且可以同时跟踪多个相关想法。

由于思维树的层次性,思维链模型在结构上更简单,计算强度也较低。此外,思维树引入了通过强化学习(RL)训练的"ToT控制器"概念。这个控制器可以潜在地从新数据或自我对弈中学习,允许思维树系统在固定语言模型的情况下进化和获取新知识。

思维链-SC(带有思维链的自一致性)使用简单的提示技术。它没有明确提到使用搜索算法。思维树采用广度优先搜索(BFS)和深度优先搜索(DFS)等搜索算法,以实现系统的思维探索。它将这些算法与树结构结合用于问题解决。因此,思维树的表现显著优于其他方法。

对于简单、较短的文本,你可以选择思维链;对于复杂、较长的文本和问题解决任务,思维树可能更合适。

本文翻译自该原文:
https://www.mercity.ai/blog-post/guide-to-chain-of-thought-prompting

提示词工程技术图谱-prompt engineering

提示词工程技术栈

提示词工程技术的不同方法和分类

无需大量训练的新任务(New Tasks Without Extensive Training)

  • 零样本提示(Zero-shot Prompting)
  • 少样本提示(Few-shot Prompting)
  • 连续链提示(Chain-of-Thought (CoT) Prompting)
  • 自动化连续链提示(Automatic Chain-of-Thought (Auto-CoT))
  • 自我一致性(Self-Consistency)
  • 逻辑链提示(Logical CoT (LogiCoT) Prompting)
  • 符号链提示(Chain-of-Symbol (CoS) Prompting)
  • 思维树提示(Tree-of-Thoughts (ToT) Prompting)
  • 思维图提示(Graph-of-Thought (GoT) Prompting)
  • 系统2注意力提示(System 2 Attention Prompting)
  • 思维线程提示(Thread of Thought (ThoT) Prompting)
  • 表格链提示(Chain of Table Prompting)

推理与逻辑(Reasoning and Logic)

  • 检索增强生成(Retrieval Augmented Generation (RAG))
  • 反应式提示(ReAct Prompting)
  • 验证链提示(Chain-of-Verification (CoVe) Prompting)
  • 注释链提示(Chain-of-Note (CoN) Prompting)
  • 知识链提示(Chain-of-Knowledge (CoK) Prompting)

减少幻觉(Reduce Hallucination)

  • 主动提示(Active-Prompt)

用户交互(User Interaction)

  • 自动提示工程师(Automatic Prompt Engineer (APE))
  • 自动化推理和工具使用(Automatic Reasoning and Tool-use (ART))

微调和优化(Fine-Tuning and Optimization)

– 对比连续链提示(Contrastive Chain-of-Thought Prompting (CCoT))

基于知识的推理和生成(Knowledge-Based Reasoning and Generation)

  • 情绪提示(Emotion Prompting)

提高一致性和连贯性(Improving Consistency and Coherence)

  • 抓取提示(Scratchpad Prompting)
  • 思维程序提示(Program of Thought (PoT) Prompting)

情绪和语气管理(Managing Emotions and Tone)

  • 程序化连续链提示(Structured Chain-of-Thought Prompting (SCoT))

代码生成和执行(Code Generation and Execution)

  • 代码链提示(Chain of Code (CoCo) Prompting)

优化和效率(Optimization and Efficiency)

  • 提示优化(Optimization by Prompting)

理解用户意图(Understanding User Intent)

  • 重述和响应提示(Rephrase and Respond Prompting)

元认知和自我反思(Metacognition and Self-Reflection)

  • 退一步思考提示(Take a Step Back Prompting)

图解云计算概念,数字时代基石

2024-06-23 14:09:00 星期日

什么是云计算?

云计算是一种基于互联网的计算方式,它提供共享的计算资源和数据,根据需求向计算机和其他设备提供服务。它是一种模式,可以实现对可配置计算资源(如计算机网络、服务器、存储、应用程序和服务)的无处不在、按需访问,这些资源可以快速进行配置和释放,管理工作量最小化。云计算和存储解决方案为用户和企业提供了在第三方数据中心存储和处理数据的各种能力,这些数据中心可能位于用户远距离的地方,从城市内到世界各地都有。云计算依赖于资源共享以实现一致性和规模经济,类似于电网覆盖电力网络的效果。 —维基百科。

传统计算到云计算的转变

从传统计算到云计算的转变是信息技术行业的一个重大变革,主要体现在以下几个方面:

  • 计算资源的交付模式发生转变
    传统计算模式下,组织需要购买服务器、存储设备等硬件设施,自行建设数据中心。而云计算允许用户按需获取所需的计算资源,并按使用量付费,无需购置昂贵的硬件设备。
  • 资源利用效率提高
    传统模式下,组织往往需要购买超出实际需求的硬件资源,以应对将来业务增长。而云计算可实现资源池化,通过虚拟化技术共享底层硬件资源,提高资源利用率。
  • 运维模式改变
    传统模式下,IT人员需要花费大量精力维护硬件设施、操作系统和应用程序。而云计算将大部分维护工作交给云服务提供商,用户可专注于自身业务创新。
  • 业务敏捷性增强
    传统架构下,组织扩展IT资源需要经历复杂的采购、部署流程。而云计算能够实现快速伸缩计算资源,显著提高业务响应速度。
  • 成本结构改变
    传统模式下,大部分IT支出为资本支出。而云计算则转变为按需付费的运营支出模式,降低前期投资压力。

云计算服务模型

云计算服务通常分为三种主要的服务模型:

  • 基础设施即服务(Infrastructure as a Service, IaaS)
    IaaS提供基础的IT资源,如虚拟化的计算、存储和网络资源。用户可自行部署操作系统、中间件和应用程序。典型的IaaS服务包括亚马逊AWS的EC2、Microsoft Azure的虚拟机等。
  • 平台即服务(Platform as a Service, PaaS)
    PaaS为开发者提供完整的应用程序开发生命周期管理,包括编程环境、数据库、Web服务器等。开发者只需关注应用程序本身的开发,而无需管理底层的基础架构。典型的PaaS有AWS Elastic Beanstalk、Microsoft Azure App Service等。
  • 软件即服务(Software as a Service, SaaS)
    SaaS是云计算中最高级别的服务,提供通过互联网访问的完整应用程序,无需在本地安装和运行。软件由服务提供商完全管理,用户只需通过Web浏览器或客户端访问。常见的SaaS应用包括Office 365、Salesforce、Google G Suite等。

云计算的基本分层架构

云计算的基本分层架构通常包括以下几个层次:

  • 硬件资源层(Hardware Resource Layer)
    这是云计算架构的基础设施层,由大量的物理服务器、存储设备和网络设备组成。这些硬件资源通过虚拟化技术可以被划分为多个资源池共享使用。
  • 虚拟化层(Virtualization Layer)
    通过虚拟化技术如虚拟机(VM)或容器将底层硬件资源虚拟化,形成可供灵活调度的资源池。虚拟化层对资源进行抽象,屏蔽掉底层硬件的物理特征。
  • 资源管理层(Resource Management Layer)
    负责对资源池中的虚拟化资源进行统一调度和管理,实现资源的动态分配和弹性伸缩。通常采用自动化的资源编排工具实现。
  • 平台层(Platform Layer)
    在虚拟资源之上,为开发者提供应用运行的平台环境,如操作系统、中间件、开发框架等。开发者可在此基础上部署和运行应用程序。
  • 应用层(Application Layer)
    最顶层是为用户提供的各种云应用和服务,可以是SaaS形式直接交付,也可以是PaaS或IaaS模式下的自建应用。

    – 管理层(Management Layer)

    贯穿整个分层架构的管理层,负责实现云资源的调配、访问控制、监控、计费等管理职能。

云计算的关键技术

云计算的实现依赖于几项关键技术,主要包括:

  • 虚拟化技术
    虚拟化是云计算的基础,它能将计算、存储、网络等物理资源对象化、池化,以软件定义的方式灵活分配和管理。虚拟机、容器是两种主要的虚拟化技术。
  • 资源调度与自动化
    要高效整合海量的虚拟化资源,需要自动化的资源调度与编排技术,实现资源按需分配、弹性伸缩、负载均衡等管理。常用的工具如Kubernetes、Mesos等。
  • 分布式存储技术
    为应对大规模数据存储需求,需要分布式存储系统将数据分散存储在多个节点上,提供高可靠、高扩展、高性能的存储服务,如HDFS、Ceph等。
  • 分布式计算技术
    针对大数据、高并发等计算需求,利用分布式计算框架如Hadoop、Spark在数据中心规模内并行处理任务,提高计算效率。
  • 网络虚拟化技术
    通过软件定义网络(SDN)、网络功能虚拟化(NFV)等技术,在同构硬件之上构建弹性灵活、可编程的虚拟网络架构。
  • 安全技术
    涉及身份认证、访问控制、数据加密、隔离安全等技术,确保多租户场景下的资源、数据、隐私安全。
  • DevOps
    融合开发(Dev)和运维(Ops)理念的一种文化和实践,通过自动化、持续集成等手段,加快应用交付和部署效率。

如何在运行时使用 CppUTest 注入模拟类

这是一个简单的指南,教您如何将模拟类注入产品代码中,并让您的产品类在 CppUTest 单元框架下可测试。

下图是类之间的关系。ProductClassB 依赖于 ProductClassA(ProductClassB 调用 ProductClassB.method() 中的 ProductClassA.method1()),现在当我们对 ProductClassB 进行单元测试时,应该模拟 ProductClassA。

下面的代码展示了如何使用 CppUTest 使用新方法来模拟依赖的类。

ProductClassA 有一些方法,如果您希望这些方法可以被模拟,则应将这些方法声明为虚拟方法。

ProductClassA.hpp:

#ifndef _INCLUDE_PRODUCT_A_CLASS_
#define _INCLUDE_PRODUCT_A_CLASS_
#include <string>

class ProductClassA {
public:
ProductClassA() {
}

~ProductClassA() {
}
public:
virtual int method1(const std::string& arg1);
virtual int method2(const std::string& arg1);
};

#endif

ProductClassA.cpp:

#include <iostream>
#include "ProductClassA.hpp"

int ProductClassA::method1(const std::string& arg1) {
std::cout << arg1 << " ProductClassA class method1" <<std::endl;
return 0;
}

int ProductClassA::method2(const std::string& arg1) {
std::cout << arg1 << " ProductClassA class method2" <<std::endl;
return 0;
}

如果你想在对 ProductClassB 进行单元测试时模拟依赖的类 ProductClassA,则应在 ProductClassB 中声明一个具有引用类型的私有 ProductClassA 变量,并且在 ProductClassB 中可以有两个构造函数,一个用于产品代码,一个用于单元测试代码,如下所示。

ProductClassB.hpp:

#include <string>
#include "ProductClassA.hpp"

class ProductClassB {
public:
// for unit test
ProductClassB(ProductClassA& ainstance): _ainstance(ainstance) {
}
// for product code
ProductClassB(): _ainstance(ProductClassA()) {
}
~ProductClassB() {
}

public:
int method();

private:
ProductClassA& _ainstance;
};

ProductClassB.cpp:

#include "ProductClassB.hpp"
#include <iostream>

int ProductClassB::method() {
std::cout<< "this is B class method"<<std::endl;
return this->_ainstance.method1("B invoke");
}

ProductClassAMock类是ProductClassA的派生类,其中的方法将以mock的方式重新实现。

ProductClassAMock.hpp:

#include "ProductClassA.hpp"

class ProductClassAMock : public ProductClassA
{
public:
virtual int method1(const std::string& arg1);
virtual int method2(const std::string& arg1);
};

ProductClassAMock.cpp:

#include "ProductClassAMock.hpp"

#include <iostream>
#include "CppUTest/TestHarness.h"
#include "CppUTestExt/MockSupport.h"

int ProductClassAMock::method1(const std::string& arg1) {
std::cout << arg1 << " ProductClassAMock method1"<<std::endl;
mock().actualCall("method1");
return 0;
}

int ProductClassAMock::method2(const std::string& arg1) {
mock().actualCall("method2");
return 0;
}

ProductClassB 的单元测试将使用测试构造函数在 bInstance 中用模拟类 ProductClassAMock 初始化 _ainstance,然后根据 C++ 多态机制,将 _ainstance.method1() 替换为类 ProductClassAMock 中的 method1。

ProductClassB_unittests.cpp:

#include "ProductClassB.hpp"
#include "ProductClassAMock.hpp"

#include "CppUTest/CommandLineTestRunner.h"
#include "CppUTest/TestHarness.h"
#include "CppUTestExt/MockSupport.h"

TEST_GROUP(BClassFooTests)
{
void teardown()
{
mock().clear();
}
};

TEST(BClassFooTests, MockAsExpected)
{
mock().expectOneCall("method1");
ProductClassAMock aMockInstance;
ProductClassB bInstance(aMockInstance);
bInstance.method();
mock().checkExpectations();
}

int main(int ac, char** av)
{
return CommandLineTestRunner::RunAllTests(ac, av);
}

产品代码只需使用ProductClassB的产品构造函数,bInstance._ainstance将使用真实的类ProductClassA进行初始化。

main.cpp:

#include "ProductClassB.hpp"

int main() {
ProductClassB bInstance();
bInstance.method();
return 0;
}

如何构建代码:

# build main
g++ ProductClassA.cpp ProductClassB.cpp main.cpp -o main

# build unit test
g++ ProductClassA.cpp ProductClassB.cpp ProductClassAMock.cpp ProductClassB_unittests.cpp -lstdc++ -lCppUTest -lCppUTestExt -o testrunner

参考:

深入解析Reflexion提示词模式

深入解析Reflexion提示词模式

摘要

本报告旨在对Reflexion提示词模式进行深入而全面的阐述。Reflexion是一种新颖的框架,通过语言反馈而非模型权重更新来强化语言智能体,使其能够通过自我反思和经验记忆来优化决策和行为。报告将详细介绍Reflexion的核心概念、工作原理、关键组件(Actor、Evaluator、Self-Reflection)、迭代自我纠正机制,并探讨其在复杂推理、编程和决策制定等任务中的显著优势。此外,报告还将Reflexion与Chain-of-Thought (CoT) 和 Tree of Thoughts (ToT) 等相关提示词技术进行比较,并分析其潜在的局限性与挑战。最后,报告将特别探讨Reflexion及其相关反思技术在缓解LLM幻觉问题上的贡献,并对未来的发展方向进行展望。

引言

大型语言模型(LLM)在理解和生成人类语言方面取得了突破性进展,其应用已广泛渗透到文本创作、机器翻译、智能问答等多个领域。然而,尽管能力强大,LLM在处理复杂逻辑推理、执行多步骤任务、避免生成不准确或虚构信息(即幻觉)以及实现持续自主学习方面,仍面临着固有的挑战。这些挑战限制了LLM在更复杂、更关键应用场景中的可靠性和效用。

在此背景下,提示词工程作为引导和优化LLM行为的关键手段,其重要性日益凸显。通过精心设计的指令和上下文,提示词工程能够有效提升模型输出的质量,并帮助模型克服上述挑战。Reflexion提示词模式正是在这一发展趋势下应运而生的一种创新方法。它独特地通过“语言反馈”机制而非传统的模型参数更新来增强LLM的自我改进能力 ,从而模拟人类从经验中学习并不断进步的过程。

本报告将对Reflexion提示词模式进行系统性、深入的剖析。报告将首先阐述其核心定义和基本原理,随后详细解析其内部的工作机制和关键组件。接着,将探讨Reflexion在实际应用中的显著优势和典型案例,并将其与现有主流的高级提示词技术(如Chain-of-Thought和Tree of Thoughts)进行对比分析。报告还将审视Reflexion当前面临的局限性与挑战,并特别关注其在减少LLM幻觉方面的潜在贡献。最终,报告将对Reflexion的未来发展方向进行展望,旨在为读者提供一个全面、深入且具有实践指导意义的Reflexion提示词模式视图。

Reflexion提示词模式概述

定义核心概念

Reflexion提示词模式,由Shinn等人于2023年提出,是一种新颖的框架,其核心在于通过语言反馈而非直接更新模型权重来强化语言智能体 。这一范式被其提出者描述为一种“口头强化”(verbal reinforcement)机制,它将智能体的策略参数化为记忆编码与LLM参数选择的结合 。

Reflexion的核心运作方式在于其独特的语言反馈机制。它能够将来自环境的反馈信号——这些信号可以是简单的标量值(例如,任务成功或失败的二进制指示),也可以是更具描述性的自由形式语言——转化为一种特殊的语言形式,即“自我反思” 。这种自我反思随后被作为额外的上下文信息,输入到LLM智能体中,以指导其在后续尝试中做出更优的决策 。

这种机制的设计理念与人类学习和改进的方式高度相似 。正如人类会反思过去的错误、总结经验教训并将其知识融入未来的决策以持续改进表现,Reflexion也赋予了智能体类似的能力。通过这种方式,智能体能够以更具解释性的方式理解其行为的成功与失败,从而实现自我引导的性能提升。

Reflexion与传统强化学习或模型微调方法的根本区别在于其不依赖于模型权重的更新。传统的强化学习通常需要通过梯度下降等方式修改模型参数,这往往伴随着高昂的计算成本和大量数据需求 。Reflexion则提供了一种轻量级且计算效率更高的替代方案,避免了昂贵的模型重新训练或微调过程 。这种不更新权重的语言强化范式,使得AI的改进不再局限于模型训练阶段,而可以延伸到推理和交互阶段,从而显著降低了计算成本和数据需求,使得AI系统能够更快速、更灵活地适应新情境和纠正错误。

背景与目的

Reflexion的提出背景源于对LLM自我纠正能力的需求以及对传统强化学习局限性的考量 。传统的LLM在处理需要多步骤规划、复杂逻辑推理或迭代修正的任务时,往往面临挑战,因为它们缺乏明确的结构化纠错机制或长期记忆来指导其行为 。标准提示词方法通常直接生成响应,缺乏分解任务或自我修正的能力,这使其在应对复杂推理或多步骤任务时表现不佳 。

Reflexion的设计灵感来源于人类的认知过程,特别是人类如何进行自我纠正和迭代学习 。正如人类在解决问题时,通常会先尝试一个初步方案,然后根据反馈(无论是内部的自我反思还是外部的评价)进行迭代修订,直到找到满意的解决方案,Reflexion也试图赋予LLM类似的学习和适应能力 。这种对人类认知模式的模仿不仅是设计理念上的优势,也间接提升了系统的可解释性。当LLM通过语言进行“自我反思”时,这些反思文本实际上构成了其学习过程的“可解释日志”,这与传统强化学习的黑箱特性形成鲜明对比。这种透明度对于AI的信任、调试和合规性至关重要,尤其是在高风险应用领域。

Reflexion的核心目的在于通过其独特的迭代自我评估和自我反思循环,显著提升语言智能体在各种复杂任务中的性能。这些任务包括但不限于顺序决策、复杂的编程问题和高级语言推理 。其性能提升的显著性体现在具体案例中:例如,Reflexion在HumanEval编码基准测试中取得了高达91%的pass@1准确率,这一成绩显著超越了此前最先进的GPT-4所实现的80%准确率 。这不仅证明了Reflexion在代码生成方面的强大能力,也确立了其在特定任务领域的领先地位。通过这种方式,Reflexion旨在使LLM能够持续演进和学习,应对复杂动态的现实世界挑战 。

工作原理与执行流程

Reflexion框架的强大之处在于其模块化设计和迭代循环,它由三个相互协作的独立模型组成,这些模型共同实现其迭代学习和自我纠正能力 。

核心组件:Actor, Evaluator, Self-Reflection

  • Actor (执行者):
    Actor是Reflexion智能体的“执行大脑”,其核心职责是根据从环境中获得的观察生成具体的文本输出并执行相应的动作 。在一次尝试中,Actor在环境中采取行动,并接收相应的观察结果。这一系列动作和观察共同构成了一个“轨迹”(trajectory),代表了智能体在本次尝试中的完整行为序列 。值得注意的是,Reflexion并非从零开始构建新的语言模型,而是巧妙地利用了现有先进的提示词技术。具体而言,Chain-of-Thought (CoT) 和 ReAct 等技术被用作Actor模型的基础,这表明Reflexion是建立在这些有效技术之上的高级扩展 。此外,Actor内部集成了一个记忆组件,用于存储和提供额外的上下文信息。这有助于智能体在生成动作和文本时,能够利用更丰富的背景知识,从而做出更明智的决策 。

  • Evaluator (评估者):
    Evaluator是Reflexion框架的“批判性思维”部分,其核心职责是对Actor生成的输出进行客观评分 。它接收Actor生成的完整轨迹(也称为短期记忆)作为输入,并基于预设的评估标准输出一个量化的奖励分数,以衡量其表现的优劣 。根据不同任务的性质,Evaluator可以采用多种奖励函数。这包括使用LLM自身进行判断性评估(例如,让LLM判断代码是否正确,或答案是否符合预期),或者采用基于规则的启发式方法进行决策评估,以确保评估的准确性和相关性 。

  • Self-Reflection (自我反思者):
    Self-Reflection模型是Reflexion框架的“学习和改进引擎”,其主要功能是生成口头形式的强化提示(verbal reinforcement cues),以帮助Actor进行自我改进 。这一关键角色通常由另一个LLM来承担,它负责分析过去的表现并提供有价值的反馈,指导未来的尝试 。为了确保生成的反馈具体且具有指导意义,自我反思模型会综合利用评估者提供的奖励信号、当前失败或成功的轨迹细节以及其持久性记忆(长期记忆)中的历史经验 。这些存储的经验被智能体高效利用,以快速改进决策,避免重复过去的错误 。

Reflexion的模块化设计不仅提高了框架的清晰度,更重要的是赋予了其高度的可插拔性和灵活性。这意味着开发者可以根据具体任务的需求,选择或替换不同的LLM作为Actor、Evaluator或Self-Reflection模块,甚至可以为Evaluator设计特定的规则启发式函数 。例如,在金融领域,Evaluator可以集成特定的合规性检查规则。这种灵活性使得Reflexion能够适应广泛的应用场景,并且可以随着LLM技术的发展而轻松升级其内部组件,而无需重新设计整个框架。这种组件级的创新和优化,使得Reflexion成为一个面向未来的、可演进的AI架构。

迭代与自我纠正机制

Reflexion过程的关键步骤形成了一个紧密的迭代循环,使智能体能够持续地从经验中学习、适应并优化其行为 。这一循环是Reflexion实现自我纠正的基石。

整个过程可分解为以下五个核心步骤:

  • 定义任务 (Define a task):整个过程的起点是明确且精确地定义智能体需要完成的具体任务和目标 。清晰、无歧义的任务定义是有效评估和反思的前提,它为智能体的后续行为设定了方向。

  • 生成轨迹 (Generate a trajectory):在任务定义之后,Actor模型开始工作,在环境中生成一系列动作和相应的观察结果,从而形成一个完整的“轨迹”或尝试序列 。这个轨迹记录了智能体在一次尝试中的所有相关行为和环境反馈。

  • 评估 (Evaluate):紧接着,Evaluator模型介入,对Actor生成的轨迹进行分析和评分。它根据预设的成功标准(例如,代码是否通过测试,决策是否达到目标),为该轨迹提供一个量化的奖励信号,以衡量其表现的优劣 。

  • 执行反思 (Perform reflection):这是Reflexion模式最独特和关键的步骤。Self-Reflection模型接收来自Evaluator的奖励信号、当前轨迹的详细信息(包括成功或失败的原因)以及其长期记忆中的相关历史数据。基于这些信息,它生成详细的语言反馈,明确指出本次尝试中的错误、不足之处以及潜在的改进方向 。反思的触发器可以是错误、意外结果或需要重新评估的“中断” 。反思行为包括重新思考、质疑或修改想法以响应LLM反馈 。反思内容示例包括调整初始想法、响应意外结果、提出更新的问题解决结构、细化LLM提示词以获得精确需求描述、通过复制粘贴错误提醒触发LLM调试,以及向LLM寻求程序或代码解释 。

  • 生成下一轨迹 (Generate the next trajectory):最后,智能体将上一步生成的自我反思作为新的上下文信息,融入到下一次尝试的输入中。智能体利用这些反思来指导其生成新的轨迹,旨在纠正过去尝试中的错误,并以更优化的策略来解决任务 。

这个迭代循环使得Reflexion智能体能够持续地从经验中学习、适应并优化其行为 。Reflexion通过引入明确的自我评估、自我反思和记忆组件,对ReAct框架进行了显著扩展 。这使得Reflexion智能体不仅能像ReAct那样进行推理和行动,还能在此基础上进行深层次的自我纠正和持续改进,从而在复杂任务中表现出更强的适应性和鲁棒性。

Reflexion对“自由形式语言”反馈和“内部模拟”反馈的支持,意味着它能够处理比简单数值更丰富、更具语义的反馈信息 。这种细致入微的语言反馈允许智能体更深入地理解其错误,并进行更有针对性的改进 。例如,一个编程任务的反馈不仅仅是“通过/失败”,还可以是“你的代码在处理边界条件时存在逻辑错误,考虑使用循环优化性能”。这种高质量的诊断性反馈是实现高效自我纠正的关键,也反映了其对人类学习过程的深层模拟,即人类从具体、详细的指导中学习效果最佳。

优势与应用场景

关键优势

Reflexion提示词模式凭借其独特的机制,展现出多方面的显著优势,使其在复杂任务中表现卓越:

  • 从试错中高效学习: Reflexion的核心优势在于其能够使智能体通过反思过去的错误,并将这些宝贵的经验知识融入到未来的决策中,从而实现性能的持续改进。这使得Reflexion特别适合那些需要通过反复试验和错误修正来逐步收敛到解决方案的任务,例如复杂问题的调试或多步骤决策序列的优化 。

  • 轻量级替代方案: 相较于需要大量训练数据和昂贵计算资源进行模型微调的传统强化学习方法,Reflexion提供了一种显著更轻量级且高效的替代方案。它无需对底层语言模型进行微调,而是通过上下文学习和语言反馈进行强化,从而在数据收集和计算资源消耗方面都更为经济和高效 。这对于资源有限的团队或需要快速部署和迭代的场景具有重要意义。

  • 细致入微的语言反馈: Reflexion利用其独特的口头反馈机制,这种反馈比传统RL中常用的简单标量奖励(如0或1)更为细致和具体。这种丰富的语言反馈使得智能体能够更深入、更精确地理解其错误所在,例如具体的逻辑缺陷或不当的行动选择,从而在后续尝试中做出更有针对性的改进 。这种高质量的诊断性反馈是其实现高性能的根本原因,它将LLM的自我修正能力从粗粒度提升到细粒度。

  • 可解释和显式记忆: Reflexion提供了一种比传统RL方法更具可解释性且显式的事件记忆形式。智能体的自我反思过程被清晰地记录并存储在其记忆中,这极大地便利了对智能体学习过程的分析和理解 。这种透明度对于调试、审计和建立用户信任至关重要,因为它允许开发者审查模型的“思维过程”,而非仅仅依赖黑箱输出。

  • 迭代优化与持续演进: 通过定义任务、生成轨迹、评估、反思和生成下一轨迹的紧密迭代过程,Reflexion智能体能够持续地优化其行为,以解决各种复杂任务 。这种内在的适应性使得Reflexion支持的AI智能体能够持续演进和学习,从而更有效地应对复杂动态的现实世界挑战 。这种跨领域的高效性表明Reflexion不仅仅是一个针对特定任务的优化,而是一种通用的问题解决范式。其核心机制——生成、评估、反馈、再生成——可以抽象应用于任何可以明确定义“任务”、“输出”、“成功标准”和“错误诊断”的领域。这预示着Reflexion可能成为未来构建更通用、更自主的AI智能体的基础架构之一。

典型应用案例

Reflexion模式已在多个复杂领域展现出卓越的性能,证明了其作为通用问题解决框架的强大潜力:

  • 顺序决策 (Sequential Decision-Making):
    Reflexion智能体在诸如AlfWorld等顺序决策任务中表现出显著的性能改进 。这类任务通常要求智能体在复杂的环境中进行导航,并完成一系列相互依赖的多步骤目标,智能体需要连续做出决策才能最终达成目标 。在AlfWorld任务的评估中,结合了ReAct的Reflexion(ReAct + Reflexion)显著优于单独使用ReAct的方法,成功完成了134个任务中的130个,充分展示了其在复杂决策链中的卓越能力 。

  • 推理 (Reasoning):
    Reflexion显著提高了智能体在HotPotQA等推理任务上的性能 。HotPotQA是一个需要智能体对多篇文档进行深入推理和信息综合才能得出答案的问答数据集,这要求高度的逻辑分析和信息整合能力 。在仅进行推理的场景中,Reflexion与Chain-of-Thought (CoT) 结合(Reflexion + CoT)以及在添加了最近轨迹的事件记忆后,均优于单独使用CoT和带有事件记忆的CoT基线模型 。

  • 编程 (Programming):
    Reflexion智能体在HumanEval和MBPP等代码生成基准测试中展现出编写高质量代码的强大能力 。在这些编程任务中,Reflexion在某些情况下取得了最先进的成果,通常优于Python和Rust代码编写的现有最先进方法 。一个突出例子是,Reflexion在HumanEval上达到了91%的pass@1准确率,这一成就超越了此前GPT-4的80% ,凸显了其在代码生成和纠错方面的强大实力。

  • 其他潜在应用:
    Reflexion的迭代精炼特性使其适用于多种需要高精度和质量控制的场景。这包括:精炼敏感信息传递,确保输出的准确性和恰当性;对AI输出进行压力测试以发现潜在问题和漏洞;以及对初步想法进行综合和改进,从而提升创意和解决方案的质量 。

与相关提示词技术的比较

Reflexion提示词模式并非孤立存在,它与当前LLM领域内其他先进的提示词技术存在紧密的联系和显著的区别。理解这些关系有助于更全面地把握Reflexion的独特价值和适用场景。

与思维链 (CoT) 的关系

Chain-of-Thought (CoT) 提示词是一种通过引导LLM生成一系列详细的、分步的推理过程来解决复杂问题的方法 。它模仿人类的逐步思考过程,从而显著提高LLM在复杂任务(如算术、常识推理和符号问题解决)中的准确性,并增强其推理过程的透明度和可靠性,有助于调试 。

在Reflexion框架中,CoT并非被取代,而是被巧妙地整合并用作Actor模型的一部分 。这意味着Reflexion将CoT作为其基础推理和行动的构建块,在其之上叠加了更高级的自我纠正和学习机制。实验结果有力地表明,Reflexion与CoT结合(Reflexion + CoT)在推理任务中显著优于单独使用CoT或仅带有事件记忆的CoT 。这清晰地证明了Reflexion的自我反思和记忆组件能够进一步增强CoT的内在推理能力,使其在复杂问题解决中表现出更强大的鲁棒性和准确性。这表明Reflexion不是一个独立的、与CoT/ReAct并列的提示词技术,而是一个更高层次的“元框架”或“元学习”机制。它利用CoT和ReAct提供的基础推理和行动能力,并在此之上添加了一个智能体能够“学习如何改进自身表现”的循环。

与 ReAct 框架的扩展

ReAct (Reasoning and Acting) 框架是一种结合了推理(Reasoning)和行动(Acting)的提示词技术。它允许LLM在生成响应的同时,通过观察环境并采取行动来动态规划和交互,从而解决需要外部工具或多步骤交互的任务。

Reflexion被明确设计为对ReAct框架的扩展。它通过引入三个关键组件——明确的自我评估(Self-Evaluation)、自我反思(Self-Reflection)和记忆(Memory)——来增强ReAct的能力 。这使得ReAct智能体不仅能推理和行动,还能从其行动结果中学习并改进。在顺序决策任务(如AlfWorld)的评估中,结合了Reflexion的ReAct(ReAct + Reflexion)显著优于单独的ReAct基线模型,成功完成了绝大多数任务(134个任务中的130个)。这突出显示了Reflexion在ReAct基础上增加的迭代自我改进层在提升智能体决策能力方面的有效性。

与思维树 (ToT) 的异同

Tree of Thoughts (ToT) 是一种更高级的框架,它概括了CoT提示词,旨在解决需要广泛探索或战略性前瞻的复杂任务 。ToT通过维护一个“思维树”来实现这一点,其中每个“思维”都是解决问题过程中的一个连贯的语言序列中间步骤。ToT允许LLM通过深思熟虑的推理过程自我评估通过中间思维取得的进展,并结合搜索算法(如深度优先搜索DFS/广度优先搜索BFS)进行前瞻和回溯 。

尽管Reflexion和ToT都旨在解决复杂问题并超越简单的CoT,但它们在核心机制和策略上存在显著差异:

共同点:

  • 模拟人类认知: Reflexion和ToT都旨在模拟人类的认知策略,以增强LLM的推理和问题解决能力。Reflexion模仿人类的迭代学习和自我纠正 ,而ToT则模拟人类在解决复杂问题时探索多种可能解决方案的树状思考方式 。

  • 迭代与自我评估: 两者都涉及某种形式的迭代过程和对中间步骤的自我评估,以指导后续的生成或决策 。

  • 超越简单CoT: 两者都旨在超越简单的线性CoT推理,以处理更具挑战性的、需要更深层次思考和规划的任务 。

不同点:

  • 探索策略: ToT的核心在于“探索”和“战略性前瞻”,通过生成和评估多个分支路径以及利用搜索算法来探索多种潜在解决方案 。而Reflexion则更侧重于对单一轨迹的“迭代精炼”和“自我纠正”,通过语言反馈优化当前路径,使其在每次尝试中变得更好 。

  • 反馈机制: Reflexion主要依赖于将环境反馈转化为语言形式的自我反思,这种反馈通常是关于特定尝试的成功或失败 。ToT则通过对不同思维路径的自我评估和剪枝来实现进步,其反馈更侧重于路径的可行性和有效性 。

  • 学习机制: Reflexion通过“语言强化”避免权重更新,使其成为一种轻量级的、无需微调的改进方法 。而ToT的一些高级变体(如Long (2023) 提出的ToT Controller)可以通过强化学习进行训练,即使LLM固定也能持续学习新知识 。这表明ToT可以结合更深层次的训练机制,以实现更长期的、数据驱动的演进。

  • 复杂性: ToT框架通常涉及更复杂的搜索算法和状态管理,需要对思维树进行遍历和剪枝 。而Reflexion的迭代循环相对更直接,但其内部反思过程也可能涉及复杂的语言生成和分析。

ToT与Reflexion代表了两种不同的高级问题解决范式。ToT更像一个“规划者”或“探索者”,在问题空间中寻找最佳路径,适用于需要发散性思维和多方案比较的开放式问题(如创意生成、复杂规划)。而Reflexion更像一个“迭代优化器”或“自我调试器”,专注于改进当前的解决方案,适用于有明确成功标准、需要精确和高效迭代改进的问题(如代码调试、特定决策序列、客服机器人优化)。这种差异决定了它们在不同类型任务中的适用性,也暗示了未来可能出现融合两者优势的混合框架。

局限性与挑战

尽管Reflexion提示词模式展现出显著的优势和广阔的应用前景,但在实际部署和进一步发展中,它也面临着一些不容忽视的局限性与挑战。

对自我评估能力的依赖

Reflexion的有效性高度依赖于智能体自身准确评估其性能并生成有用自我反思的能力 。如果智能体无法正确识别自身错误,或者其评估不够精确,那么后续的迭代改进将无从谈起。对于高度复杂或开放式的任务而言,LLM进行准确的自我评估尤其具有挑战性 。这些任务可能没有明确的对错标准,或者错误模式过于隐蔽,使得LLM难以进行有效的自我诊断。

LLM能否有效纠正错误,其首要前提是能否检测到错误,而这正是整个自我纠正过程中的一个关键瓶颈 。研究表明,LLM在检测自身错误方面可能存在困难,尤其是在答案不明显或需要获取中间反馈的情况下 。此外,LLM可能表现出一种“自我偏见”(或“自恋”),即它们倾向于偏爱自己生成的输出,即使这些输出并非客观上更好 。这种偏见在优化过程中可能加剧,导致文本措辞改善但答案质量并未实质性提高 。这揭示了一个核心矛盾:Reflexion的力量源于其自我评估,但其最大的脆弱性也恰恰在于这种评估的内在局限性。如果LLM无法准确识别错误,或者其自我评估被“自恋”偏见所扭曲,那么迭代循环可能只是在“优化”一个次优或错误的解决方案,而非真正纠正它。尽管存在这些挑战,但随着LLM模型架构和训练数据的不断进步,预计其自我评估能力也将随之增强,从而逐步缓解这一局限性 。

长期记忆的限制

Reflexion在目前的实现中,通常使用具有最大容量的“滑动窗口”机制来管理其长期记忆 。这意味着只有最近的少量历史经验能够被智能体直接访问和利用。对于需要长时间上下文依赖或涉及大量历史信息的复杂任务而言,这种方法可能不足以存储和利用所有必要的历史经验,从而限制了智能体的学习能力和决策质量。

记忆容量和管理方式直接影响Reflexion处理长期依赖和复杂任务的能力。滑动窗口的局限性意味着智能体可能无法记住足够远的过去错误或成功经验来指导当前决策,尤其是在需要多轮复杂交互的任务中。报告建议,对于更复杂的任务,使用更高级的结构,如向量嵌入或SQL数据库,可能更有利于管理长期记忆 。引入外部数据库或向量记忆不仅增加了记忆容量,更重要的是,它允许更高效的检索和更复杂的记忆组织(如语义搜索),从而使智能体能够访问和利用更丰富、更相关的历史经验,这对于其在真实世界复杂场景中的可扩展性和鲁棒性至关重要。

特定任务的挑战

Reflexion在特定任务领域也面临着独特的挑战:

  • 代码生成限制: 在代码生成任务中,Reflexion面临与测试驱动开发相关的限制。例如,对于非确定性生成函数或其输出受硬件影响的函数,很难指定准确的输入-输出映射,这会影响自我纠正的精确性 。这意味着在这些场景下,自动化的评估和反思可能无法提供足够清晰的信号来指导模型改进。

  • 开放式任务的挑战: 对于生成开放式对话、创意写作或科学发现等任务,很难定义什么是“错误”并提供客观反馈 。在这些领域,缺乏明确的成功标准使得自我纠正的应用变得困难。目前,LLM的自我纠正主要集中在有明确答案或可量化评估的任务上 。

泛化性与误差检测

除了上述挑战,Reflexion作为一种自我纠正机制,也面临着一些普遍存在于LLM自我修正中的问题:

  • 自我偏见 (Self-Bias): LLM可能表现出“自我偏见”(或“自恋”),即它们倾向于偏爱自己生成的输出,即使这些输出并非客观上更好 。这种偏见在优化过程中可能加剧,导致文本措辞改善但答案质量并未实质性提高 。这强调了未来研究需要关注如何提高LLM的“元认知”能力,即它们如何判断自己的知识状态和输出质量,可能需要结合外部验证机制或更强大的内部一致性检查来缓解这一问题。

  • 次优提示与泛化性: 一些研究显示LLM纠正错误的成功案例使用了简单或次优的提示,导致结果容易改进,但这些有利结果可能不具泛化性,意味着LLM只能在非常具体的任务上进行自我纠正 。这提示我们,Reflexion的成功可能在一定程度上依赖于任务的特性,而非普遍适用于所有场景。

  • 反馈准确性: 自我纠正最困难的部分是获取非常准确的反馈,特别是中间反馈 。在复杂的多步骤任务中,仅仅知道最终结果的对错不足以指导有效的纠正,智能体需要知道在哪一步出了问题,以及具体原因。

减少幻觉的贡献

LLM的幻觉问题,即模型生成看似合理但事实上不准确或虚构的信息,是其在实际应用中面临的重大挑战。Reflexion及其相关的反思机制,通过其内在的自我纠正和验证循环,为缓解这一问题提供了重要的途径。

反思机制如何缓解幻觉

Reflexion通过其反馈循环和迭代自我纠正机制,使模型能够反思过去的输出并学习错误,从而间接有助于减少幻觉 。虽然没有直接声明Reflexion“减少幻觉”,但其“学习错误”和“提高准确性”的能力与减少幻觉的努力是高度一致的 。幻觉通常源于模型内部知识的不确定性或推理错误。Reflexion通过强制模型“停下来,思考,检查”其输出,并根据反馈进行调整,实际上是在其输出管道中引入了一个动态的、基于语言的“质量门”。这种内部验证和修正机制,虽然与外部知识检索(RAG)不同,但同样能提升输出的可靠性和事实一致性,因为它迫使模型对自己的“思考”负责。

Reflexion被认为通过纳入一种质量控制形式来帮助减少幻觉 。通过迭代地批判或改进自身答案,模型成为自己的编辑,重新审视逻辑、语气或清晰度并进行相应修正 。这种自我编辑过程有助于识别和修正不一致或不准确的陈述。此外,提示词驱动的自我精炼和反思方法,通过多步生成和基于置信度的答案重排,在事实一致性方面显示出模型无关的增益 。这表明反思机制能够提升模型输出的内在连贯性和事实准确性。

相关反思技术的应用

除了Reflexion本身,更广泛的“反思技术”也为幻觉缓解提供了多种策略,其中一些与Reflexion的核心思想相通:

  • 自我一致性反思 (Self-Consistency Reflection):这种技术涉及生成多个候选响应以回答同一查询。其核心思想是,虽然幻觉可能因不同的生成尝试而异,但事实正确的信息往往在多次生成中保持一致。通过识别并优先处理这些在不同尝试中保持一致的事实性声明,可以有效降低幻觉的风险 。

  • 事实核查反思 (Fact-Checking Reflection):这种方法提示模型在生成响应后立即验证其自身声明的事实准确性和置信度。模型首先生成初步响应,然后进入事实核查阶段,最后修订响应以移除或限定不确定的声明 。这为模型提供了一个内部的验证循环。

  • 对抗性自我批判 (Adversarial Self-Critique):这种方法将反思推向更深层次,提示模型采取怀疑态度,主动识别自身输出中潜在的幻觉。模型生成初步响应后,会尝试以“对抗性思维”挑战可疑声明,用具体反驳进行质询,并最终生成修订后的响应 。尽管计算密集,但在受控研究中显示出显著的幻觉率降低。

  • 结合外部知识检索的反思 (External Knowledge Retrieval with Reflection):这种技术将外部知识检索整合到反思过程中,允许模型根据权威来源验证声明,而非仅依赖其内部的参数化知识。模型首先检索相关文档,然后利用这些上下文生成初步答案,接着反思答案与检索信息的对齐程度,并最终精炼答案以消除未经验证的声明 。这显著提高了输出的事实基础。

  • 反思安全层 (Reflection Security Layer):这是一个概念性的架构,所有输出在呈现给用户前都通过专门的验证层。该系统根据置信度分数、引用验证和已知错误类型模式匹配来标记潜在幻觉,特别适用于医疗、金融和法律等高风险领域 。

尽管这些反思技术在缓解幻觉方面表现出色,但也存在挑战,例如计算开销的增加。一个更深层次的挑战是可能出现“元幻觉”(meta-hallucinations),即模型在反思过程中本身产生幻觉 。这是一个关键的观察,它揭示了AI自我纠正机制并非完美无缺,甚至可能在“纠正”的过程中引入新的错误。这表明,虽然反思机制提供了强大的自我改进能力,但其鲁棒性仍需进一步研究。未来的工作不仅要关注如何让LLM更好地反思,还要关注如何确保“反思本身”是可靠和准确的,可能需要引入独立的、更客观的验证机制来监控反思过程的质量。

结论与展望

总结Reflexion的关键贡献

Reflexion提示词模式代表了大型语言模型自我改进范式的一次重要创新。它通过语言反馈而非传统的模型权重更新来强化LLM,在复杂任务中展现出卓越的性能提升,尤其是在代码生成、语言推理和顺序决策方面 。其模块化的Actor-Evaluator-Self-Reflection架构,以及紧密的迭代自我纠正循环,使得智能体能够高效地从试错中学习,并提供可解释的记忆路径 。Reflexion并非取代Chain-of-Thought (CoT) 或 ReAct 等现有技术,而是通过引入明确的自我评估、自我反思和记忆组件,对其进行了有效的扩展 。这使得LLM智能体从简单的执行者向具备自主学习和适应能力的学习者迈进,体现了其作为一种元学习框架的潜力。此外,Reflexion及其相关的反思技术在缓解LLM幻觉问题上也展现出积极作用,通过内部的质量控制和迭代验证,提升了输出的事实一致性和可靠性 。

展望未来的发展方向和潜在研究领域

Reflexion提示词模式为LLM的自我改进和复杂问题解决开辟了新的道路,但其发展仍处于早期阶段,未来有诸多值得深入探索的方向:

  • 增强自我评估能力: 当前Reflexion的有效性高度依赖于智能体准确评估自身错误的能力,而这对于复杂任务仍是挑战 。未来的研究应聚焦于如何提高LLM的“元认知”能力,使其能够更精确地识别自身知识边界和输出缺陷,可能需要结合更先进的元学习技术或引入外部验证信号来校准其自我评估。

  • 优化长期记忆管理: Reflexion目前使用的滑动窗口记忆机制在处理长期依赖或需要大量历史经验的任务时存在局限 。探索和实现更高效、可扩展的长期记忆结构,如高级向量数据库、知识图谱或混合记忆系统,将是关键。这将使智能体能够访问和利用更丰富、更相关的历史经验,从而支持更复杂、多轮次的任务。

  • 缓解“元幻觉”: 反思过程中模型自身产生幻觉的“元幻觉”问题是一个深层次的挑战 。未来的研究应开发新的检测和缓解策略,确保反思过程本身的可靠性和准确性,可能需要引入独立的、更客观的验证机制来监控反思过程的质量。

  • Reflexion与其他高级技术的融合: 深入研究Reflexion与Tree of Thoughts (ToT) 、多智能体系统、检索增强生成(RAG)等其他高级提示词和架构的协同效应,以构建更强大、更通用的AI智能体。例如,Reflexion可以为ToT的搜索和剪枝过程提供更精细的反馈,或者与RAG结合以增强事实基础。

  • 更广泛的应用探索: 将Reflexion应用于更多开放式、需要创造性和复杂交互的领域,如开放域对话、科学发现、艺术创作等,并探索其在这些领域中的泛化能力和局限性。这将推动Reflexion从结构化任务向更广阔的非结构化领域扩展。

  • 理论基础的深化: 进一步探索Reflexion与人类认知科学、学习理论之间的深层联系,例如其与人类批判性思维、经验学习循环的对应关系 。这将为AI的自我改进机制提供更坚实的理论基础,并可能启发更多仿生智能体的设计。

Reflexion提示词模式的出现,标志着LLM在迈向真正智能和自主学习的道路上迈出了重要一步。通过持续的研究和创新,Reflexion有望在未来AI系统的设计和部署中发挥越来越核心的作用。

本文系本站原创文章,著作版权属于作者,未经允许不得转载,如需转载或引用请注明出处或者联系作者。