openaiapi1.py(askai2)
askai2ではaskai時のものをベースに少し改良している。
特徴
複数の問い合わせを並行できる
Windowsのみ動作確認済
LinuxやMacは知らん(並行部分をどうやるか。たぶん&つけて実行とかすればええんか?
使い方(変わった部分のみ)
プロンプトファイルとは
プロンプトを書くMarkdownファイル
実行はpython openaiapi1.py --input (プロンプトファイル)
以下のようなバッチファイルをつくると良い
code:1.bat
@echo off
start /b "" cmd /c python openaiapi1.py --input 1.md
これは1.mdに書き込んだプロンプトでGPT.iconに問い合わせる
かつ、結果も1.mdに書き込まれる(あとログとしてaskailog.mdには常にprependされる)
このバッチをつくった場合、実行時はこれでいい
code:terminal
$ 1.bat
code:実はこれで良い
$ 1
ソース
code:openaiapi1.py
import datetime
import os
import openai
# ========
def parse_arguments():
import argparse
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument('--input', default=None, required=True)
parser.add_argument('--use-ssl', default=None)
args = parser.parse_args()
return args
# ========
def ask(prompt):
response = openai.ChatCompletion.create(
model='gpt-4',
messages=[
{'role': 'user', 'content': prompt},
]
)
return response
def todaystr_long():
todaydt = datetime.datetime.today()
datestr = todaydt.strftime('%Y/%m/%d')
timestr = todaydt.strftime('%H:%M:%S')
wd = todaydt.weekday()
return f'{datestr} {dow_e} {timestr}'
def file2str(filepath):
ret = ''
with open(filepath, encoding='utf8', mode='r') as f:
ret = f.read()
return ret
def str2file(filepath, s):
with open(filepath, encoding='utf8', mode='w') as f:
f.write(s)
class Outputter:
def __init__(self, prompt, response):
self._response = response
self._todaystr = todaystr_long()
self._prompt = prompt
self._answer = response.choices0.message.content self._answer_role = response.choices0.message.role self._consumed_prompt_token = response.usage.prompt_tokens
self._consumed_completion_token = response.usage.completion_tokens
def out(self):
raise NotImplementedError
class Logger(Outputter):
def __init__(self, prompt, response):
super().__init__(prompt, response)
self._logfilepath = 'PLEASE_GIVE_EXPLICITLY__askailog.md'
def set_target_filepath(self, markdown_filepath):
self._logfilepath = markdown_filepath
def out(self):
prependee = f"""# {self._todaystr} {self._consumed_prompt_token} {self._consumed_completion_token}
{self._prompt}
{self._answer}"""
logcontent = file2str(self._logfilepath)
outstr = f"""{prependee}
{logcontent}"""
str2file(self._logfilepath, outstr)
class Stdouter(Outputter):
def __init__(self, prompt, response):
super().__init__(prompt, response)
def out(self):
print('=== prompt ===')
print(self._prompt)
print('')
print('=== answer ===')
print(self._answer)
print('')
print(f'tokens : prompt {self._consumed_prompt_token}, completion {self._consumed_completion_token}')
class SimpleStdouter(Outputter):
def __init__(self, prompt, response):
super().__init__(prompt, response)
def out(self):
summary = self._prompt:16 print(f'{summary}({self._consumed_prompt_token}->{self._consumed_completion_token})..., Done.')
class Appender(Outputter):
def __init__(self, prompt, response):
super().__init__(prompt, response)
self._filepath = 'PLEASE_GIVE_EXPLICITLY_APPENDER_NAME.md'
NEW_BLANKLINE = '\n'
self._content = f'{self._prompt}{NEW_BLANKLINE}{self._answer}{NEW_BLANKLINE}'
def set_target_filepath(self, markdown_filepath):
self._filepath = markdown_filepath
def out(self):
str2file(self._filepath, self._content)
# ========
args = parse_arguments()
if args.use_ssl:
promptfilename = args.input
if not os.path.exists(promptfilename):
raise RuntimeError(f'Please prepare the prompt file {promptfilename}.')
q = file2str(promptfilename)
prompt=q
response = ask(prompt)
# コマンド入力中にstdoutされると鬱陶しいのでなくすか
logger = Logger(prompt, response)
logger.set_target_filepath('askailog.md')
appender = Appender(prompt, response)
appender.set_target_filepath(promptfilename)
logger.out()
appender.out()