她在丛中笑 發表於 2025-11-22 22:52:00

Hello-Agents 《从零开始构建智能体》实践

<p>最近在DataWhale参加Agents开发的组队学习,虽然课程才刚满两周,但我这颗想搞事的心早就按捺不住了!今天,我终于要正式“出道”,成为一名智能体系统构建者啦~<br><br>我最近调研发现某部门的小伙伴们得频繁巡检机房设备,工作量巨大不说,机房那噪音、辐射、还有不明气体……简直是对健康的“全方位关爱” 😅 <br>于是他们悄悄问我:能不能让AI来帮忙巡检?我一听,这不就是我学《从零开始构建智能体》之后练手的好机会嘛!灵感瞬间爆发,火速整理思路,项目火速上线👇</p>
<p>&nbsp;</p>
<p><strong>项目名称:</strong>机房巡检助手</p>
<p><strong>问题分析</strong>:当前机房巡检工作面临几个核心痛点:人工巡检效率低下,工作环境对人员不友好,机房内的噪音、辐射和有害气体影响健康<em>。</em>传统巡检模式存在盲区,易出错等问题。</p>
<p><strong>核心功能</strong>:通过API工具采集机房环境数据,智能分析与决策模块 负责数据处理与决策。实现根因分析:当多指标异常时,能智能推断故障根源,辅助快速定位问题。人机交互支持聊天对话。<span style="font-style: italic">&nbsp;</span></p>
<p><strong>预期成果</strong>:实现聊天对话框内巡检机房环境数据,并智能分析总结,辅助快速定位问题。</p>
<p><br><strong>项目地址</strong>:https://gitee.com/yisheng163/hello-agents-ys<br>由于从 GitHub 拉取/推送代码的网络延迟较高,为提升协作效率,我将项目同步开源至 Gitee。</p>
<p>&nbsp;效果图:</p>
<p><img src="https://img2024.cnblogs.com/blog/27928/202511/27928-20251123000455000-2089498429.png"></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h4>开发环境准备</h4>
<p>1,下载 vs code 安装 。</p>
<p>2,# 安装HelloAgents</p>
<p>pip install hello-agents</p>
<p>测试 python -c "import hello_agents; print(dir(hello_agents))"</p>
<p>安装gradio库,低代码搭建聊天对话界面。</p>
<p>pip install gradio<br><br><strong>编写代码</strong></p>
<div class="cnblogs_code"><img id="code_img_closed_fb15004b-2dce-453a-9f42-bead1383fafe" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_fb15004b-2dce-453a-9f42-bead1383fafe" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_fb15004b-2dce-453a-9f42-bead1383fafe" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> os
</span><span style="color: rgba(0, 0, 255, 1)">from</span> openai <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> OpenAI
</span><span style="color: rgba(0, 0, 255, 1)">from</span> dotenv <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> load_dotenv
</span><span style="color: rgba(0, 0, 255, 1)">from</span> typing <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> List, Dict

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 加载 .env 文件中的环境变量</span>
<span style="color: rgba(0, 0, 0, 1)">load_dotenv()

</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> HelloAgentsLLM:
    </span><span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(128, 0, 0, 1)">
    为本书 "Hello Agents" 定制的LLM客户端。
    它用于调用任何兼容OpenAI接口的服务,并默认使用流式响应。
    </span><span style="color: rgba(128, 0, 0, 1)">"""</span>
    <span style="color: rgba(0, 0, 255, 1)">def</span> <span style="color: rgba(128, 0, 128, 1)">__init__</span>(self, model: str = None, apiKey: str = None, baseUrl: str = None, timeout: int =<span style="color: rgba(0, 0, 0, 1)"> None):
      </span><span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(128, 0, 0, 1)">
      初始化客户端。优先使用传入参数,如果未提供,则从环境变量加载。
      </span><span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(0, 0, 0, 1)">
      self.model </span>= model <span style="color: rgba(0, 0, 255, 1)">or</span> os.getenv(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">LLM_MODEL_ID</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
      apiKey </span>= apiKey <span style="color: rgba(0, 0, 255, 1)">or</span> os.getenv(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">LLM_API_KEY</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
      baseUrl </span>= baseUrl <span style="color: rgba(0, 0, 255, 1)">or</span> os.getenv(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">LLM_BASE_URL</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
      timeout </span>= timeout <span style="color: rgba(0, 0, 255, 1)">or</span> int(os.getenv(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">LLM_TIMEOUT</span><span style="color: rgba(128, 0, 0, 1)">"</span>, 60<span style="color: rgba(0, 0, 0, 1)">))
      
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(0, 0, 255, 1)">not</span><span style="color: rgba(0, 0, 0, 1)"> all():
            </span><span style="color: rgba(0, 0, 255, 1)">raise</span> ValueError(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">模型ID、API密钥和服务地址必须被提供或在.env文件中定义。</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)

      self.client </span>= OpenAI(api_key=apiKey, base_url=baseUrl, timeout=<span style="color: rgba(0, 0, 0, 1)">timeout)

    </span><span style="color: rgba(0, 0, 255, 1)">def</span> think(self, messages: List], temperature: float = 0) -&gt;<span style="color: rgba(0, 0, 0, 1)"> str:
      </span><span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(128, 0, 0, 1)">
      调用大语言模型进行思考,并返回其响应。
      </span><span style="color: rgba(128, 0, 0, 1)">"""</span>
      <span style="color: rgba(0, 0, 255, 1)">print</span>(f<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">🧠 正在调用 {self.model} 模型...</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
      </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">:
            response </span>=<span style="color: rgba(0, 0, 0, 1)"> self.client.chat.completions.create(
                model</span>=<span style="color: rgba(0, 0, 0, 1)">self.model,
                messages</span>=<span style="color: rgba(0, 0, 0, 1)">messages,
                temperature</span>=<span style="color: rgba(0, 0, 0, 1)">temperature,
                stream</span>=<span style="color: rgba(0, 0, 0, 1)">True,
            )
            
            </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 处理流式响应</span>
            <span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">✅ 大语言模型响应成功:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
            collected_content </span>= []<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 创建空列表用于收集所有响应片段</span>
            <span style="color: rgba(0, 0, 255, 1)">for</span> chunk <span style="color: rgba(0, 0, 255, 1)">in</span> response:<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 遍历流式响应中的每个数据块</span>
                content = chunk.choices.delta.content <span style="color: rgba(0, 0, 255, 1)">or</span> <span style="color: rgba(128, 0, 0, 1)">""</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 提取当前数据块中的文本内容,如果没有则为空字符串</span>
               
                <span style="color: rgba(0, 0, 255, 1)">print</span>(content, end=<span style="color: rgba(128, 0, 0, 1)">""</span>, flush=True)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 实时打印内容,不换行并立即刷新输出缓冲区</span>
                collected_content.append(content)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 将当前内容添加到收集列表中</span>
            <span style="color: rgba(0, 0, 255, 1)">print</span>()<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 在流式输出结束后换行</span>
            <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 0, 1)">""</span>.join(collected_content)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 将收集的所有内容拼接成完整字符串并返回</span>

      <span style="color: rgba(0, 0, 255, 1)">except</span><span style="color: rgba(0, 0, 0, 1)"> Exception as e:
            </span><span style="color: rgba(0, 0, 255, 1)">print</span>(f<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">❌ 调用LLM API时发生错误: {e}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
            </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> None
   
    </span><span style="color: rgba(0, 0, 255, 1)">def</span> invoke(self, messages: List], **kwargs) -&gt;<span style="color: rgba(0, 0, 0, 1)"> str:
      </span><span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(128, 0, 0, 1)">
      兼容SimpleAgent的调用方法
      </span><span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(0, 0, 0, 1)">
      temperature </span>= kwargs.get(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">temperature</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, 0)
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> self.think(messages, temperature)

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> --- 客户端使用示例 ---</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(128, 0, 128, 1)">__name__</span> == <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">__main__</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">:
    </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">:
      llmClient </span>=<span style="color: rgba(0, 0, 0, 1)"> HelloAgentsLLM()
      
      exampleMessages </span>=<span style="color: rgba(0, 0, 0, 1)"> [
            {</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">role</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">system</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">content</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">You are a helpful assistant that writes Python code.</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">},
            {</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">role</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">user</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">content</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">写一个快速排序算法</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">}
      ]
      
      </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">--- 调用LLM ---</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
      responseText </span>=<span style="color: rgba(0, 0, 0, 1)"> llmClient.think(exampleMessages)
      </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> responseText:
            </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">\n\n--- 完整模型响应 ---</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
            </span><span style="color: rgba(0, 0, 255, 1)">print</span><span style="color: rgba(0, 0, 0, 1)">(responseText)

    </span><span style="color: rgba(0, 0, 255, 1)">except</span><span style="color: rgba(0, 0, 0, 1)"> ValueError as e:
      </span><span style="color: rgba(0, 0, 255, 1)">print</span>(e)</pre>
</div>
<span class="cnblogs_code_collapse">HelloAgentsLLM.py</span></div>
<div class="cnblogs_code"><img id="code_img_closed_4808bc8d-4722-46ff-8498-d6b5fa42ce7c" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_4808bc8d-4722-46ff-8498-d6b5fa42ce7c" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_4808bc8d-4722-46ff-8498-d6b5fa42ce7c" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> my_llm.py</span>
<span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> os
</span><span style="color: rgba(0, 0, 255, 1)">from</span> typing <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> Optional
</span><span style="color: rgba(0, 0, 255, 1)">from</span> openai <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> OpenAI
</span><span style="color: rgba(0, 0, 255, 1)">from</span> hello_agents <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> HelloAgentsLLM

</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> MyLLM(HelloAgentsLLM):
    </span><span style="color: rgba(0, 0, 255, 1)">def</span> <span style="color: rgba(128, 0, 128, 1)">__init__</span><span style="color: rgba(0, 0, 0, 1)">(
      self,
      model: Optional </span>=<span style="color: rgba(0, 0, 0, 1)"> None,
      api_key: Optional </span>=<span style="color: rgba(0, 0, 0, 1)"> None,
      base_url: Optional </span>=<span style="color: rgba(0, 0, 0, 1)"> None,
      provider: Optional </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">auto</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
      </span>**<span style="color: rgba(0, 0, 0, 1)">kwargs
    ):
      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 检查provider是否为我们想处理的'modelscope'</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> provider == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">modelscope</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">:
            </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">正在使用自定义的 ModelScope Provider</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
            self.provider </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">modelscope</span><span style="color: rgba(128, 0, 0, 1)">"</span>
            
            <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 解析 ModelScope 的凭证</span>
            self.api_key = api_key <span style="color: rgba(0, 0, 255, 1)">or</span> os.getenv(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">MODELSCOPE_API_KEY</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
            self.base_url </span>= base_url <span style="color: rgba(0, 0, 255, 1)">or</span> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">https://api-inference.modelscope.cn/v1/</span><span style="color: rgba(128, 0, 0, 1)">"</span>
            
            <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 验证凭证是否存在</span>
            <span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(0, 0, 255, 1)">not</span><span style="color: rgba(0, 0, 0, 1)"> self.api_key:
                </span><span style="color: rgba(0, 0, 255, 1)">raise</span> ValueError(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">ModelScope API key not found. Please set MODELSCOPE_API_KEY environment variable.</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)

            </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 设置默认模型和其他参数</span>
            self.model = model <span style="color: rgba(0, 0, 255, 1)">or</span> os.getenv(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">LLM_MODEL_ID</span><span style="color: rgba(128, 0, 0, 1)">"</span>) <span style="color: rgba(0, 0, 255, 1)">or</span> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Qwen/Qwen2.5-VL-72B-Instruct</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
            self.temperature </span>= kwargs.get(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">temperature</span><span style="color: rgba(128, 0, 0, 1)">'</span>, 0.7<span style="color: rgba(0, 0, 0, 1)">)
            self.max_tokens </span>= kwargs.get(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">max_tokens</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
            self.timeout </span>= kwargs.get(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">timeout</span><span style="color: rgba(128, 0, 0, 1)">'</span>, 60<span style="color: rgba(0, 0, 0, 1)">)
            
            </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 使用获取的参数创建OpenAI客户端实例</span>
            self._client = OpenAI(api_key=self.api_key, base_url=self.base_url, timeout=<span style="color: rgba(0, 0, 0, 1)">self.timeout)

      </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">:
            </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 如果不是 modelscope, 则完全使用父类的原始逻辑来处理</span>
            super().<span style="color: rgba(128, 0, 128, 1)">__init__</span>(model=model, api_key=api_key, base_url=base_url, provider=provider, **kwargs)</pre>
</div>
<span class="cnblogs_code_collapse">my_llm.py</span></div>
<p>配置.env文件<br><br>编写通过API查询机房环境信息的类</p>
<div class="cnblogs_code"><img id="code_img_closed_f4df6049-7784-43f7-81b9-2b9e0a9ad090" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_f4df6049-7784-43f7-81b9-2b9e0a9ad090" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_f4df6049-7784-43f7-81b9-2b9e0a9ad090" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> os
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> requests
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> hashlib
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> json
</span><span style="color: rgba(0, 0, 255, 1)">from</span> typing <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> Optional, Union

</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> api_Temperature:
    </span><span style="color: rgba(0, 0, 255, 1)">def</span> <span style="color: rgba(128, 0, 128, 1)">__init__</span><span style="color: rgba(0, 0, 0, 1)">(self):
      self.session </span>=<span style="color: rgba(0, 0, 0, 1)"> requests.Session()
      self.base_url </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">http://192.169.200.5:3900</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      self.base_url </span>= os.getenv(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">ROOM_API_URL</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
      
      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 获取加盐值</span>
      salt_url = f<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{self.base_url}/api/Plugin.Base/Log/Salt</span><span style="color: rgba(128, 0, 0, 1)">"</span>
      
      <span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">:
            response </span>=<span style="color: rgba(0, 0, 0, 1)"> self.session.get(salt_url)
            response.raise_for_status()
            re_body </span>=<span style="color: rgba(0, 0, 0, 1)"> response.json()
            </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> print(f"re_body: {re_body}")</span>
<span style="color: rgba(0, 0, 0, 1)">
            fixed_salt </span>= re_body.get(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">data</span><span style="color: rgba(128, 0, 0, 1)">"</span>, {}).get(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">FixedSalt</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
            temp_salt </span>= re_body.get(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">data</span><span style="color: rgba(128, 0, 0, 1)">"</span>, {}).get(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">TempSalt</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
            
            </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> print(f"fixed_salt: {fixed_salt}")</span>
            <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> print(f"temp_salt: {temp_salt}")</span>
            
            <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 登录</span>
            login_url = f<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{self.base_url}/api/Plugin.Base/Log/In</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
            
            account </span>= os.getenv(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">ROOM_API_USERNAME</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
            password </span>= os.getenv(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">ROOM_API_USERPASS</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
            remember_me </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">true</span><span style="color: rgba(128, 0, 0, 1)">"</span>
            
            <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 计算密文 md5(md5({账号}+{固定加盐值}+{密码})+{临时加盐值})</span>
            password_step1 = self.md5_hash(account + fixed_salt +<span style="color: rgba(0, 0, 0, 1)"> password)
            encrypted_password </span>= self.md5_hash(password_step1 +<span style="color: rgba(0, 0, 0, 1)"> temp_salt)
            
            post_data </span>=<span style="color: rgba(0, 0, 0, 1)"> {
                </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Account</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: account,
                </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Password</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: encrypted_password,
                </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">RememberMe</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: remember_me
            }
            
            login_response </span>= self.session.post(login_url, data=<span style="color: rgba(0, 0, 0, 1)">post_data)
            login_response.raise_for_status()

            </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 输出登陆结果</span>
            <span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">=</span><span style="color: rgba(128, 0, 0, 1)">"</span> * 50<span style="color: rgba(0, 0, 0, 1)">)
            </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> print("登录结果详情:")</span>
            <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> print(f"请求URL: {login_url}")</span>
            <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> print(f"请求方法: POST")</span>
            <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> print(f"请求体: {login_response.request.body}")</span>
            <span style="color: rgba(0, 0, 255, 1)">print</span>(f<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">响应状态码: {login_response.status_code}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
            </span><span style="color: rgba(0, 0, 255, 1)">print</span>(f<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">响应内容: {login_response.text}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
            </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">=</span><span style="color: rgba(128, 0, 0, 1)">"</span> * 50<span style="color: rgba(0, 0, 0, 1)">)
            
      </span><span style="color: rgba(0, 0, 255, 1)">except</span><span style="color: rgba(0, 0, 0, 1)"> requests.exceptions.RequestException as e:
            </span><span style="color: rgba(0, 0, 255, 1)">print</span>(f<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">初始化失败: {e}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
   
    @staticmethod
    </span><span style="color: rgba(0, 0, 255, 1)">def</span> md5_hash(text: str) -&gt;<span style="color: rgba(0, 0, 0, 1)"> str:
      </span><span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(128, 0, 0, 1)">MD5哈希计算</span><span style="color: rgba(128, 0, 0, 1)">"""</span>
      <span style="color: rgba(0, 0, 255, 1)">return</span> hashlib.md5(text.encode(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">utf-8</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)).hexdigest()
   
    </span><span style="color: rgba(0, 0, 255, 1)">def</span> get_temperature_value(self, object_id: str) -&gt;<span style="color: rgba(0, 0, 0, 1)"> float:
      </span><span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(128, 0, 0, 1)">取单个温度值</span><span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(0, 0, 0, 1)">
      re_value </span>= 0.0<span style="color: rgba(0, 0, 0, 1)">
      url </span>= f<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{self.base_url}/api/Plugin.Data/Property/RealTimeData</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      
      params </span>=<span style="color: rgba(0, 0, 0, 1)"> {
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Clazz</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Plugin.Env.Model.Device</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">objectId</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: object_id,
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">provider</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Plugin.Env.Providers.Data.Device.Property_Point</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">propertyId</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">HT_Temp</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      }
      
      </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">:
            response </span>= self.session.get(url, params=<span style="color: rgba(0, 0, 0, 1)">params)
            response.raise_for_status()
            re_body </span>=<span style="color: rgba(0, 0, 0, 1)"> response.json()
            
            </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 屏幕打印日志</span>
            <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">print(f"[{self.get_current_time()}] {json.dumps(re_body)}")</span>
<span style="color: rgba(0, 0, 0, 1)">
            ht_temp_value </span>= re_body.get(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">data</span><span style="color: rgba(128, 0, 0, 1)">"</span>, {}).get(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">value</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
            </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> ht_temp_value:
                re_value </span>=<span style="color: rgba(0, 0, 0, 1)"> float(ht_temp_value)
               
      </span><span style="color: rgba(0, 0, 255, 1)">except</span><span style="color: rgba(0, 0, 0, 1)"> (requests.exceptions.RequestException, ValueError) as e:
            </span><span style="color: rgba(0, 0, 255, 1)">print</span>(f<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">获取温度值失败: {e}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
            
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> re_value
   
    </span><span style="color: rgba(0, 0, 255, 1)">def</span> get_leak_judge_value(self, object_id: str, property_id: str) -&gt;<span style="color: rgba(0, 0, 0, 1)"> bool:
      </span><span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(128, 0, 0, 1)">取单个漏水判定</span><span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(0, 0, 0, 1)">
      url </span>= f<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{self.base_url}/api/Plugin.Data/Property/RealTimeData</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      
      params </span>=<span style="color: rgba(0, 0, 0, 1)"> {
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Clazz</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Plugin.Env.Model.Device</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">objectId</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: object_id,
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">provider</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Plugin.Env.Providers.Data.Device.Property_Point</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">propertyId</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: property_id
      }
      
      </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">:
            response </span>= self.session.get(url, params=<span style="color: rgba(0, 0, 0, 1)">params)
            response.raise_for_status()
            re_body </span>=<span style="color: rgba(0, 0, 0, 1)"> response.json()
            </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">print(json.dumps(re_body))</span>
<span style="color: rgba(0, 0, 0, 1)">            
            mk_judge_value </span>= re_body.get(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">data</span><span style="color: rgba(128, 0, 0, 1)">"</span>, {}).get(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">value</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
            re_value </span>=<span style="color: rgba(0, 0, 0, 1)"> float(mk_judge_value)
            </span><span style="color: rgba(0, 0, 255, 1)">return</span> re_value == 1
            
      <span style="color: rgba(0, 0, 255, 1)">except</span><span style="color: rgba(0, 0, 0, 1)"> (requests.exceptions.RequestException, ValueError) as e:
            </span><span style="color: rgba(0, 0, 255, 1)">print</span>(f<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">获取漏水判定失败: {e}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
            </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> False
   
    </span><span style="color: rgba(0, 0, 255, 1)">def</span> get_leak_locate_value(self, object_id: str, property_id: str) -&gt;<span style="color: rgba(0, 0, 0, 1)"> float:
      </span><span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(128, 0, 0, 1)">取单个漏水位置</span><span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(0, 0, 0, 1)">
      re_value </span>= 0.0<span style="color: rgba(0, 0, 0, 1)">
      url </span>= f<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{self.base_url}/api/Plugin.Data/Property/RealTimeData</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      
      params </span>=<span style="color: rgba(0, 0, 0, 1)"> {
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Clazz</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Plugin.Env.Model.Device</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">objectId</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: object_id,
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">provider</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Plugin.Env.Providers.Data.Device.Property_Point</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">propertyId</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: property_id
      }
      
      </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">:
            response </span>= self.session.get(url, params=<span style="color: rgba(0, 0, 0, 1)">params)
            response.raise_for_status()
            re_body </span>=<span style="color: rgba(0, 0, 0, 1)"> response.json()
            </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">print(json.dumps(re_body))</span>
<span style="color: rgba(0, 0, 0, 1)">            
            mk_locate_value </span>= re_body.get(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">data</span><span style="color: rgba(128, 0, 0, 1)">"</span>, {}).get(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">value</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
            re_value </span>=<span style="color: rgba(0, 0, 0, 1)"> float(mk_locate_value)
            
      </span><span style="color: rgba(0, 0, 255, 1)">except</span><span style="color: rgba(0, 0, 0, 1)"> (requests.exceptions.RequestException, ValueError) as e:
            </span><span style="color: rgba(0, 0, 255, 1)">print</span>(f<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">获取漏水位置失败: {e}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
            
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> re_value
   
    </span><span style="color: rgba(0, 0, 255, 1)">def</span> get_all_value(self) -&gt;<span style="color: rgba(0, 0, 0, 1)"> str:
      </span><span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(128, 0, 0, 1)">获取所有值</span><span style="color: rgba(128, 0, 0, 1)">"""</span>

      <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 分院信息</span>
      SD_Temp_Main = 0.0<span style="color: rgba(0, 0, 0, 1)">
      SD_Temp_UPS </span>= 0.0
      
      <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 获取温度值</span>
      SD_Temp_Main = self.get_temperature_value(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">30.wsd5</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
      SD_Temp_UPS </span>= self.get_temperature_value(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">30.wsd1</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
      
      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 获取漏水判断值</span>
      SD_Leak_Judge_Main1 = self.get_leak_judge_value(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">30.ls1</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Leak_Judge</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
      SD_Leak_Judge_Main2 </span>= self.get_leak_judge_value(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">30.ls2</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Leak_Judge</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
      
      SD_Leak_Locate_Main1 </span>= 0.0<span style="color: rgba(0, 0, 0, 1)">
      SD_Leak_Locate_Main2 </span>= 0.0
      
      <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 处理漏水定位逻辑(@ref)</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> SD_Leak_Judge_Main1:
            SD_Leak_Locate_Main1 </span>= self.get_leak_locate_value(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">30.ls1</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Leak_Locate</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
      
      </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> SD_Leak_Judge_Main2:
            SD_Leak_Locate_Main2 </span>= self.get_leak_locate_value(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">30.ls2</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Leak_Locate</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
            </span><span style="color: rgba(0, 0, 255, 1)">if</span> SD_Leak_Locate_Main2 &gt;<span style="color: rgba(0, 0, 0, 1)"> SD_Leak_Locate_Main1:
                SD_Leak_Locate_Main1 </span>=<span style="color: rgba(0, 0, 0, 1)"> SD_Leak_Locate_Main2
      
      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">获取总院信息</span>
<span style="color: rgba(0, 0, 0, 1)">
      LY_Temp_Main </span>= 0.0<span style="color: rgba(0, 0, 0, 1)">
      LY_Temp_UPS </span>= 0.0
      
      <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 获取温度值(@ref)</span>
      LY_Temp_Main = self.get_temperature_value(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">32.wsd3</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
      LY_Temp_UPS </span>= self.get_temperature_value(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">32.wsd1</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
      
      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 获取漏水判断值</span>
      LY_Leak_Judge_Main = self.get_leak_judge_value(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">32.mk</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Path0</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
      LY_Leak_Judge_UPS </span>= self.get_leak_judge_value(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">32.mk</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Path1</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)


      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 构建分院报告</span>
      msgBody = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">分院院区</span><span style="color: rgba(128, 0, 0, 1)">"</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> SD_Temp_Main ==<span style="color: rgba(0, 0, 0, 1)"> 0:
            msgBody </span>+= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">,中心机房温度探测器故障</span><span style="color: rgba(128, 0, 0, 1)">"</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> SD_Temp_UPS ==<span style="color: rgba(0, 0, 0, 1)"> 0:
            msgBody </span>+= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">,电源机房温度探测器故障</span><span style="color: rgba(128, 0, 0, 1)">"</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> SD_Temp_Main &gt;<span style="color: rgba(0, 0, 0, 1)"> 0:
            msgBody </span>+= f<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">,中心机柜温度{SD_Temp_Main}</span><span style="color: rgba(128, 0, 0, 1)">"</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> SD_Temp_UPS &gt;<span style="color: rgba(0, 0, 0, 1)"> 0:
            msgBody </span>+= f<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">,电源机柜温度{SD_Temp_UPS}</span><span style="color: rgba(128, 0, 0, 1)">"</span>
      
      <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 漏水状态判断</span>

      <span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(0, 0, 255, 1)">not</span> SD_Leak_Judge_Main1 <span style="color: rgba(0, 0, 255, 1)">and</span> <span style="color: rgba(0, 0, 255, 1)">not</span><span style="color: rgba(0, 0, 0, 1)"> SD_Leak_Judge_Main2:
            msgBody </span>+= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">,中心机柜无漏水</span><span style="color: rgba(128, 0, 0, 1)">"</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> SD_Leak_Judge_Main1 <span style="color: rgba(0, 0, 255, 1)">or</span><span style="color: rgba(0, 0, 0, 1)"> SD_Leak_Judge_Main2:
            msgBody </span>+= f<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">,中心机柜漏水,漏水位置传感绳第{SD_Leak_Locate_Main1}米处</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      
      msgBody </span>+= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">。</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">

      msgBody </span>+= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">\n总院院区</span><span style="color: rgba(128, 0, 0, 1)">"</span>      
      
      <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 构建总院院区报告</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> LY_Temp_Main ==<span style="color: rgba(0, 0, 0, 1)"> 0:
            msgBody </span>+= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">,中心机柜温度探测器故障</span><span style="color: rgba(128, 0, 0, 1)">"</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> LY_Temp_UPS ==<span style="color: rgba(0, 0, 0, 1)"> 0:
            msgBody </span>+= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">,电源机柜温度探测器故障</span><span style="color: rgba(128, 0, 0, 1)">"</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> LY_Temp_Main &gt;<span style="color: rgba(0, 0, 0, 1)"> 0:
            msgBody </span>+= f<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">,中心机柜温度{LY_Temp_Main}</span><span style="color: rgba(128, 0, 0, 1)">"</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> LY_Temp_UPS &gt;<span style="color: rgba(0, 0, 0, 1)"> 0:
            msgBody </span>+= f<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">,电源机柜温度{LY_Temp_UPS}</span><span style="color: rgba(128, 0, 0, 1)">"</span>
      
      <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 漏水状态判断</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(0, 0, 255, 1)">not</span><span style="color: rgba(0, 0, 0, 1)"> LY_Leak_Judge_Main:
            msgBody </span>+= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">,中心机柜无漏水</span><span style="color: rgba(128, 0, 0, 1)">"</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> LY_Leak_Judge_Main:
            msgBody </span>+= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">,中心机柜漏水</span><span style="color: rgba(128, 0, 0, 1)">"</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(0, 0, 255, 1)">not</span><span style="color: rgba(0, 0, 0, 1)"> LY_Leak_Judge_UPS:
            msgBody </span>+= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">,电源机柜无漏水</span><span style="color: rgba(128, 0, 0, 1)">"</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> LY_Leak_Judge_UPS:
            msgBody </span>+= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">,电源机柜漏水</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      
      msgBody </span>+= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">。</span><span style="color: rgba(128, 0, 0, 1)">"</span>
      
      <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> msgBody

</span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(128, 0, 128, 1)">__name__</span> == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">__main__</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">:
    </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 创建API实例(会自动登录)</span>
    api =<span style="color: rgba(0, 0, 0, 1)"> api_Temperature()
   
    </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 获取所有值</span>
    getall =<span style="color: rgba(0, 0, 0, 1)"> api.get_all_value()
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(getall)</pre>
</div>
<span class="cnblogs_code_collapse">api_Temperature.py</span></div>
<div>创建包含机房巡检的工具注册表类</div>
<div>
<div class="cnblogs_code"><img id="code_img_closed_830170c5-4dd3-44fe-85a8-a2e343b2d4b1" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_830170c5-4dd3-44fe-85a8-a2e343b2d4b1" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_830170c5-4dd3-44fe-85a8-a2e343b2d4b1" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> my_calculator_tool2.py# 导入所需的模块和库</span>
<span style="color: rgba(0, 0, 255, 1)">import</span> ast            <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 抽象语法树模块,用于解析表达式</span>
<span style="color: rgba(0, 0, 255, 1)">import</span> operator         <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 操作符模块,提供基本的数学操作函数</span>
<span style="color: rgba(0, 0, 255, 1)">import</span> math             <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 数学模块,提供数学函数</span>
<span style="color: rgba(0, 0, 255, 1)">from</span> hello_agents <span style="color: rgba(0, 0, 255, 1)">import</span> ToolRegistry<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 从hello_agents导入ToolRegistry类</span>
<span style="color: rgba(0, 0, 255, 1)">from</span> api_Temperature <span style="color: rgba(0, 0, 255, 1)">import</span> api_Temperature   <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">取机房数据</span>

<span style="color: rgba(0, 0, 255, 1)">def</span> my_room_temp(expression: str) -&gt;<span style="color: rgba(0, 0, 0, 1)"> str:
    </span><span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(128, 0, 0, 1)">机房巡检</span><span style="color: rgba(128, 0, 0, 1)">"""</span>
    <span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(0, 0, 255, 1)">not</span> expression.strip():                      <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 检查表达式是否为空</span>
      <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">巡项项目不能为空</span><span style="color: rgba(128, 0, 0, 1)">"</span>                  <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 如果为空则返回错误信息</span>

    <span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">:   
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">机房</span><span style="color: rgba(128, 0, 0, 1)">"</span> <span style="color: rgba(0, 0, 255, 1)">in</span> expression <span style="color: rgba(0, 0, 255, 1)">or</span> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">温度</span><span style="color: rgba(128, 0, 0, 1)">"</span> <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> expression:            
            room_api </span>=<span style="color: rgba(0, 0, 0, 1)"> api_Temperature()
            msgBody </span>=<span style="color: rgba(0, 0, 0, 1)"> room_api.get_all_value()
            </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 确保返回有效信息</span>
            <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> msgBody:
                </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> msgBody
            </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">:
                </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">未能获取到机房信息</span><span style="color: rgba(128, 0, 0, 1)">"</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">漏水</span><span style="color: rgba(128, 0, 0, 1)">"</span> <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> expression:
            room_api </span>=<span style="color: rgba(0, 0, 0, 1)"> api_Temperature()
            msgBody </span>=<span style="color: rgba(0, 0, 0, 1)"> room_api.get_all_value()
            </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 确保返回有效信息</span>
            <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> msgBody:
                </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> msgBody
            </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">:
                </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">未能获取到漏水信息</span><span style="color: rgba(128, 0, 0, 1)">"</span>

    <span style="color: rgba(0, 0, 255, 1)">except</span><span style="color: rgba(0, 0, 0, 1)"> Exception as e:
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> f<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">查询失败: {str(e)}</span><span style="color: rgba(128, 0, 0, 1)">"</span>          <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 捕获异常并返回错误信息</span>

<span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> _eval_node(node, operators, functions):
    </span><span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(128, 0, 0, 1)">简化的表达式求值</span><span style="color: rgba(128, 0, 0, 1)">"""</span>
    <span style="color: rgba(0, 0, 255, 1)">if</span> isinstance(node, ast.Constant):            <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 如果节点是常量类型</span>
      <span style="color: rgba(0, 0, 255, 1)">return</span> node.value                           <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 直接返回常量值</span>
    <span style="color: rgba(0, 0, 255, 1)">elif</span> isinstance(node, ast.BinOp):               <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 如果节点是二元运算类型</span>
      left = _eval_node(node.left, operators, functions)   <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 递归计算左子树</span>
      right = _eval_node(node.right, operators, functions) <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 递归计算右子树</span>
      op = operators.get(type(node.op))         <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 获取对应的操作符函数</span>
      <span style="color: rgba(0, 0, 255, 1)">return</span> op(left, right)                      <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 执行运算并返回结果</span>
    <span style="color: rgba(0, 0, 255, 1)">elif</span> isinstance(node, ast.Call):                <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 如果节点是函数调用类型</span>
      func_name = node.func.id                  <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 获取函数名</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> func_name <span style="color: rgba(0, 0, 255, 1)">in</span> functions:                  <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 检查函数是否受支持</span>
            args = <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 递归计算参数值</span>
            <span style="color: rgba(0, 0, 255, 1)">return</span> functions(*args)       <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 调用函数并返回结果</span>
    <span style="color: rgba(0, 0, 255, 1)">elif</span> isinstance(node, ast.Name):                <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 如果节点是名称类型(如变量或常量)</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> node.id <span style="color: rgba(0, 0, 255, 1)">in</span> functions:                  <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 检查名称是否在函数列表中</span>
            <span style="color: rgba(0, 0, 255, 1)">return</span> functions               <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 返回对应的值</span>

<span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> create_calculator_registry():
    </span><span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(128, 0, 0, 1)">创建包含机房巡检的工具注册表</span><span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(0, 0, 0, 1)">
    registry </span>= ToolRegistry()                     <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 创建ToolRegistry实例</span>

    <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 注册计算器函数</span>
<span style="color: rgba(0, 0, 0, 1)">    registry.register_function(
      name</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">my_room_temp</span><span style="color: rgba(128, 0, 0, 1)">"</span>,                     <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 工具名称</span>
      description=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">机房巡检工具,支持温度,漏水检测</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 工具描述</span>
      func=my_room_temp                           <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 对应的函数</span>
<span style="color: rgba(0, 0, 0, 1)">    )

    </span><span style="color: rgba(0, 0, 255, 1)">return</span> registry                                 <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 返回注册表实例</span>

<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 使用示例</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(128, 0, 128, 1)">__name__</span> == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">__main__</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">:
    msgBody</span>=my_room_temp(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">机房巡检</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(msgBody)</pre>
</div>
<span class="cnblogs_code_collapse">my_room_temp_tool.py</span></div>
<p>主界面,通过gradio库,实现聊天对话界面。</p>
<div class="cnblogs_code"><img id="code_img_closed_ac02633f-b3de-4fa1-b2cc-9300facd0c64" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_ac02633f-b3de-4fa1-b2cc-9300facd0c64" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_ac02633f-b3de-4fa1-b2cc-9300facd0c64" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> gradio as gr
</span><span style="color: rgba(0, 0, 255, 1)">from</span> hello_agents <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> SimpleAgent
</span><span style="color: rgba(0, 0, 255, 1)">from</span> HelloAgentsLLM <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> HelloAgentsLLM
</span><span style="color: rgba(0, 0, 255, 1)">from</span> my_room_temp_tool <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> create_calculator_registry

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 创建LLM实例</span>
llm =<span style="color: rgba(0, 0, 0, 1)"> HelloAgentsLLM()

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 创建工具注册表</span>
registry =<span style="color: rgba(0, 0, 0, 1)"> create_calculator_registry()

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 创建智能体</span>
agent =<span style="color: rgba(0, 0, 0, 1)"> SimpleAgent(
    name</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">机房巡检助手</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
    llm</span>=<span style="color: rgba(0, 0, 0, 1)">llm,
    system_prompt</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">你是一个机房巡检助手,专门负责监控和报告机房的温度及漏水情况。当用户询问机房相关信息时,你应该使用my_room_temp工具来获取实时数据。</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
)

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 重写agent的run方法,使其能够调用我们的工具</span>
<span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> agent_run_with_tools(input_text):
    </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 检查是否需要调用工具</span>
    <span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">机房</span><span style="color: rgba(128, 0, 0, 1)">"</span> <span style="color: rgba(0, 0, 255, 1)">in</span> input_text <span style="color: rgba(0, 0, 255, 1)">or</span> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">温度</span><span style="color: rgba(128, 0, 0, 1)">"</span> <span style="color: rgba(0, 0, 255, 1)">in</span> input_text <span style="color: rgba(0, 0, 255, 1)">or</span> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">漏水</span><span style="color: rgba(128, 0, 0, 1)">"</span> <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> input_text:
      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 调用工具获取数据</span>
      tool_result = registry.execute_tool(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">my_room_temp</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, input_text)
      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 构造最终回复</span>
      messages =<span style="color: rgba(0, 0, 0, 1)"> [
            {</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">role</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">user</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">content</span><span style="color: rgba(128, 0, 0, 1)">"</span>: f<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">根据以下机房巡检结果,用自然语言回答用户问题:{input_text}\n\n巡检结果:{tool_result}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">}
      ]
      response </span>=<span style="color: rgba(0, 0, 0, 1)"> llm.think(messages)
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> response
    </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">:
      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 直接调用agent.run</span>
      <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> agent.run(input_text)

</span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> agent_chat(message, history):
    </span><span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(128, 0, 0, 1)">
    与agent进行对话
    </span><span style="color: rgba(128, 0, 0, 1)">"""</span>
    <span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">:
      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 运行agent</span>
      response =<span style="color: rgba(0, 0, 0, 1)"> agent_run_with_tools(message)
      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 确保返回的是字符串而不是None</span>
      <span style="color: rgba(0, 0, 255, 1)">return</span> response <span style="color: rgba(0, 0, 255, 1)">or</span> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">抱歉,我没有收到有效的回复。</span><span style="color: rgba(128, 0, 0, 1)">"</span>
    <span style="color: rgba(0, 0, 255, 1)">except</span><span style="color: rgba(0, 0, 0, 1)"> Exception as e:
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> f<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">发生错误: {str(e)}</span><span style="color: rgba(128, 0, 0, 1)">"</span>

<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 创建Gradio界面</span>
with gr.Blocks(title=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">机房巡检助手</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">) as demo:
    gr.Markdown(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)"># 机房巡检助手--   《Hello-Agents从零开始构建智能体》之毕业设计</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
    gr.Markdown(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">这是一个聊天界面,可以与机房巡检助手进行交互,并自动调用my_room_temp工具。</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
   
    chatbot </span>= gr.Chatbot(label=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">对话历史</span><span style="color: rgba(128, 0, 0, 1)">"</span>, type=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">messages</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
    msg </span>= gr.Textbox(label=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">输入消息</span><span style="color: rgba(128, 0, 0, 1)">"</span>, placeholder=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">请输入您的问题,例如:机房温度是多少?</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
    clear </span>= gr.Button(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">清除对话</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
    designer </span>= gr.Markdown(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">设计:西湖谊生</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
   
    </span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> add_user_message(history, message):
      </span><span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(128, 0, 0, 1)">添加用户消息到历史记录</span><span style="color: rgba(128, 0, 0, 1)">"""</span>
      <span style="color: rgba(0, 0, 255, 1)">return</span> history + [{<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">role</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">user</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">content</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: message}]
   
    </span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> bot_response(history):
      </span><span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(128, 0, 0, 1)">生成机器人回复并添加到历史记录</span><span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(0, 0, 0, 1)">
      user_message </span>= history[-1][<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">content</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">]
      bot_reply </span>=<span style="color: rgba(0, 0, 0, 1)"> agent_chat(user_message, history)
      history.append({</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">role</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">assistant</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">content</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: bot_reply})
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> history, <span style="color: rgba(128, 0, 0, 1)">""</span><span style="color: rgba(0, 0, 0, 1)">
   
    msg.submit(add_user_message, , ).then(
      bot_response, ,
    )
    clear.click(</span><span style="color: rgba(0, 0, 255, 1)">lambda</span>: [], None, chatbot, queue=<span style="color: rgba(0, 0, 0, 1)">False)

</span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(128, 0, 128, 1)">__name__</span> == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">__main__</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">:
    demo.launch(server_name</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">0.0.0.0</span><span style="color: rgba(128, 0, 0, 1)">"</span>, server_port=7861, share=False)</pre>
</div>
<span class="cnblogs_code_collapse">app.py</span></div>
<p>&nbsp;<br>编写README.md,将代码提交到远程仓库。</p>
<p>&nbsp;</p>



</div><br><br>
来源:https://www.cnblogs.com/yisheng163/p/19258818
頁: [1]
查看完整版本: Hello-Agents 《从零开始构建智能体》实践