前言
我们常常幻想着火影忍者里的影分身之术可以帮助我们同时多线程的处理日常事务。尽管在现实世界中,我们没有办法做到,但是在数字世界中,我们可以通过双手创建属于自己的个人智能助手!
我们认为一个个人智能助手应当具备的目标:它可以在你不在的时候,帮助你处理一些简单而又重复的事物,就如同游戏脚本一般。但是,游戏脚本首先花钱,其次并不是为你量身定做,第三离开了游戏他什么也不是。
而我们的个人智能助手则是在系统级别模拟你的存在,不仅可以帮助你进行游戏的自动化操作,而且可以处理除了游戏之外的事情。如果不观察客观世界你在不在,很难发现到底是不是真实的你在操作。
更重要的是,它可以随着你的能力的提升而不断的增强自身能力,并且搭配出属于你自己个性的思维方式,甚至最后完全可以通过机器学习,深度学习等手段,完成智能化的最后一步。
当然,我们这里,仅仅是开始,但是能够帮助我们做的事情已经足够多了。本人即是此产品的第一受益人。好了,闲话不多说了,我们开始进入正题。
整体框架
我们大致思路是我们想设计一个虚拟的人,它具有大脑,然后可以进行观察,进行操作。
大脑的构成
大脑的功能有长时记忆大脑模块,短时记忆大脑模块,长时记忆大脑模块主要用来记忆一些常识,这些常识可能在各个任务中都能用到,比如自己是谁,自己可以做的基本操作,以及自己的任务有哪些等等。而短时记忆大脑也称作工作大脑则是记录和特定任务相关的数据,以及具体的步骤。
比如这里以上网查阅我的博客为例。短时记忆大脑主要记录执行这个操作的具体步骤:第一步要找到浏览器,第二步双击它,第三步,找到地址栏,第四步输入百度网址,第五步输入关键字“刘炫320 CSDN”,第六步点击回车,等等。而长期记忆大脑则主要记忆基础操作,比如,单击操作、双击操作、按下按键、观察指定目标等等,这些不依赖具体任务而发生变化。
另外,我们暂时模仿人类的大脑执行方式,不进行多线程操作,因为人类也不会同步进行2件事情,都是以中断的方式进行的。因此我们这里采用单线程进行,以后熟悉了,我们再让个人智能助手具备超人能力。
执行行为的习惯
在执行行为过程中,我们有两种做法。一种是比较笨但是面对的环境相对固定,一般在一个比较稳定的岗位上,如流水线,都是这样的场景。它的做事方式是按照规定操作一步一步来,不怎么考虑实时的变化,因为所有的事情都是一成不变的,只要按照步骤来,接下来的情况都是固定的。
另一种做法则是比较灵活的,每执行一个行为后,我们都会去看反应,看看是否需要根据外界的变化调整自己的行为。这种一般都是在活跃或者交互多的场景下,例如销售、制造、实验等。
那么我们真正的行为是如何的呢?为了达到平衡,我们通常会结合这两种方法,在一些我们认为非常熟悉,甚至成竹在胸的行为上,我们不会去检验我们的做法所带来的变化,因为我们能够预期,或者不会改变未来发生的事情。而在一些关键节点上,我们还是需要反复的确认我们执行是否正确。
特定任务
特定任务就是特定场景下需要执行一系列行为并达成最终结果的集合。它包含两个部分,一个部分是一系列确定行为,另一部分一定会有预期结果。因此我们在构建任务的时候,只需要考虑这两个部分即可。
代码实现
光说不练假把式。我们将会在下面一步一步实现我们的构想。
热身准备
我们需要准备的东西有:
Python 编写程序的语言
random 随机函数
time 时间停止函数
pyautogui 自动化操作库
logging 日志记录模块
具体用途我们会在接下来的模块中详细讲解。
智能助手主体
在这个模块,我们主要是构建一个助手的主题,包括她的一些属性信息和她的一些本能反应,例如点击鼠标,观察屏幕,滑动屏幕等,这些操作我们认为是长时记忆,应用在任何领域时都要会的。
而与任务相关的我们放置到knowledge属性中,这个和具体的任务有关,在任务中赋予代理特定的知识,而且一旦她脱离了这个任务,她就会忘记这些内容。
下面是一个基本的代码,大家也可以后续添加基本操作。另外,我在编码中使用了汉语编码,是为了展示时更容易理解,建议大家还是纯英文编程。
import random
import time
import pyautogui
import logging
class Agent:
def __init__(self):
self.name="艾达"
self.knowledge=[]
logging.basicConfig(filename="log.txt",filemode="w", level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
self.logger = logging.getLogger(__name__)
def set_knowledge(self,knowledge):
"""
设置知识库
:param knowledge:
:return:
"""
self.knowledge=knowledge
def wait(self,sleep_sec=-1):
"""
停止时间
:return:
"""
if sleep_sec==-1:
sleep_sec=random.randint(1,3)
time.sleep(sleep_sec)
def find_location(self,location_name):
"""
找到特定位置
:param location_name:
:return:
"""
for point in self.knowledge:
if point.name==location_name:
return point.location
def find_color(self,goal_name):
"""
找到特定位置的颜色
:param goal_name:
:return:
"""
for point in self.knowledge:
if point.name==goal_name:
return point.color
def click_icon(self,icon_name,wait=0):
"""
点击按钮
:param icon_name:
:param wait:
:return:
"""
(x, y) = self.find_location(icon_name)
self.logger.info("点击了按钮"+str(icon_name)+":"+str(x)+","+str(y))
pyautogui.click(x, y)
time.sleep(wait)
def scroll_mouse(self,step=10):
"""
滑动鼠标滚轮
:param step: 大于0会显示更多的上部分的屏幕
:return:
"""
pyautogui.scroll(step)
def watch_screen(self,icon_name):
"""
观察屏幕的点是否符合目标值
:param icon_name:
:return:
"""
img = pyautogui.screenshot()
location=self.find_location(icon_name)
color = img.getpixel(location)
goal_color=self.find_color(icon_name)
if color==goal_color:
return True
else:
return False
def initial_wait(self,sleep_sec=15):
def initial_wait(self,sleep_sec=15):
"""
初始化等待
:param sleep_sec:
:return:
"""
print("智能机器人"+self.name+"开始启动...")
time.sleep(sleep_sec)
print("一切准备就绪,开始执行任务。")
特定任务主体
在这个部分,我们主要是构建一个特定任务,它包含自己的领域知识以及需要执行的代理人,还有想要执行的一系列操作,这些操作就如同指南一样,引导着代理人进行操作。这些记忆我们称为都是短时记忆。
这里的行为分为两部分,一种是不需要判断的,如go_collection
函数,另一种是需要判断的,如check_buttery
函数,最后都会集成到run
函数中被主函数所调用。
from point import Point
class CustomTask:
def __init__(self,task_name):
self.name=task_name
self.agent=None
self.knowledge=[]
self.create_knowledge()
def create_knowledge(self):
"""
特定领域知识,存放在这里
:return:
"""
knowledge=[]
point= Point("采集资源",(0,0),(0,0,0))
knowledge.append(point)
self.knowledge=knowledge
def set_agent(self,agent):
"""
设置代理
:param agent:
:return:
"""
self.agent=agent
self.agent.knowledge=self.knowledge
def go_collection(self):
"""
具体采集
:return:
"""
self.agent.click_icon("采集资源",1)
self.agent.click_icon("最大负重",1)
self.agent.click_icon("编队3加载",1)
self.agent.click_icon("选择武将",1)
self.agent.click_icon("自动派遣",1)
self.agent.click_icon("派遣完成",1)
self.agent.click_icon("出征",1)
self.agent.click_icon("继续出征",1)
def buy_buttery(self):
"""
购买电量
:return:
"""
self.agent.click_icon("购买电量加号",2)
self.agent.click_icon("钻石购买电量",2)
self.agent.click_icon("购买电量返回",1)
def check_buttery(self):
"""
检查是否需要购买点亮
:return:
"""
if self.agent.watch_screen("电量不足"):
self.agent.logger.info("需要买电")
self.buy_buttery()
else:
self.agent.logger.info("需要买电")
def can_go_out(self,collection_team):
"""
是否可以出征
:param collection_team:
:return:
"""
if self.agent.watch_screen(collection_team):
return False
else:
return True
def init_agent(self):
"""
初始化代理
:return:
"""
self.agent.initial_wait()
def run_collection(self,collection_team,wait_sec):
"""
执行采集
:param collection_team: 需要采集的队伍数量
:param wait_sec: 多少时间检查一次
:return:
"""
while self.can_go_out(collection_team):
self.check_buttery()
self.go_collection()
self.agent.wait(wait_sec)
主函数
这里以采集行为为例,我们使用五队采集,每次采集30秒,就可以完成自动采集的操作了。其他行为也可以参阅此行为的实现。
from task import CustomTask
from Agent import Agent
if __name__ == '__main__':
goal_task=CustomTask("自定义任务")
aida=Agent()
goal_task.set_agent(aida)
goal_task.init_agent()
# 采集5个队伍,每次采集等待30秒
goal_task.run_collection(collection_team=5,wait_sec=30)
知识采样
既然我们要模仿自己的行为,就要给出一些知识,我们这里以屏幕上需要点击的点的位置和颜色作为知识进行采集。因此需要一个知识采集的部分
import os,time
import pyautogui as pag
try:
while True:
print("Press Ctrl-C to end")
x,y = pag.position() #返回鼠标的坐标
posStr="Position:"+str(x).rjust(4)+','+str(y).rjust(4)
print (posStr)#打印坐标
img = pag.screenshot()
color = img.getpixel((x, y))
print("该坐标的像素点的颜色是:{}".format(color))
time.sleep(0.2)
os.system('cls')#清除屏幕
except KeyboardInterrupt:
print ('end....')
另外,我们也需要一些数据结构存储我们的知识,这里同样以上述例子为基础,存储一个点的位置和颜色。
class point:
def __init__(self,name="None",location=None,color=None):
self.name=name
self.location=location
self.color=color
经过以上部分,我们就能够做出一个属于自己的人工智能助手了,其中的一些逻辑都蕴含到代码里,我们这里不过多讲解,大家可以自己尝试。
github地址:https://github.com/liuxuan320/AIDA
祝大家早日实现自己的多重影分身之术。