10|代理(中):AgentExecutor究竟是怎样驱动模型和工具完成任务的?

news2024/11/16 9:41:50

LangChain 中的“代理”和“链”的差异究竟是什么?
在链中,一系列操作被硬编码(在代码中)。在代理中,语言模型被用作推理引 擎来确定要采取哪些操作以及按什么顺序执行这些操作。

Agent 的关键组件

  1. 代理(Agent):这个类决定下一步执行什么操作。它由一个语言模型和一个提示 (prompt)驱动。提示可能包含代理的性格(也就是给它分配角色,让它以特定方式进行 响应)、任务的背景(用于给它提供更多任务类型的上下文)以及用于激发更好推理能力的 提示策略(例如 ReAct)。LangChain 中包含很多种不同类型的代理。
  2. 工具(Tools):工具是代理调用的函数。这里有两个重要的考虑因素:一是让代理能访问 到正确的工具,二是以最有帮助的方式描述这些工具。
  3. 工具包(Toolkits):工具包是一组用于完成特定目标的彼此相关的工具,每个工具包中包 含多个工具。 比如 LangChain 的 Office365 工具包中就包含连接 Outlook、读取邮件列表、发送邮件等一系列工具。
  4. 代理执行器(AgentExecutor):代理执行器是代理的运行环境,它调用代理并执行代理 选择的操作。执行器也负责处理多种复杂情况,包括处理代理选择了不存在的工具的情况、 处理工具出错的情况、处理代理产生的无法解析成工具调用的输出的情况,以及在代理决策 和工具调用进行观察和日志记录。

深挖 AgentExcutor 的运行机制

llm = OpenAI(temperature=0) # 大语言模型
tools = load_tools(["serpapi", "llm-math"], llm=llm) # 工具-搜索和数学运算
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True) # 代理
agent.run("目前市场上玫瑰花的平均价格是多少?如果我在此基础上加价15%卖出,应该如何定价?") # 运行代理

上面的代码很简单,但是我们需要弄清楚2个问题:

  1. 代理每次给大模型的具体提示是什么样子的?能够让模型给出下一步的行动指南,这个提示
    的秘密何在?
  2. 代理执行器是如何按照 ReAct 框架来调用模型,接收模型的输出,并根据这个输出来调用
    工具,然后又根据工具的返回结果生成新的提示的。

开始 Debug

在 agent.run 这个语句设置一个断点, 直到我们进入了 agent.py 文件的 AgentExecutor 类的内部方法 _take_next_step
你可以看到 self.agent.plan 方法被调用,这是计划开始之处
image.png

第一轮思考:模型决定搜索

深入 self.agent.plan 方法 ,这个 Plan 的具体细节是由 Agent 类的 Plan 方法来完成的,你可以看到,输入的问题将会被传递给 llm_chain,然后接 收 llm_chain 调用大模型的返回结果
image.png

0: StringPromptValue(text='Answer the following questions as best you can. You have access to the following tools:\n\nSearch: A search engine. Useful for when you need to answer questions about current events. Input should be a search query.\nCalculator: Useful for when you need to answer questions about math.\n\nUse the following format:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction: the action to take, should be one of [Search, Calculator]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\nBegin!\n\nQuestion: 目前市场上玫瑰花的平均价格是多少?如果我在此基础上加价15%卖出,应该如何定价?\nThought:

我来给你详细拆解一下这个 prompt。注意,下面的解释文字不是原始提示,而是我添加的说明。

0: StringPromptValue(text='Answer the following questions as best you can. You have access to the following tools:\n\n

这句提示是让模型尽量回答问题,并告诉模型拥有哪些工具。

Search: A search engine. Useful for when you need to answer questions about
current events. Input should be a search query.\n

这是向模型介绍第一个工具:搜索。

Calculator: Useful for when you need to answer questions about math.\n\n

这是向模型介绍第二个工具:计算器。

Use the following format:\n\n (指导模型使用下面的格式)
Question: the input question you must answer\n (问题)
Thought: you should always think about what to do\n (思考)
Action: the action to take, should be one of [Search, Calculator]\n (行动)
Action Input: the input to the action\n (行动的输入)
Observation: the result of the action\n… (观察:行动的返回结果)
(this Thought/Action/Action Input/Observation can repeat N times)\n (上面这个过
程可以重复多次)
Thought: I now know the final answer\n (思考:现在我知道最终答案了)
Final Answer: the final answer to the original input question\n\n (最终答案)

上面,就是给模型的思考框架。具体解释可以看一下括号中的文字

Begin!\n\n

开始

Question: 目前市场上玫瑰花的平均价格是多少?如果我在此基础上加价 15% 卖出,应该
如何定价?\nThought:')

具体的任务
上面我一句句拆解的这个提示词,就是 Agent 之所以能够趋动大模型,进行思考 - 行动 - 观 察行动结果 - 再思考 - 再行动 - 再观察这个循环的核心秘密。有了这样的提示词,模型就会不 停地思考、行动,直到模型判断出问题已经解决,给出最终答案,跳出循环。


调用大模型之后,模型具体返回了什么结果呢?

Debug过程中,我们发现调用模型之后的outputs中包含下面的内容。

0: LLMResult(generations=[[Generation(text=' I need to find the current market price of roses and then calculate the new price with a 15% markup.\n 
Action: Search\nAction Input: "Average price of roses"', generation_info={'finish_reason': 'stop', 'logprobs': None})]], 
llm_output={'token_usage': {'completion_tokens': 36, 'total_tokens': 294, 'prompt_tokens': 258}, 'model_name': 'text-davinci-003'}, run=None)

把上面的内容拆解如下:

'text': ' I need to find the current market price of roses and then calculate the new price with a 15% markup.\n (Text:问题文本)
Action: Search\n (行动:搜索)
Action Input: "Average price of roses"' (行动的输入:搜索玫瑰平均价格)

它自己根据现有知识解决不了,下一步行动是需要选择工具箱中的搜索工具


第二轮思考:模型决定计算

因为任务尚未完成,第二轮思考开始,程序重新进入了Plan环节。

此时,LangChain的LLM Chain根据目前的input,也就是历史对话记录生成了新的提示信息

0: StringPromptValue(text='Answer the following questions as best you can. You have access to the following tools:\n\nSearch: A search engine. Useful for when you need to answer questions about current events. Input should be a search query.\nCalculator: Useful for when you need to answer questions about math.\n\nUse the following format:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction: the action to take, should be one of [Search, Calculator]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\nBegin!\n\nQuestion: 目前市场上玫瑰花的平均价格是多少?如果我在此基础上加价15%卖出,应该如何定价?\nThought: I need to find the current market price of roses and then calculate the new price with a 15% markup.\nAction: Search\nAction Input: "Average price of roses"\nObservation: The average price for a dozen roses in the U.S. is $80.16. The state where a dozen roses cost the most is Hawaii at $108.33. That\'s 35% more expensive than the national average. A dozen roses are most affordable in Pennsylvania, costing $66.15 on average.\nThought:

我们再来拆解一下这个prompt。

0: StringPromptValue(text='Answer the following questions as best you can. You have access to the following tools:\n\n

这句提示是让模型尽量回答问题,并告诉模型拥有哪些工具。

Search: A search engine. Useful for when you need to answer questions about current events. Input should be a search query.\n

这是向模型介绍第一个工具:搜索。

Calculator: Useful for when you need to answer questions about math.\n\n

这是向模型介绍第二个工具:计算器。

Use the following format:\n\n (指导模型使用下面的格式
Question: the input question you must answer\n (问题
Thought: you should always think about what to do\n (思考
Action: the action to take, should be one of [Search, Calculator]\n (行动
Action Input: the input to the action\n (行动的输入
Observation: the result of the action\n… (观察:行动的返回结果
(this Thought/Action/Action Input/Observation can repeat N times)\n (上面这个过程可以重复多次
Thought: I now know the final answer\n (思考:现在我知道最终答案了
Final Answer: the final answer to the original input question\n\n (最终答案

上面仍然是一段比较细节的解释说明,看一下括号中的文字。

Begin!\n\n

现在开始!

Question: 目前市场上玫瑰花的平均价格是多少?如果我在此基础上加价15%卖出,应该如何定价?\n

具体问题,也就是具体任务。
这句之前的提示,与我们在第一轮思考时看到的完全相同。

Thought: I need to find the current market price of roses and then calculate the new price with a 15% markup.\n (思考:我需要找到玫瑰花的价格,并加入15%的加价
Action: Search\nAction (行动:搜索
Input: “Average price of roses”\n (行动的输入:玫瑰花的平均价格
Observation: The average price for a dozen roses in the U.S. is $80.16. The state where a dozen roses cost the most is Hawaii at $108.33. That’s 35% more expensive than the national average. A dozen roses are most affordable in Pennsylvania, costing $66.15 on average.\n (观察:这里时搜索工具返回的玫瑰花价格信息
Thought:’

思考:后面是大模型应该进一步推理的内容。

大模型根据上面这个提示,返回了下面的output信息。

AgentAction(tool='Calculator', tool_input='80.16 * 1.15', log=' I need to calculate the new price with a 15% markup.\nAction: Calculator\nAction Input: 80.16 * 1.15')

这个输出显示,模型告诉自己,“我需要计算新的Price,在搜索结果的基础上加价15%”,并确定Action为计算器,输入计算器工具的指令为80.16*1.15。这是一个非常有逻辑性的思考。
经过解析之后的Thought在命令行中的输出如下:

有了上面的Thought做指引,AgentExecutor调用了第二个工具:LLMMath。现在开始计算。

0: StringPromptValue(text='Translate a math problem into a expression that can be executed using Python’s numexpr library. Use the output of running this code to answer the question.\n\n

指定模型用 Python 的数学库来编程解决数学问题,而不是自己计算。这就规避了大模型数学推理能力弱的局限。

Question: KaTeX parse error: Undefined control sequence: \n at position 30: … math problem.}\̲n̲ ̲(**问题**)<br />t…{single line mathematical expression that solves the problem} n\n (**问题的数学描述**)<br />...numexpr.evaluate(text)...\n通过 Python 库运行问题的数学描述
output\n${Output of running the code}\n```\n (输出的 Python 代码运行结果
Answer: ${Answer}\n\n(问题的答案
Begin.\n\n (开始

从这里开始是两个数学式的解题示例。

Question: What is 37593 * 67?\n
text\n37593 * 67\n
\n…numexpr.evaluate(“37593 * 67”)…\n
output\n2518731\n\n
Answer: 2518731\n\n
Question: 37593^(1/5)\n
text\n37593**(1/5)\n\n…
numexpr.evaluate(“37593**(1/5)”)…\n
output\n8.222831614237718\n\n
Answer: 8.222831614237718\n\n

两个数学式的解题示例结束。

Question: 80.16 * 1.15\n’)

这里是玫瑰花问题的具体描述。
下面,就是模型返回结果。

observation
'Answer: 92.18399999999998'

第三轮思考:模型完成任务

第三轮思考开始。此时,Executor的Plan应该进一步把当前的新结果传递给大模型,不出所料的话,大模型应该有足够的智慧判断出任务此时已经成功地完成了。

0: StringPromptValue(text='Answer the following questions as best you can. You have access to the following tools:\n\nSearch: A search engine. Useful for when you need to answer questions about current events. Input should be a search query.\nCalculator: Useful for when you need to answer questions about math.\n\nUse the following format:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction: the action to take, should be one of [Search, Calculator]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\nBegin!\n\nQuestion: 目前市场上玫瑰花的平均价格是多少?如果我在此基础上加价15%卖出,应该如何定价?\nThought: I need to find the current market price of roses and then calculate the new price with a 15% markup.\nAction: Search\nAction Input: "Average price of roses"\nObservation: The average price for a dozen roses in the U.S. is $80.16. The state where a dozen roses cost the most is Hawaii at $108.33. That\'s 35% more expensive than the national average. A dozen roses are most affordable in Pennsylvania, costing $66.15 on average.\nThought: I need to calculate the new price with a 15% markup.\nAction: Calculator\nAction Input: 80.16 * 1.15\nObservation: Answer: 92.18399999999998\nThought:')

拆解

0: StringPromptValue(text='Answer the following questions as best you can. You have access to the following tools:\n\n

这句提示是让模型尽量回答问题,并告诉模型拥有哪些工具。

Search: A search engine. Useful for when you need to answer questions about current events. Input should be a search query.\n

这是向模型介绍第一个工具:搜索。

Calculator: Useful for when you need to answer questions about math.\n\n

这是向模型介绍第二个工具:计算器。

Use the following format:\n\n (指导模型使用下面的格式
Question: the input question you must answer\n (问题
Thought: you should always think about what to do\n (思考
Action: the action to take, should be one of [Search, Calculator]\n (行动
Action Input: the input to the action\n (行动的输入
Observation: the result of the action\n… (观察:行动的返回结果
(this Thought/Action/Action Input/Observation can repeat N times)\n (上面这个过程可以重复多次
Thought: I now know the final answer\n (思考:现在我知道最终答案了
Final Answer: the final answer to the original input question\n\n (最终答案

仍然是比较细节的说明,看括号文字。

Begin!\n\n

现在开始!

Question: 目前市场上玫瑰花的平均价格是多少?如果我在此基础上加价15%卖出,应该如何定价?\n

具体问题,也就是具体任务。

Thought: I need to find the current market price of roses and then calculate the new price with a 15% markup.\n (思考:我需要找到玫瑰花的价格,并加入15%的加价
Action: Search\nAction (行动:搜索
Input: “Average price of roses”\n (行动的输入:玫瑰花的平均价格
Observation: The average price for a dozen roses in the U.S. is $80.16. The state where a dozen roses cost the most is Hawaii at $108.33. That’s 35% more expensive than the national average. A dozen roses are most affordable in Pennsylvania, costing $66.15 on average.\n (观察:这里时搜索工具返回的玫瑰花价格信息

这句之前的提示,与我们在第二轮思考时看到的完全相同。

Thought: I need to calculate the new price with a 15% markup.\n (思考:我需要计算玫瑰花15%的加价
Action: Calculator\n (行动:计算器工具
Action Input: 80.16 * 1.15\n (行动输入:一个数学式
Observation: Answer: 92.18399999999998\n (观察:计算得到的答案
Thought:’ (思考

可见,每一轮的提示都跟随着模型的思维链条,逐步递进,逐步完善。环环相扣,最终结果也就呼之欲出了。
继续Debug,发现模型在这一轮思考之后的输出中终于包含了 “I now know the final answer.”,这说明模型意识到任务已经成功地完成了。

总结

这些本质上都是给大模型提供Prompt, Prompt是会越来越多的,可以看看langchain是怎么解决 token上限。 此外,在AgentExecutor中,还构建了自主计划和调用 工具的逻辑。
Profile : 定义了Agent的个性、知识和经验。 提供了“选择操作序列”时推理所需的高层次背景信息。 当Agent处理特定的任务时,它会考虑Profile中的信息来做出与其“个性”和“经验”相一致的决策。
Memory (记忆): 让Agent能够记住之前的交互和决策,帮助其更好地适应和处理后续的任务。 在LLM的编程中,它可以帮助模型跟踪和使用之前的交互来生成更准确的操作序列。
Plan (计划): 是你提到的“定义操作序列”的部分。 在LLM编程范式中,这意味着Agent不是依靠硬编码的规则来执行任务,而是生成、选择和执行计 划,这些计划是基于其当前的Profile和Memory生成的。
Tool (工具): 允许Agent与外部系统和API进行交互,执行具体的任务。 在LLM编程范式中,这意味着模型可以调用外部工具或API来实现某些操作,而不仅仅是生成文本。
当你提到的“反思Reflect”是指模型的自我反思和自我调整能力,这确实是指导LLM生成推理所需的中 观信息。它可以帮助模型更好地适应任务和上下文,生成更准确的操作序列。
基于你的业务需求,使用Agent的四个模块框架是一个很好的思路。在工程化时,你可以考虑如何整 合这四个模块,并结合LLM的编程范式来处理复杂的业务逻辑和交互。

  1. 请你在 agent.py 文件中找到AgentExecutor类。
  2. 请你在AgentExecutor类中找到_take_next_step方法,对应本课的内容,分析AgentExecutor类是怎样实现Plan和工具调用的。
  3. 代码,AgentExecutor类的 实现细节
  4. 代码,LLMChain类的 实现细节

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1526796.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

静态综合实验

一&#xff0c;1.搭建拓扑结构并启动。 2.根据题意得该图需要14个网段&#xff0c;根据192.168.1.0/24划分子网段&#xff0c;如下&#xff1a; 划分完如图所示&#xff1a; 二、配置IP地址 R1路由器&#xff1a; 1.进入系统视图并改名. 2.接口配置IP地址&#xff1a…

Linux系统中安装Docker

用Linux既可以用虚拟机操作&#xff0c;也可以自己弄一个云服务器进行操作&#xff0c;两者没啥区别。 操作之前需要将用户等级升级到root级别&#xff0c;防止有些操作因为权限限制而不能操作。 安装docker非常简单&#xff0c;只需要一直按照下列命令顺序进行操作即可。 安装…

选Gitee还是GitHub?

2024年3月18日&#xff0c;周一晚上 我选择GitHub 因为GitHub可以无限创建仓库

clipboard好用的复制剪切库

clipboard是现代复制到剪贴板的工具&#xff0c;其 gzip 压缩后只有 3kb&#xff0c;能够减少选择文本的重复操作&#xff0c;点击按钮就可以复制指定内容&#xff0c;支持原生HTMLjs&#xff0c;vue3和vue2。使用方法参照官方文档&#xff0c;so easy&#xff01;&#xff01;…

数据结构(四)——串的模式匹配

4.2 串的模式匹配 4.2.1_朴素模式匹配算法 字符串模式匹配&#xff1a;在主串中找到与模式串相同的⼦串&#xff0c;并返回其所在位置 主串⻓度为n&#xff0c;模式串⻓度为 m 朴素模式匹配算法&#xff1a;将主串中所有⻓度为m的⼦串依次与模式串对⽐&#xff0c;直到找到⼀…

U盘变本地磁盘?数据恢复有妙招!

一、U盘异变本地磁盘现象 在日常工作和生活中&#xff0c;U盘作为便携式的存储设备&#xff0c;广受大家喜爱。然而&#xff0c;有时我们会遇到一个奇怪的现象&#xff1a;原本应该显示为可移动磁盘的U盘&#xff0c;在插入电脑后却变成了“本地磁盘”。这种情况不仅让人困惑&…

Android系统签名的制作与使用

目录 1. &#x1f4c2; 背景 2. &#x1f531; 制作Android系统签名 步骤一&#xff1a;找到platform.pk8和platform.x509.pem签名文件 步骤二&#xff1a;下载keytool-importkeypair签名工具 步骤三&#xff1a;使用签名文件和签名工具生成.jks签名文件 3. ✅ 使用Andro…

iPhone迎AI大革命:谷歌、OpenAI助苹果重塑智能巅峰

近日&#xff0c;有媒体报道称&#xff0c;苹果正积极寻求与谷歌和OpenAI展开合作&#xff0c;计划将这两家在全球人工智能领域具有领先地位的公司的大模型技术应用于iPhone的AI功能。这一合作将为iPhone带来革命性的智能体验&#xff0c;开启AI手机新篇章。 AI-321 | 专注于AI…

Linux-MDK can电机带导轨 C++封装

我使用的是MKS的52D can电机带导轨&#xff0c;现在我要根据电机说明书将运动指令封装&#xff0c;有一个限位开关&#xff0c; 闭合时高电平 滑块需要运动在限位开关左侧&#xff0c;所以限位归零的方向为顺时针 根据说明书&#xff0c;我要设置的命令应该是&#xff1a; ca…

【复现】【免费】基于多时间尺度滚动优化的多能源微网双层调度模型

目录 主要内容 部分代码 结果一览 1.原文结果 2.程序运行结果 下载链接 主要内容 该模型参考《Collaborative Autonomous Optimization of Interconnected Multi-Energy Systems with Two-Stage Transactive Control Framework》&#xff0c;主要解决的是一个…

蓝桥杯练习题——贡献法(隔板法)

1.孤独的照片 思路 孤独的区间一定有一头孤独的牛&#xff0c;考虑每头牛对区间的贡献是多少 #include<iostream> using namespace std; const int N 5e5 10; int n; string s;int main(){cin>>n>>s;long long res 0;for(int i 0; i < n; i){int l…

Matlab|面向低碳经济运行目标的多微网能量互联优化调度

目录 主要内容 优化流程 部分程序 结果一览 下载链接 主要内容 该程序为多微网协同优化调度模型&#xff0c;系统在保障综合效益的基础上&#xff0c;调度时优先协调微网与微网之间的能量流动&#xff0c;将与大电网的互联交互作为备用&#xff0c;降低微网与大电…

C语言 数组的应用————扫雷

前言 在上一篇博客中我们实现了简单的三子棋小游戏&#xff0c;初步运用了二维数组&#xff0c;今天还是用二维数组来实现另一个小游戏——扫雷的基础版本&#xff0c;写这两个小游戏的目的主要是理解并运用数组&#xff0c;同时巩固前面学习的知识比如循环和函数等等&#xf…

分享一个不错的three.js开源项目

项目将three.js相关内容封装为相应库 很值得学习&#xff0c;可以模仿项目学习three.js vue-vite-three.js threejs-park: 基于vue3&#xff0c;threeJS智慧园区 threejs-park

YOLOv9改进策略:注意力机制 | 用于微小目标检测的上下文增强和特征细化网络ContextAggregation,助力小目标检测,暴力涨点

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文改进内容&#xff1a;用于微小目标检测的上下文增强和特征细化网络ContextAggregation&#xff0c;助力小目标检测 yolov9-c-ContextAggregation summary: 971 layers, 51002153 parameters, 51002121 gradients, 238.9 GFLOPs 改…

ChatGPT登陆提示:“Please unblock challenges.cloudflare.com to proceed…”

ChatGPT登陆时提示&#xff1a;“Please unblock challenges.cloudflare.com to proceed”&#xff0c; 说明&#xff1a;请解除对challenges.cloudflare.com的屏蔽以继续 原因及解决方法&#xff1a; 1、出现这个问题&#xff0c;一般都是网络和本地环境问题&#xff0c;可以…

使用Nginx配置实现请求的限流操作

概述 限流&#xff08;Rate Limitting&#xff09;是服务降级的一种方式&#xff0c;通过限制系统的输入和输出流量以达到保护系统的目的。 比如我们的网站暴露在公网环境中&#xff0c;除了用户的正常访问&#xff0c;网络爬虫、恶意攻击或者大促等突发流量都可能都会对系统造…

Kotlin进阶之协程从上车到起飞

公众号「稀有猿诉」 原文链接 Kotlin进阶之协程从上车到起飞 通过前面的一篇文章我们理解了协程的基本概念&#xff0c;学会协程的基本使用方法&#xff0c;算是正式入门了&#xff0c;接下来就是要深入的学习技术细节和高级使用方法&#xff0c;以期完全掌握Kotlin协程…

【推荐系统】NCF神经协同过滤

NCF框架 NCF框架是本文要实现的3个模型的主体结构。 首先是输入层&#xff0c;分别包含两个特征向量 v u v_u vu​和 v i v_i vi​&#xff0c;描述了用户u和物品i。输入仅由一个用户向量和一个物品向量构成&#xff0c;它们分别是以one-hot编码的二值化稀疏向量。 接着是Em…

若依 ruoyi-cloud [网关异常处理]请求路径:/system/user/getInfo,异常信息:404

这里遇到的情况是因为nacos中的配置文件与项目启动时的编码不一样&#xff0c;若配置文件中有中文注释&#xff0c;那么用idea启动项目的时候&#xff0c;在参数中加上 -Dfile.encodingutf-8 &#xff0c;保持编码一致&#xff0c;&#xff08;用中文注释的配置文件&#xff0c…