ChatGPT/LangChainによるチャットシステム構築[実践]入門のプログラムを試す

![sky-high.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784222/d71e8567-1c29-0316-4ce7-70347b366dc9.jpeg)

# はじめに

　現在私は「LangChain」のプログラムに沼っており（若い人が使う言葉ですね）、今回は「ChatGPT/LangChainによるチャットシステム構築[実践]入門」を読んで、いろいろプログラミングをして楽しむことにしました。
　今まで私は「製造業の生産管理システム」や「プログラム言語の構文解析システム」など、いろいろなプログラミングをしてきたのですが、生成AI分野のように完全な正解が無く、常にアップデートしていくスタンスのものは初めてで、とても興味深いです。

　この書籍通りにプログラミングを進めてみたのですが、何度も失敗を繰り返し、何度も心が折れそうになりました。。。これから生成AI分野を目指す方々がこの書籍を読んで楽しくプログラミングができる一助になればと思い、記事の投稿をしました。

![syoseki.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784222/12174436-9f9a-1c70-4b4f-512e23c3b9a6.jpeg)

# 多くの地獄（壁）
　この書籍は2023年10月に発行されたもので、比較的新しいのですが、「LangChain」やその他のサービス仕様がバージョンアップしたため、そのままではまともにプログラムを動かすことができないことを知りました。
 　書籍の発行後、「正誤表」でバージョンを固定されていることを確認したのですが、それでだけではやはり動きませんでした。
  今回は、特に難儀した２つの地獄（壁）について、どう解決したかを記載していきたいと思います。
  

# Slack地獄
　書籍の「なぜSlackアプリを作るのか」(P156)から始まる部分を参考に、ローカルPCでプログラムを実行させたのですが、SSLに関するエラーが発生しました。

```
Slack API server: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify
```

最初はSlackの設定の問題なのかなぁと思い、いろいろ試してみたのですが、全然ダメでした。

### 環境変数を疑う
　最初は環境変数の設定誤りを疑いました。キー名称の誤りではないだろうか、そもそもキーが間違っているのではないだろうか・・・ いろいろ試してみたのですが、全然ダメでした。
　この章を飛ばして次の章からプログラミングをしようと思ったのですが、その後の章ではSlackを用いていろいろやっていくようで、ここで躓いたらthe endになりそうです。ですので、これを何とかクリアしようと思いました。 中学生の時の数学のテストで、最初で間違っていたら、そのあとはすべてアウト・・・あの時の感情がよみがえってきました💦

 ```bash:.env
# 以下のキーはすべてでたらめです。悪しからず・・・
SLACK_SIGNING_SECRET=abevrey5436nb5tvtb6vttyb6bvt5tv55
SLACK_BOT_TOKEN=xoxb-87654468554645-5457645466654-6uhtrfytui7uy5erghyuteer
SLACK_APP_TOKEN=xapp-1-A0re454534MM-0898754456779-98iyhfgfjugjhhgghji7utyghtyh7uyhthutyhtyh6
 ```
 
### プロキシサーバを疑う
　次にプロキシサーバを疑いました。
 
 https://qiita.com/ground0state/items/c4d7caa274b6e3d99e27

　上記のような記事があったので、どないかせないかんと思い、試そうとしたのですが、私の頭の問題なのですがよく理解することができず、あきらめました。
 　ただ、プロキシサーバは自動検出となっていたので、プロキシサーバ自体を外したりしたのですが、効果はありませんでした。

### プログラムを疑う
　次にプログラムを疑いました。ただ、疑おうにもどこを疑っていいのかがわかりません。
 　記事をいろいろ探す中で、SSLのチェック自体を外す方法がある事がわかりました。

https://note.com/kinpatu_com/n/n6e9a40be13b9

```python:
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
```
　設定して`app.py`を実行したのですが、あれれ・・・やっぱり同じエラーが出ました。だめだこりゃ。

### 証明書を疑う
　記事をいろいろ検索してみると、証明書の問題があるのではないかと思い始めました。その記事がこちらです。最後の部分で、環境変数に`SSL_CERT_FILE`を追加すればよいという記事があったので試してみました。
  `certifi`でpemファイルの位置を確認して、環境変数に追加をしました。

https://qiita.com/hayahaya2/items/d952455ff5fb20808262

 ```bash:.env
SSL_CERT_FILE='C:\users\・・・・・\cacert.pem'
 ```
 さあ`app.py`を実行です！　ありゃ同じエラーだ。ああ、WindowsPCだからエスケープをつけなくちゃ。

 ```bash:.env
SSL_CERT_FILE='C:\\users\\・・・・・\\cacert.pem'
 ```
あれれ💦　それじゃ、カレントディレクトリにpemファイルを持ってきて、パスを考慮しなくても良いようにして実行。

```bash:.env
SSL_CERT_FILE='cacert.pem'
 ```
 
　あら、またエラーが出た。もうあきらめた方が良いのでしょうか・・・
　エラーが出てから丸１日経ってしまいました。😨

### ローカルPCを疑う
　書籍では、ローカルPCではなく「Cloud9」を使ってやっています。唯一の違いはそこかなぁと思い、「Cloud9」で試してみることにしました。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784222/756c1320-9915-d268-10ae-df153f3a9771.png)

こんな感じです。これで再び実行です。
あらら・・また同じエラーが出てしまいました。

もう一度、pemファイルを「Cloud9」において、環境変数'SSL_CERT_FILE'にpemファイルを設定して実行しました。
やった！成功の証「Bolt app is running!」が表示されました。

```bash:
⚡️Bolt app is running!
```
これを待ってました。

# Pinecone地獄
　次に直面した地獄は「Pinecone」です。「Pinecone」は、ベクトルデータベースのSaaSであり、書籍の中でこれを利用します。
　ベクトルデータベースには、ローカルPCで構築できるものもあり、以前`Chroma` `Qdrant` `FAISS`を紹介させていただいたのですが、「Cloud9」の轍を踏むわけにはいかないので、今回はおとなしく書籍の手順に従うこととしました。

 https://qiita.com/ogi_kimura/items/d1d263ece0e23c7d7576

まず書籍に記載のある通りに実施してみたのですが、エラーが多発して全く動きませんでした。
いろいろサイトを調べてみると、`requirements.txt'に関する正誤表があり、バージョンを指定していることがわかりました。

https://github.com/yoshidashingo/langchain-book/blob/main/errata.md

これを踏まえて、改めて「Cloud9」で実行してみました。

```bash:
pip install -r requirements.txt
```

これで実行したのですが、ダメでした。ある程度覚悟はしていましたが・・・
ただ、エラーの数は減りました。

```bash:
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='controller.aaa-starter.pinecone.io', port=443): Max retries exceeded with url: /databases (Caused by NameResolutionError("<urllib3.connection.HTTPSConnection object at 0x7f05fb5b8bb0>: Failed to resolve 'controller.aaa-starter.pinecone.io' ([Errno -2] Name or service not known)"))
```

### 環境編須を疑う
環境変数を見ると`gcp`という文言があります。

```bash:.env
PINECONE_ENV=gcp-starter
```

一方、「Pinecone」ではフリーの場合だけかもしれませんが、「AWS」だけしか選べません。
設定後の「Pinecone」の画面はこんな感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784222/9dfdeaef-0a3b-1699-ec93-367d5681351c.png)

ここに問題があるのではないかと思いました。

じゃぁ`PINECONE_ENV`を`aws-starter`にすりゃいいんじゃない？と思い色々試しましたがダメでした。
ここで、書籍の212ページ目の「Pineconeへのテキストの重複登録」を改めてみてみました。

```python:recreate_index.py
import os

import pinecone
from dotenv import load_dotenv

load_dotenv()

pinecone.init(
    api_key=os.environ["PINECONE_API_KEY"],
    environment=os.environ["PINECONE_ENV"],
)

index_name = os.environ["PINECONE_INDEX"]

if index_name in pinecone.list_indexes():
    pinecone.delete_index(index_name)

pinecone.create_index(name=index_name, metric="cosine", dimension=1536)
```

LangChainのバージョンが上がりすぎてエラーになった時に検索したサイトのなかでも、このプログラムを実行すればよいということも書かれていたので、これを実行してリポジトリを作成することにしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784222/28088c2b-1fcc-7cd8-39cd-7ad64a50ad90.png)
おお、今度は`gcp`上にリポジトリができたようです。

では、改めて実行`app.py`を実行します。
今度はうまくいきました。地獄にはまってから解決まで半日かかりました・・・

# おわりに
　今回は特に苦労した２つの地獄について紹介しました。
　ただ、地獄はこれだけではなく、プチ地獄はたくさんありました。
　自分の技術力不足が起因するところも沢山ありましたので、そこは割愛します。
 
　この記事が、少しでも皆様のお役に立てればと思っております。