プロンプトを硬直させるべきでない VS プロンプトはテンプレートで高品質化させるべき

タイトルの通りなのだが、プロンプト生成およびその適用を効率化するにあたってテンプレートを導入していろいろやっている。

ところがこのプロセスを徹底しようとしたらとても不味い問題にぶち当たった。テンプレートにないプロンプトが投げられないのだ。さりとて一回こっきりのプロンプトのためにテンプレートを作るのも割に合わない。その結果、割に合うテンプレートだけを使うようにできないか、などという大変おかしな方向にまで思考が流れてしまってひどい有様になった。

プロンプトはテンプレートを使ったほうが高品質なものができる傾向がたしかにある。だが一方であまりに硬直的な利用プロセスはAIの適用範囲を無駄に狭めてしまい有害である。

テンプレートを使えるものは使えばよいが、それはそれとしてフリースタイルの利用も推奨し、その中で頻出のものをテンプレート化する方向に修正しようと思う。

ChatGPTでRAG(Retrieval-Augmented Generation)を試してみた

AIを使った開発をより徹底するために今プロンプトエンジニアリングを研究している。

そんな折Xで面白い資料を見つけたため、さっそく試してみることにした。

RAG(Retrieval-Augmented Generation)ってなによ

LLMと特定の外部データシステムを連携させることで、機能を拡張する方法

なぜRAGが必要か
●能力を強化し、より正確かつ新しい情報を提供するため
○ トレーニングデータに 、最新 情報が含まれていない場合がある
○ AGを使用することで、リアルタイム 情報取得や専門的なトピックに対応できる
(https://speakerdeck.com/mkazutaka/gptsyorijing-du-nogao-iragsisutemunogou-zhu)

RAGは、外部の知識ベースから事実を検索して、最新の正確な情報に基づいて大規模言語モデル(LLM)に回答を生成させることで、ユーザーの洞察をLLMの生成プロセスに組み込むというAIフレームワークです。
(https://www.ibm.com/blogs/solutions/jp-ja/retrieval-augmented-generation-rag/)

Before

まずRAGを使わなかった場合から紹介する。

使ったプロンプトがこう。

Generate a code to create an S3 backet `production_app_log` in Terraform. This bucket will be used to store log files. code only.

結果、ChatGPTから返ってきたのがこうであった。

Here is the Terraform code to create an S3 bucket named `production_app_log` for storing log files:

```hcl
provider "aws" {
    # Specify the AWS region
    region = "us-west-1"  # Change this to your desired AWS region
}

resource "aws_s3_bucket" "production_app_log" {
    bucket = "production_app_log"  # Bucket name

    # Bucket settings for logs
    versioning {
        enabled = true
    }

    lifecycle_rule {
        enabled = true

        noncurrent_version_expiration {
        days = 30
        }
    }

    server_side_encryption_configuration {
        rule {
            apply_server_side_encryption_by_default {
                sse_algorithm = "AES256"
            }
        }
    }

# Additional settings can be added here
}
```

This configuration includes basic settings such as versioning, lifecycle rules for noncurrent versions, and server-side encryption with AES256 algorithm. You can modify the region and add additional settings as needed.

これはこれで別に悪くないのだが、そのまま使うには厳しい。

After

次にRAG(Retrieval-Augmented Generation)を使った場合。

プロンプトはこう。

    Generate a code to create an S3 backet `production_app_log` in Terraform. This bucket will be used to store log files. 

    Please answer by referring to the sample below and outputting only the code.



    ```
    resource "aws_s3_bucket" "deployment" {
    bucket = "${var.environment}-${var.project}-deployment"
    }

    resource "aws_s3_bucket_public_access_block" "deployment" {
    bucket                  = aws_s3_bucket.deployment.id
    ignore_public_acls      = true
    restrict_public_buckets = true
    block_public_acls       = true
    block_public_policy     = true
    }

    data "aws_iam_policy_document" "deployment" {
    statement {
        principals {
        type        = "AWS"
        identifiers = [var.iam.codepipeline_role.arn]
        }

        actions = [
        "s3:Get*",
        "s3:List*",
        "s3:ReplicateObject",
        "s3:PutObject",
        "s3:RestoreObject",
        "s3:PutObjectVersionTagging",
        "s3:PutObjectTagging",
        "s3:PutObjectAcl"
        ]

        resources = [
        aws_s3_bucket.deployment.arn,
        "${aws_s3_bucket.deployment.arn}/*",
        ]
    }
    }

    resource "aws_s3_bucket_policy" "deployment" {
    bucket = aws_s3_bucket.deployment.id
    policy = data.aws_iam_policy_document.deployment.json
    }

    resource "aws_s3_bucket_ownership_controls" "deployment" {
    bucket = aws_s3_bucket.deployment.id
    rule {
        object_ownership = "BucketOwnerEnforced"
    }
    }

    resource "aws_s3_bucket_versioning" "deployment" {
    bucket = aws_s3_bucket.deployment.id
    versioning_configuration {
        status = "Enabled"
    }
    }

    resource "aws_s3_bucket_lifecycle_configuration" "deployment" {
    bucket = aws_s3_bucket.deployment.id

    rule {
        id     = "expire_old_files"
        status = "Enabled"

        expiration {
        days = 365
        }

    }
    }
    ```

返ってきた結果がこう。

```
resource "aws_s3_bucket" "production_app_log" {
bucket = "production_app_log"
}

resource "aws_s3_bucket_public_access_block" "production_app_log" {
bucket                  = aws_s3_bucket.production_app_log.id
ignore_public_acls      = true
restrict_public_buckets = true
block_public_acls       = true
block_public_policy     = true
}

data "aws_iam_policy_document" "production_app_log" {
statement {
    principals {
    type        = "AWS"
    identifiers = [var.iam.logging_role.arn]
    }

    actions = [
    "s3:Get*",
    "s3:List*",
    "s3:PutObject",
    "s3:PutObjectAcl"
    ]

    resources = [
    aws_s3_bucket.production_app_log.arn,
    "${aws_s3_bucket.production_app_log.arn}/*",
    ]
}
}

resource "aws_s3_bucket_policy" "production_app_log" {
bucket = aws_s3_bucket.production_app_log.id
policy = data.aws_iam_policy_document.production_app_log.json
}

resource "aws_s3_bucket_ownership_controls" "production_app_log" {
bucket = aws_s3_bucket.production_app_log.id
rule {
    object_ownership = "BucketOwnerEnforced"
}
}

resource "aws_s3_bucket_versioning" "production_app_log" {
bucket = aws_s3_bucket.production_app_log.id
versioning_configuration {
    status = "Enabled"
}
}

resource "aws_s3_bucket_lifecycle_configuration" "production_app_log" {
bucket = aws_s3_bucket.production_app_log.id

rule {
    id     = "expire_old_files"
    status = "Enabled"

    expiration {
    days = 365
    }

}
}
```

参考コードがテンプレートとして動くのだと思うが、RAGを使わなかった場合と比べてはるかに詳細になっている。aws_iam_policy_documentに設定していたポリシーがはしょられていたりもするが、参考をなにも渡さずに出力させた場合と比べると雲泥の差である。

まあこのような用途であればModuleにしたほうが実際は早いしクオリティが高い。もしそれができないのだとしてもコピペして手動で置換をかけるほうが多分確実だろう。

しかしゼロショットと呼ばれるようなプロンプトを使った場合よりもはるかに求めるものに近いコードが出力されたことは大きな知見である。今後に生かしたい。

ChatGPTを使ってPlantUML形式のクラス図からGolangのコードを自動生成してみた

AIを使った自動生成を徹底的に行うためクラス図からコード生成をやってみた。

PlantUML形式のクラス図

クラス図これ。

@startuml

entity Prompt {
  contents string 

  get_next() void
}

interface AIClient {
  ask(promt Prompt) string
}

class ChatGPTClient {
  ask(promt Prompt) string
}

interface CodeRepository {
  load(key string) void
  save(key string, contents string) void
}

class FileIORepository {
  load(key string) void
  save(key string, contents string) void
}

class CodeOperator {
  generate(order string, key string) string
  request(promt Prompt) string
}


FileIORepository --|> CodeRepository

ChatGPTClient --|> AIClient
Prompt --- AIClient : ask

CodeOperator ..> AIClient
CodeOperator ..> CodeRepository
CodeOperator --- Prompt


@enduml

Generator.py

ChatGPTにプロンプトを投げるpythonスクリプトがこれ

import os
from openai import OpenAI

client = OpenAI(
    # This is the default and can be omitted
    api_key=os.environ.get("OPENAI_API_KEY"),
)

def call(content: str) -> str: 
    print ("Call GPT-4 with: ```" + content + "```")

    completion = client.chat.completions.create(
        messages=[
            {
                "role": "user",
                "content": content,
            }
        ],
        model="gpt-4",
    )

    return completion.choices[0].message.content



def load_file(file_name: str):
    with open(file_name, "r", encoding="utf-8") as f:
        return f.read()

def save_file(file_name: str, content: str):
    with open(file_name, "w", encoding="utf-8") as f:
        f.write(content)


class_diagram = load_file("my-class-diagrams.puml")


msg = '''\
    Generate code in Golang from class diagrams using PlantUML.

    - Separate the code for each class, entity, and interface.
    - Output the generated code in the following format.
    ```
    filename:{class name lowercase}
    {code}
    ```

    The class diagrams is below. 
'''

result = call(msg + class_diagram)
save_file("generated.go", result)

print ("Finished!")

出来たファイル

出来たファイルがこれ

filename:prompt.go
```golang
package main

type Prompt struct {
    Contents string
}

func (p *Prompt) get_next() {
}
```

filename:aiclient.go
```golang
package main

type AIClient interface {
    Ask(promt Prompt) string
}
```

filename:chatgptclient.go
```golang
package main

type ChatGPTClient struct {
}

func (c *ChatGPTClient) Ask(promt Prompt) string {
    return ""
}
```

filename:coderepository.go
```golang
package main

type CodeRepository interface {
    Load(key string)
    Save(key string, contents string)
}
```

filename:fileiorepository.go
```golang
package main

type FileIORepository struct {
}

func (f *FileIORepository) Load(key string) {
}

func (f *FileIORepository) Save(key string, contents string) {
}
```

filename:codeoperator.go
```golang
package main

type CodeOperator struct {
}

func (co *CodeOperator) Generate(order string, key string) string {
    return ""
}

func (co *CodeOperator) Request(promt Prompt) string {
    return ""
}
```

separator.py

手動で分割するのが嫌だったので分割するスクリプトを書いた。これ。

import re
import os
import asyncio

with open("generated.go", 'r') as file:
    lines = file.readlines()

code_block = False
for line in lines:
    # ファイル名の検出
    if re.match(r'filename:(.+\.go)', line):
        file_name_match = re.match(r'filename:(.+\.go)', line)
        new_file_name = file_name_match.group(1).strip()
        code_block = True
        code = ''
        continue

    if line.strip() == '```golang':
        continue

    # コードブロックの終了を検出
    if line.strip() == '```' and code_block:
        code_block = False
        with open(new_file_name, 'w') as new_file:
            new_file.write(code)
        continue

    # コードブロックの中のテキストを追加
    if code_block:
        code += line

書いたというか大半ChatGPTとCopilotに書かせて自分は軽く手直ししただけなのだが。

結果

こんな感じのファイルが生成された。

package main

type CodeOperator struct {
}

func (co *CodeOperator) Generate(order string, key string) string {
    return ""
}

func (co *CodeOperator) Request(promt Prompt) string {
    return ""
}

所感

悪くないんだがこれだけだと所詮足場にすぎないし、あまりに不徹底。この程度で終わりでは話にならない。結局クラス図は処理の情報がないから処理部分が書けない。

しかし知見は得られた。

  1. 手間のかかるプロンプト作成を予めスクリプトに仕込んでおくと再利用性を期待できる。開発に必要なスクリプトはある程度決まっているものも多かろうし、ポリシー、プロシージャ、そしてプロンプトを最初から用意しておくと相当に効果的であろう。
  2. ファイルのRead/WriteとChatGPT APIを組み合わせることで、コピペではできない速度の開発ができる。msレベルの速度は必要ないし(っていうかどうせAPIの呼び出しで時間がかかるので非同期とパラレルができれば大差ない)pythonが楽。
  3. クラス図からでは生成できるものがちゃちすぎる。詳細設計レベルまで落とし込む必要がある。

メモ:AIを使った開発を試してみて思ったことメモ20231213

課題

AIをしばらく試用してみて、十分実用に足ると確信を持った。

今のところAIを「ちょっと強力なIntellisense」ぐらいにしか活用できていないが、この程度で満足すべきでない。徹底的にAIを使い倒すプロセスを編み出したい。

先にまとめ

  • AIを使っても開発の基本的な流れは変わらない
  • すべてをAI任せにすることはできない。苦手なところはアシストが限界だし、強みを生かせるところでも検収や修正が必要で人間の手がかかる。

メモ

開発の基本は変わらない

  1. 何を作るのか決めて(設計)
  2. 決めたことを形にして(開発)
  3. その出来を確かめる(テスト)

この流れは結局一緒。AI利用だろうが一緒。

一度、「AIすごい!」に意識が向いてしまって、「いかにAIを使うか」すなわち2から発想を始めてしまったが、結局さんざん迷走したあげく行き詰った。

「それはなぜ作らないといけないのか?」「いったい何がしたいのか?」「どこの誰にどのような価値があるのか?」そういったことを考えずにAIと勢い込んで相談を進めても、結局どこかで「で、それは何故作るの?」という疑問にぶち当たり、失速し、墜落する。

「それはなぜ作らないといけないのか?」「いったい何がしたいのか?」「どこの誰にどのような価値があるのか?」これがAI利用の有無に関係なく極めて大事なことだ。

開発の各フェイズにおけるAIの活用

とにかく闇雲にやってみた。結果、以下の結論を得た。

  1. 何を作るのか決めて(設計)
  2. なぜ作るのか。なにがしたいのか
    • ここは自分が決めるしかない。ただし相談したいことがあればするとよい。
  3. 消費できる時間とお金の限界はそれぞれいくらか(予算とスケジュール)
    • ここも自分が決めるしかない。
    • もっとも根拠として投入できるデータがあるなら別だ。AIを使えるだろう。私には(そしておそらくは多くの人も)ないというだけだ。
  4. 具体的にどのような機能が必要か
    • ここは結構AIが強い。いい線いってる回答が返ってくる。どんどん活用していい。
  5. さらに具体的に、その機能を実現するソリューションは何か
    • AIがやたら強い。早いし広い。深くはないが十分。活用しないほうがおかしいレベルでGood。
  6. 決めたことを形にして(開発)
  7. AIが最高に強い。まあ完璧ではなくて、全部で10までの工程を行わなければ完成しないとすると、せいぜい7~9くらいで止まる。なので欠けている部分は自分で補うしかない。
  8. その出来を確かめる(テスト)
  9. 単体テストはできる。できるが、そもそもの量が多いだけにAIにプロンプトを投げる作業自体が多い。ここも自動化するべきだ。改善の余地が大きい。
  10. 結合テストシステムテストになると活用の方法を考えるのが難しい。ただやりようはある気はする。ここも何とかしたい部分。

フェイズごとにまとめると以下のようになる。

  1. 要求定義 ・・・ ほぼ全部自分でやる
  2. 要求定義 -> 要件定義 ・・・ 大半を自分でやることになるが、AIも相談相手になる。
  3. 要件定義 -> 基本設計 ・・・ AIにドラフトを作成させ、自分は肉付けと仕上げを行う
  4. 基本設計 -> 詳細設計 ・・・ 大半をAIにやらせる前提で行い、足りない部分だけ自分で補う
  5. テスト単体テストに関してはかなりできる。課題も多いが、徹底活用する方向で考えるべき。

ただテンプレートやライブラリ、フレームワークなど、そもそも作る必要自体がないものもたくさんある。そんなものをAIで生成できるからと言って生成するのはナンセンスだ。大抵の場合、作らないのがコスパ最高のソリューションである。すなわちフレームワークやライブラリは結局今後も活用するべきということになる。

将来、要求定義さえ出せればあとはフルスクラッチで一から完全に最適化された最高のアプリケーションをAIが作ってくれるようになるのかもしれない。しかしそれは今ではない。 今は、AIで生成する部分と、人間が作る部分を組み合わせることになる。

思ったこと

今後は開発者はフルスクラッチで書こうと思えば書ける技術に加えて、AIを使ってより効率的に開発する技術も持つ必要があるだろう。開発者は手間の部分では楽になるが、必要なスキルは今よりさらに高度かつ広範になる。

また、低スキルでも頭数だけ揃っていればいいとする類のプロジェクトマネジメントは、ゼロにはならないとしても、その有効性をだいぶ減じることになろう。今後は低スキルの開発者10人よりもAIを使いこなせる高スキルの開発者1人のほうが品質・速度・コストすべての面で勝ることになるのではないか。分野を限定すれば50人いても勝てるかもしれない。

deeplearning.ai のChatGPT Prompt Engineering for Developersを見た際のメモ

タイトルの通り、メモ書き。リンクはこちら

Introduction

  • Base LLM
    • 単語の集合からそれっぽい文章を生成する。なんか近い単語を選んでる、それだけ。みたいな感じ。
  • Instruction Tuned LLM
    • チューニングしてちゃんと指示に従うようにしているらしい。
    • 今熱いのはこっち

Guidelines

  • Prisiple 1

    • 「明確に、具体的に、指定せよ」
    • 勘違いしてはいけないが、「明確に」書こうとして「短く」してはならない
    • デリミタを使うことで誤解を防ぎやすくなる。使おう。
      • たとえば"```"で囲むのがデリミタを使うテクニックだ。
    • 返答のスタイルを指定することができる。
  • Prisiple 2

    • 考える時間を渡せ
      • ここでは処理時間を伸ばせというだけのことではない。
        1. プロンプトでIssueを細かいTaskに分割していくことを要求することができる。
          1. たとえば、"Perform the following actions: "と指定してから、まず要約せよ。次にそれを翻訳せよ。と指定する。
        2. 正答が正しいか、「自分で答えを出せ」そして「比較せよ」とすることもできる
          1. これを実施させるためのプロンプトはかなり長い!

モデルは特に元データがすくないものについては捏造してしまいやすい(ハルシネーションと呼んでいる)。これを防ぐためには、良好な元データを渡すことだそうだ。

Iterative

一発で素晴らしい答えが返ってくると思ってはならず、プロンプトをくりかえし、チューニングしていくことが必要。下記のように。

  1. 明確に指定せよ
  2. (いい答えが返ってこなかったら)なぜ結果が期待に沿わなかったか考えよ
  3. アイディアとプロンプトを修正せよ
  4. 1-3を繰り返せ

例えば、もし長すぎると思ったら"Use ato most 50 words(sentences)"と指定することで50単語以内に収まるようにする、といったことができる。

特にフォーカスさせたい事柄がある場合

"focus on the XXXXX"などのように指定することができる。

講師の人曰く「最終形となるプロンプトにたどり着くまでには試行錯誤が必要だ。これに一発でたどり着ける人を私は知らない(意訳)」だそうである。

「最高のプロンプトとは、「俺の考えた最強プロンプトBest10」みたいなものではなくて、そこに至るための試行錯誤プロセスのことだ(意訳)」

すばらしい。まったく同感。

Summarizing

要約ができる!

今のところドキュメントの要約はそこまで要らないなあ、と思っていたが、コードを読ませて仕様を書かせる、みたいなことに使えるかもしれない。

最初は興味なかったが、実はかなり大事かもしれない。

Inferring(推論)

推論ができる。

これは本当にすごい。テキストベースに限定される必要もないのではなかろうか。端的にレコメンドとかもこれでできるはず。

Transforming(変換)

英語 -> 日本語とかだけでなく、文章をHTMLにしたりもできる

Expanding(拡張)

こう頼むと

Please expand it ```Thank you for your cooperation!``` i would like to send email to costomer support.

こう返ってくる

ChatGPT
To expand the phrase "Thank you for your cooperation!" into a more detailed and polite message suitable for an email to customer support, you might want to include a few key elements: appreciation for their assistance, a reference to your specific issue or interaction, and a courteous closing. Here’s an example:

Subject: Appreciation for Your Support

Dear [Customer Support Team/Specific Representative's Name],

I hope this message finds you well. I am writing to express my sincere gratitude for the support and assistance you have provided me. Your prompt and effective handling of [mention your specific issue or request here] has not only resolved my concerns but also significantly enhanced my experience with your services.

Your team's dedication to customer satisfaction is truly commendable, and I wanted to take a moment to acknowledge the excellent service I received. It is clear that your team goes above and beyond to ensure that customers' needs are addressed with care and professionalism.

Thank you once again for your cooperation and support. It is greatly appreciated and does not go unnoticed. Please feel free to forward this message to your supervisor or team leader, as I believe such exemplary service deserves recognition.

I look forward to continuing my association with your company and will certainly recommend your services to my colleagues and friends.

Warm regards,

[Your Name]
[Your Contact Information, if necessary]

Feel free to personalize this template according to your situation and the specifics of your interaction with customer support.

まとめ

  • 原則  - 明確に指定せよ  - 考える時間を与えよ
  • プロンプトを繰り返しチューニングせよ
  • できること
    • 要約
    • 推論
    • 変換
    • 拡張

deeplearning.ai のChatGPT Prompt Engineering for Developersを見た際のメモ

リンクはこちら

Introduction

  • Base LLM
    • 単語の集合からそれっぽい文章を生成する。なんか近い単語を選んでる、それだけ。みたいな感じ。
    • Copilotは割とこちらっぽい挙動が多いよなー
  • Instruction Tuned LLM
    • チューニングしてちゃんと指示に従うようにしているらしい。
    • 今熱いのはこっち

Guidelines

  • Prisiple 1

    • 明確に、具体的に、指定せよ
    • 勘違いしてはいけないが、「明確に」書こうとして「短く」してはならない
    • デリミタを使うことで誤解を防ぎやすくなる。使おう。
      • たとえば"```"で囲むのがデリミタを使うテクニックだ。
      • 返答のスタイルを指定することができる。
  • Prisiple 2

    • 考える時間を渡せ
      • ここでは処理時間を伸ばせというだけのことではない。
        1. プロンプトでIssueを細かいTaskに分割していくことを要求することができる。
          1. たとえば、"Perform the following actions: "と指定してから、まず要約せよ。次にそれを翻訳せよ。と指定する。
        2. 正答が正しいか、「自分で答えを出せ」そして「比較せよ」とすることもできる
          1. これを実施させるためのプロンプトはかなり長い!

モデルは特に元データがすくないものについては捏造してしまいやすい(ハルシネーションと呼んでいる)。これを防ぐためには、良好な元データを渡すことだ。

Iterative

一発で素晴らしい答えが返ってくると思ってはいけない。プロンプトをくりかえし、チューニングしていくことが必要だ。下記のように。

  1. 明確に指定せよ
  2. (いい答えが返ってこなかったら)なぜ結果が期待に沿わなかったか考えよ
  3. アイディアとプロンプトを修正せよ
  4. 1-3を繰り返せ

長すぎる場合

もし長すぎると思ったら"Use ato most 50 words(sentences)"と指定することで、50単語以内に収まるようにすることができる。

特にフォーカスさせたい事柄がある場合

"focus on the XXXXX"などのように指定することができる。

講師曰く「最終形となるプロンプトにたどり着くまでには試行錯誤が必要だ。これに一発でたどり着ける人を私は知らない(要約)」だそうである。

「最高のプロンプトとは、「俺の考えた最強プロンプトBest10」みたいなものではなくて、そこに至るための試行錯誤プロセスのことだ(要約)」

すばらしい。

Summarizing

要約ができるよ!

ってことなんだけど、まあたしかにすごいんだけど、自分の興味からははずれるなあ・・・。

Inferring(推論)

これはマジですごいんだが、テキストベースに限定される必要がないはずなんだよなー。端的にレコメンドとかもこれのはず。

Transforming(変換)

英語 -> 日本語とかだけでなく、文章をHTMLにしたりもできる

Expanding(拡張)

こう頼むと

Please expand it ```Thank you for your cooperation!``` i would like to send email to costomer support.

こう返ってくる

ChatGPT
To expand the phrase "Thank you for your cooperation!" into a more detailed and polite message suitable for an email to customer support, you might want to include a few key elements: appreciation for their assistance, a reference to your specific issue or interaction, and a courteous closing. Here’s an example:

Subject: Appreciation for Your Support

Dear [Customer Support Team/Specific Representative's Name],

I hope this message finds you well. I am writing to express my sincere gratitude for the support and assistance you have provided me. Your prompt and effective handling of [mention your specific issue or request here] has not only resolved my concerns but also significantly enhanced my experience with your services.

Your team's dedication to customer satisfaction is truly commendable, and I wanted to take a moment to acknowledge the excellent service I received. It is clear that your team goes above and beyond to ensure that customers' needs are addressed with care and professionalism.

Thank you once again for your cooperation and support. It is greatly appreciated and does not go unnoticed. Please feel free to forward this message to your supervisor or team leader, as I believe such exemplary service deserves recognition.

I look forward to continuing my association with your company and will certainly recommend your services to my colleagues and friends.

Warm regards,

[Your Name]
[Your Contact Information, if necessary]

Feel free to personalize this template according to your situation and the specifics of your interaction with customer support.

まとめ

  • 原則  - 明確に指定せよ  - 考える時間を与えよ
  • プロンプトを繰り返しチューニングせよ
  • できること
    • 要約
    • 推論
    • 変換
    • 拡張

AWS EC2(Amazon Linux 2023)にfluent-bitをインストールする

タイトルの通りなのだが、妙なハマり方をしたのでメモ。

Install Commands

curl https://raw.githubusercontent.com/fluent/fluent-bit/master/install.sh | sh

sudo systemctl start fluent-bit 

ここまででインストールはできる。

Fix

しかし妙なエラーが出た。

systemctl status fluent-bit
● fluent-bit.service - Fluent Bit
     Loaded: loaded (/usr/lib/systemd/system/fluent-bit.service; disabled; preset: disabled)
     Active: active (running) since Mon 2023-08-14 07:38:09 UTC; 42s ago
       Docs: https://docs.fluentbit.io/manual/
   Main PID: 2732 (fluent-bit)
      Tasks: 7 (limit: 2131)
     Memory: 7.9M
        CPU: 216ms
     CGroup: /system.slice/fluent-bit.service
             └─2732 /opt/fluent-bit/bin/fluent-bit -c //etc/fluent-bit/fluent-bit.conf

Aug 14 07:38:09 i-0a307d0088fc56aa3.ap-northeast-1.compute.internal fluent-bit[2732]: [2023/08/14 07:38:09] [ info] [output:file:file.0] worker #0 started
Aug 14 07:38:09 i-0a307d0088fc56aa3.ap-northeast-1.compute.internal fluent-bit[2732]: [2023/08/14 07:38:09] [ warn] [aws_credentials] Failed to initialize profile provider: HOME, AWS_CONFIG_FILE, and AWS_SHARED>
Aug 14 07:38:09 i-0a307d0088fc56aa3.ap-northeast-1.compute.internal fluent-bit[2732]: [2023/08/14 07:38:09] [ info] [output:cloudwatch_logs:cloudwatch_logs.1] worker #0 started
Aug 14 07:38:09 i-0a307d0088fc56aa3.ap-northeast-1.compute.internal fluent-bit[2732]: [2023/08/14 07:38:09] [ warn] [aws_credentials] Failed to initialize profile provider: HOME, AWS_CONFIG_FILE, and AWS_SHARED>
Aug 14 07:38:09 i-0a307d0088fc56aa3.ap-northeast-1.compute.internal fluent-bit[2732]: [2023/08/14 07:38:09] [ info] [output:kinesis_firehose:kinesis_firehose.2] worker #0 started
Aug 14 07:38:09 i-0a307d0088fc56aa3.ap-northeast-1.compute.internal fluent-bit[2732]: [2023/08/14 07:38:09] [ info] [output:s3:s3.3] Using upload size 1000000 bytes
Aug 14 07:38:09 i-0a307d0088fc56aa3.ap-northeast-1.compute.internal fluent-bit[2732]: [2023/08/14 07:38:09] [ info] [output:s3:s3.3] total_file_size is less than 10 MB, will use PutObject API
Aug 14 07:38:09 i-0a307d0088fc56aa3.ap-northeast-1.compute.internal fluent-bit[2732]: [2023/08/14 07:38:09] [ warn] [aws_credentials] Failed to initialize profile provider: HOME, AWS_CONFIG_FILE, and AWS_SHARED>
Aug 14 07:38:09 i-0a307d0088fc56aa3.ap-northeast-1.compute.internal fluent-bit[2732]: [2023/08/14 07:38:09] [ info] [sp] stream processor started
Aug 14 07:38:09 i-0a307d0088fc56aa3.ap-northeast-1.compute.internal fluent-bit[2732]: [2023/08/14 07:38:09] [ info] [output:s3:s3.3] worker #0 started

7:38:09] [ warn] [aws_credentials] Failed to initialize profile provider: HOME, AWS_CONFIG_FILE, and AWS_SHAREDの部分である。

結論、こちらを参考にし、/usr/lib/systemd/system/fluent-bit.serviceを編集して環境変数を設定してやれば解決した。

[ec2-user@i-0a307d0088fc56aa3 fluent-bit]$ sudo cat /usr/lib/systemd/system/fluent-bit.service
[Unit]
Description=Fluent Bit
Documentation=https://docs.fluentbit.io/manual/
Requires=network.target
After=network.target

[Service]
Type=simple
EnvironmentFile=-/etc/sysconfig/fluent-bit
EnvironmentFile=-/etc/default/fluent-bit
ExecStart=/opt/fluent-bit/bin/fluent-bit -c //etc/fluent-bit/fluent-bit.conf
Restart=always
Environment="ENVIRONMENT=development"
Environment="PROJECT=mybook"
Environment="HOME=/root"
Environment="AWS_CONFIG_FILE=/root/.aws/config"
Environment="AWS_SHARED_CREDENTIALS_FILE=/root/.aws/credentials"



[Install]
WantedBy=multi-user.target
[ec2-user@i-0a307d0088fc56aa3 fluent-bit]$ 

この通り。

[ec2-user@i-0a307d0088fc56aa3 fluent-bit]$ sudo systemctl status fluent-bit
● fluent-bit.service - Fluent Bit
     Loaded: loaded (/usr/lib/systemd/system/fluent-bit.service; disabled; preset: disabled)
     Active: active (running) since Mon 2023-08-14 07:54:30 UTC; 1s ago
       Docs: https://docs.fluentbit.io/manual/
   Main PID: 3375 (fluent-bit)
      Tasks: 7 (limit: 2131)
     Memory: 7.9M
        CPU: 201ms
     CGroup: /system.slice/fluent-bit.service
             └─3375 /opt/fluent-bit/bin/fluent-bit -c //etc/fluent-bit/fluent-bit.conf

Aug 14 07:54:30 i-0a307d0088fc56aa3.ap-northeast-1.compute.internal fluent-bit[3375]: [2023/08/14 07:54:30] [ warn] [filter:rewrite_tag:rewrite_tag.0] 'Match' may cause infinite loop.
Aug 14 07:54:30 i-0a307d0088fc56aa3.ap-northeast-1.compute.internal fluent-bit[3375]: [2023/08/14 07:54:30] [ info] [input:emitter:re_emitted] initializing
Aug 14 07:54:30 i-0a307d0088fc56aa3.ap-northeast-1.compute.internal fluent-bit[3375]: [2023/08/14 07:54:30] [ info] [input:emitter:re_emitted] storage_strategy='memory' (memory only)
Aug 14 07:54:30 i-0a307d0088fc56aa3.ap-northeast-1.compute.internal fluent-bit[3375]: [2023/08/14 07:54:30] [ info] [output:file:file.0] worker #0 started
Aug 14 07:54:30 i-0a307d0088fc56aa3.ap-northeast-1.compute.internal fluent-bit[3375]: [2023/08/14 07:54:30] [ info] [output:cloudwatch_logs:cloudwatch_logs.1] worker #0 started
Aug 14 07:54:30 i-0a307d0088fc56aa3.ap-northeast-1.compute.internal fluent-bit[3375]: [2023/08/14 07:54:30] [ info] [output:kinesis_firehose:kinesis_firehose.2] worker #0 started
Aug 14 07:54:30 i-0a307d0088fc56aa3.ap-northeast-1.compute.internal fluent-bit[3375]: [2023/08/14 07:54:30] [ info] [output:s3:s3.3] Using upload size 1000000 bytes
Aug 14 07:54:30 i-0a307d0088fc56aa3.ap-northeast-1.compute.internal fluent-bit[3375]: [2023/08/14 07:54:30] [ info] [output:s3:s3.3] total_file_size is less than 10 MB, will use PutObject API
Aug 14 07:54:30 i-0a307d0088fc56aa3.ap-northeast-1.compute.internal fluent-bit[3375]: [2023/08/14 07:54:30] [ info] [sp] stream processor started
Aug 14 07:54:30 i-0a307d0088fc56aa3.ap-northeast-1.compute.internal fluent-bit[3375]: [2023/08/14 07:54:30] [ info] [output:s3:s3.3] worker #0 started
[ec2-user@i-0a307d0088fc56aa3 fluent-bit]$ 

ちなみにテストのためCloudwatch、S3、Kinesis Firehoseにログを出力する設定を入れていた。