みらいテックラボ

音声・画像認識や機械学習など, 週末プログラマである管理人が興味のある技術の紹介や実際にトライしてみた様子などメモしていく.

「LangChain完全入門 生成AIアプリケーション開発がはかどる大規模言語モデルの操り方」の紹介

最近, 趣味で開発しているKingyo AI Navi[1]で生成AIを使ってみようと, GPT-3.5/4やPaLM2(Google Vertex AI)など大規模言語モデル(LLM)を試している.
当初はChatGPT等のAPIを直接利用していたが, LangChainという「ChatGPTなどの大規模言語モデルの機能拡張を効率的に実装するためのライブラリ」のことを知った.
LangChainの基本的な使い方をまとめた本を探していたところ, この「LangChain完全入門」に出会った.
この本は, LangChaingの6つのモジュールの基本的な使い方を, ソースコードの提示&解説していくスタイルで書かれており, とてもわかりやすい内容であった.
ChatGPTやPaLM2などに興味を持ち, これらを使ってチャットシステムなど何かプログラムでも作ってみたいと思う方には, まず最初にこの本を読むことオススメします.


  CONTENTS

CHAPTER 1 ChatGPTとLangChain
CHAPTER 2 Model I/O - 言語モデルを扱いやすくする
CHAPTER 3 Retrieval - 未知のデータを扱えるようにする
CHAPTER 4 Memory - 過去の対話を短期・長期で記憶する
CHAPTER 5 Chains - 複数の処理をまとめる
CHAPTER 6 Agents - 自律的に外部と干渉して言語モデルの限界を超える
CHAPTER 7 Callbacks - さまざまなイベント発生時に処理を行う


ただ, 1点不満をあげると, 本の発売(2023.10.21)から1ヶ月ちょいしか経っていないのだが, 本で使用されている各種ライブラリのバージョンが少し古いようで, 最新のバージョンではエラーが発生する箇所がいくつかあった.

バージョン:

ライブラリ 本(2023.10発売) 今回(2023.11)
openai 0.27.8 1.3.5
langchain 0.0.261 0.0.340
chainlit 0.5.2 0.7.604
pydantic 1.10.12 2.4.2


以下に, エラーが発生した箇所の修正内容を記しておく. (正誤表ではなく, あくまでバージョン違いによる対応表です.)
ただし, 類似のエラーの場合は最初のエラー箇所のみ記載しているので, これらを参考に適宜修正してください.

・CHAPTER 1, P40 sample.py
[本]

import json
import openai

response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",
    messages=[
        {
            "role": "user",
            "content": "iPhone8のリリース日を教えて"
        },
    ]
)

print(json.dumps(response, indent=2, ensure_ascii=False))

[修正後]

import os
from openai import OpenAI

client = OpenAI()

response = client.chat.completions.create(
    model="gpt-3.5-turbo",
    messages=[
        {
            "role": "user",
            "content": "iPhone8のリリース日を教えて"
        }
    ],
)

print(response)

・CHAPTER 2, P83, 84 pydantic_output_parser.py
[本]

from langchain.chat_models import ChatOpenAI
from langchain.output_parsers import PydanticOutputParser
from langchain.schema import HumanMessage
from pydantic import BaseModel, Field, validator

chat = ChatOpenAI()

class Smartphone(BaseModel):
    release_date: str = Field(descriptions="スマートフォンの発売日")
    screen_inches: float = Field(description="スマートフォンの画面サイズ(インチ)")
    os_installed: str = Field(description="スマートフォンにインストールされているOS")
    model_name: str = Field(description="スマートフォンのモデル名")
    
    @validator("screen_inches")
    def validate_screen_inches(cls, field):
        if field <= 0:
            raise ValueError("Screen inches must be a positive number")
        return field

   (以下, 省略)

[修正後]

from langchain.chat_models import ChatOpenAI
from langchain.output_parsers import PydanticOutputParser
from langchain.schema import HumanMessage
from pydantic import BaseModel, Field, field_validator

chat = ChatOpenAI()

class Smartphone(BaseModel):
    release_date: str = Field(descriptions="スマートフォンの発売日")
    screen_inches: float = Field(description="スマートフォンの画面サイズ(インチ)")
    os_installed: str = Field(description="スマートフォンにインストールされているOS")
    model_name: str = Field(description="スマートフォンのモデル名")
    
    @field_validator("screen_inches")
    def validate_screen_inches(cls, field):
        if field <= 0:
            raise ValueError("Screen inches must be a positive number")
        return field

・CHAPTER 3, P116 chat_1.py
[本]

import chainlit as cl

@cl.on_chat_start
async def on_chat_start():
    await cl.Message(content="準備ができました! メッセージを入力してください!").send()
    
@cl.on_message
async def on_message(input_message):
    print("入力されたメッセージ:" + input_message)
    await cl.Message(content="こんにちは!").send()

[修正後]

import chainlit as cl

@cl.on_chat_start
async def on_chat_start():
    await cl.Message(content="準備ができました! メッセージを入力してください!").send()
    
@cl.on_message
async def on_message(input_message):
    print("入力されたメッセージ:" + input_message.content)
    await cl.Message(content="こんにちは!").send()

・CHAPTER 3, P121-124 chat_3.py
[本]

   (078まで省略)

    result = chat([
        HumanMessage(content=prompt.format(documents=documents_string,
                                           query=input_message)) #← input_messageに変更
    ])
    await cl.Message(content=result.content).send()

[修正後]

    result = chat([
        HumanMessage(content=prompt.format(document=documents_string, 
                                           query=input_message.content))
    ])
    await cl.Message(content=result.content).send()

----
参照URL:
[1] Kingyo AI NaviでChatGPTを試す(2)