今回は、最近注目されている「バイブコーディング」についてご紹介します。難しそうに聞こえるかもしれませんが、バイブコーディングは初心者の方でもAIと一緒に気軽にチャレンジできるコーディング手法です。私自身も、Pythonを少し触った程度のスキルしか持ち合わせておりませんが、実際に業務で役立つツールをAIと一緒に作ることができました。
ここでは、「バイブコーディングとは何か?」の解説から、私が実際にAIと作ったWebアプリの事例まで、わかりやすくご紹介していきます!
目次
バイブコーディングって何?
CursorやGitHub Copilotに代表されるAI開発環境の登場により、AIがコード作成をサポートすることが当たり前になりつつあります。そのおかげで、以前に比べて、コーディングは経験の浅い人でも取り組みやすいものに変化してきています。
バイブコーディングとは、「こんなことをやりたい!」という気持ちをプロンプトでAIに伝え、AIがコードを生成してくれる新しい開発スタイルのことです。
「バイブ(vibe)」という言葉には、「ノリ」や「直感」という意味もあります。細かい仕様にこだわりすぎず、AIとテンポよくやりとりしながらプログラムを作っていくイメージです。
この考え方は、2025年2月にオープンAIの共同創業者、アンドレイ・カーパシー氏が提唱したことで一気に広まりました。最近ではメディアや業界でも多く取り上げられています。
バイブコーディングのメリット
初心者でも取り組みやすい
プログラムの細かい書き方がわからなくても、「こういうことがしたい」とAIに伝えるだけで、コードのたたき台を作ってもらえるので、プログラミング初心者にも優しいスタイルです。
エラーが出ても安心
仮にエラーが出ても、その内容をそのままAIに伝えれば、「ここをこう直してね」と教えてくれるので、安心して進められます!
実際にやってみた!「Pythonコードを用いて、GUIでPDFを分割するツールの作成」
課題
ある雑誌のお仕事で、編集作業後に全頁見開き連結PDFを作成して納品 という作業があったのですが、たまたま先方から「P10-11、26-27、60-61、・・・・・の10見開き分のPDFをください」という依頼がきました。
- 作業オペレータに依頼する
- 自分でAcrobatで1見開きずつPDFを切り出していく
という選択肢がありましたが、「WebアプリでPDFをドラッグ&ドロップして自動で分割する、もしくは範囲指定した分だけページを分割するPythonコードが作れないものかな・・・」と、ふと思いたち、バイブコーディングに挑戦してみました。
AIへの依頼内容
AIには下記のような簡単なプロンプトで命令してみました。
以下の機能を実装したPDF分割ツールを作成したい
1. ブラウザ上にPDFファイルをドラッグ&ドロップしてアップロードできる
2. 全ページPDFをバラに分割させたい or ページの範囲を指定してPDFをバラに分割させたい
上記プロンプト1回で動くコードを生成するのは、正直難しいかと思います。
が、エラーが出たら、そのままエラー内容をコピペし、修正されたコードで再度実行し、
追加したい要素があったら後でそれをプロンプトに盛り込んだりして・・・。
そんなことを繰り返していくと、以下のようなコードが生成され、エラーが出ずにプログラムを動かすことができました!
// import streamlit as st
import PyPDF2
import os
from io import BytesIO
import zipfile
def split_pdf_page_range(pdf_reader, start_page, end_page):
"""指定ページ範囲のPDF分割処理 (辞書で {ページ番号: BytesIOオブジェクト} を返す) <- 修正: 辞書を返すように変更"""
splitted_pdfs = {} # 辞書で分割されたPDFを保持するように変更
# ページ番号は0始まりなので-1
for page_num in range(start_page - 1, end_page):
if page_num < len(pdf_reader.pages): # ページ範囲チェック
pdf_writer = PyPDF2.PdfWriter() # ループ内で毎回新しい PdfWriter を作成 <- 修正: ループ内で毎回作成
pdf_writer.add_page(pdf_reader.pages[page_num])
output_stream = BytesIO()
pdf_writer.write(output_stream)
output_stream.seek(0)
splitted_pdfs[page_num + 1] = output_stream # ページ番号は1始まりで辞書に保存
return splitted_pdfs # 辞書を返すように変更
def split_pdf_every_page(pdf_reader):
"""PDFを1ページずつ分割 (辞書で {ページ番号: BytesIOオブジェクト} を返す)"""
splitted_pdfs = {}
for page_num in range(len(pdf_reader.pages)):
pdf_writer = PyPDF2.PdfWriter()
pdf_writer.add_page(pdf_reader.pages[page_num])
output_stream = BytesIO()
pdf_writer.write(output_stream)
output_stream.seek(0)
splitted_pdfs[page_num + 1] = output_stream # ページ番号は1始まり
return splitted_pdfs
def create_zip_file(splitted_pdfs, zip_filename_base="splitted_pdf"):
"""分割されたPDF群をZIPファイルに圧縮 (BytesIOオブジェクトを返す)"""
zip_buffer = BytesIO()
with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zipf:
for page_num, pdf_stream in splitted_pdfs.items():
zipf.writestr(f"{zip_filename_base}_page_{page_num}.pdf", pdf_stream.getvalue())
zip_buffer.seek(0)
return zip_buffer
st.title("PDF分割ツール")
st.write("PDFファイルを分割します。")
uploaded_file = st.file_uploader("分割したいPDFファイルをアップロードしてください", type="pdf")
if uploaded_file:
pdf_reader = PyPDF2.PdfReader(uploaded_file)
split_method = st.radio(
"分割方法を選択してください",
('すべてのページを個別に分割', 'ページ範囲を指定して分割')
)
if split_method == 'ページ範囲を指定して分割':
start_page = st.number_input("開始ページ", min_value=1, max_value=len(pdf_reader.pages), value=1)
end_page = st.number_input("終了ページ", min_value=start_page, max_value=len(pdf_reader.pages), value=len(pdf_reader.pages)) # 開始ページ以降をデフォルト値とする
else:
start_page = None
end_page = None
if st.button("PDF分割実行"):
with st.spinner("PDF分割処理中..."):
if split_method == 'ページ範囲を指定して分割':
if start_page <= end_page:
splitted_pdfs = split_pdf_page_range(pdf_reader, start_page, end_page) # 修正: 関数呼び出し結果を splitted_pdfs に代入
if splitted_pdfs: # 修正: splitted_pdfs が空でないかチェック
zip_buffer = create_zip_file(splitted_pdfs, zip_filename_base=os.path.splitext(uploaded_file.name)[0] + f"_pages_{start_page}-{end_page}") # ZIPファイル名にページ範囲を追加
st.success(f"{start_page}ページから{end_page}ページを分割しました。(ZIPファイルでダウンロード)") # メッセージを修正
st.download_button(
label="分割済みPDF (ZIP) をダウンロード", # ボタンラベルを修正
data=zip_buffer,
file_name=f"{os.path.splitext(uploaded_file.name)[0]}_pages_{start_page}-{end_page}.zip", # ZIPファイル名にページ範囲を追加
mime="application/zip"
)
else:
st.error("指定されたページ範囲にはページが存在しません。") # エラーメッセージを修正
else:
st.error("開始ページは終了ページより小さくなければなりません。")
elif split_method == 'すべてのページを個別に分割':
splitted_pdfs = split_pdf_every_page(pdf_reader)
if splitted_pdfs:
zip_buffer = create_zip_file(splitted_pdfs, zip_filename_base=os.path.splitext(uploaded_file.name)[0]) # ZIPファイル名に元のファイル名を使用
st.success(f"全{len(pdf_reader.pages)}ページを個別に分割しました。(ZIPファイルでダウンロード)")
st.download_button(
label="分割済みPDF (ZIP) をダウンロード",
data=zip_buffer,
file_name=f"{os.path.splitext(uploaded_file.name)[0]}_splitted_pages.zip", # ZIPファイル名に元のファイル名を使用
mime="application/zip"
)
else:
st.error("PDF分割に失敗しました。")
else:
st.info("PDFファイルをアップロードしてください。")

実際に作成したツールを使ってみて、いくつかのポイントに気づきました。
使ってみた感想
- シンプルで使いやすいUIデザインで、誰でも迷わず操作できる
- ファイルアップロード後すぐにPDFのページ数が認識され、適切な範囲選択が可能になる
- ページ範囲指定時に、開始ページは自動的に1に、終了ページは最大ページ数に設定される便利な初期値がある
- 分割処理中は進捗状況が表示され、完了時には成功メッセージが表示される
- 大きなPDFでも比較的スムーズに処理できる
また、このツールは、以下のような場面で役立つと考えられます。
実用シーン
- スキャンした複数ページの文書を個別ファイルに分けたい時
- 大きなマニュアルやレポートから必要な章だけを抽出したい時
- 複数人で分担して資料を確認する際に、ページごとに分けて配布したい時
これらの実用シーンを踏まえると、このツールには業務効率化の観点から、以下のような価値があると考えられます。
業務効率化の観点からの価値
- 従来のPDF編集ソフトを起動して操作する手間が省け、数クリックで分割処理が完了する
- 複数ファイルの分割作業が必要な場合、一連の操作が単純化されるため作業時間が大幅に短縮される
- 必要なページのみを共有することで、情報過多を防ぎ、相手の確認時間も短縮できる
おわりに
バイブコーディングは、プログラミングのハードルをグッと下げてくれる、これからの開発スタイルになるのではないでしょうか。
Python初心者でも、AIを相棒にすることで、自分の業務に役立つツールを気軽に・楽しく作れるようになります。
これからも、身近な業務改善ツールや、ちょっとした自動化アイデアを、バイブコーディングのスタイルでどんどん試していきたいと思います!
読んでいただき、ありがとうございました!

