乐于分享
好东西不私藏

OpenClaw之庖丁解牛

OpenClaw之庖丁解牛

#openclaw #AI #deepseek

1.前言

随着AI的快速发展,全民掀起了热热闹闹的养虾潮,对于大部分来说,都觉得新奇和迷惑;为此,跟随笔者抽丝剥茧去了解这个虾是怎样逐步建立起来的,需要一点点的编程经验,这里主要学习了B站up主飞天闪客的视频创作内容编写。工作环境:python3安装包: pip3 install openai

2.大模型API调用

市面上大部分的大模型厂商,都提供了一个API接口,可以直接访问大模型。这里以是用Deepseek为例,具体API调用文档参考 https://api-docs.deepseek.com/参考以上网址的信息,可以先编写python代码以验证链接是否成功。

#claw00.pyimport osfrom openai import OpenAIclient = OpenAI(api_key="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxx", base_url="https://api.deepseek.com")response = client.chat.completions.create(    model="deepseek-chat",    messages=[        {"role": "system", "content": "You are a helpful assistant"},        {"role": "user", "content": "Hello"},    ],    stream=False)print(response.choices[0].message.content)
以上代码的api_key为对应大模型所申请的,注意,在每次创建API-key时一定要记得保存,它只会显示一次。将申请的代码替换代码对应中的api-key="sk-xxxxxxxxxxx"即可,相当于通过api的方式和大模型进行聊天。messages里面有两个角色,一个为系统的角色,该角色的用途是告知大模型在扮演何种角色,另外一个为用户的角色,发送给大模型的内容为"Hello"。代码最后打印接收到的是大模型回复内容。
以上为实际的运行结果,代表已经和大模型正常连接。

3.与大模型对话

上面仅仅代表和大模型连接成功,现在开始模仿与AI对话,进一步修改python代码。

#claw01.pyimport osfrom openai import OpenAIclient = OpenAI(api_key="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxx", base_url="https://api.deepseek.com")while True:    user_input = input("\nYOU: ")    response = client.chat.completions.create(        model="deepseek-chat",        messages=[            {"role": "system", "content": "You are a helpful assistant"},            {"role": "user", "content": user_input},        ],        stream=False    )    print(response.choices[0].message.content)

运行结果如下图片,但是发现当继续问AI,”上面的结果再+1“的时候,大模型回复出现错误,这是由于没有将之前的结果保存下来,没有上下文的结果直接问AI,导致AI无法回答。

为此,需要再将代码继续优化。

#claw02.pyimport osfrom openai import OpenAIclient = OpenAI(api_key="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxx",  base_url="https://api.deepseek.com")messages=[]messages.append({"role": "system", "content": "You are a helpful assistant"})while True:    user_input = input("\nYOU: ")    if user_input.lower() == 'quit':        break    messages.append({"role": "user", "content": user_input})    response = client.chat.completions.create(        model="deepseek-chat",        messages=messages,        stream=False    )    reply = response.choices[0].message.content    messages.append({"role":"assistant", "content": reply})    print(reply)

可以看到定义了messages,在后面是用append方法将之前的上下文进行保存,从而实现AI能正常根据上下文来聊天。聊天结果和正常在https://chat.deepseek.com/ 网站聊天类似。

4.Agent实现

如下图所示,以下为Agent的简要运行原理图示:
首先用户User下达的指令,将内容告知Agent,Agent获得用户下达的命令,并将信息转发给大模型,而大模型根据指定的用户角色定义来返回指定的内容,其内容通常是能运行的命令操作,Agent在运行指定的指令,从而为用户完成指定的操作。
#claw03_agent.pyimport osfrom openai import OpenAIclient = OpenAI(api_key="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxx", base_url="https://api.deepseek.com")messages=[]messages.append({"role": "system", "content": open("Agent.md","r", encoding="utf-8").read()})while True:    user_input = input("\nYOU: ")    if user_input.lower() == 'quit':        break    messages.append({"role": "user", "content": user_input})    print("\n-----------Agent Loop begining-------------\n")    while True:        response = client.chat.completions.create(            model="deepseek-chat",            messages=messages,            stream=False        )        reply = response.choices[0].message.content        messages.append({"role":"assistant", "content": reply})        print(f"【AI】{reply}")        if reply.strip().startswith("完成:"):            print("\n-----------Agent Loop End------------------\n")            print(f"【AI】{reply.strip().split('完成:')[1].strip()}")            break        command = reply.strip().split("命令:")[1].strip()        command_result = os.popen(command).read()        content = f"执行完毕{command_result}"        print(f"【Agent】{content}")        messages.append({"role": "user", "content": content})

以上为对应python的实现,先根据对应的角色文件为系统定义角色内容,定义的文件名为Agent.md,其本质目的是让大模型返回指定的命令,以及怎样去结束,这样在Agent根据接收到命令,通过os.popen(command)运行对应的指令。

如上图所示,为claw03_agent.py运行的结果,根据B站的链接地址,下载对应的视频,并将其转为mp3文件。从结果来看,第一次运行"youtube-dl -x --audio-format mp3 https://www.bilibili.com/video/BV1vT411i7ET"这个命令,其实是错误的,后来再次与大模型对话,返回的命令"yt-dlp -x --audio-format mp3 https://www.bilibili.com/video/BV1vT411i7ET"从结果可知,返回的结果是正确的,且正常下载了对应的文件,并生成对应的mp3文件。

5.添加技能

而Agent为了获得某项技能,必须给它指定的操作,或者告知大模型以什么样的路径可以做到,那么就可以编写对应的skill.md文件了。而对应skill.md文件可以自己编写,也可以借用网络成千上万的网友编写的skill.md,按需去找即可。

6.本地部署

经过以上步骤,实现了Openclaw的功能,但又有一个疑问,Openclaw都能远程操控,从结果来看,之前的程序,还差一个壳,为此为了模拟远程调用大模型干同样的活,我们可以在本地建一个服务器,通过在内网访问测试,达到同样的目的。

#claw05_agent.pyimport osfrom openai import OpenAIfrom flask import Flask, request, jsonifyclient = OpenAI(api_key="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxx", base_url="https://api.deepseek.com")messages=[]messages.append({"role": "system", "content": open("Agent.md","r", encoding="utf-8").read()})messages.append({"role": "system", "content": open("SKILL.md","r", encoding="utf-8").read()})app = Flask(__name__)HTML = open("index.html", "r", encoding="utf-8").read()@app.get("/")def index():    return HTML@app.post("/chat")def chat():    user_input = request.json["message"]    print(f"【用户】{user_input}")    messages.append({"role": "user", "content": user_input})    steps = []    while True:        response = client.chat.completions.create(            model="deepseek-chat",            messages=messages,            stream=False        )        reply = response.choices[0].message.content        messages.append({"role":"assistant", "content": reply})        print(f"\033[32m【AI】{reply}\033[0m")        steps.append({"type":"ai","content":reply})        if reply.strip().startswith("完成:"):            break        command = reply.strip().split("命令:")[1].strip()        command_result = os.popen(command).read()        print(f"【Agent】执行完毕{command_result}")        steps.append({"type":"cmd","content": command_result})        messages.append({"role": "user", "content": f"执行完毕{command_result}"})    return jsonify(steps=steps)if __name__ == "__main__":    app.run(host="0.0.0.0", debug=True, port=5000)
这里使用了flask框架,直接在本地启用了一个服务,端口为5000,另外在编写对应的html,为了快速达到效果,这里借助了deepseek,自动生成了一个html文件,实现对应的功能。
以上为服务端在启动的时候,所提示的内容信息。一个是本地启动的接口为https://127.0.0.1:5000;另外一个为内网的启动接口 https://192.168.2.99:5000 。打印结果分别展示了具体的聊天过程。
如下图所示为本地端访问,与大模型对话的过程。
下图为手机端访问的过程,包括压缩打包所有的txt文件,以及在本地端可以看到对应的文件生成过程。

结语

从怎样与大模型通信,到怎么与大模型对话,以及Agent的工作原理,再到Skill的作用,以及在Agent的本地部署,这是简易版的Openclaw实现逻辑,实际的Openclaw远远比这个复杂,只是为了更好的理解Openclaw怎么工作的,以上仅仅代表笔者的理解;以及向网络上那些大牛学习的成果。

参考

  • • https://www.bilibili.com/video/BV19hwTzwETF/?spm_id_from=0.0.homepage.video_card.click
  • • https://skills.sh/