業務効率化

PAD:ファイルをインプットにしたAI返答取得フロー

PADによる、指定ファイル内容+プロンプトをインプットとしてChatGPT返答を取得するフローです。エクセルやtxt等ファイルを指定し、内容の纏め等を指示取得することが可能です。返答を元に条件分岐などすれば、ファイル内容に基づいたフローを実現できます。

記事の内容

・挙動

・コード

・ポイント機能

・挙動

指定したファイルをテキストとして取得し、プロンプトと合わせてAIに投げ返答を取得します。

例えば下記のファイルを元に、どのようなファイルか質問を投げます。

Inputとして与えるファイル
プロンプト

返答としてはプロンプト分に基づいた内容が取得されます。今回はウィンドウで返答を表示しています。この返答を元に条件分岐などすることで、ファイル内容に基づいた条件分岐するフローを実現できます。

・コード

➤コードはこちら
SET FilePath TO $'''テストファイルのフルパスを記載(\"\"は不要)'''
Scripting.RunVBScript.RunVBScript VBScriptCode: $'''Option Explicit

\'=========================
\' 設定(ここを書き換える)
\'=========================
Const BR = \"\\r\\n\"   \' API用 改行置換文字

Dim targetPath
targetPath = \"%FilePath%\"
\' 例:
\' targetPath = \"C:\\test\\sample.xlsx\"
\' targetPath = \"C:\\test\\sample.pptx\"
\' targetPath = \"C:\\test\\sample.txt\"


\'=========================
\' メイン
\'=========================
Dim resultText
resultText = ExtractText(targetPath)
resultText = SafeForAPI(resultText)
WScript.Echo resultText


\'=========================
\' 共通:拡張子判定 → 抽出
\'=========================
Function ExtractText(path)
    Dim fso, ext, text
    Set fso = CreateObject(\"Scripting.FileSystemObject\")

    If Not fso.FileExists(path) Then
        ExtractText = \"ERROR: ファイルが存在しません\"
        Exit Function
    End If

    ext = LCase(fso.GetExtensionName(path))

    Select Case ext
        Case \"doc\", \"docx\"
            text = GetTextFromWord(path)

        Case \"xls\", \"xlsx\"
            text = GetTextFromExcel(path)

        Case \"ppt\", \"pptx\"
            text = GetTextFromPPT(path)

        Case \"txt\"
            text = GetTextFromTxt(path)

        Case Else
            text = \"ERROR: 未対応形式 (\" & ext & \")\"
    End Select

    ExtractText = NormalizeText(text)
End Function


\'=========================
\' 改行正規化(API向け)
\'=========================
Function NormalizeText(str)
    If IsNull(str) Or str = \"\" Then
        NormalizeText = \"\"
        Exit Function
    End If

    str = Replace(str, vbCrLf, BR)
    str = Replace(str, vbCr, BR)
    str = Replace(str, vbLf, BR)

    NormalizeText = str
End Function


\'=========================
\' Word
\'=========================
Function GetTextFromWord(path)
    Dim app, doc

    Set app = CreateObject(\"Word.Application\")
    app.Visible = False

    Set doc = app.Documents.Open(path, False, True)
    GetTextFromWord = doc.Content.Text

    doc.Close False
    app.Quit
End Function


\'=========================
\' Excel(全シート・全セル)
\'=========================
Function GetTextFromExcel(path)
    Dim app, book, sheet, cell
    Dim result

    result = \"\"

    Set app = CreateObject(\"Excel.Application\")
    app.Visible = False
    app.DisplayAlerts = False

    Set book = app.Workbooks.Open(path)

    For Each sheet In book.Worksheets
        result = result & \"【Sheet:\" & sheet.Name & \"】\" & vbCrLf

        For Each cell In sheet.UsedRange
            If Trim(cell.Value & \"\") <> \"\" Then
                result = result & cell.Value & vbCrLf
            End If
        Next
    Next

    book.Close False
    app.Quit

    GetTextFromExcel = result
End Function


\'=========================
\' PowerPoint(全スライド)
\'=========================
Function GetTextFromPPT(path)
    Dim app, pres, slide, shape
    Dim result

    result = \"\"

    Set app = CreateObject(\"PowerPoint.Application\")
    app.Visible = False

    Set pres = app.Presentations.Open(path, False, False, False)

    For Each slide In pres.Slides
        result = result & \"【Slide \" & slide.SlideIndex & \"】\" & vbCrLf

        For Each shape In slide.Shapes
            If shape.HasTextFrame Then
                If shape.TextFrame.HasText Then
                    result = result & shape.TextFrame.TextRange.Text & vbCrLf
                End If
            End If
        Next
    Next

    pres.Close
    app.Quit

    GetTextFromPPT = result
End Function


\'=========================
\' TXT
\'=========================
Function GetTextFromTxt(path)
    Dim fso, ts
    Set fso = CreateObject(\"Scripting.FileSystemObject\")
    Set ts = fso.OpenTextFile(path, 1, False)

    GetTextFromTxt = ts.ReadAll
    ts.Close
End Function

Function SafeForAPI(str)
    Dim i, ch, code, result
    result = \"\"

    For i = 1 To Len(str)
        ch = Mid(str, i, 1)
        code = AscW(ch)

        \' 制御文字を除外(改行は事前に置換済み前提)
        If code = 9 Then
            result = result & \" \"          \' TAB → 空白
        ElseIf code = 160 Then
            result = result & \" \"          \' NBSP → 空白
        ElseIf code < 32 Then
            \' NULL, BEL, その他制御文字は捨てる
        Else
            result = result & ch
        End If
    Next

    \' 連続スペースを圧縮
    Do While InStr(result, \"  \") > 0
        result = Replace(result, \"  \", \" \")
    Loop

    SafeForAPI = result
End Function

''' ScriptOutput=> FileInput
Text.Replace Text: FileInput TextToFind: $'''\\r\\n''' IsRegEx: True IgnoreCase: False ReplaceWith: $'''\\n''' ActivateEscapeSequences: False Result=> FileInput
Display.InputDialog Title: $'''プロンプトを入力してください''' InputType: Display.InputType.SingleLine IsTopMost: False UserInput=> UserPrompt ButtonPressed=> ButtonPressed2
SET UserInput TO $'''%UserPrompt%%FileInput%'''
SET APIKey TO $'''APIキーを記載'''
Web.InvokeWebService.InvokeWebServicePost Url: $'''https://api.openai.com/v1/chat/completions''' Accept: $'''application/json''' ContentType: $'''application/json''' CustomHeaders: $'''Authorization: Bearer %APIKey%''' RequestBody: $'''{
  \"model\": \"gpt-3.5-turbo\",
  \"messages\": [{\"role\": \"user\", \"content\": \"%UserInput%\"}],
  \"temperature\": 0.7
}''' ConnectionTimeout: 30 FollowRedirection: True ClearCookies: False FailOnErrorStatus: False EncodeRequestBody: False UserAgent: $'''Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.21) Gecko/20100312 Firefox/3.6''' Encoding: Web.Encoding.AutoDetect AcceptUntrustedCertificates: False TrimRequestBody: True ResponseHeaders=> WebServiceResponseHeaders Response=> WebServiceResponse StatusCode=> StatusCode
Variables.ConvertJsonToCustomObject Json: WebServiceResponse CustomObject=> JsonAsCustomObject
Display.ShowMessageDialog.ShowMessage Title: $'''ChatGPTの返答''' Message: JsonAsCustomObject.choices[0].message.content Icon: Display.Icon.None Buttons: Display.Buttons.OK DefaultButton: Display.DefaultButton.Button1 IsTopMost: False ButtonPressed=> ButtonPressed

使用のために、ChatGPTAPIキーを取得し、APIkey変数に格納してください。

また、指定ファイルはFileInput変数に固定格納しています。動的にする場合は、PADメソッドからファイル選択ダイアログ表示などに置き換え、FilePathに格納ください。

・ポイント機能

・ファイル内容の改行置き換え

・PADメソッド:Webサービスを呼び出します

ファイル内容の改行置き換え

API利用時、Jason形式で送るインプットに改行があるとうまく回答が取得できません。「ウェブサービスを呼び出します」でファイルを添付する設定値があるようですが、エラーが起きるため今回はファイル内容を開業無しのプレーンテキストとして渡します。

改行の置き換え

PADでは改行等特殊文字は正規表現として置換える必要があります。相当する\r\nを指定することで与えたテキスト内の改行を置き換えることができます。

PADメソッド:Webサービスを呼び出します

ウェブサービス使用のAPIをPADで利用するには、「Webサービスを呼び出します」を使用します。このメソッド内のプロパティを設定することで、APIを活用することができます。今回はChatGPTを使うため、下記の専用URLを指定し、下記のようにその他プロパティを指定します。

コンテンツタイプ

HTTP リクエストの Content-Type(コンテンツの種類) を表す値です。

このリクエストのデータ形式がJSONとサーバーに伝えるための MIME タイプ(メディアタイプ)です。API にデータを送るとき、サーバーは「どんな形式で送られてきたデータなのか」を知る必要があるため、そのために Content-Type ヘッダーを使います。

要求本文

APIを使用する際に指定するおなじみの構文内容です。下記では、ChatGPTではモデルとメッセージ、Temperature(応答のランダム性)を指定しています。モデルは非常にコスパ良い「3.5-turbo」を指定しています。Temperatureは任意指定です。

temperatureとは応答のランダム性(創造性)を制御する数値です。値は 0.0 〜 2.0 の範囲で設定できます(通常は 0.0〜1.0 で十分)。

特徴
0.0非常に決まりきった応答。論理的で一貫性が高い。
0.7バランス型。少し創造性がありつつ、安定した応答。
1.02.0非常に創造的。ユニークな表現や意外な回答が出やすい。

例:

  • temperature: 0.2 → 正確で堅実な回答(FAQや事実ベースに向いている)
  • temperature: 0.9 → 柔軟で面白い回答(物語生成やアイデア出しに向いている)

その他

  • max_tokens: 応答の最大長を制限
  • top_p: temperatureと似た確率分布の制御
  • stop: 応答を途中で止めるトリガー文字列

-業務効率化