[PYTHON] J'ai essayé de créer une commande de recherche de documents slack à l'aide de Kendra annoncée immédiatement à re: Invent 2019

Bonjour, c'est le huitième jour du Calendrier de l'Avent ABEJA.

introduction

Un service intéressant a été annoncé à re: Invent 2019 l'autre jour. Oui, service de recherche d'entreprise [Amazon Kendra Release](https://aws.amazon.com/jp/about-aws/whats-new/2019/12/announcing-amazon-kendra-reinventing-enterprise-search-with -apprentissage-machine /). Screenshot from 2019-12-08 07-56-38.png Il existe différents outils de communication dans l'entreprise. Cependant, tous ont tendance à être des informations de flux et ne sont pas organisés, et il existe un problème de disparité des informations. C'est exactement la tâche sur mesure de Kendra. Quand c'est annoncé, cela doit être fait! J'ai été surpris. J'ai donc créé une commande souple qui permet de rechercher des documents par des phrases naturelles comme celle-ci. Screenshot_2019-12-08 Slack yuta nakagawa ABEJA, Inc .png Ci-dessous, je vais vous présenter comment j'ai créé Kendra en la touchant immédiatement.

Configuration du système

Kendra est une version préliminaire à partir du 8 décembre 2019. Par conséquent, les services qui peuvent être utilisés comme sources de données sont limités à ce qui suit.

J'ai donc trouvé un moyen d'activer la recherche de texte naturel en collectant une fois des documents internes dans S3 et en utilisant Kendra. Cependant, ce n'est pas toujours simple. Eh bien, comme je l'imaginais, Kendra ne supporte pas le japonais. Screenshot_2019-12-08 Amazon Kendra FAQs - Amazon Web Services.png Par conséquent, je vais essayer de le résoudre en le combinant avec le service de traduction d'AWS Amazon Translate. Si vous utilisez Translate pour placer le document dans S3 et l'interroger, le IF peut être dans n'importe quelle langue en interne avec un traitement en anglais uniquement. (Je veux vraiment que Kendra soutienne le japonais dès que possible) En ce qui concerne IF, j'ai choisi slack car il est facile d'implémenter des commandes car la communication normale est lente.

Eh bien, il n'y a pas de modération, mais en résumé, l'architecture ressemble à ceci. Architecture.png

Préparation de documents

C'est l'histoire du cadre supérieur de la configuration du système. Fondamentalement, tout ce que vous avez à faire est de télécharger le document spécifié, de le traduire et de le télécharger sur S3, mais Translate limite la taille des phrases qui peuvent être traduites en une seule fois, alors j'essaye de traduire ligne par ligne. Pour cette raison, il peut être traduit en anglais un peu étrange, mais comme il s'agit d'une vérification, je vais procéder sans m'en soucier. De plus, lorsque j'ai exécuté la commande slack, je voulais un lien vers le document d'origine, j'essaie donc de le lier aux métadonnées de S3 Object.

def translate_and_upload(url, title, content):
    client = boto3.client('translate')
    bucket = boto3.resource('s3').Bucket('ynaka-kendra')
    # Translate content to English.
    translated = ''
    for line in content.splitlines():
        if len(line) > 0:
            response = client.translate_text(
                Text=line,
                SourceLanguageCode='ja',
                TargetLanguageCode='en'
            )
            translated += (response['TranslatedText'] + os.linesep)
        else:
            translated += os.linesep
    # Upload to S3.
    file_obj = io.BytesIO(translated.encode('utf-8'))
    bucket.upload_fileobj(file_obj, title, ExtraArgs={'Metadata': {'url': url}})

Recherche de documents

C'est l'histoire du châssis inférieur de la configuration du système. C'est là que Kendra, le protagoniste du jour, apparaît.

Construire Kendra

Tout d'abord, nous allons construire Kendra, qui est la base de cette recherche. En gros, vous pouvez le créer en suivant Getting Started with the Console.

Commencez par générer un index. Screenshot_2019-12-07 Kendra.png La création d'un nouveau rôle IAM pour Kendra prend environ 30 secondes à générer. Screenshot_2019-12-07 Kendra (1).png De plus, il faut environ 30 minutes pour générer l'index, alors prenons une longue pause café lol Screenshot_2019-12-07 Kendra(1).png Vient ensuite la sélection de la source de données. Cette fois, sélectionnez S3. Screenshot_2019-12-07 Kendra(2).png Screenshot_2019-12-07 Kendra(3).png Spécifiez le chemin de S3 à lier. Vous pouvez également définir la fréquence à laquelle vous souhaitez synchroniser, mais cette fois je l'ai fait, donc j'ai choisi "Exécuter à la demande". Screenshot_2019-12-07 Kendra(4).png L'écran de révision des paramètres apparaît, Screenshot_2019-12-07 Kendra(5).png Si vous prenez une pause-café un peu plus longue, la construction est terminée. Screenshot_2019-12-07 Kendra(6).png Screenshot_2019-12-07 Kendra(7).png J'ai déjà la documentation dans S3, donc je vais commencer la synchronisation avec Kendra. Screenshot_2019-12-07 Kendra(8).png Cependant, si cela est laissé tel quel, IAM sera insuffisant et une erreur se produira. Screenshot_2019-12-07 Kendra(9).png Par conséquent, ajoutez la propre autorité de Kendra et l'autorité de S3. Screenshot_2019-12-07 IAM Management Console(4).png La synchronisation est enfin réussie. Screenshot_2019-12-07 Kendra(11).png

API de recherche de documents

La coopération avec slack sera implémentée avec Slash Commands. Il s'agit d'une configuration API Gateway + Lambda commune. N'oubliez pas d'ajouter les privilèges Kendra au rôle qui exécute Lambda. Notez également que Kendra ne peut être utilisé qu'avec le dernier boto3.

import boto3
import base64
import json
import logging
import os
import urllib


logger = logging.getLogger()
logger.setLevel(logging.INFO)


def respond(err, res=None):
    return {
        'statusCode': '400' if err else '200',
        'response_type': 'in_channel',
        'body': err.message if err else json.dumps({
            'response_type': 'in_channel',
            'text': res 
        }), 
        'headers': {
            'Content-Type': 'application/json',
        },  
    }   


def handler(event, context):
    # Prepare clients.
    translate = boto3.client('translate')
    kendra = boto3.client('kendra')
    s3 = boto3.resource('s3')
    # Parse request.
    body = event['body']
    params = urllib.parse.parse_qs(base64.b64decode(body).decode('utf-8'))
    token = params['token'][0]
    if token != os.environ['VERIFY_TOKEN']:
        logger.error(f'Request token ({token}) does not match expected.')
        return respond(Exception('Invalid request token.'))
    if 'text' not in params:
        logger.error(f'The text should be included in command.')
        return respond(Exception('Need text.'))
    query = params['text'][0]
    # Translate query to English.
    response = translate.translate_text(
        Text=query,
        SourceLanguageCode='ja',
        TargetLanguageCode='en'
    )
    query = response['TranslatedText']
    # Find the most relevant document.
    response = kendra.query(IndexId=os.environ['INDEX_ID'], QueryText=query)
    # Create response message.
    message = ''
    for i, item in enumerate(response['ResultItems'][:3]):
        title = item['DocumentTitle']['Text']
        excerpt = item['DocumentExcerpt']['Text']
        s3_uri = item['DocumentId'].replace('s3://', '').split('/')
        url = s3.Object(s3_uri[0], '/'.join(s3_uri[1:])).metadata['url']
        message_i = f'{i + 1}. *{title}*{os.linesep}url: {url}{os.linesep}```{excerpt}```{os.linesep}{os.linesep}'
        message += message_i
    # Return result.
    return respond(None, message)

Le SDK de Kendra nécessite ʻIndexId`, alors définissons-le dans la variable d'environnement. Les trois points suivants sont élaborés.

--Kendra ne prend en charge que l'anglais, donc je traduis également la requête. «Puisqu'il y a des situations où je cherchais réellement le document que d'autres voulaient trouver, je l'ai posté sur ʻin_channel`.

résultat

Vous pouvez maintenant rechercher par texte naturel comme celui-ci en utilisant Kendra + Translate. Screenshot_2019-12-08 Slack yuta nakagawa ABEJA, Inc .png En réponse à la question "Quelle est la carte de compétences d'ABEJA?", J'ai répondu à la carte de compétences qui est en train d'être organisée en premier, et à la seconde [Technology Stack] récemment publiée (https://tech-blog.abeja.asia/entry). Il semble que cela fonctionne comme ça lorsque je publie un article sur / tech-stack-201911). Comme prévu, une partie du document est floue, mais sentez l'atmosphère.

En passant, bien sûr, vous pouvez également rechercher en anglais. Screenshot_2019-12-08 Slack yuta nakagawa ABEJA, Inc (2).png Dans Kendra, différents emplacements dans le même document peuvent être touchés, il semble donc nécessaire de réfléchir à la manière de gérer cela en fonction de ce que vous voulez réaliser avec les commandes.

De plus, la réaction au sein de l'entreprise est bonne et je suis très heureux. Screenshot_2019-12-08 Slack proj_tech_branding ABEJA, Inc .png

Résumé

J'ai immédiatement essayé d'utiliser Amazon Kendra annoncé à re: Invent 2019 l'autre jour et j'ai créé une commande de recherche de documents en interne. Bien que le temps d'attente ait été long et qu'il ait fallu beaucoup de temps à résoudre en raison d'une erreur mystérieuse, j'ai senti que Kendra est généralement facile à utiliser et que c'est un très bon service pour pouvoir rechercher dans des phrases naturelles. Cette fois, j'ai essayé de le faire en utilisant uniquement certains documents de l'entreprise en raison de la relation entre le temps et le coût, mais je peux collecter toutes sortes d'informations et effectuer des recherches à partir de slack, apprendre en voyant les résultats par d'autres et l'historique de recherche Il semble que vous puissiez dessiner une vision du monde où la distribution de l'information est visualisée et l'information est structurée, et vos rêves se répandront. Je me demande s'ils soutiendront le japonais dès que possible. À propos, veuillez noter qu'une erreur de serveur interne peut être renvoyée si vous insérez un document inattendu tel qu'un document japonais dans Kendra. Cependant, j'ai eu le courage de le publier même s'il y avait une erreur. Screenshot_2019-12-04 Kendra(21).png

Recommended Posts

J'ai essayé de créer une commande de recherche de documents slack à l'aide de Kendra annoncée immédiatement à re: Invent 2019
J'ai créé un jeu ○ ✕ avec TensorFlow
J'ai fait un chronomètre en utilisant tkinter avec python
J'ai créé un éditeur de texte simple en utilisant PyQt
J'ai essayé de créer une expression régulière de "montant" en utilisant Python
J'ai essayé de créer une expression régulière de "temps" en utilisant Python
J'ai essayé de créer une expression régulière de "date" en utilisant Python
J'ai essayé de créer une application todo en utilisant une bouteille avec python
J'ai créé une API Web
[Python] J'ai essayé de créer un programme simple qui fonctionne sur la ligne de commande en utilisant argparse
J'ai essayé de créer un BOT de traduction qui fonctionne avec Discord en utilisant googletrans
J'ai essayé de faire MAP rapidement une personne suspecte en utilisant les données d'adresse Geolonia
J'ai essayé de faire un "putain de gros convertisseur de littérature"
J'ai essayé de dessiner un diagramme de configuration à l'aide de diagrammes
[LPIC 101] J'ai essayé de résumer les options de commande qui sont faciles à faire une erreur
J'ai essayé de rechercher des vidéos à l'aide de l'API de données Youtube (débutant)
J'ai essayé d'automatiser [une certaine tâche] à l'aide d'une tarte à la râpe
J'ai essayé de créer une caméra de surveillance à détection de mouvement avec OpenCV en utilisant une caméra WEB avec Raspberry Pi
J'ai essayé d'utiliser l'émojinateur Slack
[5e] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé d'obtenir une base de données sur les courses de chevaux en utilisant Pandas
[2nd] J'ai essayé de créer un certain outil de type Authenticator avec python
[Python] J'ai essayé d'implémenter un tri stable, alors notez
[3ème] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé de faire un processus d'exécution périodique avec Selenium et Python
J'ai essayé d'obtenir une liste de noms AMI en utilisant Boto3
J'ai essayé de créer une application de notification de publication à 2 canaux avec Python
[4th] J'ai essayé de créer un certain outil de type Authenticator avec python
[1er] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé de faire une étrange citation pour Jojo avec LSTM
J'ai essayé de créer un mécanisme de contrôle exclusif avec Go
Comment créer un bot slack
J'ai essayé de faire un diagnostic de visage AI pour les golfeuses professionnelles ②
J'ai appris le grattage à l'aide de sélénium pour créer un modèle de prédiction de courses de chevaux.
J'ai essayé de créer un LINE BOT "Sakurai-san" avec API Gateway + Lambda
J'ai essayé de faire un signal avec Raspeye 4 (édition Python)
J'ai essayé d'effectuer une analyse de cluster de clients à l'aide des données d'achat
Notes J'ai recherché la création d'outils de ligne de commande en Python
J'ai créé un exemple pour accéder à Salesforce en utilisant Python et Bottle
J'ai essayé de créer un service de raccourcissement d'url sans serveur avec AWS CDK
Je souhaite créer une application Web en utilisant React et Python flask
J'ai essayé de créer un linebot (implémentation)
J'ai essayé d'utiliser Azure Speech to Text.
J'ai essayé de résumer la commande umask
J'ai essayé de créer un linebot (préparation)
J'ai essayé de jouer au jeu ○ ✕ en utilisant TensorFlow
J'ai essayé de dessiner une ligne en utilisant une tortue
J'ai essayé de classer le texte en utilisant TensorFlow
J'ai essayé d'utiliser la recherche sélective comme R-CNN
J'ai essayé d'utiliser pipenv, alors prenez note
J'ai essayé de faire un processus périodique avec CentOS7, Selenium, Python et Chrome
J'ai fait une application d'envoi de courrier simple avec tkinter de Python
[Python] Deep Learning: J'ai essayé d'implémenter Deep Learning (DBN, SDA) sans utiliser de bibliothèque.
Quand j'ai essayé de créer un VPC avec AWS CDK mais que je n'ai pas pu le faire