故事開始於2010年7月28日,「未來道具研究所」社團的兩人,岡部倫太郎和椎名真由理去
秋葉原廣播會館參加中鉢博士的
時間旅行理論發表會,見到了年僅18歲就在《
科學》雜誌上發表學術論文的天才少女牧瀨紅莉栖。發表會結束不久後,在會館8樓深處,岡部發現了身上滿是鮮血的紅莉栖。驚慌失措的他帶著真由理立刻離開會館,給社團另一成員橋田至發送一條電子郵件告知這一事件。然而發送後的瞬間,岡部愕然發現街道人群消失,廣播會館及周圍早已因不明
人造衛星墜落緣故被封鎖,沒有人記得他所經歷的事件。
數小時後,岡部和阿至在大學講習現場再次遇見紅莉栖,引發一陣騷亂。對岡部所說的話感到興趣而至「未來道具研究所」的紅莉栖偶然見到了岡部他們進行的實驗,一連串研究發現岡部發送的電子郵件在一周前被收到!「未來道具研究所」研製的未來道具8號「電話
微波爐(暫名)」竟然具備著將電子郵件發送到過去這一
時間機器的功能。此時,岡部他們還不知道,這一發明,和他那封送到過去的電子郵件,已經影響了整個世界的未來……
作品中從架空的事物到實際存在的企業、大學、商品都以真名登場,現實中流傳的
都市傳說、
陰謀論、
網路語言等話題也有提及。故事的核心由自稱為
未來人、實際上存在的網路人物
約翰·提托所流傳的話語、通過主人公的言行和
手機進行操縱的遊戲系統、網絡上流傳的「la jodaso stiana(食堂之男)」等為主題的小故事等構成,並藉此虛實結合地展開故事。其開始時稍難理解,過半時突然展開。其中多有
伏筆,結尾一氣呵成。有評論稱本作品「通關後還想消除記憶再來一次」。
[7]
命運石之門第二季
看完第一季,馬上又接續第二季,所以感覺還滿連貫的,我非常的融入劇情當中。第二季主要是接續著第23β話,也就是主角岡倫沒有救到紅莉栖的世界線發展,與第一季的正統23畫有救到紅莉栖不同。
沒救到紅莉栖的岡倫,在第二季不斷欺騙自己這已經是最好的結果了,放棄了改變過去的念頭,而已死的紅莉栖這角色,則由一個以紅莉栖記憶為基礎製造出的AI─AMADEUS所取代。
第二季的時空和世界交錯比第一季更為龐大與複雜,有好幾次我都差點消化不良,角色不斷在過去、現在和未來穿梭,不得不佩服編劇能在如此眾多角色(甚至同一個角色可能不只一位)和時間線當中理清所有環節,實在了不起,當然是否有BUG出現,我沒有特別深入研究就不清楚了。
只有一些戰鬥場面,感覺比較扯吧,而且動作不算太流暢,但也已相當有水準。
第二季某些地方也呼應著第一季埋下的伏筆。最後岡倫總算醒悟,他自以為最好的世界其實並不是最好的,而變回以往那個中二病的鳳凰院凶真,展開改變過去之旅,最後成功的和第一季23話有救到紅莉栖的結果銜接。岡倫為了大家獨自奮戰的身影總是令人動容,他一個人背負的種種痛苦也讓人心疼。
所幸最後仍迎來最好的結果,紅莉栖將會獲救,而未來的岡倫則回到飄流至西元好幾年以前的真由里與鈴羽重逢。
↓最後感人的重逢一幕
這篇我要做的就是AI─AMADEUS
首先去Line 做一個帳號放紅莉栖頭像
接下來就是用python串接這個line帳號讓他活起來
其中用到了openai的人工智能聊天系統
openai的人工智能聊天系統現在最厲害的聊天機器人
代碼就修改一下我2019年做的一個金融機器人
# -*- coding: utf-8 -*-
from flask import Flask, request, abort
import requests
import json
from linebot import (
LineBotApi, WebhookHandler
)
import time
from linebot.exceptions import (
InvalidSignatureError
)
from linebot.models import (
MessageEvent, TextMessage, TextSendMessage ,SourceUser
)
from linebot.models import *
import pandas as pd
import configparser
import datetime
import json
import requests
from bs4 import BeautifulSoup
from chatgpt import ChatGPT
chatgpt = ChatGPT()
#爬玩股網
def wantgoo(sid):
target_url = 'https://www.wantgoo.com/stock/'+sid
rs = requests.session()
res = rs.get(target_url)#verify=False
soup = BeautifulSoup(res.text, 'html.parser')
content = ''
if len(soup.select('.cn div'))!=0:
for titleURL in soup.select('.cn div'):
title = titleURL.text.replace(' ','').replace('\n','').replace('\r','')
data = '{}\n'.format(title)
content += data
else:
content += '沒有搜尋到匹配的股票'
return '{}\n{}'.format(sid,content)
app = Flask(__name__,static_url_path = "/images" , static_folder = "./images/" )
#Line的一些使用者金鑰設定
line_bot_api = LineBotApi('*******************************')
handler = WebhookHandler('********************************')
host_id="******************************"
#定義路由器
@app.route("/", methods=['POST'])
def index():
# get X-Line-Signature header value
signature = request.headers['X-Line-Signature']
# get request body as text
body = request.get_data(as_text=True)
app.logger.info("Request body: " + body)
# handle webhook body
try:
handler.handle(body, signature)
except InvalidSignatureError:
abort(400)
return 'OK'
#定義接收到文字訊息要如何處理
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
if event.message.text == 'profile':
if isinstance(event.source, SourceUser):
profile = line_bot_api.get_profile(event.source.user_id)
line_bot_api.reply_message(
event.reply_token, [
TextSendMessage(text='Display name: ' + profile.display_name),
TextSendMessage(text='Status message: ' + profile.status_message)
]
)
else:
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text="Bot can't use profile API without user ID"))
#當別人密我時回報他的group_id/user_id位置
if event.source.user_id!=host_id:
if event.source.type=='group':
group_id=event.source.group_id
group_text=event.message.text+'\n'+'from'+'\n'+group_id
line_bot_api.push_message(host_id,TextSendMessage(text=group_text))
else:
guest_id=event.source.user_id
guest_text=event.message.text+'\n'+'from'+'\n'+guest_id
line_bot_api.push_message(host_id,TextSendMessage(text=guest_text))
#傳訊
if (event.source.user_id==host_id) and (event.message.text.split(':')[0]=='@傳訊'):
host_text=event.message.text
To_userid=host_text.split(':')[1]
My_message=host_text.split(':')[2:]
content=""
for i in My_message:
content+=i
line_bot_api.push_message(To_userid,TextSendMessage(text=content))
#取得個資
if (event.source.user_id==host_id) and (event.message.text.split(':')[0]=='@取得個資'):
user_id=event.message.text.split(':')[1]
profile = line_bot_api.get_profile(user_id)
line_bot_api.reply_message(event.reply_token,[
TextSendMessage(text='Display name: ' + str(profile.display_name)),
TextSendMessage(text='Status message: ' + str(profile.status_message)),
TextSendMessage(text='Photo url: ' + str(profile.picture_url))])
#玩股網診股
elif (event.message.text.split(' ')[0]=="技術健診") and (len(event.message.text.split(' '))==2):
sid=event.message.text.split(' ')[1]
content=wantgoo(sid)
line_bot_api.reply_message(event.reply_token,TextSendMessage(content))
#chatgpt
elif(event.message.text != "個股健診")&(event.message.text != "選股")&(event.message.text != "走勢預測"):
chatgpt.add_msg(f"Human:{event.message.text}?\n")
reply_msg = chatgpt.get_response().replace("AI:", "", 1)
chatgpt.add_msg(f"AI:{reply_msg}\n")
line_bot_api.reply_message(event.reply_token,TextSendMessage(text=reply_msg))
#run
if __name__ == "__main__":
app.run(host='127.0.0.1', port=2336, debug=True)
其中from chatgpt import ChatGPT
chatgpt = ChatGPT()
我們來看看這個package
from prompt import Prompt
import os
import openai
openai.api_key = "***********************************************"
class ChatGPT:
def __init__(self):
self.prompt = Prompt()
self.model = os.getenv("OPENAI_MODEL", default = "text-davinci-003")
self.temperature = float(os.getenv("OPENAI_TEMPERATURE", default = 0))
self.frequency_penalty = float(os.getenv("OPENAI_FREQUENCY_PENALTY", default = 0))
self.presence_penalty = float(os.getenv("OPENAI_PRESENCE_PENALTY", default = 0.6))
self.max_tokens = int(os.getenv("OPENAI_MAX_TOKENS", default = 240))
def get_response(self):
response = openai.Completion.create(
model=self.model,
prompt=self.prompt.generate_prompt(),
temperature=self.temperature,
frequency_penalty=self.frequency_penalty,
presence_penalty=self.presence_penalty,
max_tokens=self.max_tokens
)
return response['choices'][0]['text'].strip()
def add_msg(self, text):
self.prompt.add_msg(text)
其中from prompt import Prompt代碼如下
import os
chat_language = os.getenv("INIT_LANGUAGE", default = "zh")
MSG_LIST_LIMIT = int(os.getenv("MSG_LIST_LIMIT", default = 20))
LANGUAGE_TABLE = {
"zh": "嗨!",
"en": "Hi!"
}
class Prompt:
def __init__(self):
self.msg_list = []
self.msg_list.append(f"AI:{LANGUAGE_TABLE[chat_language]}")
def add_msg(self, new_msg):
if len(self.msg_list) >= MSG_LIST_LIMIT:
self.remove_msg()
self.msg_list.append(new_msg)
def remove_msg(self):
self.msg_list.pop(0)
def generate_prompt(self):
return '\n'.join(self.msg_list)
接下來就把該填的key填完
openai.api_key = "***********************************************"
#Line的一些使用者金鑰設定
line_bot_api = LineBotApi('*******************************')
handler = WebhookHandler('********************************')
host_id="************************
openai api_key 可以去
An API for accessing new AI models developed by OpenAI
取得
line 的api key可以去
Line Developers的 Basic setting and Messaging API取得
自己勤勞點找一下往下滑不難找到
在來就是執行主程式
這裡port
#run
if __name__ == "__main__":
app.run(host='127.0.0.1', port=2336, debug=True)
也不一定要2336可以自行設定
然後開ngrok
把反白處貼到
Webhook settings
測試
一直跟我兜圈子
改一下參數
大功告成.
最大限度上用現代科技做了一個仿製命運石之門的聊天機器人
不確定能否增加傲嬌屬性