多重影分身之術!快來領取屬於自己的個人智能助手!

前言

我們常常幻想着火影忍者裏的影分身之術可以幫助我們同時多線程的處理日常事務。儘管在現實世界中,我們沒有辦法做到,但是在數字世界中,我們可以通過雙手創建屬於自己的個人智能助手!

我們認爲一個個人智能助手應當具備的目標:它可以在你不在的時候,幫助你處理一些簡單而又重複的事物,就如同遊戲腳本一般。但是,遊戲腳本首先花錢,其次並不是爲你量身定做,第三離開了遊戲他什麼也不是。

而我們的個人智能助手則是在系統級別模擬你的存在,不僅可以幫助你進行遊戲的自動化操作,而且可以處理除了遊戲之外的事情。如果不觀察客觀世界你在不在,很難發現到底是不是真實的你在操作。

更重要的是,它可以隨着你的能力的提升而不斷的增強自身能力,並且搭配出屬於你自己個性的思維方式,甚至最後完全可以通過機器學習,深度學習等手段,完成智能化的最後一步。

當然,我們這裏,僅僅是開始,但是能夠幫助我們做的事情已經足夠多了。本人即是此產品的第一受益人。好了,閒話不多說了,我們開始進入正題。

整體框架

我們大致思路是我們想設計一個虛擬的人,它具有大腦,然後可以進行觀察,進行操作。

大腦的構成

大腦的功能有長時記憶大腦模塊,短時記憶大腦模塊,長時記憶大腦模塊主要用來記憶一些常識,這些常識可能在各個任務中都能用到,比如自己是誰,自己可以做的基本操作,以及自己的任務有哪些等等。而短時記憶大腦也稱作工作大腦則是記錄和特定任務相關的數據,以及具體的步驟。

比如這裏以上網查閱我的博客爲例。短時記憶大腦主要記錄執行這個操作的具體步驟:第一步要找到瀏覽器,第二步雙擊它,第三步,找到地址欄,第四步輸入百度網址,第五步輸入關鍵字“劉炫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

祝大家早日實現自己的多重影分身之術。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章