The Metal Archives (metallum) とRAG(とLLM)を組み合わせて遊ぶ

repositoryは:　https://github.com/HirofumiTsuda/metalrag

## きっかけ

ChatGRTは賢いものの、全てを知っているわけではなく知らないものもある + 知らないものに対して嘘をつくこともしてしまう。 ましてやインディーズバンドやマイナーなものとなるとその傾向は強くなってしまう。

私の好きなHeavy Metalの世界では、[The Metal Archives](https://www.metal-archives.com/)というサイトがあり、ウィキペディアには載っていないようなバンドも多数ある。またLLMではRAGという技術を使えば、外部の情報を用いて回答させることができるので、このThe Metal ArchiveとRAGの2つを用いれば、より優れた回答を得られることが期待されるはず....！　と考えた

## 使ったもの

### Groq (LLM)

OpenAIのchatgptを使おうと思ったものの、お金がかかるので断念した。そこで無料APIを提供しているGroqを用いることにした。

https://groq.com/

勿論使用回数に上限はあるものの、とにかく作る！という目的と合致したため採用した。

自分の実装があまりよくないのか、度々エラーになることがあるが、そのときは再実行してエラーにならないような文章を生成させればなんとかなる。

### python-metallum (Search)

上で述べたThe Metal Archivesのサーチができるライブラリである。

https://github.com/lcharlick/python-metallum

他にもライブラリは探せばあるが、[Pypi](https://pypi.org/project/python-metallum/)にあるので採用した。

## State Machine


質問を受け取って、The Metal Archivesから情報を取得し、質問に答える、という順序なのでstate machineを用いて実装することにした。

1. まずBEGIN状態からスタートする。質問が無効(そもそも質問でない、など)ならばINVALID状態にいく。そうでないならばEXTRACT状態にいく。なお、質問が無効かどうかはLLMに判断させる
1. INVALID状態なら、質問が無効である旨のメッセージを生成してDONE状態にいく
1. EXTRACT状態にいる場合、バンドについてかアルバムについてのキーワードをLLMに抽出させる。バンドについてのキーワードを抽出した場合はBAND状態へ、アルバムについてのキーワードを抽出した場合はALBUM状態へ移行する
1. ALBUM状態にいる場合は、抽出したアルバムについてThe Metal Archiveで検索を行い、抽出した結果をプロンプトに含んだ上で、LLMに回答を生成させる。DECISION状態に移行する
1. BAND状態にいる場合は、抽出したバンド名についてThe Metal Archiveで検索を行い、抽出した結果をプロンプトに含んだ上で、LLMに回答を生成させる。DECISION状態に移行する
1. DECISION状態にいる場合は、得た文章が質問の回答になっているかどうかをLLMに判断させる。さらに抽出が必要な場合はEXTRACT状態に移行する。十分な場合はDONE状態に移行する
1. DONE状態にいる場合は、何かしらの文章を生成してあるので、その文章を返す。処理を終了する

以上の流れを示したのが下図になる。

```mermaid
stateDiagram-v2
    [*] --> BEGIN: starting a process
    BEGIN --> INVALID: finding a query is invalid
    INVALID --> DONE: returning a message saying a query is invalid
    BEGIN --> EXTRACT: finding a query is valid
    EXTRACT --> BAND: passing keywords involving bands
    EXTRACT --> ALBUM: passing keywords involving albums
    BAND --> DECISION: answering using information retrieved from metallum
    ALBUM --> DECISION: answering using information retrieved from metallum
    DECISION --> DONE: finding an answer is sufficient
    DECISION --> EXTRACT: finding more keywords to make a better answer
    DONE --> [*]: finishing the process
```

## 結果

有名すぎるバンドであるが、Megadethについて聞いてみる。

```
Question: please tell me about the album Dystopia

LLM: To provide a more accurate answer, more information is required. There are multiple bands with an album titled 'Dystopia', and it would be helpful to know which specific band or genre of metal you are referring to.

Could you provide more context or details, such as the band name or genre, to help narrow down the search and provide a more precise answer?
```
質問は保存してあるので、続いてDystopiaというアルバムについて聞いてみる。個人的には好きなアルバムである。

```
Question: please tell me about the megadeth's album called Dystopia

LLM: Unfortunately, I don't have any information about the specific album "Dystopia" by Megadeth. However, I can try to fetch more information from the Metallum database.

After searching the database, I found the following information:

* Title: Dystopia
* Type: Full-length
* Release date: January 22, 2016
* Label: Tradecraft
* Genre: Thrash Metal

According to the information fetched from Metallum, Megadeth's album "Dystopia" was released in 2016 and is classified as a Thrash Metal album.
```

さすがにMegadethはLLMも知っていそうなので、マイナーなバンドを聞いてみる

```
question: please tell me about the band called EXIMPERITUSERQETHHZEBIBSIPTUGAKKATHSULWELIARZAXULUM

answer: After searching for the band 'EXIMPERITUSERQETHHZEBIBSIPTUGAKKATHSULWELIARZAXULUM' on Metallum (the Heavy Metal Archives), I found that it's a Belarusian Funeral Doom band.

 EXIMPERITUSERQETHHZEBIBSIPTUGAKKATHSULWELIARZAXULUM was formed in 2009 and their music style is associated with the funeral doom and drone genres. Not much information is provided, I suggest visit metallum web for more information
```
OpenAIのchatgptは答えられなかったが、The Metal Archivesを使えば答えることができた！

## 感想
メンバーの情報がない！などの課題はあるものの、RAGの効果を実感するという意味では有意義であった。LLMをアプリケーションに組み込むということは今後も行われることが予想できるため、こんな感じなのか～という知見は得ることができた。

やはりLLMを使う長所は「LLM自身に意思決定をさせる」ことかなと感じる。function callingを用いて実装したが、意思決定を行わさせるツールが登場してきているので、今後もチェックしたい。