Function Calling で社内システムを自動化

2024/07/30に公開されました。
2024/07/30に更新されました。

Function Calling で社内システムを自動化


author: ryutah

はじめに

こんにちは、技術推進グループのグループマネージャのryutahです。

今回はFunction Callingを用いて社内システムを自動化する方法を、Goのコード例を交えて解説します。

Function Calling とは

Function Callingは、LLM (大規模言語モデル) が実行可能な関数を定義し、LLMの出力に応じて適切な関数を呼び出す仕組みです。LLMは直接関数を呼び出すのではなく、関数名と引数を構造化データとして出力します。この出力を受け取ったサーバー側で、実際の関数の実行をします。

前提

  • 社内システムは人事評価システム
  • 人事評価システムにユーザーを登録する機能を実装
  • 登録時に確認メッセージを表示し、確認が取れた場合のみ登録

社内システム ユーザ登録の関数を定義

// 登録処理
// user ユーザー名,isconfirm 確認チェック
func insertUser(user string, isconfirm bool) map[string]any {
	if !isconfirm {
		return map[string]any{
			"isconfirm": isconfirm,
		}
	}

	// ユーザー登録処理...
	return map[string]any{
		"user":      user,
		"isconfirm": isconfirm,
	}
}

関数の登録

Function Callingで使用する関数を登録します。ポイントは DescriptionPropertiesisConfirm です。

  • Description: 関数の説明に加え、実行条件 (確認) を明記します。
  • Properties: 関数実行の判断に使うbool値 (isConfirm) を定義します。
insertUserTool := &genai.Tool{
	FunctionDeclarations: []*genai.FunctionDeclaration{{
		Name:        "insertUser",
		Description: "ユーザー登録処理。この関数を実行する場合は確認をとってください。",
		Parameters: &genai.Schema{
			Type: genai.TypeObject,
			Properties: map[string]*genai.Schema{
				"username": {
					Type:        genai.TypeString,
					Description: "登録するユーザー名",
				},
				"isConfirm": { // isConfirm に修正
					Type:        genai.TypeBoolean,
					Description: "この関数を実行してよいか確認済みか。",
				},
			},
			Required: []string{"username"},
		},
	}},
}

確認を伴う Function Calling の実行例

以下に、確認を伴うFunction Callingのコード例を示します。

// (main 関数内の処理)

model := client.GenerativeModel("gemini-1.5-flash")
model.Tools = []*genai.Tool{insertUserTool}
session := model.StartChat()

// ... (プロンプト入力処理)

// レスポンスを解析し、関数呼び出しを実行
part := resp.Candidates[0].Content.Parts[0]
funcall, ok := part.(genai.FunctionCall)
if !ok {
	log.Fatalf("Expected type FunctionCall, got %T", part)
}
if g, e := funcall.Name, insertUserTool.FunctionDeclarations[0].Name; g != e {
	log.Fatalf("Expected FunctionCall.Name %q, got %q", e, g)
}

isConfirm, ok := funcall.Args["isConfirm"].(bool) // isConfirm に修正
if !ok {
	log.Fatal("Expected FunctionCall.Args isConfirm")
}

username, ok := funcall.Args["username"].(string)
if !ok {
	log.Fatal("Expected FunctionCall.Args username")
}

apiResult := insertUser(username, isConfirm) // isConfirm に修正

// ... (結果の表示、登録確認処理)

実行結果

登録する場合:

ユーザ名:佐藤を登録してください。
確認のため、もう一度入力してください。
ユーザ名:佐藤を登録しますか? はい or いいえ を入力してください。

はい
ユーザー:佐藤を登録しました。

登録しない場合:

ユーザ名:佐藤を登録してください。
確認をとってから登録してください。
登録しないです。
了解しました。

コード解説

  • 関数呼び出しの検証: LLMからのレスポンスが、想定した関数 (insertUser) を呼び出しているかを確認します。

※下記コードで実際に外部関数が呼ばれいるかのチェックを行なっています。

if g, e := funcall.Name, insertUserTool.FunctionDeclarations[0].Name; g != e {
	log.Fatalf("Expected FunctionCall.Name %q, got %q", e, g)
}
  • 登録確認: answer に入力された内容に基づいて、実際にユーザー登録をするか判断します。

まとめ

Function Callingを利用することで、LLMを活用した社内システムの自動化が容易になります。特に、確認を伴う処理を組み込む場合は、bool値で制御するとシンプルに実装できます。

Function Callingを効果的に活用するには、FunctionDeclarations に関数の説明を簡潔かつ明確に記述することが重要です。

※本記事は、ジーアイクラウド株式会社の見解を述べたものであり、必要な調査・検討は行っているものの必ずしもその正確性や真実性を保証するものではありません。

※リンクを利用する際には、必ず出典がGIC dryaki-blogであることを明記してください。
リンクの利用によりトラブルが発生した場合、リンクを設置した方ご自身の責任で対応してください。
ジーアイクラウド株式会社はユーザーによるリンクの利用につき、如何なる責任を負うものではありません。