智能体实战之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)

智能体实战之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

本文系本站原创文章,著作版权属于作者,未经允许不得转载,如需转载或引用请注明出处或者联系作者。