Amazon Lex と Kendra をつなぐ
はじめに
ChatGPTが盛り上がっているので、AI Chatbotなるものを触ってみようと。
やったこと
弊社では、AWSのサービスを使用したSaaS開発を行っているので、AWSのサービスを使ったAI Chatbotだとどんな感じになるのかやってみました。
Chatbotを作るのはAmazon Lexで、Amazon Lexが上手に回答するため、エンタープライズ検索エンジンのAmazon Kendraをつないだらいい感じになるんじゃない?
と思って検索したら、ありました。
Amazon KendraとAmazon Lexが統合できない?
Amazon Kendraは、2023年2月から東京リージョンでも利用可能になっていたので、当然ながら東京リージョンで日本語で設定していきます。
KendraのIndexを作るところまでは問題なかったのですが、LexのBotに組み込みインテントのAMAZON.KendraSearchIntentを設定する箇所で候補にでてこないのです。
実は、AMAZON.KendraSearchIntentは、この記事を書いている時点(2023/3/23)では、en-USロケール、および米国東部(バージニア北部)、米国西部(オレゴン)、欧州(アイルランド)のリージョンのみ使用できます。ということでした。
ダメじゃん。ということで、もう一度検索したら、ありました。(ありがとう。中の人)
これをそのまま動かすと、うちでは、Invalid PhysicalResourceIdエラーになってしまったので、以下のように変更して、無事動かすことができました。
@@ -42,7 +42,7 @@ export class DataSource extends Construct {
this.resource = new cdk.CustomResource(
this,
- `CustomResourceDataSource${id}`,
+ 'CustomResourceDataSource',
{
serviceToken: customResourceHandler.functionArn,
resourceType: 'Custom::DataSource',
golangでLexのLambda書けない?
AMAZON.KendraSearchIntentが使えなくても、Lambdaでやればいいんだね。
弊社はLambda開発の標準言語はgolangなので、いろいろいじるならgolangで書いてみようということで、まずは、ここから。
こんな感じのを動かしてみたら、
runtime error: invalid memory address or nil pointer dereference: errorString
これって、Lex V1かな?
...ということで、Lex V2 の構造体から書かないといけないのでした。
ちょっと長いので見たい方だけどうぞ
package main
// LexV2Event は、Lambda 関数の入力パラメータ
// https://docs.aws.amazon.com/lexv2/latest/dg/lambda.html
// @types/aws-lambda/triggrt/lex-v2.ts
type LexV2Event struct {
MessageVersion string `json:"messageVersion"`
InvocationSource string `json:"invocationSource"`
InputMode string `json:"inputMode"`
ResponseContentType string `json:"responseContentType"`
SessionID string `json:"sessionId"`
InputTranscript string `json:"inputTranscript"`
Bot LexV2Bot `json:"bot"`
Interpretations []LexV2Interpretation `json:"interpretations"`
ProposedNextState struct {
DialogAction LexV2DialogAction `json:"dialogAction"`
Intent LexV2Intent `json:"intent"`
} `json:"proposedNextState"`
RequestAttributes map[string]string `json:"requestAttributes"`
SessionState *LexV2SessionState `json:"sessionState"`
Transcriptions []LexV2Transcription `json:"transcriptions"`
}
// LexV2Bot は、Lamabda を起動したボット
type LexV2Bot struct {
ID string `json:"id"`
Name string `json:"name"`
AliasID string `json:"aliasId"`
AliasName string `json:"aliasName"`
LocaleID string `json:"localeId"`
Version string `json:"version"`
}
// LexV2Interpretation は、Lex が行った会話の解釈
// https://docs.aws.amazon.com/lexv2/latest/dg/API_runtime_Interpretation.html
type LexV2Interpretation struct {
Intent LexV2Intent `json:"intent"`
NluConfidence float64 `json:"nluConfidence"`
SentimentResponse LexV2SentimentResponse `json:"sentimentResponse"`
}
// LexV2Intent は、Lex が解釈した意図
// https://docs.aws.amazon.com/lexv2/latest/dg/API_runtime_Intent.html
type LexV2Intent struct {
ConfirmationState string `json:"confirmationState"`
Name string `json:"name"`
Slots map[string]LexV2Slot `json:"slots"`
State string `json:"state"`
KendraResponse interface{} `json:"kendraResponse"`
}
// LexV2SentimentResponse は、Comprehend が解釈した応答の感情
// https://docs.aws.amazon.com/lexv2/latest/dg/API_runtime_SentimentResponse.html
type LexV2SentimentResponse struct {
Sentiment string `json:"sentiment"`
SentimentScore LexV2SentimentScore `json:"sentimentScore"`
}
// LexV2SentimentScore は、4つの感情を示す
// https://docs.aws.amazon.com/lexv2/latest/dg/API_runtime_SentimentScore.html
type LexV2SentimentScore struct {
Mixed float64 `json:"mixed"`
Negative float64 `json:"negative"`
Neutral float64 `json:"neutral"`
Positive float64 `json:"positive"`
}
// LexV2SessionState は、Lex のユーザーセッション情報
// https://docs.aws.amazon.com/lexv2/latest/dg/API_runtime_SessionState.html
type LexV2SessionState struct {
ActiveContexts []LexV2ActiveContext `json:"activeContexts,omitempty"`
SessionAttributes map[string]string `json:"sessionAttributes,omitempty"`
DialogAction LexV2DialogAction `json:"dialogAction,omitempty"`
Intent LexV2Intent `json:"intent"`
OriginatingRequestID string `json:"originatingRequestId"`
}
// LexV2ActiveContext は、セッションの文脈
// https://docs.aws.amazon.com/lexv2/latest/dg/API_runtime_ActiveContext.html
type LexV2ActiveContext struct {
Name string `json:"name"`
ContextAttributes map[string]string `json:"contextAttributes"`
TimeToLive struct {
TimeToLiveInSeconds int `json:"timeToLiveInSeconds"`
TurnsToLive int `json:"turnsToLive"`
} `json:"timeToLive"`
}
// LexV2DialogAction は、会話の次のアクション
// https://docs.aws.amazon.com/lexv2/latest/dg/API_runtime_DialogAction.html
type LexV2DialogAction struct {
Type string `json:"type"`
SlotToElicit string `json:"slotToElicit"`
SlotElicitationStyle string `json:"slotElicitationStyle,omitempty"`
}
// LexV2Result は、Lambda 関数のレスポンス
// https://docs.aws.amazon.com/lexv2/latest/dg/lambda.html#lambda-response-format
type LexV2Result struct {
SessionState *LexV2SessionState `json:"sessionState"`
Messages []*LexV2Message `json:"messages"`
}
// LexV2Message は、ユーザーに返される回答文の入れ物
// https://docs.aws.amazon.com/lexv2/latest/dg/API_runtime_Message.html
type LexV2Message struct {
ContentType string `json:"contentType"`
Content string `json:"content,omitempty"`
ImageResponseCard *LexV2ImageResponseCard `json:"imageResponseCard,omitempty"`
}
// LexV2ImageResponseCard は、メッセージプラットホームでユーザーに表示されるカード
// https://docs.aws.amazon.com/lexv2/latest/dg/API_runtime_ImageResponseCard.html
type LexV2ImageResponseCard struct {
Title string `json:"title"`
Subtitle string `json:"subtitle,omitempty"`
ImageURL string `json:"imageUrl,omitempty"`
Buttons []*LexV2Button `json:"buttons,omitempty"`
}
// LexV2Button は、ユーザーに表示されるカード上のボタン
// https://docs.aws.amazon.com/lexv2/latest/dg/API_runtime_Button.html
type LexV2Button struct {
Text string `json:"text"`
Value string `json:"value"`
}
// LexV2Slot は、Lex がインテントを満たすために使用する値
// https://docs.aws.amazon.com/lexv2/latest/dg/API_runtime_Slot.html
type LexV2Slot struct {
Shape string `json:"shape"`
Value LexV2SlotValue `json:"value"`
Values []LexV2Slot `json:"values,omitempty"`
}
// LexV2SlotValue は、スロットの値
// https://docs.aws.amazon.com/lexv2/latest/dg/API_runtime_Value.html
type LexV2SlotValue struct {
InterpretedValue string `json:"interpretedValue,omitempty"`
OriginalValue string `json:"originalValue"`
ResolvedValues []string `json:"resolvedValues"`
}
// LexV2Transcription は、ユーザーの音声発話に対応する書き起こし
// https://docs.aws.amazon.com/lexv2/latest/dg/using-transcript-confidence-scores.html
type LexV2Transcription struct {
Transcription string `json:"transcription"`
TranscriptionConfidence float64 `json:"transcriptionConfidence"`
ResolvedContext struct {
Intent string `json:"intent"`
} `json:"resolvedContext"`
ResolvedSlots map[string]LexV2Slot `json:"resolvedSlots"`
}
まとめ
- ということで、現時点(2023/3/23)でも東京リージョンでAmazon LexとKendraを組み合わせた日本語のチャットボットは動作可能でした。
- AMAZON.KendraSearchIntentが日本語で東京リージョンで使えるなら、会社中のドキュメントの内容を知っている優秀なチャットボットが簡単にできそうなので、期待したいです。
Discussion