• ふーちゃん通信

【業務効率化】議事録作成AIをつくってみた②🤖

2026.03.27(Fri)

こんにちは!いつも(?)AIを使った効率化について書いている人です🤖

前回は「なぜチャットAIじゃなくてシステム化なのか」をお伝えしました。

今回はいよいよ「じゃあ具体的にどう作ったの?」という設計の話です🔧
……正直、私もわかってない部分もあります。AIと二人三脚で作ったので。

でも「せっかくだから共有したい!」という気持ちが勝ちました。
コードの意味は正直半分くらいしかわかってないんですが、
「たぶんこういうことだと思う…」という解釈でお届けします🙏 

🗺️ まずは全体像

「ファイルを置く → 議題ごとに分割 → AI整理 → Word出力」というフローでした。
このシステム、実はいくつかのファイル(部品みたいなもの)が組み合わさってできています。
「それぞれ何をしてるの?」って聞いたら、AIがこういうツリー図を出してきました👇

minutes_full/ # メインのパッケージ(「パッケージ」=部品の入れ物らしい)
├── memo_parser.py # ①「◎」で議題を切り出す係
├── prompt_builder.py # ②AIへの指示文を組み立てる係
├── openai_client.py # ③AIに実際に投げる係(お金もここで考えてる)
└── schema.py # 出力形式の定義(「JSON型」って言ってた。よくわからん)
app.py # 画面まわり。ボタンとかここ

見せられたとき「うわ…」ってなりました。でも落ち着いて読むと、役割分担してるだけなんですよね。
今回は特に重要な3つのしくみに絞って、「こういうことだと思う」という解釈込みでご紹介します。

· · ·

🔍 しくみ①「◎」で議題を作っておく

一番最初の課題は、「長い会議の文字起こし(全部で数万文字!)から、議題をうまく見つける」ことでした。
「数万文字」って、短編小説くらいの量です。さすがに多すぎる😇

最初は「AIに全部丸投げすればよくない?」と思ってたんですが、
やってみると毎回結果が変わったり、なんか謎の議題が生えてきたりして🌱
それで別のアプローチを考えました。

❌ 最初にやったこと

「この文字起こしから議事録を作成して」とAIに頼む。
→ 毎回結果が変わる。長文だと途中で切れることも😭
→ なんか知らん議題が生えてくる🌱

✅ 採用した方法

「◎…について」と書いた会議メモをAIに渡す。
→ 毎回同じ結果。コストもゼロ。
→ 謎の議題は生えてこない🌱✋

つまり、議題を作らせるのではなくあらかじめ議題とそのざっくりとした内容を渡しておくことで内容の補完や修正を任せられます。「AIに事前にルールを共有する」という考え方です。
「◎は議題のこと、内容は~」と事前に知らせておきます。

ただし全部の議題を処理させるとそれはそれでパンクするので議題を分割してAIに渡します。そこはプログラムで設計します!全部AIに頼もうとしなくてもいいんです🤔

実際のコードを見てみよう(memo_parser.py)

コードが出てきますが、日本語のコメント(#のあと)だけ読めば大丈夫です👇

memo_parser.py(←このファイル名もよくわかってない)
# ◎(や〇●○)で始まる行を「議題の見出し」と認識するルール
HEADER_RE = re.compile(r"^\s*[\ufeff]?[◎〇●]\s*(.+?)\s*$")
# ↑ここは何書いてあるか全然わかりません。呪文です。

def parse_agendas(memo_text: str) -> List[Agenda]:
    lines = memo_text.splitlines()   # テキストを1行ずつに分ける
    indices = []

    for i, line in enumerate(lines):
        m = HEADER_RE.match(line)
        if m:
            title = m.group(1).strip()
            indices.append((i, title))   # 「何行目に◎があるか」を記録する

    agendas = []
    for idx, (start, title) in enumerate(indices):
        end = indices[idx + 1][0] if idx + 1 < len(indices) else len(lines)
        block = "\n".join(lines[start:end])  # ◎〜次の◎の直前まで = 1つの議題
        agendas.append(Agenda(
            agenda_id=f"AG{idx+1:03d}",  # AG001, AG002... と番号を振ってる(かわいいね)
            title=title,
            block_text=block
        ))
    return agendas
💡
「正規表現」って?
re.compile(r"^[◎〇●]...") これが「正規表現」というやつらしいです。
「テキストの中から特定のパターンを探すためのルールを書く方法です」と言ってました。
要は「◎で始まる行を探せ」を1行で書いたもの、らしいです。なるほどね(全然わかってない)

会議メモの書き方(ここは簡単!)

このシステムを使うのに人間が覚えることはほぼゼロです。
「◎をつけるだけ」。以上。本当に以上。

会議メモの書き方(これだけ!)
 先月の売上報告
・目標比 95%
・東日本エリアが好調

 新商品の販促計画について
・4月以降のキャンペーン案を議論
・予算は前期比20%増で検討

 次回開催日程の確認
・候補日:4/5 か 4/12
これだけ!本当にこれだけ!
「◎」を議題の頭につける。後は箇条書きでメモ。
システムがこれを読んで、自動で3ブロックに切り分けてくれます。
AG001AG003 という管理番号も勝手につきます。「AG」って何の略か聞いたら「Agendaです」って言われました。そのままやん。
· · ·

✍️ しくみ②「良い議事録」を書かせるAIへの指示の工夫

「AIへの指示文なんて、適当でよくない?」
…実際やってみたら、指示の仕方ひとつで出力の品質がかなり変わるんですよね。

このシステムでは、AIへの指示を3層構造に分けているらしいです👇

① system(システムプロンプト)

「あなたはプロの議事録作成者です。箇条書きで、発言者名を明記して書いてください」みたいな指示。
← AIの基本的な役割やルールを最初に決める部分。一回設定したら毎回同じ。「AIの人格設定」みたいなイメージ。

② base_user(ベースコンテキスト)

「これが今日の会議の文字起こし全文です:〔数万文字…〕。議題一覧はこちらです:AG001〜AG003」
文字起こしの全文と議題リストを渡す部分。超重い。

③ target_user(処理対象の指定)

「AG001の議事録を作ってください」「AG002とAG003をまとめて作ってください」
今回どれを処理するかだけを伝える。軽い。バッチごとにここだけ変わる。

🗝️
3つに分ける意味
「数万文字の文字起こし(めちゃ重い)」は最初の1回だけ渡す(②)。
「どの議題を処理するか(軽い)」は毎回変える(③)。
こうすると重いデータを毎回送らなくて済むから、コストが減ります。
荷物を全部毎回持ち歩くんじゃなくてロッカーに預けておく感じ?たぶん🧳

出力形式をJSONで固定する(Structured Outputs)

「Structured Outputs」って言葉が出てきて一瞬「?」ってなりましたが、
要は「返ってくるデータの形を固定する」ということらしいです。
普通に頼むと毎回フォーマットが微妙に違うやつが返ってきて困るから、「必ずこの形で返して!」という型紙を渡すイメージ。

schema.py(「JSON」って何?って聞いたら「データの形式です」と言われた)
# AIに「必ずこのJSON形式で返して」と強制するスキーマ(型紙みたいなもの)
{
  "agendas": [
    {
      "agenda_id": "AG001",
      "agenda_title": "先月の売上報告",
      "rows": [
        { "speaker": "田中", "text": "東日本エリアが目標を上回った" },
        { "speaker": "鈴木", "text": "西日本は95%で着地" }
      ],
      "uncertainties": ["具体的な数値が不明瞭な箇所あり"],
      "need_more_context": false  # ← "false"って書いてあるとfalse以外返せないらしい。へぇ
    }
  ]
}
📐
スキーマ=型紙
「スキーマ」って言葉が出てきたとき「また難しい言葉…」ってなったんですが、
「型紙を渡してAIに形を守らせること」と理解しました。
これがあると speakertext という形から外れた返答ができなくなるらしいです。
「今日の気分で形式を変えるAI」は困るので、これは大事!
· · ·

💰 しくみ③ お金の話:バッチ処理とキャッシュ

API(OpenAIのサービス)は使うほどお金がかかります。
文字起こしが数万文字あるので、なにも考えずに使うと請求が増える一方💸
(とはいえ、数万文字読ませるだけなら数円程度ですが)
「AIすごい! → 請求書がすごい!」を回避するために2つの工夫があります。

工夫その1:バッチ処理(まとめて送る)

議題を1つずつ処理するんじゃなく、まとめて複数送るという方法です。
宅配便で1個ずつ送るより、まとめて1箱に入れた方が安い、ということですね!📦

app.py(バッチ処理の核心部分らしい)
batch_size = 3  # 1回のAPIコールで議題を最大3つまとめて処理(この数字は変えられる)
total_batches = (len(agendas) + batch_size - 1) // batch_size
# ↑「何回に分けるか計算してるだけ」らしい

for i in range(total_batches):
    batch_agendas = agendas[i * batch_size : (i + 1) * batch_size]
    # → [AG001, AG002, AG003] を1回のAPI呼び出しで処理
    #    [AG004, AG005, AG006] を次の呼び出しで処理...という具合

    target_user = render_target_user(prompt_pack.target_user, batch_agendas)
    out = llm.generate_minutes(prompt_pack.system, base_user, target_user)
    # ↑「llm」って変数名、「Large Language Model」の略らしいです。言われたらそうだった
📊
バッチサイズ3の効果
議題9個の場合:
・バッチなし → API 9回呼ぶ(9回分の料金)
・バッチサイズ3 → API 3回で済む(1/3の料金!)
画面から数字を変えられるので、「お金大事!」という日は小さくして、「品質大事!」な日は大きくする感じで使えます💰

工夫その2:プロンプトキャッシュ(同じデータを使いまわす)

「文字起こし全文(数万文字)」は毎回送るとその分お金がかかります。
でも2回目以降も同じ文字起こしを使う必要があります。
「キャッシュ」って言葉が出てきたとき、ブラウザのキャッシュと同じ感じ?と思ったら、まあそういうことらしいです📚

PROMPT CACHE の仕組み
1回目
「全部送る」(ここだけ頑張る)

「文字起こし全文(数万文字)+AG001〜AG003」を送る。重い。お金かかる。でも cache_key という「引換券」みたいなものを発行しておく。

2回目
引換券を使う ✨

文字起こし部分はキャッシュから出してくる。新しく送るのはAG004〜AG006の指示だけ。コスト減🎉

3回目~
まだ引換券使える ✨

以降もずっとキャッシュ活用。議題が何個あっても、文字起こし分のコストは最初の1回だけ。便利すぎる。

openai_client.py(キャッシュの設定らしい)
# cache_key を設定することで、同じ文字起こしを何度も送る際のコストを削減
kwargs = dict(
    model=self.settings.model,
    input=input_items,
    text={"format": text_format},
)

if self.settings.prompt_cache_key:
    kwargs["prompt_cache_key"] = self.settings.prompt_cache_key
    kwargs["prompt_cache_retention"] = "in_memory"  # 起動中はキャッシュを保持

resp = self.client.responses.create(**kwargs)
# ↑最後の **kwargs 、「**なんとか」の書き方がずっと謎。
# AIに聞いたら「辞書を展開する記法です」と言われた。わかんない。

コスト削減の工夫まとめ

工夫 内容 効果
バッチ処理 複数議題をまとめてAIに投げる(デフォルト3つ) APIコール数を最大1/3に削減
プロンプトキャッシュ 数万文字の文字起こしを最初の1回だけ処理して使い回す 2回目以降のコスト減
Reasoningを「low」に AIの「考える深さ」を抑える 速度アップ+コスト削減。議事録には十分
バッチ中断機能 処理途中でも「停止」ボタンで止められる 「あ、やっぱやめた」ができる。
· · ·

🚀 まとめ:設計の3原則

長くなりましたが、結局このシステムで大事にしていることは3つ。

設計の3原則
原則①
「AIに一気に頼まない」

文字おこしデータは膨大。分割して処理させる。分割はプログラムで実行。使い分けが大事。

原則②
「AIの返し方は固定させる」

型紙(スキーマ)を渡して、フォーマットを守らせる。「今日の気分で形式が変わるAI」はシステムに組み込めないから。

原則③
「お金のことは最初から考える」

バッチ処理+キャッシュで、重いデータを賢く使い回す。「AIすごい → 請求書がすごい」はリアルな落とし穴なので、最初から仕組みで防ぐ。

「何をAIに任せて、何は任せないか」を整理するだけで、グッと扱いやすくなる
というのはこのシステムを作っていて強く感じました。
AIは万能じゃないし。得意・不得意を使い分けるだけです。

この考え方、議事録AIだけじゃなく「定型業務の自動化」全般に使えると思います。
「うちの会社の議事録作成、これで解決できるかも……」と思った方、ぜひ試してみてください🔥
(私でも作れたので、たぶんだいじょぶです)

そして完成しました!!

「文字おこしデータ」と「メモ」をメール✉️で送るだけで、
整形された議事録が自動返信されるようにしました!🎉

社内の人ならだれでもメールを送るだけで出来上がった議事録が返ってきます!やったー!🥳

 

……と思っていましたが。

残念ながら「情報の整理くらいは人間がやるべき」とのご意見をいただき、導入は見送りとなりました😢

全力で作ったのに……!!あばばば……🦐

では、次の更新もお楽しみに~~🎉

ふたば産業オリジナルカタログ・【新登場】野菜カタログはこちら!

          ふたば産業オリジナルカタログ

          野菜カタログ