てけとーぶろぐ。

ソフトウェアの開発と、お絵かきと、雑記と。

Python + Rye + Gemini API でAIチャットを作る

ChatGPTだとかCopilotだとか、AIチャットというのでしょうか。 最近ちょこちょこ使っています。

便利でありがたいのですけど、質問の一部だけが毎回異なるような定型的な質問が簡単にできると更に便利だなと思っています。

例えば「英単語のXXXとXXXの違いと使い分けを教えてください」という質問はXXXの部分を変えて何度もしていたりします。

そういうのはGhatGPTのAPIを使えばできるよ、という記事は何度も見かけたのですけど APIの利用料など気にせずに、できれば無料で行いたい…。 何かないかなと探してみるとGoogleのGemini APIが通常の使用では制限を気にせず無料で使えそうでした。

ということでGemini APIを使ってまずは試しに単純なチャットを作ってみました。 いくらか使い慣れているPythonで作ります。

Gemini APIの使い方に関しては以下を参考にしています。

ai.google.dev

Ryeのインストール

セットアップを簡単にするためPythonのパッケージマネージャーにはRyeを使います。

Ryeをインストールしていない場合は以下の「Installation Instructions」に従ってインストールします。

rye.astral.sh

プロジェクトの作成

プロジェクトを作成します。

$ rye init gemini-tutorial
$ cd gemini-tutorial
$ rye sync
パッケージのインストール

Gemini API 用の Python SDK が含まれる google-generativeai パッケージをインストールします。

$ rye add google-generativeai
$ rye sync
Pythonファイルの作成

gemini-tutorial/src/gemini_tutorial/main.py として以下の内容でPythonファイルを作成します。

import google.generativeai as genai
import os

GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY")

if GOOGLE_API_KEY is None:
    print("環境変数 GOOGLE_API_KEY がセットされていません")
    exit()

genai.configure(api_key=GOOGLE_API_KEY)

model = genai.GenerativeModel("gemini-1.5-flash")

chat = model.start_chat(history=[])

print("メッセージを入力してください(「exit」で終了します)")
print("")

while True:
    print("あなた:")
    message = input()
    print("")
    if message == "exit":
        print("終了します")
        break
    response = chat.send_message(message)
    print("AI:")
    print(response.text)
APIキーの取得

以下のサイトの「APIキーを取得する」ボタンをクリックしてAPIの使用に必要なAPIキーを取得します。

ai.google.dev

取得したら以下のようにして「GOOGLE_API_KEY」という環境変数に取得したAPIキーをセットします。 ("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"の部分は取得したAPIキー) Pythonプログラムからこの環境変数を参照します。

$ export GOOGLE_API_KEY="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

セキュリティを考えてこうしているだけで プログラムを公開しないというのであればPythonプログラム内で

GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY")

の代わりに

GOOGLE_API_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

としても構いません。

プログラムの実行
$ rye run python src/gemini_tutorial/main.py
プログラムの実行結果
$ rye run python src/gemini_tutorial/main.py
メッセージを入力してください(「exit」で終了します)

あなた:
こんにちは!

AI:
こんにちは! 何かご用でしょうか?

あなた:
あなたは誰ですか?100文字程度で教えてください。

AI:
私は、Googleによって訓練された、大規模言語モデルです。 私は、テキストを理解し、生成することが得意です。 質問に答えたり、物語を書いたり、コードを生成したりできます。

あなた:
exit

終了します

たったこれだけのコードでできてしまうなんて驚きです。

.env ファイルの作成

上記のようにAPIキーを環境変数にセットしているとターミナルを立ち上げるたびに環境変数にセットしなければなりません。 それは面倒なのでプログラム実行時にファイルからAPIキーを読み込むようにしてみましょう。 gemini-tutorial/.env を以下の内容で作成します。("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"の部分は取得したAPIキー)

GOOGLE_API_KEY="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
.gitignore ファイル編集

.envファイルにはAPIキーが書かれているわけですから ここでもセキュリティを考えて.envファイルをリポジトリーの管理対象外としたいのであれば gemini-tutorial/.gitignore に以下を追記します。

# env
.env
pyproject.toml ファイルの編集

.envファイルから環境変数に値をセットしてプログラムの実行をするような スクリプトを gemini-tutorial/pyproject.toml に定義します。 pyproject.tomlに以下を追記します。

[tool.rye.scripts]
run-main = { cmd = "python src/gemini_tutorial/main.py", env-file = ".env" }
スクリプトを使ってのプログラムの実行

そしてプログラムの実行を以下のコマンドで行うようにします。

$ rye run run-main

Ubuntuでネットワークの不調の原因を探る

Ubuntuを快適に使っていたのですが 近頃Webブラウジングで固まったり、Web会議で映像や音声が途切れたりといった ネットワークの不調があって困っていました。

結果的にwifiの電波状況の問題で wifiルーターを再起動してオートチャネルセレクトを強制的に行わせ 動作中にも定期的にオートチャネルセレクトがなされるようにルーターの設定を変更して 改善しました。 →2024/03/27追記: 改善したと思いきや時間帯などによってはdropが10%を超えるので、さらにバンドステアリング機能もオフにしたところ、今度こそ改善したっぽいです。不調になったら接続先のSSIDの切り替えで周波数が切り替えられるのでこちらのほうが良さそうです。

運悪く不調を感じはじめた時期がUbuntuのバージョンを変えたタイミングだったことや、 WindowsAndroidだと不調を感じることがなかったことから、 Ubuntuの何かが原因だと思ってしまい解決まで遠回りをしてしまいました。

解決にあたっては以下の記事がとても役に立ちました。

gihyo.jp

ここで紹介されているwavemonを以下のコマンドでインストールして

$ sudo apt-get install wavemon

以下のコマンドで起動。

$ wavemon

起動しておいて、不調を感じたときに見てみるとStaticsのdropが10%を超えていました。 普段でも数%以上。 一方で、そういえば不調を感じないなと思った別の場所、つまり別のwifi環境で見てみるとdropは0.X%でした。 このことからwifiの電波状況だと判断しました。

Fire HD 10 タブレット(≒Androidタブレット)をPC風に使う(ソフトウェア編)

当初この記事を書こうと考えたときは以下の動画にあるような Linuxをインストールしてあれこれというのを紹介しようと思っていました。

【改造不要】Fireタブレットでデスクトップが使いたい!2/2 Termux編【Amazon Fire HD 10 Plus (2021)】 - YouTube

しかし実際にやってみて自分としてはAndroidへのLinuxのインストールは実用的ではないと感じました。 それで結局、人に勧められると思ったPC風に使う方法としては以下の2つとなりました。

それぞれについて説明します。

PCにリモートデスクトップ接続して使う

タイトルの通りです。接続先のPCはWindows, Mac, Linux どれでも。 Fire HD 10 タブレット にインストールするリモートデスクトップクライアントアプリとしては探した中では以下のいずれかが良さそうです。

使い方のポイントとしては設定で解像度を指定してやることです。 Fire HD 10 タブレット だと 1920x1200 が画面の解像度なので この縦横比になるように、かつ操作しやすい表示になるように、例えばこの75%とかの解像度を指定してやります。

Fire HD 10 タブレットの場合、Google Playがインストールされていないのでアプリがインストールしづらいですね…。 Google Play をインストールしたり、APKダウンロードサイトからダウンロードしてきたりもできそうではありますけど あまり紹介されていないやり方としては aRDP, bVNC についてはオープンソースなので、ソースコードからビルドしてAPKを作ってインストールするという手があります。

以下のサイトの Building に従って、あっさりビルドできました。

github.com

それから出先から接続するのであればPCに何らかの方法でインターネット経由で接続できるようにしなければなりません。 ngrokを使ったり、VPNを経由するのがいいと思います。

ngrok.com

VPN接続にはVPNクライアントが必要ですがOpen SSTP Clientなんかがおすすめです。 こちらもオープンソースで、こちらについては自分でビルドせずともGitHubからAPKがダウンロード可能です。

github.com

PC風にWebブラウザーを使う

Fire HD 10 タブレット に接続したキーボードとマウスを使ってPC風に操作できるWebブラウザーアプリを使ってWebブラウジングします。

タブバーを表示できるなど、PC風なUIになるWebブラウザーアプリを選ぶことになります。 以下をお勧めします。

いずれも公式サイトでAPKを配布しています。

Vivaldi Browser

以下のサイトの「Alternative download stores.」をクリックして表示される「Download the app (apk):」からダウンロードします。

vivaldi.com

Kiwi Browser 以下のサイトの「Download now (.APK)」からダウンロードします。

kiwibrowser.com

Kiwi Browser についてはChrome拡張が使える点も素晴らしいです。

Fire HD 10 タブレット(≒Androidタブレット)をPC風に使う(ハードウェア編)

自分は「タブレットは不要、結局PCが必要になるんだよね。」という意見なのですけど 先日安さと性能に惹かれてFire HD 10 タブレットを買ってしまいました。

せっかくなのでPC風に使えるのか試してみました。

結論を先に言ってしまうと、使うだけならこんなことをせずにLIFEBOOKなどの軽量ノートPCを買った方がいいです。 ただ用途によっては値段の割に使えますし、何よりどうすれば使いやすくなるかなとあれこれ考えて試すことが楽しいです。 そしてその中で気づきなどもあります。

今回気づいたことの中で特に共有しておきたいと思ったことはオープンソースAndroidアプリって結構あるんだなってことです。

Termux, aRDP, bVNC, XServer XSDL と今回主に使ったアプリはいずれもオープンソースでした。

前置きはこの辺にして早速やっていきます。まずはハードウェア編です。

ハードウェアって何のこと?かと思いますので説明しますと、PC風に使うためにFire HD 10に追加で必要なもののことです。キーボード、マウスなどです。

追加で必要なものを選ぶ際には主に重量・携帯性、使いやすさを重視しています。 特に重量・携帯性はタブレットをPC風に使う上でノートPCといい勝負ができる数少ない点だと思います。

それであれこれ考えて以下に落ち着きました。

折りたたみスティック型スタンド

重量、開きやすさ、角度調整の自由さを考えるとこういうスタンドだと思います。

item.rakuten.co.jp

TPUケース

ごく普通のTPUケースです。いろいろなところで似たようなものが売られていると思います。 TPUケースをつけて、TPUケースに上記のスタンドを貼り付けています。 傷を気にしない人はTPUケースは使わずタブレットに直接スタンドを貼ってしまうと更に軽くなるかと思います。

ガラスフィルム

これまたごく普通のガラスフィルムです。傷を気にしない人は不要かと…。

Bluetoothキーボード

キーボードの接続方法はつなぎやすさや持ち運びの妨げにならないことを考えるとBluetoothではないでしょうか。 そして、重量、英語配列、Ctrlキーの位置、それなりのうちやすさといったところでこれに落ち着きました。 いまのところ問題なしですけど耐久性があるのか不明です。

Bluetoothマウス

薄さ、重量、使いやすさでこれに落ち着きました。鉄板のロジクール

Reader CaptureでKindle for PCの電子書籍をPDFにする手順の変更

電子書籍をPDFファイル/ZIPファイルに変換できるWindows用アプリReader CaptureKindle for PCの電子書籍をPDFにする手順に変更があったのでお知らせします。

どうも最近Kindle for PCは、書籍によって、フルスクリーンにしても画面の上辺・下辺に細い枠線が表示されるようになったようです。

この場合にReader Captureでうまくキャプチャーするには、固定トリミングを今までの左右に加えて、上下に 上: 1、下: 1 と設定する必要あります。

最新の Reader Capture 1.15.0.0 ではこれをデフォルトの設定としました。

Reader CaptureでKindle for PCの電子書籍をPDFにする手順の全体は Reader Capture - 電子書籍をPDFファイル/ZIPファイルに変換! をご参照ください。

細かいことを言うと、上辺・下辺に細い枠線が表示されない場合は、固定トリミング 上: 1、下: 1 となっていると1ピクセル切れてしまうことになるんですよね。 気になる方は「範囲選択機能」で細い枠線があるのかチェックするといいかもしれません。

格安HDMIキャプチャーボードでスマホをラズパイのディスプレイにする

ラズパイ(Raspberry Pi 2 Model B)にUbuntuをインストールして家庭内サーバーにしようとしました。

以下の記事の手順に従えばラズパイにディスプレイもキーボードもつなぐことなくSSHログインしてセットアップができるはずなのですが、なんだかんだ、はじめだけちょっとディスプレイをつないで確認しながらやりたくなりました。

zenn.dev

かといってこれのために5千円以上かけてディスプレイを買うのも…となっていたところに使えそうなものを見つけました。 それがこの格安のHDMIキャプチャーボードです。

これにUSB 変換アダプタとHDMIケーブルをつないで、Androidスマホとラズパイをつなぎます。

スマホで以下のアプリを起動しておけばスマホが簡易ディスプレイになります。

play.google.com

ただし画面の表示の様子はこんなですので長時間の作業には向きません。

スクリーンショット

このHDMIキャプチャーボード、えらい安いですし、大丈夫なのかと疑ってしまいますが 多少遅延もあったり、Motion JPEGでのノイズがあったりなので値段相応なのかもしれません。

多くのHDMIキャプチャーボードの使い方には耐えないように思いますけど、今回の使い方はちょうどではないでしょうか。

スマホでなくタブレットだったら画面の大きさにも満足ですかねー。

Reader Capture 機能紹介: 中断時の保存機能

電子書籍をPDFファイル/ZIPファイルに変換できるWindows用アプリReader Captureに追加した機能を紹介します。 今回はキャプチャー中断時の保存機能です。

Reader Capture は自動で電子書籍のページを進めながら

  • ページが進められなくなるか(ページ数「自動」の場合)
  • 指定のページ数になるか(ページ数「手動」の場合)

するまでキャプチャーしていくのですが、キャプチャー中にCtrl+F12を押したり、Reader Captureのウィンドウの停止ボタンをクリックしたりすることでキャプチャーを中断できます。

そしてこれまでは、キャプチャーを中断したとき、そこまでキャプチャーした内容は破棄されていました。

それがこの度の機能追加で、そこまでキャプチャーした内容を保存することもできるようになりました。

やり方は簡単。キャプチャーを中断すると保存するか聞かれるので保存したければ「はい」を選ぶだけです。

この機能がどんなときに嬉しいのか? 例えば以下のような用途が考えられます。

  • 今の設定でどんな感じにキャプチャーされるか試しに数ページキャプチャーする

  • キャプチャー開始から気が変わって、とりあえず今のページまでキャプチャーできていればいいやとなった

  • 最後のページまでキャプチャーされたが画面に表示が変わり続ける部分があってページ数「自動」がきかずキャプチャーが終わらない

1つ目は今まではページ数「手動」で数ページを設定する方法を紹介していましたけど中断→保存の方が楽ですね。