プロキシ環境下のローカルPCに "Dify" を導入して、Bedrockする

# はじめに
お疲れ様です。yuki_inkです。

今年のGWあたりからにわかに「Difyがすごいらしい」と話題になりましたが、今まで触れられていませんでした。

https://dify.ai/jp

それから約1か月が経ち、ネット上の情報がかなり厚くなってきた今日この頃（界隈の皆さん強すぎですね）
ちょっと調べてみると、どうやらDifyはローカル環境でも動くらしいとのこと。
え、自社端末で使いたい！！
というモチベーションで色々やってみたという記事です。


# やったこと
1. WSL 導入
1. Docker 導入
1. Git 導入
1. Dify 導入
1. Dify で「ワイのかわりに検索くん」を作る
1. 「ワイのかわりに検索くん」をBedrockする

## 前提条件
- Windows10のPCで作業しています。
- Docker Desktopは利用しません。
- この記事ではプロキシの IP アドレスを `192.168.11.9`、プロキシのポートを `3128` として説明します。
この記事を参考にされる際は、実際のプロキシの情報に置き換えて設定してください。

## (1) WSL 導入

以下の手順を参照して、PCにWSLを導入します。

https://learn.microsoft.com/ja-jp/windows/wsl/install-manual

- [手順 1 - Linux 用 Windows サブシステムを有効にする](https://learn.microsoft.com/ja-jp/windows/wsl/install-manual#step-1---enable-the-windows-subsystem-for-linux)
- [手順 2 - WSL 2 の実行に関する要件を確認する](https://learn.microsoft.com/ja-jp/windows/wsl/install-manual#step-2---check-requirements-for-running-wsl-2)
- [手順 3: 仮想マシンの機能を有効にする](https://learn.microsoft.com/ja-jp/windows/wsl/install-manual#step-3---enable-virtual-machine-feature)
- [手順 4 - Linux カーネル更新プログラム パッケージをダウンロードする](https://learn.microsoft.com/ja-jp/windows/wsl/install-manual#step-4---download-the-linux-kernel-update-package)
- [手順 5 - WSL 2 を既定のバージョンとして設定する](https://learn.microsoft.com/ja-jp/windows/wsl/install-manual#step-5---set-wsl-2-as-your-default-version)
- [手順 6 - 選択した Linux ディストリビューションをインストールする](https://learn.microsoft.com/ja-jp/windows/wsl/install-manual#step-6---install-your-linux-distribution-of-choice)

私は [Ubuntu 22.04.3 LTS](https://apps.microsoft.com/detail/9pn20msr04dw?rtc=1&hl=ja-jp&gl=JP) を入れました。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/c000996f-69a2-2bab-ffc6-582796a1948c.png)

取得したインストーラを実行するとこのような画面が開きます。
ここでユーザ名とパスワードを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/2d13ccb7-f3f9-e789-fac6-73116529dc89.png)


:::note info
私の環境では「**[Ubuntuインストール時に0.0%でスタック](https://qiita.com/Sintuba/items/efa0a0452367857a7de6)**」する事象が発生してしまったので、記事に記述されている通りの対応を行い、無事WSLを導入できました。

> 管理者権限でpowershellに
wsl --update --web-download
↓実行
wsl --install --web-download
↓実行
とインストールが完了しユーザー名とパスワード入力後Ubuntuが起動しました。
:::

PowerShellで `wsl --list --verbose` コマンドを実行し、導入したディストリビューションのステータスが `Running` となっていることを確認します。
```
> wsl --list --verbose
  NAME      STATE           VERSION
* Ubuntu    Running         2
```

【参考にした記事】

https://blog.ecbeing.tech/entry/2021/09/07/150000#Docker-Engine%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB:~:text=be%20working%20correctly.-,sudo%E3%81%AA%E3%81%97%E3%81%A7docker%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%99%E3%82%8B,-docker%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92

https://qiita.com/Sintuba/items/efa0a0452367857a7de6

## (2) Docker 導入
### Ubuntu（WSL）へのプロキシ設定
スタート画面から先ほど取得した `Ubuntu 22.04.3 LTS` をクリックし、起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/d4552241-9e4f-1b69-2490-5815e8e4e2be.png)


とりあえず、Linux環境でよくあるプロキシ設定を入れておきます。
`sudo -i` コマンドでrootになって、`/etc/profile` の末尾に以下の記述を追記。
```
# http://<id>:<password>@X.X.X.X:<port番号>
PROXY='http://192.168.11.9:3128'

# httpおよびhttpsを使う際に参照するプロキシのURLを指定する
export http_proxy=$PROXY
export HTTP_PROXY=$PROXY
export https_proxy=$PROXY
export HTTPS_PROXY=$PROXY

# localhostやプロキシ内(社内イントラなど)に存在し、プロキシを経由させるべきでないものを指定する
export no_proxy=localhost,127.0.0.1
export NO_PROXY=${no_proxy}
```
`source /etc/profile` コマンドで設定を反映し、`printenv | grep -i proxy` コマンドで確認します。
```
# source /etc/profile

# printenv | grep -i proxy
http_proxy=http://192.168.11.9:3128
HTTP_PROXY=http://192.168.11.9:3128
https_proxy=http://192.168.11.9:3128
HTTPS_PROXY=http://192.168.11.9:3128
no_proxy=localhost,127.0.0.1
NO_PROXY=localhost,127.0.0.1
```
各環境変数にプロキシの値が入っていたらOK！

あわせて、後続手順で利用する `apt` コマンドがプロキシを通るように設定していきます。
`/etc/apt/apt.conf` を作成し、以下の通り記述します。
```/etc/apt/apt.conf
Acquire::http::Proxy "http://192.168.11.9:3128";
Acquire::https::Proxy "http://192.168.11.9:3128";
```
ここで `exit` して、rootから抜けておきましょう。
一般ユーザに戻ったら、念のため、再度 `source /etc/profile` コマンドで設定を反映し、`printenv | grep -i proxy` コマンドで確認。

【参考にした記事】

https://zenn.dev/junkor/articles/ca961ca70f441a

https://qiita.com/m-tmatma/items/e3d9de76be50763ac01c


### Docker インストール
以下の手順を参照して、Dockerをインストールします。

https://weblabo.oscasierra.net/docker-ce-install-ubuntu1604/

- 事前準備
- Docker リポジトリの追加
- Docker CE のインストール

インストールが完了しました～（3分クッキング感）
```
$ docker -v
Docker version 26.1.4, build 5650f9b
```

### Docker 関連の設定
以下の手順を参考に、Dockerのプロキシの設定をします。

https://qiita.com/nounashi-pochigoro/items/16f0916c840afc5a99cc

まず、`mkdir` コマンドでディレクトリを作っておきます。
```
$ sudo mkdir /etc/systemd/system/docker.service.d/
$ mkdir ~/.docker
```

続いて以下2つのファイルを作成します。
```/etc/systemd/system/docker.service.d/override.conf
[Service]
Environment="HTTP_PROXY=http://192.168.11.9:3128"
Environment="HTTPS_PROXY=http://192.168.11.9:3128"
Environment="NO_PROXY=localhost,127.0.0.1"
```

```~/.docker/config.json
{
  "proxies": {
    "default": {
      "httpProxy": "http://192.168.11.9:3128",
      "httpsProxy": "http://192.168.11.9:3128",
      "noProxy": "localhost,127.0.0.1"
    }
  }
}
```

以下のコマンドで設定反映 & Docker を再起動し、設定が適切に反映されていることを確認します。
ついでに、「[sudoなしでdockerコマンドを実行できるようにする](https://blog.ecbeing.tech/entry/2021/09/07/150000#Docker-Engine%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB:~:text=be%20working%20correctly.-,sudo%E3%81%AA%E3%81%97%E3%81%A7docker%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%99%E3%82%8B,-docker%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92)」ために `sudo usermod -a -G docker (ユーザ名)` コマンドを実行しておきます。
```
$ sudo systemctl daemon-reload

$ sudo systemctl restart docker

$ sudo systemctl show --property=Environment docker
Environment=HTTP_PROXY=http://192.168.11.9:3128 HTTPS_PROXY=http://192.168.11.9:3128 NO_PROXY=localhost,127.0.0.1

$ sudo usermod -a -G docker `whoami`

$ exit
```
最後に `exit` して、プロンプトを閉じたので、再度プロンプトを立ち上げます。

【参考にした記事】

https://matsuand.github.io/docs.docker.jp.onthefly/config/daemon/systemd/#httphttps-proxy


### Dockerの動作確認
以前やった手順をそのまま実施し、Nginxを動かしてみました。

https://qiita.com/yuki_ink/items/1fc12d019cd33929d46b#4-web%E3%82%B5%E3%83%BC%E3%83%90%E3%82%92%E5%8B%95%E3%81%8B%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B

```
$ docker image pull nginx

$ docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
nginx        latest    4f67c83422ec   8 days ago   188MB

$ docker container run -d -p 8080:80 --name webserver nginx
285f67e5b734fe0fb6b985193257e3d7d6fd005471f4cb450e3f957251d5afe7
```
ブラウザを立ち上げ、`http://localhost:8080/` にアクセス。
動いた！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/a0a2b706-430f-94b0-8305-bbd7cd3aadc6.png)

問題なく動作していることが確認できたので、コンテナを止めておきます。
`docker container ps` コマンドでプロセスが何も表示されなければOK。
```
$ docker container stop webserver
webserver

$ docker container ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
```

## (3) Git 導入
`sudo apt-get install git` コマンドでGitをインストール。
`dpkg -l git` コマンドでGitがインストールされたか確認します。
```
$ sudo apt-get install git

$ dpkg -l git
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name           Version              Architecture Description
+++-==============-====================-============-===================================================
ii  git            1:2.34.1-1ubuntu1.11 amd64        fast, scalable, distributed revision control system
```

以下のコマンドを実行して、Gitのプロキシを設定し、設定が反映されているか確認します。
```
$ git config --global http.proxy http://192.168.11.9:3128

$ git config --global -l
http.proxy=http://192.168.11.9:3128
```

:::note warn
Gitのプロキシ設定はOSユーザごとに必要になります。
※設定は `~/.gitconfig` ファイルに記述されます。
:::

【参考にした記事】

https://qiita.com/tommy_g/items/771ac45b89b02e8a5d64

https://qiita.com/ryotaro76/items/0e40ffb6173b1580e671


## (4) Dify 導入
まずは `git clone` コマンドで資材をダウンロードします。
```
$ cd (資材を置きたいディレクトリ)
$ git clone https://github.com/langgenius/dify.git
```
次に、コンテナからプロキシ経由でインターネットに出ていけるように、`./dify/docker/docker-compose.yaml` を修正します。
具体的には、`environment` キーのところに `HTTP_PROXY` と `HTTPS_PROXY` の設定を書いていきます。

:::note info
`docker-compose.yaml` の修正を行わないと、Dify上でLLMのAPIキーの検証などができません。
※ローカルLLMの利用に限定するなど、あえてインターネットとの通信を行いたくない場合には、この修正いらないかも。。
:::

以下、修正の差分のところに色を付けておきます。
<details><summary>修正後の docker-compose.yaml</summary>

:::note warn
とりあえず各サービスの`environment` キーのところに `HTTP_PROXY` と `HTTPS_PROXY` の設定を追記しましたが、全部やる必要あったかの確認（取捨選択の検証）は行っていません。
本来プロキシ設定がいらないところにも書いてしまっている気がします。。
そのような箇所がありましたら、ご指摘いただけますと幸いです。
:::



```diff:docker-compose.yaml
version: '3'
services:
  # API service
  api:
    image: langgenius/dify-api:0.6.10
    restart: always
    environment:
      # Startup mode, 'api' starts the API server.
      MODE: api
      # The log level for the application. Supported values are `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`
      LOG_LEVEL: INFO
      # enable DEBUG mode to output more logs
      # DEBUG : true
      # A secret key that is used for securely signing the session cookie and encrypting sensitive information on the database. You can generate a strong key using `openssl rand -base64 42`.
      SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
      # The base URL of console application web frontend, refers to the Console base URL of WEB service if console domain is
      # different from api or web app domain.
      # example: http://cloud.dify.ai
      CONSOLE_WEB_URL: ''
      # Password for admin user initialization.
      # If left unset, admin user will not be prompted for a password when creating the initial admin account.
      INIT_PASSWORD: ''
      # The base URL of console application api server, refers to the Console base URL of WEB service if console domain is
      # different from api or web app domain.
      # example: http://cloud.dify.ai
      CONSOLE_API_URL: ''
      # The URL prefix for Service API endpoints, refers to the base URL of the current API service if api domain is
      # different from console domain.
      # example: http://api.dify.ai
      SERVICE_API_URL: ''
      # The URL prefix for Web APP frontend, refers to the Web App base URL of WEB service if web app domain is different from
      # console or api domain.
      # example: http://udify.app
      APP_WEB_URL: ''
      # File preview or download Url prefix.
      # used to display File preview or download Url to the front-end or as Multi-model inputs;
      # Url is signed and has expiration time.
      FILES_URL: ''
      # File Access Time specifies a time interval in seconds for the file to be accessed.
      # The default value is 300 seconds.
      FILES_ACCESS_TIMEOUT: 300
      # When enabled, migrations will be executed prior to application startup and the application will start after the migrations have completed.
      MIGRATION_ENABLED: 'true'
      # The configurations of postgres database connection.
      # It is consistent with the configuration in the 'db' service below.
      DB_USERNAME: postgres
      DB_PASSWORD: difyai123456
      DB_HOST: db
      DB_PORT: 5432
      DB_DATABASE: dify
      # The configurations of redis connection.
      # It is consistent with the configuration in the 'redis' service below.
      REDIS_HOST: redis
      REDIS_PORT: 6379
      REDIS_USERNAME: ''
      REDIS_PASSWORD: difyai123456
      REDIS_USE_SSL: 'false'
      # use redis db 0 for redis cache
      REDIS_DB: 0
      # The configurations of celery broker.
      # Use redis as the broker, and redis db 1 for celery broker.
      CELERY_BROKER_URL: redis://:difyai123456@redis:6379/1
      # Specifies the allowed origins for cross-origin requests to the Web API, e.g. https://dify.app or * for all origins.
      WEB_API_CORS_ALLOW_ORIGINS: '*'
      # Specifies the allowed origins for cross-origin requests to the console API, e.g. https://cloud.dify.ai or * for all origins.
      CONSOLE_CORS_ALLOW_ORIGINS: '*'
      # CSRF Cookie settings
      # Controls whether a cookie is sent with cross-site requests,
      # providing some protection against cross-site request forgery attacks
      #
      # Default: `SameSite=Lax, Secure=false, HttpOnly=true`
      # This default configuration supports same-origin requests using either HTTP or HTTPS,
      # but does not support cross-origin requests. It is suitable for local debugging purposes.
      #
      # If you want to enable cross-origin support,
      # you must use the HTTPS protocol and set the configuration to `SameSite=None, Secure=true, HttpOnly=true`.
      #
      # The type of storage to use for storing user files. Supported values are `local` and `s3` and `azure-blob` and `google-storage`, Default: `local`
      STORAGE_TYPE: local
      # The path to the local storage directory, the directory relative the root path of API service codes or absolute path. Default: `storage` or `/home/john/storage`.
      # only available when STORAGE_TYPE is `local`.
      STORAGE_LOCAL_PATH: storage
      # The S3 storage configurations, only available when STORAGE_TYPE is `s3`.
      S3_ENDPOINT: 'https://xxx.r2.cloudflarestorage.com'
      S3_BUCKET_NAME: 'difyai'
      S3_ACCESS_KEY: 'ak-difyai'
      S3_SECRET_KEY: 'sk-difyai'
      S3_REGION: 'us-east-1'
      # The Azure Blob storage configurations, only available when STORAGE_TYPE is `azure-blob`.
      AZURE_BLOB_ACCOUNT_NAME: 'difyai'
      AZURE_BLOB_ACCOUNT_KEY: 'difyai'
      AZURE_BLOB_CONTAINER_NAME: 'difyai-container'
      AZURE_BLOB_ACCOUNT_URL: 'https://<your_account_name>.blob.core.windows.net'
      # The Google storage configurations, only available when STORAGE_TYPE is `google-storage`.
      GOOGLE_STORAGE_BUCKET_NAME: 'yout-bucket-name'
      # if you want to use Application Default Credentials, you can leave GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64 empty.
      GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64: 'your-google-service-account-json-base64-string'
      # The type of vector store to use. Supported values are `weaviate`, `qdrant`, `milvus`, `relyt`.
      VECTOR_STORE: weaviate
      # The Weaviate endpoint URL. Only available when VECTOR_STORE is `weaviate`.
      WEAVIATE_ENDPOINT: http://weaviate:8080
      # The Weaviate API key.
      WEAVIATE_API_KEY: WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
      # The Qdrant endpoint URL. Only available when VECTOR_STORE is `qdrant`.
      QDRANT_URL: http://qdrant:6333
      # The Qdrant API key.
      QDRANT_API_KEY: difyai123456
      # The Qdrant client timeout setting.
      QDRANT_CLIENT_TIMEOUT: 20
      # The Qdrant client enable gRPC mode.
      QDRANT_GRPC_ENABLED: 'false'
      # The Qdrant server gRPC mode PORT.
      QDRANT_GRPC_PORT: 6334
      # Milvus configuration Only available when VECTOR_STORE is `milvus`.
      # The milvus host.
      MILVUS_HOST: 127.0.0.1
      # The milvus host.
      MILVUS_PORT: 19530
      # The milvus username.
      MILVUS_USER: root
      # The milvus password.
      MILVUS_PASSWORD: Milvus
      # The milvus tls switch.
      MILVUS_SECURE: 'false'
      # relyt configurations
      RELYT_HOST: db
      RELYT_PORT: 5432
      RELYT_USER: postgres
      RELYT_PASSWORD: difyai123456
      RELYT_DATABASE: postgres
      # pgvector configurations
      PGVECTOR_HOST: pgvector
      PGVECTOR_PORT: 5432
      PGVECTOR_USER: postgres
      PGVECTOR_PASSWORD: difyai123456
      PGVECTOR_DATABASE: dify
      # tidb vector configurations
      TIDB_VECTOR_HOST: tidb
      TIDB_VECTOR_PORT: 4000
      TIDB_VECTOR_USER: xxx.root
      TIDB_VECTOR_PASSWORD: xxxxxx
      TIDB_VECTOR_DATABASE: dify
      # Mail configuration, support: resend, smtp
      MAIL_TYPE: ''
      # default send from email address, if not specified
      MAIL_DEFAULT_SEND_FROM: 'YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)'
      SMTP_SERVER: ''
      SMTP_PORT: 465
      SMTP_USERNAME: ''
      SMTP_PASSWORD: ''
      SMTP_USE_TLS: 'true'
      SMTP_OPPORTUNISTIC_TLS: 'false'
      # the api-key for resend (https://resend.com)
      RESEND_API_KEY: ''
      RESEND_API_URL: https://api.resend.com
      # The DSN for Sentry error reporting. If not set, Sentry error reporting will be disabled.
      SENTRY_DSN: ''
      # The sample rate for Sentry events. Default: `1.0`
      SENTRY_TRACES_SAMPLE_RATE: 1.0
      # The sample rate for Sentry profiles. Default: `1.0`
      SENTRY_PROFILES_SAMPLE_RATE: 1.0
      # Notion import configuration, support public and internal
      NOTION_INTEGRATION_TYPE: public
      NOTION_CLIENT_SECRET: you-client-secret
      NOTION_CLIENT_ID: you-client-id
      NOTION_INTERNAL_SECRET: you-internal-secret
      # The sandbox service endpoint.
      CODE_EXECUTION_ENDPOINT: "http://sandbox:8194"
      CODE_EXECUTION_API_KEY: dify-sandbox
      CODE_MAX_NUMBER: 9223372036854775807
      CODE_MIN_NUMBER: -9223372036854775808
      CODE_MAX_STRING_LENGTH: 80000
      TEMPLATE_TRANSFORM_MAX_LENGTH: 80000
      CODE_MAX_STRING_ARRAY_LENGTH: 30
      CODE_MAX_OBJECT_ARRAY_LENGTH: 30
      CODE_MAX_NUMBER_ARRAY_LENGTH: 1000
      # SSRF Proxy server
      SSRF_PROXY_HTTP_URL: 'http://ssrf_proxy:3128'
      SSRF_PROXY_HTTPS_URL: 'http://ssrf_proxy:3128'
      # Indexing configuration
      INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: 1000
+     # Add proxy settings
+     HTTP_PROXY: 'http://192.168.11.9:3128'
+     HTTPS_PROXY: 'http://192.168.11.9:3128'
    depends_on:
      - db
      - redis
    volumes:
      # Mount the storage directory to the container, for storing user files.
      - ./volumes/app/storage:/app/api/storage
    # uncomment to expose dify-api port to host
    # ports:
    #   - "5001:5001"
    networks:
      - ssrf_proxy_network
      - default

  # worker service
  # The Celery worker for processing the queue.
  worker:
    image: langgenius/dify-api:0.6.10
    restart: always
    environment:
      CONSOLE_WEB_URL: ''
      # Startup mode, 'worker' starts the Celery worker for processing the queue.
      MODE: worker

      # --- All the configurations below are the same as those in the 'api' service. ---

      # The log level for the application. Supported values are `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`
      LOG_LEVEL: INFO
      # A secret key that is used for securely signing the session cookie and encrypting sensitive information on the database. You can generate a strong key using `openssl rand -base64 42`.
      # same as the API service
      SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
      # The configurations of postgres database connection.
      # It is consistent with the configuration in the 'db' service below.
      DB_USERNAME: postgres
      DB_PASSWORD: difyai123456
      DB_HOST: db
      DB_PORT: 5432
      DB_DATABASE: dify
      # The configurations of redis cache connection.
      REDIS_HOST: redis
      REDIS_PORT: 6379
      REDIS_USERNAME: ''
      REDIS_PASSWORD: difyai123456
      REDIS_DB: 0
      REDIS_USE_SSL: 'false'
      # The configurations of celery broker.
      CELERY_BROKER_URL: redis://:difyai123456@redis:6379/1
      # The type of storage to use for storing user files. Supported values are `local` and `s3` and `azure-blob` and `google-storage`, Default: `local`
      STORAGE_TYPE: local
      STORAGE_LOCAL_PATH: storage
      # The S3 storage configurations, only available when STORAGE_TYPE is `s3`.
      S3_ENDPOINT: 'https://xxx.r2.cloudflarestorage.com'
      S3_BUCKET_NAME: 'difyai'
      S3_ACCESS_KEY: 'ak-difyai'
      S3_SECRET_KEY: 'sk-difyai'
      S3_REGION: 'us-east-1'
      # The Azure Blob storage configurations, only available when STORAGE_TYPE is `azure-blob`.
      AZURE_BLOB_ACCOUNT_NAME: 'difyai'
      AZURE_BLOB_ACCOUNT_KEY: 'difyai'
      AZURE_BLOB_CONTAINER_NAME: 'difyai-container'
      AZURE_BLOB_ACCOUNT_URL: 'https://<your_account_name>.blob.core.windows.net'
      # The Google storage configurations, only available when STORAGE_TYPE is `google-storage`.
      GOOGLE_STORAGE_BUCKET_NAME: 'yout-bucket-name'
      # if you want to use Application Default Credentials, you can leave GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64 empty.
      GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64: 'your-google-service-account-json-base64-string'
      # The type of vector store to use. Supported values are `weaviate`, `qdrant`, `milvus`, `relyt`, `pgvector`.
      VECTOR_STORE: weaviate
      # The Weaviate endpoint URL. Only available when VECTOR_STORE is `weaviate`.
      WEAVIATE_ENDPOINT: http://weaviate:8080
      # The Weaviate API key.
      WEAVIATE_API_KEY: WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
      # The Qdrant endpoint URL. Only available when VECTOR_STORE is `qdrant`.
      QDRANT_URL: http://qdrant:6333
      # The Qdrant API key.
      QDRANT_API_KEY: difyai123456
      # The Qdrant client timeout setting.
      QDRANT_CLIENT_TIMEOUT: 20
      # The Qdrant client enable gRPC mode.
      QDRANT_GRPC_ENABLED: 'false'
      # The Qdrant server gRPC mode PORT.
      QDRANT_GRPC_PORT: 6334
      # Milvus configuration Only available when VECTOR_STORE is `milvus`.
      # The milvus host.
      MILVUS_HOST: 127.0.0.1
      # The milvus host.
      MILVUS_PORT: 19530
      # The milvus username.
      MILVUS_USER: root
      # The milvus password.
      MILVUS_PASSWORD: Milvus
      # The milvus tls switch.
      MILVUS_SECURE: 'false'
      # Mail configuration, support: resend
      MAIL_TYPE: ''
      # default send from email address, if not specified
      MAIL_DEFAULT_SEND_FROM: 'YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)'
      SMTP_SERVER: ''
      SMTP_PORT: 465
      SMTP_USERNAME: ''
      SMTP_PASSWORD: ''
      SMTP_USE_TLS: 'true'
      SMTP_OPPORTUNISTIC_TLS: 'false'
      # the api-key for resend (https://resend.com)
      RESEND_API_KEY: ''
      RESEND_API_URL: https://api.resend.com
      # relyt configurations
      RELYT_HOST: db
      RELYT_PORT: 5432
      RELYT_USER: postgres
      RELYT_PASSWORD: difyai123456
      RELYT_DATABASE: postgres
      # pgvector configurations
      PGVECTOR_HOST: pgvector
      PGVECTOR_PORT: 5432
      PGVECTOR_USER: postgres
      PGVECTOR_PASSWORD: difyai123456
      PGVECTOR_DATABASE: dify
      # tidb vector configurations
      TIDB_VECTOR_HOST: tidb
      TIDB_VECTOR_PORT: 4000
      TIDB_VECTOR_USER: xxx.root
      TIDB_VECTOR_PASSWORD: xxxxxx
      TIDB_VECTOR_DATABASE: dify
      # Notion import configuration, support public and internal
      NOTION_INTEGRATION_TYPE: public
      NOTION_CLIENT_SECRET: you-client-secret
      NOTION_CLIENT_ID: you-client-id
      NOTION_INTERNAL_SECRET: you-internal-secret
      # Indexing configuration
      INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: 1000
+     # Add proxy settings
+     HTTP_PROXY: 'http://192.168.11.9:3128'
+     HTTPS_PROXY: 'http://192.168.11.9:3128'
    depends_on:
      - db
      - redis
    volumes:
      # Mount the storage directory to the container, for storing user files.
      - ./volumes/app/storage:/app/api/storage
    networks:
      - ssrf_proxy_network
      - default

  # Frontend web application.
  web:
    image: langgenius/dify-web:0.6.10
    restart: always
    environment:
      # The base URL of console application api server, refers to the Console base URL of WEB service if console domain is
      # different from api or web app domain.
      # example: http://cloud.dify.ai
      CONSOLE_API_URL: ''
      # The URL for Web APP api server, refers to the Web App base URL of WEB service if web app domain is different from
      # console or api domain.
      # example: http://udify.app
      APP_API_URL: ''
      # The DSN for Sentry error reporting. If not set, Sentry error reporting will be disabled.
      SENTRY_DSN: ''
    # uncomment to expose dify-web port to host
    # ports:
    #   - "3000:3000"
+     # Add proxy settings
+     HTTP_PROXY: 'http://192.168.11.9:3128'
+     HTTPS_PROXY: 'http://192.168.11.9:3128'
  # The postgres database.
  db:
    image: postgres:15-alpine
    restart: always
    environment:
      PGUSER: postgres
      # The password for the default postgres user.
      POSTGRES_PASSWORD: difyai123456
      # The name of the default postgres database.
      POSTGRES_DB: dify
      # postgres data directory
      PGDATA: /var/lib/postgresql/data/pgdata
+     # Add proxy settings
+     HTTP_PROXY: 'http://192.168.11.9:3128'
+     HTTPS_PROXY: 'http://192.168.11.9:3128'
    volumes:
      - ./volumes/db/data:/var/lib/postgresql/data
    # uncomment to expose db(postgresql) port to host
    # ports:
    #   - "5432:5432"
    healthcheck:
      test: [ "CMD", "pg_isready" ]
      interval: 1s
      timeout: 3s
      retries: 30

  # The redis cache.
  redis:
    image: redis:6-alpine
    restart: always
    volumes:
      # Mount the redis data directory to the container.
      - ./volumes/redis/data:/data
    # Set the redis password when startup redis server.
    command: redis-server --requirepass difyai123456
    healthcheck:
      test: [ "CMD", "redis-cli", "ping" ]
    # uncomment to expose redis port to host
    # ports:
    #   - "6379:6379"

  # The Weaviate vector store.
  weaviate:
    image: semitechnologies/weaviate:1.19.0
    restart: always
    volumes:
      # Mount the Weaviate data directory to the container.
      - ./volumes/weaviate:/var/lib/weaviate
    environment:
      # The Weaviate configurations
      # You can refer to the [Weaviate](https://weaviate.io/developers/weaviate/config-refs/env-vars) documentation for more information.
      QUERY_DEFAULTS_LIMIT: 25
      AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'false'
      PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
      DEFAULT_VECTORIZER_MODULE: 'none'
      CLUSTER_HOSTNAME: 'node1'
      AUTHENTICATION_APIKEY_ENABLED: 'true'
      AUTHENTICATION_APIKEY_ALLOWED_KEYS: 'WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih'
      AUTHENTICATION_APIKEY_USERS: 'hello@dify.ai'
      AUTHORIZATION_ADMINLIST_ENABLED: 'true'
      AUTHORIZATION_ADMINLIST_USERS: 'hello@dify.ai'
    # uncomment to expose weaviate port to host
    # ports:
    #  - "8080:8080"
+     # Add proxy settings
+     HTTP_PROXY: 'http://192.168.11.9:3128'
+     HTTPS_PROXY: 'http://192.168.11.9:3128'
  # The DifySandbox
  sandbox:
    image: langgenius/dify-sandbox:0.2.1
    restart: always
    environment:
      # The DifySandbox configurations
      # Make sure you are changing this key for your deployment with a strong key.
      # You can generate a strong key using `openssl rand -base64 42`.
      API_KEY: dify-sandbox
      GIN_MODE: 'release'
      WORKER_TIMEOUT: 15
      ENABLE_NETWORK: 'true'
-     # HTTP_PROXY: 'http://ssrf_proxy:3128'        #コメントアウト
-     # HTTPS_PROXY: 'http://ssrf_proxy:3128'       #コメントアウト
      SANDBOX_PORT: 8194
+     # Add proxy settings
+     HTTP_PROXY: 'http://192.168.11.9:3128'
+     HTTPS_PROXY: 'http://192.168.11.9:3128'
    volumes:
      - ./volumes/sandbox/dependencies:/dependencies
    networks:
      - ssrf_proxy_network

  # ssrf_proxy server
  # for more information, please refer to
  # https://docs.dify.ai/getting-started/install-self-hosted/install-faq#id-16.-why-is-ssrf_proxy-needed
  ssrf_proxy:
    image: ubuntu/squid:latest
    restart: always
    volumes:
      # pls clearly modify the squid.conf file to fit your network environment.
      - ./volumes/ssrf_proxy/squid.conf:/etc/squid/squid.conf
    networks:
      - ssrf_proxy_network
      - default
  # Qdrant vector store.
  # uncomment to use qdrant as vector store.
  # (if uncommented, you need to comment out the weaviate service above,
  # and set VECTOR_STORE to qdrant in the api & worker service.)
  # qdrant:
  #   image: langgenius/qdrant:v1.7.3
  #   restart: always
  #   volumes:
  #     - ./volumes/qdrant:/qdrant/storage
  #   environment:
  #     QDRANT_API_KEY: 'difyai123456'
  #   # uncomment to expose qdrant port to host
  #   # ports:
  #   #  - "6333:6333"
  #   #  - "6334:6334"

  # The pgvector vector database.
  # Uncomment to use qdrant as vector store.
  # pgvector:
  #   image: pgvector/pgvector:pg16
  #   restart: always
  #   environment:
  #     PGUSER: postgres
  #     # The password for the default postgres user.
  #     POSTGRES_PASSWORD: difyai123456
  #     # The name of the default postgres database.
  #     POSTGRES_DB: dify
  #     # postgres data directory
  #     PGDATA: /var/lib/postgresql/data/pgdata
  #   volumes:
  #     - ./volumes/pgvector/data:/var/lib/postgresql/data
  #   # uncomment to expose db(postgresql) port to host
  #   # ports:
  #   #   - "5433:5432"
  #   healthcheck:
  #     test: [ "CMD", "pg_isready" ]
  #     interval: 1s
  #     timeout: 3s
  #     retries: 30


  # The nginx reverse proxy.
  # used for reverse proxying the API service and Web service.
  nginx:
    image: nginx:latest
    restart: always
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/proxy.conf:/etc/nginx/proxy.conf
      - ./nginx/conf.d:/etc/nginx/conf.d
      #- ./nginx/ssl:/etc/ssl
    depends_on:
      - api
      - web
    ports:
      - "80:80"
      #- "443:443"
networks:
  # create a network between sandbox, api and ssrf_proxy, and can not access outside.
  ssrf_proxy_network:
    driver: bridge
    internal: true
```
</details>

修正がおわったら `docker compose up` コマンドでコンテナを起動します。
```
$ cd dify/docker

$ docker compose up -d

$ docker ps
CONTAINER ID   IMAGE                              COMMAND                  CREATED       STATUS                 PORTS                               NAMES
4bed53ca7cce   nginx:latest                       "/docker-entrypoint.…"   2 hours ago   Up 2 hours             0.0.0.0:80->80/tcp, :::80->80/tcp   docker-nginx-1
bf3129805a71   langgenius/dify-api:0.6.10         "/bin/bash /entrypoi…"   2 hours ago   Up 2 hours             5001/tcp                            docker-worker-1
ec2bc6bf860d   langgenius/dify-api:0.6.10         "/bin/bash /entrypoi…"   2 hours ago   Up 2 hours             5001/tcp                            docker-api-1
d6f546a6ebd4   langgenius/dify-web:0.6.10         "/bin/sh ./entrypoin…"   2 hours ago   Up 2 hours             3000/tcp                            docker-web-1
fca4ae5c2ab4   langgenius/dify-sandbox:0.2.1      "/main"                  2 hours ago   Up 2 hours                                                 docker-sandbox-1
361d126ef3ba   ubuntu/squid:latest                "entrypoint.sh -f /e…"   2 hours ago   Up 2 hours             3128/tcp                            docker-ssrf_proxy-1
6034908d1378   semitechnologies/weaviate:1.19.0   "/bin/weaviate --hos…"   2 hours ago   Up 2 hours                                                 docker-weaviate-1
849c68f67fd1   redis:6-alpine                     "docker-entrypoint.s…"   2 hours ago   Up 2 hours (healthy)   6379/tcp                            docker-redis-1
0152977f8d27   postgres:15-alpine                 "docker-entrypoint.s…"   2 hours ago   Up 2 hours (healthy)   5432/tcp                            docker-db-1
```

コンテナが起動したら、ブラウザを立ち上げ `http://localhost/install` にアクセス。
こんな画面が開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/877ba223-f229-a592-adbe-9d4793475271.png)


画面の案内通りにメアドとユーザ名とパスワードを入れて、管理者アカウントをセットアップ。
セットアップが完了するとログイン画面が開くので、先ほど入力したメアドとパスワードでログインします。
スタジオの画面に遷移したらOK！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/0d2b908f-4542-e118-77b5-a532be4ef616.png)

【参考にした記事】

https://qiita.com/araryo/items/89dcee526210c56dcc45

https://qiita.com/nounashi-pochigoro/items/16f0916c840afc5a99cc

## (5) Dify で「ワイのかわりに検索くん」を作る
みのるんさん @minorun365 の記事に沿って手を動かしてみました。

https://qiita.com/minorun365/items/4c5dba1de7977c386249

`最初から作成` ボタンを押すとポップアップが開きます。
「チャットボット」、「テキスト ジェネレーター」、「エージェント」、「ワークフロー」から選べるようです。
> **チャットボット**
チャット形式のアプリケーションを構築します。このアプリは質問と回答の形式を使用し、複数のラウンドの継続的な会話を可能にします
>
>**テキスト ジェネレーター**
プロンプトに基づいて高品質のテキストを生成するアプリケーションを構築します。記事、要約、翻訳などを生成します
>
>**エージェント**
タスクを自動的に完了するためのツールを選択できるインテリジェント エージェントを構築します
>
>**ワークフロー**
高度なカスタマイズが可能なワークフローに基づいて高品質のテキストを生成するアプリケーションを構築します。経験豊富なユーザー向けです

いろんなことがやれそうで既にワクワクが止まりません！
今回は「ワークフロー」を選択。
アプリ名に「ワイのかわりに検索くん」と入力し、`作成する` ボタンを押します。
アイコンカスタマイズできるのちょっと嬉しいw
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/e90c4a77-9ea6-8268-48d1-70a736e17717.png)

> 最初に配置されている「開始」というモジュールをクリックして、「入力フィールド」に `Input` という名前の変数を定義しておきます。
これによって、まずアプリの開始時にユーザーから質問を受け取れるようにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/fa9c2dc6-6e36-e1f0-9774-9f24efa36c33.png)

> 次に、開始モジュール右側の「＋」ボタンから新しいコンポーネントを追加します。
ユーザーの質問をもとに、まずGoogle検索をさせたいので「GoogleSearch」を追加しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/f95aba7f-3f73-4ae6-dfd3-71a9b1976b88.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/0679c548-54f1-a5c6-97c4-3c1258f7440e.png)

`承認するには` ボタンをクリックし、画面上でSerpApiのAPIキーを入れると、入力変数が定義できるようになります。
> 入力変数に、先ほど「開始」モジュールで設定した Input を指定し、Result typeをURLではなく text に設定しておきましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/7b32fe29-3dee-857e-6ba1-ae2053f0f147.png)

> その後、検索結果を受け取って推論する「LLM」モジュールを追加します。
モデルは、無料で選べる中で高性能な gpt-3.5-turbo-16k-0613 を選択し、Systemプロンプトに以下を入力します。

モジュール追加してモデルを、、　**おや、、？ 何も表示されない？**
ローカル環境のDifyだとモデルは自分で登録しないとダメみたいですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/c9dbfed2-857a-842c-91b5-8908e518b437.png)

というわけでモデルを登録します。
画面右上のユーザー名をクリックし、表示されるメニューから`設定` を選択。
左のメニューから `モデルプロバイダー` を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/2b2506fd-96a4-76ae-9d32-45c0ac1fdd27.png)

今回はAnthropicを選択。
`API Key` にAPIキーを入れて `保存` ボタンをクリックします。
※APIキーはダイアログ左下の `Get your API Key from Anthropic` をクリックして、遷移先のページで取得すると楽です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/c510cf84-6d8a-fcad-5a6f-97435ce87abd.png)

登録されたっぽい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/a3494ef9-00d2-686a-2067-6dc29296bcd2.png)

「LLM」モジュールからClaudeが選べるようになりました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/1a40d1f5-b74b-fccd-82ab-e90d170617e3.png)

今回は `claude-3-sonnet` を選び、`SYSTEM` 欄にプロンプトを書きます。
半角スラッシュ `/` 打ったら変数のサジェスト出てくるの便利～～！ ※Qiita感覚で使えるw
```
> SYSTEM
以下の「ユーザーの質問」に対して、「Google検索結果」を用いて回答してください。
「ユーザーの質問」：※変数
「Google検索結果」：※変数
```

:::note warn
後述しますが、Claudeの場合、`SYSTEM` 欄だけでなく `USER` 欄にもプロンプトを書く必要がありました。
:::


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/5436d38c-60da-7c36-4631-c534c93a776e.png)

> 最後に「終了」モジュールを追加すれば完成です。
LLMの回答が出力されるように、出力変数に LLM / text を設定しておきましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/01287e40-5dc5-4cb5-5578-70dc54f9963f.png)

コンポーネント横一列に並べるのきつくなってきたので、ドラッグアンドドロップで位置を変えてみました。
便利～～！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/2332cb0b-b2a0-32c7-c9da-120ca0c5c6c9.png)

> いざ、テスト！
それでは実際に使ってみます。
画面右上の「実行」を押して、テストウィンドウの入力に「Difyって何？」と入力してみます。素のGPTはまだ知らない知識なので、Google検索しないと正しく回答できない質問です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/832e580f-6943-cc6c-1dca-eafa138dd331.png)

**おや、、？？**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/4dba3288-4e44-fceb-0cd4-c5cf355807b9.png)
LLMからエラーが返ってきました。
> Node LLM run failed: [anthropic] Bad Request Error, Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error', 'message': 'messages: at least one message is required'}}

ふむ、、パラメータがイケてないっぽい。
「LLM」モジュールの設定画面から `＋メッセージを追加` ボタンをクリックし、`USER` の入力フォームを表示します。
`SYSTEM` と `USER` について、以下のようにプロンプトを入力し直しました。
```
> SYSTEM
あなたはIT知識に乏しい日本人向けのアドバイザーです。
質問に対する回答は必ず日本語で記述してください。

> USER
以下の「ユーザーの質問」に対して、「Google検索結果」を用いて回答してください。
「ユーザーの質問」：※変数
「Google検索結果」：※変数
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/c2b4d593-dba5-1734-7c82-36f4aee4f563.png)


いざ再テスト！うまくいった！
> Difyとは、プログラミングの知識がなくてもAIアプリケーションを簡単に作成できるオープンソースのプラットフォームです。
主な特徴は以下の通りです。
>- 直感的なインターフェースでドラッグ&ドロップによる操作が可能
>- 大規模言語モデル(LLM)を活用して、チャットボットからAIワークフローまで幅広いアプリを作成可能
>- RAG(Retrieval-Augmented Generation)エンジンを使い、大量のデータを参照しながらアプリを生成
>- LangChainよりも本番環境に適した設計
>- オープンソースなので無料で利用可能
>
>プログラミング知識がなくても、Difyの直感的なインターフェースを使えば、AIチャットボットやデータ分析ツール、業務自動化アプリなど、様々なAIアプリケーションを手軽に作ることができます。AIの発展に伴い、こうしたノーコードAIツールの需要が高まっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/7b237075-357d-5354-0b38-a40f7d0cc744.png)

:::note
先ほども触れた「LLM」モジュールの `SYSTEM` と `USER` の役割の使い分けについて、「ワイのかわりに検索くん」に聞いてみると、以下のように答えてくれました。
有能！！
> DifyのLLMには、SYSTEMとUSERという2つの役割があります。
>
>SYSTEMは、LLMに与える指示や設定を記述する部分です。例えば、LLMに与えるタスクの内容、制約条件、出力形式などを指定します。SYSTEMはLLMの振る舞いを制御する役割を担います。
>
>一方、USERは、LLMに入力する実際のデータや質問を記述する部分です。USERからの入力に対してLLMが応答を生成します。
>
>つまり、SYSTEMではLLMの動作設定を記述し、USERではLLMに与える具体的な入力データを記述するという使い分けになります。この2つを適切に使い分けることで、目的に応じたLLMの動作を実現できます。SYSTEMを適切に設定し、USERに適切な入力を与えることが、DifyでLLMを効果的に活用するためのポイントになります。
:::


## (6) 「ワイのかわりに検索くん」をBedrockする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/8e32dfd6-38de-e41d-7b11-f8a7441009ab.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/6333b4cd-21fa-773c-890d-ffd8e412560b.png)
（出典） [宇宙最速!? でAmazon Bedrockを本格導入したプロダクト「2つ」開発してみた件](https://speakerdeck.com/minorun365/yu-zhou-zui-su-deamazon-bedrockwoben-ge-dao-ru-sitapurodakuto-2tu-kai-fa-sitemitajian?slide=38)

ということで張り切っていきましょう。
まずは、先ほどと同様の手順で、モデルとしてBedrockを登録します。

> 画面右上のユーザー名をクリックし、表示されるメニューから`設定` を選択。
左のメニューから `モデルプロバイダー` を選択します。

Bedrockがいました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/821b2f55-20fa-9e91-0c2f-2efbc49ae89c.png)

セットアップ画面を開き、パラメータを入れていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/e7c0dfcd-3180-bda5-8027-d04a62fe643a.png)

スタジオの画面に戻り、「LLM」モジュールを選択。
`モデル` のプルダウンを開き、Bedrockのアイコンが付いているものに変更します。
今回は `Claude 3 Haiku` に変えてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/bd8134b7-6fec-5dbc-14db-30aef7e30f4a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/6027b47c-bddf-a38d-ba06-ef9d4978e15d.png)

Bedrockできました！簡単！
再び「Difyって何？」と聞いてみると、先ほどとは少し違うものの、似たような内容が返ってきました。
> Difyは、プログラミングの知識がなくてもドラッグ&ドロップで簡単にAIアプリケーションを作成できるオープンソースのプラットフォームです。
>主な特徴は以下の通りです:
>
>- GPT-4やClaude 3などの最新のAIモデルを統合しているため、高度なAIアプリケーションを開発できます。
>- 直感的なインターフェースにより、プログラミング経験がなくても簡単にアプリを作成できます。
>- RAGエンジンを使用して、エージェントから複雑なAIワークフローまでLLMアプリを開発できます。
>- オープンソースのため、無料で利用できます。
>- LangChainよりも本番環境に適しているため、実用的なAIアプリの開発に向いています。
>
>つまり、Difyを使えば、プログラミングの知識がなくても、簡単にAIアプリケーションを開発できるというものです。ノーコードでAIアプリを作れるため、これからAIを活用したいと考えている日本人にとても便利なツールだと言えます。

【参考にした記事】

https://qiita.com/akiraabe/items/2b2e856d9bafc6d32440


# 終わりに
以上、プロキシ環境下のローカルPCに "Dify" を導入して、Bedrockしてみました！
結構大変でした笑
おとなしくインターネット経由でサービスを使っておけばよいものを!! 思う反面、実際の仕事では、簡単にはその選択ができない事情もあると思います。
そんな大人の世界で戦ってらっしゃる皆様に、この記事がお役に立てば幸いです。

最後までお目通しいただき、ありがとうございました。