CloudflareのWorkers Analytics EngineでRAGの結果を記録させてみる

生成系AIを利用したFAQアプリの精度向上を目指し、Cloudflare Workers上にRAGの仕組みを構築し、それを使って回答を生成し、記録する仕組みを作成しました。回答の精度を評価するため、Analytics Engineを使用し、REST API形式でSQLクエリを送信して結果を取得します。しかし、一部の回答が精度に疑問を残すこともあり、性能評価には追加の処理が必要です。また、プライバシー保護にも配慮する必要があります。

広告ここから
広告ここまで

目次

    生成系AIを使ったFAQアプリの精度をレビューするため、回答履歴を記録する仕組みを少し調べています。RAGの仕組み自体をCloudflare Workers上に作ることが多いため、Workers Analytics Engineを試してみました。

    使い方

    LangChain.jsを使って回答を生成する処理を、Hono上に作りました。その中で回答を記録する処理を追加しています。

    ragApp.post('/ask', async c => {
      const {query:question} = await c.req.json<{
          query: string
      }>()
      const chain = createIndexChain(c.env)
      const answerStream = await chain.stream({question})
      return streamText(c, async (stream) => {
        let answer: string = ''
          for await (const s of answerStream) {
            const answerChunk = (s as any).answer
            if (answerChunk) {
              answer = `${answer}${answerChunk}`
            }
            await stream.write(JSON.stringify(s))
          }
          try {
            c.env.ANALYTICS_ENGINE.writeDataPoint({
              blobs: [question, answer],
            })
          } catch (e) {
            console.log(e)
          }
    
      })
    })

    Workers系のサービスですので、Bindingすることで、c.envから利用できました。writeDataPointでは配列形式でデータを投入しています。

    結果をクエリする

    Analytics Engineでは、REST API形式でSQLクエリを送信できます。先ほど実装したコードでは、「1つ目のblobがquestion、2つめがanser」なのでASでキャストして実行してみましょう。

    curl -X POST "https://api.cloudflare.com/client/v4/accounts/{YOUR_CLOUDFLARE_ACCOUNT_ID}/analytics_engine/sql" \
    -H "Authorization: Bearer {YOUR_CLOUDFLARE_API_TOKEN}" \
    -d "SELECT timestamp, blob1 AS question, blob2 AS answer FROM wcasia2024"  | jq .

    取得できたデータを確認する

    実行結果はこのようなものでした。metaで項目ごとの簡単な概要が取れますので、テーブルなどに描画したい場合は、これを使うと良さそうです。

    {
      "meta": [
        {
          "name": "timestamp",
          "type": "DateTime"
        },
        {
          "name": "question",
          "type": "String"
        },
        {
          "name": "answer",
          "type": "String"
        }
      ],
      "data": [
        {
          "timestamp": "2024-03-06 15:08:26",
          "question": "Headless wordpressについての話を聞きたい",
          "answer": "イベントでは、Headless WordPressについて2つのセッションが開催されます。\n\n1. セッション: Fighting the JavaScript Fatigue: Picking the right framework for Headless WordPress\n   - 日時: 2024年3月9日 10:00 am\n   - スピーカー: Phoomparin Mano\n   - 概要: このセッションでは、Headless WordPressを使用する際に最適なフレームワークの選択方法について議論します。2023年時点でのAstro, SvelteKit, Nuxt, Nextなどのフロントエンドフレームワークを検討し、それぞれのフレームワークの強みと落とし穴を紹介します。\n\n2. セッション: Journey of 5 Years with Headless WordPress: Evolution, Challenges, and Opportunities\n   - 日時: 2024年3月9日 1:00 pm\n   - スピーカー: Hidetaka Okamoto\n   - 概要: スピーカーがHeadless CMSとしてWordPressを使用した経験について、その進化、課題、機会について語ります。Express、Netlify、Next.js、AWS Amplifyなどのさまざまなインフラストラクチャを探索しながら、毎年のサイトリニューアルで対面した課題と学んだことを共有します。\n\nこれらのセッションは、それぞれ異なる視点からHeadless WordPressの使用法と考え方、最新のフレームワーク選択やインフラの活用方法について詳述します。特にHeadless WordPressの具体的な活用方法やフレームワーク選択に関心がある方にとって有益な情報が得られるでしょう。"
        },
        {
          "timestamp": "2024-03-17 13:40:47",
          "question": "I want to learn about a Headless WordPress development.",
          "answer": "Based on your interest in learning about Headless WordPress development, the following sessions could be particularly beneficial:\n\n1. \"Fighting the JavaScript Fatigue: Picking the right framework for Headless WordPress\"  \n   - Date and time: March 9, 2024, at 10:00 am\n   - Speaker: Phoomparin Mano \n   - Session details: This session will give you insights into various front-end frameworks like Astro, SvelteKit, Nuxt, and Next and their strengths and drawbacks for use in creating interactive content. The speaker, Phoomparin Mano, will also provide a detailed opinion on which framework is best for specific use cases. This session will help you understand the role of JavaScript frameworks in Headless WordPress development.\n\n2. \"Journey of 5 Years with Headless WordPress: Evolution, Challenges, and Opportunities\" \n   - Date and time: March 9, 2024, at 1:00 pm\n   - Speaker: Hidetaka Okamoto\n   - Session details: Hidetaka Okamoto will share his extensive experience using WordPress as a Headless CMS for over 5 years. He will outline the evolution of headless architecture, the transformation in website building and management it has led to, and the different infrastructures like Express, Netlify, Next.js, and AWS Amplify that he used. This session could provide you with practical insights into working with Headless WordPress over an extended period.\n\nBoth of these sessions complement each other, starting with identifying the right tools for Headless WordPress development and later delving into the application of these tools based on Okamoto's extensive experience. This comprehensive overview about Headless WordPress development will make your learning experience at the event more relevant and advantageous."
        },
      ],
      "rows": 25,
      "rows_before_limit_at_least": 25
    }

    何回かテスト的にRAGを実行してみたところ、精度が少し怪しい回答も記録されていました。

        {
          "timestamp": "2024-03-08 02:44:25",
          "question": "テーマ制作の話はありますか?",
          "answer": "指定された情報に基づいて、テーマ制作に具体的に関するセッションの情報は提供されていません。与えられた情報は主にAIとWordPressの統合やAIによるWordPressサイトの構築と保守、そしてAIチャットボットの未来について述べられています。\n具体的なテーマ制作についてのセッションを探す場合は、さらに詳細な情報や他のセッションに関する情報が必要になるかもしれません。"
        }

    実運用で使うには

    今回は全件取得としましたが、もしRAGの性能評価に使う場合は、ここに何かしらの形で回答精度を評価したものを入れる必要がありそうです。おそらく手早く使えるのは、ベクトル検索時に取得できることがあるスコアの値でしょうか。

    また、手元で動かす用途としてのみ使いましたが、第三者が利用できる形にする場合は、プライバシーの問題も考慮が必要です。個人情報(PII)などが質問・回答に含まれないようするか、Analyticsに記録されないように意識する必要がありそうです。LangChainの場合は、MaskするChainもある様子ですので、この辺りを試してみるか、AWSやAzure / GCPのデータ処理系サービスを利用して適切に処理するように作る必要があるかなと思いました。

    あとは・・・LangSmithなどのそれむけに作られたツールを、素直に使ったほうがよいかな、というところでしょうか。

    参考記事

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark