この連載でやること――アプリのコードは生成AIに書かせます。そして作ったものを、シミュレータではなく本物の量子コンピュータで動かします。
シミュレータというのは、量子コンピュータの振る舞いを普通のパソコンで計算して真似したものです。理想的な答えが返ってきます。いっぽう本物の機械は、まだ誤りが多く、答えがずれます。そのずれた数字を、そのまま載せます。難しい数式は使いません。
第1回は、ボタンを押すと「表」か「裏」が出るだけのアプリです。
それだけ?と思われるかもしれません。ですがこの1本で、量子コンピュータのいちばん基本的な性質と、それを普通のWebアプリから使う道すじが、両方とも通ります。
作るもの
画面に大きく「表」か「裏」が出て、ボタンを押すたびに変わります。中身では、そのつど本物の量子回路を1回動かしています。

必要なもの
Pythonと、2つのライブラリだけです。
pip install blueqat flaskblueqat は量子回路を書いて動かすためのライブラリ、Flask はWebアプリを作るためのライブラリです。どちらもこの1行で入ります。
動かないときは、blueqat の版を確かめてください。(2026年9月3日 追記)
新しい scipy と組み合わせると、blueqat 2.0.4 で AttributeError: type object 'csr_matrix' has no attribute '_mul_vector' が出ることがあります。blueqat そのものではなく、内部で使う計算ライブラリが scipy の変更に追いついていないためです。
まず自分の版を見てください。
python3 -c "import blueqat; print(blueqat.__version__)"2.0.4 だった場合は、計算方法を指定すると動きます。この記事のコードでいうと run(shots=1) を run(shots=1, backend="numpy") に変えてください。
2.1.3 以降だった場合は、何も変えないでください。この版に numpy という指定は無く、書くとかえって動かなくなります。既定のまま動きます。
バックエンド
まず、量子回路を動かして結果を返す部分です。ここが心臓部ですが、実質3行しかありません。
from flask import Flask, jsonify, send_from_directory
from blueqat import Circuit
app = Flask(__name__)
@app.route("/api/toss")
def toss():
result = Circuit().h[0].m[0].run(shots=1)
bit = list(result.keys())[0]
return jsonify({"face": "表" if bit == "0" else "裏"})
@app.route("/")
def index():
return send_from_directory(".", "index.html")
if __name__ == "__main__":
app.run(port=5099)Circuit().h[0].m[0].run(shots=1) の一行だけ、少し説明します。
Circuit() は空の量子回路です。.h[0] は0番目の量子ビットにHゲートを掛けます。Hゲートは、0か1かが決まっていない状態を作るものです。「まだどちらでもない」状態にする、と考えてください。これを重ね合わせと呼びます。
.m[0] は測定です。重ね合わせの状態は、測るとどちらかに決まります。shots=1 は1回だけ測る、という指定です。返ってくるのは {'0': 1} か {'1': 1} のどちらかで、これがコインの表と裏になります。
フロントエンド
画面のほうです。ボタンを押したらさきほどのAPIを呼んで、返ってきた文字を大きく出すだけです。
<div class="card">
<h1>量子コイン</h1>
<p class="lead">本物の量子回路で 1 枚だけ投げます</p>
<div id="face">—</div>
<button onclick="toss()">投げる</button>
<div id="log"></div>
</div>
<script>
let 表 = 0, 裏 = 0;
async function toss() {
const r = await fetch('/api/toss').then(x => x.json());
document.getElementById('face').textContent = r.face;
r.face === '表' ? 表++ : 裏++;
document.getElementById('log').textContent = `表 ${表} 回 / 裏 ${裏} 回`;
}
</script>fetch('/api/toss') でバックエンドを呼び、返ってきた face を画面に書き込んでいます。特別なことは何もしていません。量子コンピュータを使っていても、フロントエンドから見れば普通のAPIです。
動かす
2つのファイルを同じフォルダに置いて、python app.py を実行します。ブラウザで http://127.0.0.1:5099/ を開くと、上の画面が出ます。
実際にボタンを7回押したところ、表が3回、裏が4回でした。上の写真がそのときの画面です。
普通の乱数と何が違うのか
random.choice(["表", "裏"]) と書けば同じことができます。そのとおりです。
違うのは、出方の理由です。普通のプログラムの乱数は、決められた計算手順で「乱数っぽい数」を作っています。手順と出発点が分かれば、次に何が出るか計算できます。
いっぽうHゲートで作った重ね合わせは、測るまでどちらか決まっていません。同じ回路を同じ条件で動かしても、次に何が出るかは原理的に計算できません。ここが違います。
ただし今回動かしたのはシミュレータです。手元のパソコンが量子の振る舞いを計算で真似しているので、この回に限れば出どころは普通の乱数と同じです。
実機でも投げてみました
そこで、同じコードを本物の量子コンピュータにも投げました。東京にある OQC Toshiko Tokyo-1 という32量子ビットの機械です。1,000回ぶん実行しました。コードは1行も変えていません。
| 出た目 | 回数 | |
|---|---|---|
| 0(表) | 486 | 48.6% |
| 1(裏) | 514 | 51.4% |
理想は500回ずつです。実際は14回ぶん、1.4ポイントずれました。
ほぼ半々ですが、ぴったりではありません。実機には必ずこういうずれがあります。手元のシミュレータでは、ここまできれいに半々にはならなくても、原理的なずれは入りません。
なお、実機はいつでも動くわけではありません。決まった稼働枠でしか動かず、順番待ちもあります。今回は投げてから結果を確認できるまでに時間が空きました。0.02秒で返るシミュレータとは、そこも違います。
この1.4%は小さいのか
小さく見えます。実際、この回路はHゲート1つと測定1回しかありません。操作が少なければ、ずれも小さい。
次回は量子ビットを2個にして、ゲートを1つ増やします。そのとき、このずれがどうなるか見てください。同じ機械で、はるかに大きくずれます。
次回
離れた2枚のコインが必ず同じ面になるアプリを作ります。量子コンピュータでいちばん有名な性質を、画面で見えるようにします。
そして同じように実機にも投げます。今回の1.4%と比べてみてください。

