「Opus 4.1」登場!Sonnet 4を超えた?Anthropic最新LLMを徹底解説

Opus 4.1 登場 Sonnet 4 超えた Anthropic 最新 LLM
押さえておきたいポイント
  • コーディング・推論能力が向上
  • SWE-bench Verifiedスコア74.5%に到達しており、Opus 4から飛躍的に性能アップ
  • エージェント系タスクでも従来モデルより一歩抜きん出る

2025年8月6日、Anthropicから新たにClaude Opus 4.1がリリースされました!

今回リリースされたClaude Opus 4.1はOpus 4に比べ、推論やコーディング性能が向上、最大コンテキスト長は 200,000 トークン、最大出力トークンは32,000トークン

本記事ではClaude Opus 4.1の概要から使い方、従来モデルとの比較をしてみたいと思います!最後までお読みいただければ、Claude Opus 4.1の理解が深まり、うまく扱うことができるようになります。

ぜひ最後までお読みください!

\生成AIを活用して業務プロセスを自動化/

目次

Claude Opus 4.1の概要

2025年8月6日、AnthropicはClaude Opus 4.1をリリースしました。前バージョンClaude Opus 4からさらなる性能向上を果たし、特に複雑な推論・マルチファイルのコードリファクタリング・実用的なエージェントタスクへの対応力が向上。

複数ファイルにまたがるリファクタリングやバグ修正の精度が劇的に改善しており、実際に楽天グループがOpus 4.1を使用したところ「不要な変更を加えずに正確に修正できる能力」を高く評価しています。※1

また、最大20万トークンのコンテキストを活かしたドキュメント理解や連続的な推論も可能であり、「思考の可視化(thought scaffolding)」に対応し、複雑な意思決定タスクにも強いです。

Claude Opus 4.1の性能

特にコーディング精度は、SWE-bench Verifiedスコア74.5%に到達しています。

参考:https://www.anthropic.com/news/claude-opus-4-1

SWE-bench Verifiedスコアは、ソフトウェアエンジニアリングタスクを評価するためのベンチマークデータセットです。実際のソフトウェア開発で発生する課題に対して、AIモデルの性能でどこまで対応できるのかを評価するベンチマークです。※2

そのほかの性能は下記の図をご覧ください。

参考:https://www.anthropic.com/news/claude-opus-4-1

Opus 4とOpus 4.1を横並びで見てみると、Opus 4.1の性能向上がわかりやすいですね。基本的には全ての項目でOpus 4.1が上回っています。

また、Gemini 2.5Proとの比較もでき、コーディング性能についてはOpus 4.1が優れていることがわかります。

Claude Opus 4.1の料金

個人利用は無料または低コストで利用することができ、法人向けには管理機能などが付属。

用途に応じて適切なプランを選んでコストを最適化しましょう。

プラン名月額料金主な機能
無料プラン0円基本的な質問応答や簡単なタスク向け
Proプラン$20/月高度な推論や長文処理、優先アクセスあり
Max 5xプラン$100/月Proプランの5倍の利用が可能
Max 20xプラン$200/月Proプランの20倍の利用が可能
Enterpriseプラン要相談専用カスタムモデルや追加機能を提供
API入力:$15/百万トークン
出力:$75/百万トークン
フル機能を提供
参考:https://docs.anthropic.com/en/docs/about-claude/models/overview

AnthropicのAPI料金一覧は下記です。

スクロールできます
ModelBase Input Tokens5m Cache Writes1h Cache WritesCache Hits & RefreshesOutput Tokens
Claude Opus 4.1$15 /百万トークン$18.75 /百万トークン$30 /百万トークン$1.50 /百万トークン$75 /百万トークン
Claude Opus 4$15 /百万トークン$18.75 /百万トークン$30 /百万トークン$1.50 /百万トークン$75 /百万トークン
Claude Sonnet 4$3 /百万トークン$3.75 /百万トークン$6 /百万トークン$0.30 /百万トークン$15 /百万トークン
Claude Sonnet 3.7$3 /百万トークン$3.75 /百万トークン$6 /百万トークン$0.30 /百万トークン$15 /百万トークン
Claude Sonnet 3.5$3 /百万トークン$3.75 /百万トークン$6 /百万トークン$0.30 /百万トークン$15 /百万トークン
Claude Haiku 3.5$0.80 /百万トークン$1 /百万トークン$1.6 /百万トークン$0.08 /百万トークン$4 /百万トークン
Claude Opus 3$15 /百万トークン$18.75 /百万トークン$30 /百万トークン$1.50 /百万トークン$75 /百万トークン
Claude Haiku 3$0.25 /百万トークン$0.30 /百万トークン$0.50 /百万トークン$0.03 /百万トークン$1.25 /百万トークン
参考:https://docs.anthropic.com/en/docs/about-claude/models/overview

なお、これまでにないAIエージェントでコーディングからテストまで自動化について詳しく知りたい方は、下記の記事を合わせてご確認ください。

Claude Opus 4.1の使い方

Claude Opus 4.1の使い方は簡単です。Claudeにアクセスし、右下からClaude Opus 4.1を選択すればOKです。

実際にClaude Opus 4.1とSonnet 4で比較してみます。

Sonnet 4の結果はこちら
日本の2015年から2024年までの経済成長について、最新のデータと分析を調べてみます。日本 経済成長率 GDP 2015-202410件の結果国民経済計算(GDP統計) : 経済社会総合研究所 - 内閣府cao.go.jp日本の経済成長率の推移(1980~2025年) - 世界経済のネタ帳ecodb.net日本 - GDP成長率 | 1980-2023 データ | 2024-2026 予測tradingeconomics.comMofamofa.go.jp図録▽経済成長率の推移(日本)sakura.ne.jp日本の経済成長率の推移 - 世界経済のネタ帳ecodb.net日本のGDPの推移 - 世界経済のネタ帳ecodb.net経済成長率の推移(1980~2024年)(日本, 中国, アメリカ) - 世界経済のネタ帳ecodb.net表面的な数字よりも厳しい日本経済(2024年10-12月GDP統計):賃上げではなく円安修正が経済を救うnri.com日本 | 名目GDP成長率 | 1981 – 2025 | 経済指標 | CEICceicdata.com詳細な経済成長率データと要因分析のため、さらに具体的な情報を調べます。日本の経済成長率の推移 - 世界経済のネタ帳を取得しましたecodb.net次に、日本経済の低成長の要因について詳しく調べます。日本経済 低成長 要因 人口減少 デフレ 2015-202410件の結果停滞感が強まる日本経済 ─ 本質的課題は「デフレ脱却」から供給制約へ変化 ─ | みずほリサーチ&テクノロジーズmizuho-rt.co.jp人口減少下の日本経済と財政の長期展望|NIRA総合研究開発機構nira.or.jp社会経済研究所[SERC] - マクロ経済展望:低成長が当たり前の時代にdenken.or.jp第2節 物価・賃金の動向とデフレ脱却に向けた現在地 - 内閣府cao.go.jp人口減少、高齢化は経済成長をどれだけ抑制してきたのか |ニッセイ基礎研究所nli-research.co.jp日本の経済成長率が「世界最低」である、バカバカしいほど“シンプルな理由”diamond.jpꂩ̓{̂߂ɍlmof.go.jp第2節 高齢化・人口減少の下での経済成長の展望 - 内閣府cao.go.jpQ13 デフレによってどのような問題が生じていますか|選択する未来 - 内閣府cao.go.jp2025年の日本で気にすべきは、インフレか、それともデフレか -政府はデフレを気にし、日本銀行はインフレを気にしている?- | 研究プログラム | 東京財団tkfd.or.jpさらに具体的な要因について詳しく調べます。日本 労働生産性 推移 国際比較 2015-202410件の結果労働生産性の国際比較 | 調査研究・提言活動 | 公益財団法人日本生産性本部jpc-net.jpJiljil.go.jp日本の労働生産性の動向 | 調査研究・提言活動 | 公益財団法人日本生産性本部jpc-net.jp労働生産性の国際比較2023 | 調査研究・提言活動 | 公益財団法人日本生産性本部jpc-net.jp国際比較からみた日本の労働生産性 | 一般財団法人 日本経済研究所jeri.or.jp日本生産性本部 「労働生産性の国際比較2024」を公表 日本 ...newprinet.co.jp総務省|平成30年版 情報通信白書|生産性向上の必要性soumu.go.jp【最新2024年】労働生産性のランキング国際比較 | 日本は現在何位?1位は? | ビズクロchatwork.comJpc-netjpc-net.jpデータブック国際労働比較2024|労働政策研究・研修機構(JILPT)jil.go.jp最後に、コロナ禍と最近の金融政策の影響について調べます。日本 コロナ禍 経済影響 アベノミクス 異次元緩和 2020-202410件の結果「異次元緩和」10年を振り返る(下) | 研究プログラム | 東京財団tkfd.or.jpアベノミクスの過ち(上)/異次元緩和破綻し円売りjcp.or.jp異次元緩和とは 日銀、デフレから脱却目指し2013年導入 - 日本経済新聞nikkei.com日本経済は、スタグフレーションに突入へ 異次元金融緩和政策の空回りは続いている | 慢性デフレと新型バブル | 東洋経済オンラインtoyokeizai.net停滞感が強まる日本経済 ─ 本質的課題は「デフレ脱却」から供給制約へ変化 ─ | みずほリサーチ&テクノロジーズmizuho-rt.co.jpMetimeti.go.jp異次元緩和 アベノミクス第1の矢: 日本経済新聞nikkei.com第1編 第1章 1. (2) 「異次元金融緩和」の下での景気回復 : SMBCグループ二十年史smfg.co.jp日本経済の中期見通し(2021~2030年度)~コロナ禍の教訓を活かせるかが中期的な成長力を左右する~ | 三菱UFJリサーチ&コンサルティングmurc.jp第1節 日本経済の動向と持続的な回復に向けた課題 - 内閣府cao.go.jp2025年から過去10年間(2015年~2024年)の日本の経済成長について、収集したデータと分析結果をもとに包括的に説明いたします。
日本経済の成長率推移(2015-2024年)
経済成長率の実績
2015年から2024年にかけての日本の実質GDP成長率は以下の通りです:

2015年:1.56%
2016年:0.75%
2017年:1.68%
2018年:0.64%
2019年:-0.40%
2020年:-4.17%
2021年:2.70%
2022年:0.94%
2023年:1.49%
2024年:0.08% 停滞感が強まる日本経済 ─ 本質的課題は「デフレ脱却」から供給制約へ変化 ─ | みずほリサーチ&テクノロジーズ

この10年間の平均成長率は約0.3%という非常に低い水準にとどまっています。
低成長の主要要因
1. 長期デフレとその影響
日本は1998年以降、基本的にずっとデフレ状態が続いており、これは第二次世界大戦後、世界で初めて20年を超える異例の長期デフレです ꂩ̓{̂߂ɍl。1990年代のバブル崩壊以降、企業は短期的な収益確保のため、賃金や成長の源泉である投資を抑制し、結果として消費の停滞や物価の低迷、さらには経済成長の抑制がもたらされ、我が国経済は「低物価・低賃金・低成長」という悪循環に陥っていました 人口減少、高齢化は経済成長をどれだけ抑制してきたのか |ニッセイ基礎研究所。
2. 人口減少・高齢化の構造的課題
消費者物価上昇率が3年連続で2%を上回るなど、日本経済は長年続いたデフレからは脱却したが、経済成長率は低迷が続いている 日本の経済成長率が「世界最低」である、バカバカしいほど“シンプルな理由”。ただし、日本の実質GDP成長率の長期低迷に大きく寄与しているのは、一人当たりGDP成長率の低下であり、人口減少の影響は限定的である 日本の経済成長率が「世界最低」である、バカバカしいほど“シンプルな理由”。
3. 労働生産性の低迷
2022年の日本の時間当たり労働生産性(就業1時間当たり付加価値)は、52.3ドル(5,099円/購買力平価(PPP)換算)。OECD加盟38カ国中30位だった 国際比較からみた日本の労働生産性 | 一般財団法人 日本経済研究所。データが取得可能な1970年以降、最も低い順位になっている 国際比較からみた日本の労働生産性 | 一般財団法人 日本経済研究所。
4. 需要から供給制約への課題変化
少子高齢化が進展する中で日本経済の本質的な課題が需要不足(デフレ脱却)から人手不足へと変化しつつある 人口減少下の日本経済と財政の長期展望|NIRA総合研究開発機構。個人消費を中心に需要が力強さを欠く中でも人手不足が深刻化して23~24年の高水準の賃上げにつながっている現状は、供給サイドからみた経済成長の天井がそれだけ低いことを示唆している 人口減少下の日本経済と財政の長期展望|NIRA総合研究開発機構。
政策対応とその効果
アベノミクスと異次元緩和
日銀が2013年4月から始めた大規模な金融緩和政策「異次元緩和」は、資金供給量を大幅に増やして人々の期待に働きかけ、デフレ経済からの脱却を目指した 日本経済は、スタグフレーションに突入へ 異次元金融緩和政策の空回りは続いている | 慢性デフレと新型バブル | 東洋経済オンライン。円安・株高基調をもたらし、国内景気は2012年11月を景気の谷として緩やかな回復傾向に転じ、消費者物価(総合)も2013年6月には前年同月比プラスに転じ、アベノミクスはデフレからの脱却に一定の成果を挙げた 第1節 日本経済の動向と持続的な回復に向けた課題 - 内閣府。
コロナ禍の影響
2020年の成長率は-4.17%と大幅なマイナス成長を記録しましたが、2021年には2.70%のプラス成長に回復しました 停滞感が強まる日本経済 ─ 本質的課題は「デフレ脱却」から供給制約へ変化 ─ | みずほリサーチ&テクノロジーズ。しかし、その後の回復は力強さを欠いています。
現在の状況と課題
個人消費の低迷
2024年10-12月期の実質個人消費は前期比+0.1%と下振れ、内需では実質設備投資、実質住宅投資、実質政府消費、実質公的固定資本形成も低迷した 表面的な数字よりも厳しい日本経済(2024年10-12月GDP統計):賃上げではなく円安修正が経済を救う。輸入の減少は内需の弱さの裏返しであり、成長率へのプラス寄与は一時的なものと考えられる 表面的な数字よりも厳しい日本経済(2024年10-12月GDP統計):賃上げではなく円安修正が経済を救う。
デフレ脱却への道筋
日本経済が、現在、インフレの状況にあることについては、政府も日本銀行も認識を一にする一方、再びデフレに陥るリスクの評価にある 労働生産性の国際比較 | 調査研究・提言活動 | 公益財団法人日本生産性本部。政府は依然としてデフレ脱却を完全には宣言していません。
今後の展望
求められるのは「需要不足」あるいは「デフレ脱却」への対応よりも、人手不足の深刻化が経済成長のボトルネックになることを回避するための取組みである 人口減少下の日本経済と財政の長期展望|NIRA総合研究開発機構。幅広い労働者のスキルアップや、企業のDX投資、省力化投資、研究開発への支援等を通じ、官民連携して生産性の向上に取り組むことが必要 人口減少下の日本経済と財政の長期展望|NIRA総合研究開発機構です。
この10年間の日本経済は、長期デフレからの脱却過程にありながらも、構造的な人口減少・高齢化、労働生産性の低迷、そして需要不足から供給制約への課題の変化という複合的な要因により、低成長が続いています。今後は生産性向上と人的資本投資が鍵となると考えられます。
opus 4.1の結果はこちら
日本の過去10年間(2015-2024年)の経済成長について、データと根拠を基に説明させていただきます。
経済成長の推移
実質GDP成長率の動向
日本の実質GDP成長率は、この10年間で大きな変動を経験しました:

2015-2019年:平均約0.5-1.0%の低成長が続きました。2019年は0.3%と特に低調でした
2020年:COVID-19パンデミックにより-4.1%の大幅なマイナス成長
2021年:2.6%のプラス成長に回復
2022-2024年:1.0-1.9%程度の緩やかな成長で推移

最新の2024年のデータを確認させてください。日本 GDP成長率 2024年10件の結果国民経済計算(GDP統計) : 経済社会総合研究所 - 内閣府cao.go.jp表面的な数字よりも厳しい日本経済(2024年10-12月GDP統計):賃上げではなく円安修正が経済を救うnri.com2024~2026年度経済見通しnli-research.co.jpGDP、10〜12月年率2.8%増 24年名目初の600兆円超え - 日本経済新聞nikkei.com24年名目GDP、最高の609兆円 企業投資などけん引 - 日本経済新聞nikkei.com日本 - GDP成長率 | 1980-2023 データ | 2024-2026 予測tradingeconomics.com2025~2026年度日本経済見通し(2025年3月)(2024年10-12月期GDP2次速報後改定) | 新家 義貴 | 第一生命経済研究所dlri.co.jp2024~2025年度日本経済見通し(2024年11月)(2024年7-9月期GDP1次速報後改定) | 新家 義貴 | 第一生命経済研究所dlri.co.jp2024~2025年度日本経済見通し(2024年7月)(2024年1-3月期GDP再改定値反映) | 新家 義貴 | 第一生命経済研究所dlri.co.jp2025~2026年度日本経済見通し(2025年2月)(2024年10-12月期GDP1次速報後改定) | 新家 義貴 | 第一生命経済研究所dlri.co.jp2024年の実質GDP成長率は前年比0.1%とほぼゼロ成長にとどまりました 表面的な数字よりも厳しい日本経済(2024年10-12月GDP統計):賃上げではなく円安修正が経済を救う。2024年10-12月期は前期比0.7%(年率2.8%)となりましたが、内需は前期比-0.1%と低迷し、輸入の大幅減少による外需が成長を押し上げる形となりました 表面的な数字よりも厳しい日本経済(2024年10-12月GDP統計):賃上げではなく円安修正が経済を救う。
低成長の主な要因
1. 構造的要因
人口減少と高齢化

生産年齢人口の継続的な減少により、労働力供給が制約されています
高齢化による消費構造の変化(貯蓄率の上昇、消費性向の低下)

生産性の伸び悩み

デジタル化・DXの遅れ
企業の新陳代謝の停滞
イノベーション創出力の相対的な低下

2. 循環的要因
物価高による実質所得の目減り
2024年も3%前後の消費者物価上昇率が続き、これは輸入物価上昇によるコストプッシュ型で、個人消費に逆風となっています 表面的な数字よりも厳しい日本経済(2024年10-12月GDP統計):賃上げではなく円安修正が経済を救う。
個人消費の低迷
2024年10-12月期の実質個人消費は前期比0.1%増にとどまり、年間でも前年比-0.0%とほぼ横ばいでした Nomura Research InstituteNLI Research。民間消費はコロナ禍前(2019年)の水準を0.4%下回っています 2024~2026年度経済見通し。
外部環境の変化

中国経済の減速による輸出への影響
円安による輸入物価上昇
地政学的リスクの高まり

3. 政策面での課題
金融政策の転換期

長期にわたる超低金利政策からの出口戦略
円安抑制と景気配慮のバランス

財政制約

高水準の政府債務による財政出動の制約
社会保障費の増大による政策余地の縮小

今後の展望
2025年の春闘賃上げ率は5.20%と2年連続で5%台を維持することが見込まれています 2024~2026年度経済見通し。実質GDP成長率は2024年度0.7%、2025年度0.8%、2026年度0.9%と予測されています 2025~2026年度日本経済見通し(2025年3月)(2024年10-12月期GDP2次速報後改定) | 新家 義貴 | 第一生命経済研究所。
ただし、以下のリスク要因に注意が必要です:

米国トランプ政権の関税政策:対米自動車輸出への25%関税が課される場合、実質GDPを0.1-0.3%程度押し下げる可能性があります 表面的な数字よりも厳しい日本経済(2024年10-12月GDP統計):賃上げではなく円安修正が経済を救う
物価動向:実質賃金の改善には物価上昇率の鈍化が不可欠
個人消費の回復力:賃上げが消費拡大につながるかが鍵

日本経済は潜在成長率(0%台半ば)程度の低成長が続いていますが、賃上げの継続と物価安定の実現により、緩やかな回復軌道に乗ることが期待されています。

生成速度自体はOpus 4.1の方が速かったですが、文字数の違いからOpus 4.1が先に完了したのかなと思います。

どちらの回答がより現実的かの判断は悩むところですが。Opus 4.1は米国トランプ政権の関税に関しての言及もあるため、最新の情報を含んでの回答になっていますね。

APIの使い方

google colaboratoryでAPIを使ってOpus 4.1を使う手順は下記です。

!pip install -q anthropic

サンプルコードはこちら
import anthropic
import os

os.environ["ANTHROPIC_API_KEY"] = ""

client = anthropic.Anthropic()

model_id = "claude-opus-4-1-20250805"
prompt_text = """アリスはビルより背が高く、チャーリーはアリスより背が低いです。
では、誰が一番背が高いですか?理由も説明してください。"""

response = client.messages.create(
    model=model_id,
    max_tokens=1024,
    temperature=0.3,
    messages=[
        {"role": "user", "content": prompt_text}
    ]
)

print(response.content[0].text.strip())
結果はこちら
この問題を順番に整理してみます。

与えられた情報:
1. アリスはビルより背が高い(アリス > ビル)
2. チャーリーはアリスより背が低い(チャーリー < アリス)

これらの関係から:
- アリス > ビル
- アリス > チャーリー

つまり、アリスは他の2人(ビルとチャーリー)よりも背が高いことが分かります。

ビルとチャーリーの直接的な比較はできませんが、どちらもアリスより背が低いことは確実です。

**答え:アリスが一番背が高いです。**

**理由:アリスはビルより背が高く、かつチャーリーより背が高いため、3人の中で最も背が高いことが確定します。**

APIを使う上での注意点ですが、temperatureとtop_pは同時に指定できません。

The API remains the same for Opus 4 and Opus 4.1 models, but updated API form validation in Opus 4.1 does not allow both temperature and top_p parameters to be specified. Please use only one.

Models overview

日本語訳
Opus 4およびOpus 4.1モデルではAPIの形式は同じですが、Opus 4.1ではフォームバリデーションが更新されており、temperatureとtop_pの両方を同時に指定することはできません。いずれか一方のみを使用してください。

Claude Opus 4.1とGemini 2.5 Proでコーディング性能を検証

Opus 4.1とOpus 4ではコーディング性能に大きく差がないので、Opus 4.1とGemini 2.5 Proを比較してみたいと思います。

使用するプロンプトはこちら
次の要件を満たす Python 関数群を実装してください。

### 要件
- 入力はJSON形式のファイルで、ユーザーの購買履歴が含まれている(例を下記に示します)。
- 関数 `summarize_purchases(json_path)` を作成し、以下のような処理を行ってください:
  1. 各ユーザーごとに、合計購入金額を算出。
  2. 購入回数の多い順にユーザーを並べて返す。
  3. ファイル読み込みエラーやフォーマットエラーがあれば丁寧に処理する。

### 入力例(JSONファイル)
```json
[
  {"user": "alice", "item": "apple", "price": 120},
  {"user": "bob", "item": "banana", "price": 80},
  {"user": "alice", "item": "milk", "price": 200}
]
Opus 4.1の結果はこちら
import json
from typing import Dict, List, Tuple, Optional
from pathlib import Path


def summarize_purchases(json_path: str) -> Optional[List[Tuple[str, Dict[str, any]]]]:
    """
    JSONファイルから購買履歴を読み込み、ユーザーごとの統計情報を返す
    
    Args:
        json_path: 購買履歴JSONファイルのパス
    
    Returns:
        購入回数の多い順に並んだユーザー情報のリスト
        各要素は (ユーザー名, {'total_amount': 合計金額, 'purchase_count': 購入回数}) のタプル
        エラーの場合はNone
    """
    try:
        # ファイルの存在確認
        if not Path(json_path).exists():
            print(f"エラー: ファイル '{json_path}' が見つかりません。")
            return None
        
        # JSONファイルの読み込み
        with open(json_path, 'r', encoding='utf-8') as f:
            data = json.load(f)
        
        # データ形式の検証
        if not isinstance(data, list):
            print("エラー: JSONデータはリスト形式である必要があります。")
            return None
        
        # ユーザーごとの集計
        user_stats = {}
        
        for i, record in enumerate(data):
            # レコードの検証
            if not isinstance(record, dict):
                print(f"警告: {i+1}番目のレコードが辞書形式ではありません。スキップします。")
                continue
            
            # 必須フィールドの確認
            if 'user' not in record or 'price' not in record:
                print(f"警告: {i+1}番目のレコードに必須フィールド(user, price)がありません。スキップします。")
                continue
            
            user = record['user']
            
            # 価格の検証
            try:
                price = float(record['price'])
                if price < 0:
                    print(f"警告: {i+1}番目のレコードの価格が負の値です。スキップします。")
                    continue
            except (TypeError, ValueError):
                print(f"警告: {i+1}番目のレコードの価格が数値ではありません。スキップします。")
                continue
            
            # ユーザー統計の更新
            if user not in user_stats:
                user_stats[user] = {
                    'total_amount': 0,
                    'purchase_count': 0,
                    'items': []
                }
            
            user_stats[user]['total_amount'] += price
            user_stats[user]['purchase_count'] += 1
            if 'item' in record:
                user_stats[user]['items'].append(record['item'])
        
        # 結果が空の場合
        if not user_stats:
            print("警告: 有効な購買データが見つかりませんでした。")
            return []
        
        # 購入回数の多い順にソート
        sorted_users = sorted(
            user_stats.items(),
            key=lambda x: (x[1]['purchase_count'], x[1]['total_amount']),
            reverse=True
        )
        
        return sorted_users
        
    except json.JSONDecodeError as e:
        print(f"エラー: JSONファイルの解析に失敗しました。\n詳細: {e}")
        return None
    except PermissionError:
        print(f"エラー: ファイル '{json_path}' への読み取り権限がありません。")
        return None
    except Exception as e:
        print(f"予期しないエラーが発生しました: {e}")
        return None


def display_summary(summary: Optional[List[Tuple[str, Dict[str, any]]]]) -> None:
    """
    購買サマリーを見やすく表示する
    
    Args:
        summary: summarize_purchases関数の戻り値
    """
    if summary is None:
        print("サマリーを表示できません。")
        return
    
    if not summary:
        print("表示するデータがありません。")
        return
    
    print("\n" + "="*60)
    print("購買履歴サマリー(購入回数順)")
    print("="*60)
    
    for rank, (user, stats) in enumerate(summary, 1):
        print(f"\n{rank}. ユーザー: {user}")
        print(f"   合計購入金額: ¥{stats['total_amount']:,.0f}")
        print(f"   購入回数: {stats['purchase_count']}回")
        print(f"   平均購入金額: ¥{stats['total_amount']/stats['purchase_count']:,.0f}")
        if stats['items']:
            print(f"   購入商品: {', '.join(stats['items'][:5])}", end="")
            if len(stats['items']) > 5:
                print(f" 他{len(stats['items'])-5}点")
            else:
                print()


def get_top_customers(summary: Optional[List[Tuple[str, Dict[str, any]]]], n: int = 3) -> List[str]:
    """
    購入回数上位nユーザーのリストを返す
    
    Args:
        summary: summarize_purchases関数の戻り値
        n: 取得する上位ユーザー数
    
    Returns:
        上位ユーザー名のリスト
    """
    if not summary:
        return []
    
    return [user for user, _ in summary[:n]]


def get_user_statistics(summary: Optional[List[Tuple[str, Dict[str, any]]]], username: str) -> Optional[Dict[str, any]]:
    """
    特定ユーザーの統計情報を取得
    
    Args:
        summary: summarize_purchases関数の戻り値
        username: 検索するユーザー名
    
    Returns:
        ユーザーの統計情報、見つからない場合はNone
    """
    if not summary:
        return None
    
    for user, stats in summary:
        if user == username:
            return stats
    return None


# 使用例とテスト
if __name__ == "__main__":
    # テスト用のJSONファイルを作成
    test_data = [
        {"user": "alice", "item": "apple", "price": 120},
        {"user": "bob", "item": "banana", "price": 80},
        {"user": "alice", "item": "milk", "price": 200},
        {"user": "charlie", "item": "bread", "price": 150},
        {"user": "bob", "item": "eggs", "price": 180},
        {"user": "alice", "item": "cheese", "price": 300},
        {"user": "david", "item": "coffee", "price": 500},
        {"user": "bob", "item": "yogurt", "price": 120}
    ]
    
    # テストファイルを作成
    test_file = "test_purchases.json"
    with open(test_file, 'w', encoding='utf-8') as f:
        json.dump(test_data, f, ensure_ascii=False, indent=2)
    
    print("テストファイルで実行:")
    
    # メイン関数の実行
    result = summarize_purchases(test_file)
    
    # 結果の表示
    display_summary(result)
    
    # その他の関数のテスト
    print("\n" + "="*60)
    print("追加機能のテスト")
    print("="*60)
    
    top_customers = get_top_customers(result, 2)
    print(f"\n上位2ユーザー: {top_customers}")
    
    alice_stats = get_user_statistics(result, "alice")
    if alice_stats:
        print(f"\naliceの詳細統計:")
        print(f"  合計: ¥{alice_stats['total_amount']:,.0f}")
        print(f"  回数: {alice_stats['purchase_count']}回")
    
    # エラーケースのテスト
    print("\n" + "="*60)
    print("エラーハンドリングのテスト")
    print("="*60)
    
    print("\n1. 存在しないファイル:")
    summarize_purchases("nonexistent.json")
    
    print("\n2. 不正なJSON形式のテスト:")
    with open("invalid.json", 'w') as f:
        f.write("{invalid json}")
    summarize_purchases("invalid.json")
    
    print("\n3. 不正なデータ形式のテスト:")
    with open("wrong_format.json", 'w') as f:
        json.dump({"not": "a list"}, f)
    summarize_purchases("wrong_format.json")
    
    # クリーンアップ
    import os
    for file in [test_file, "invalid.json", "wrong_format.json"]:
        if os.path.exists(file):
            os.remove(file)
    
    print("\nテスト完了!")
Gemini 2.5 Proの結果はこちら
### 実装コード

```python
import json
from collections import defaultdict

def summarize_purchases(json_path: str):
    """
    JSONファイルから購買履歴を読み込み、ユーザーごとの合計購入金額と
    購入回数を集計し、購入回数の多い順にソートして返します。

    Args:
        json_path (str): 購買履歴が記録されたJSONファイルのパス。

    Returns:
        list | None: 成功した場合は、各ユーザーの情報(ユーザー名、合計金額、購入回数)が
                      購入回数の多い順に並んだリストを返します。
                      エラーが発生した場合はNoneを返します。
    """
    try:
        with open(json_path, 'r', encoding='utf-8') as f:
            purchases = json.load(f)
            # 入力がリスト形式であることを確認
            if not isinstance(purchases, list):
                print(f"エラー: JSONのトップレベルはリストである必要があります。")
                return None

    except FileNotFoundError:
        print(f"エラー: ファイルが見つかりません: {json_path}")
        return None
    except json.JSONDecodeError:
        print(f"エラー: ファイルのJSON形式が正しくありません: {json_path}")
        return None
    except Exception as e:
        print(f"予期せぬエラーが発生しました: {e}")
        return None

    # ユーザーごとのデータを集計
    # defaultdictを使うと、キーが存在しない場合の初期化処理を簡潔に書けます。
    user_summary = defaultdict(lambda: {'total_price': 0, 'purchase_count': 0})

    for purchase in purchases:
        # 必要なキーが存在するかチェック
        if not all(k in purchase for k in ['user', 'price']):
            print(f"警告: 必要なキー('user', 'price')が含まれていないレコードをスキップします: {purchase}")
            continue
        
        user = purchase['user']
        price = purchase['price']

        # 金額が数値であることを確認
        if not isinstance(price, (int, float)):
            print(f"警告: 'price'が数値でないレコードをスキップします: {purchase}")
            continue

        user_summary[user]['total_price'] += price
        user_summary[user]['purchase_count'] += 1

    # 集計結果を購入回数の多い順に並べ替え
    # sorted関数のkeyにラムダ式を使い、purchase_countで降順ソートします。
    sorted_users = sorted(user_summary.items(), key=lambda item: item[1]['purchase_count'], reverse=True)

    # 返り値を整形
    result = [
        {
            'user': user,
            'total_price': data['total_price'],
            'purchase_count': data['purchase_count']
        }
        for user, data in sorted_users
    ]

    return result

```

-----

### 実行方法

1.  **サンプルJSONファイルの作成**
    まず、`purchases.json` という名前で以下の内容のファイルを作成します。

    **purchases.json**

    ```json
    [
      {"user": "alice", "item": "apple", "price": 120},
      {"user": "bob", "item": "banana", "price": 80},
      {"user": "alice", "item": "milk", "price": 200},
      {"user": "carol", "item": "bread", "price": 180},
      {"user": "bob", "item": "juice", "price": 150},
      {"user": "alice", "item": "egg", "price": 220},
      {"user": "carol", "item": "cheese", "price": 300},
      {"user": "bob", "item": "water", "price": 100},
      {"user": "alice", "item": "vegetable", "price": 250}
    ]
    ```

2.  **Pythonスクリプトの実行**
    次に、上記のPython関数を `main.py` などのファイル名で保存し、同じディレクトリで以下のコードを実行します。

    **main.py**

    ```python
    # 上記で実装した summarize_purchases 関数をここに貼り付ける

    if __name__ == "__main__":
        file_path = 'purchases.json'
        summary_data = summarize_purchases(file_path)

        if summary_data:
            print("--- ユーザー別購買サマリー(購入回数順) ---")
            for user_data in summary_data:
                print(
                    f"ユーザー: {user_data['user']:<8} "
                    f"合計金額: ¥{user_data['total_price']:<5} "
                    f"購入回数: {user_data['purchase_count']}回"
                )

        print("\n--- エラーハンドリングのテスト ---")
        # 存在しないファイル
        summarize_purchases('non_existent_file.json')
        # 不正なJSON
        with open('invalid.json', 'w') as f:
            f.write('[{"user": "test", "price": 100},]') #末尾にカンマがある不正な形式
        summarize_purchases('invalid.json')

    ```

### 実行結果

上記の `main.py` を実行すると、以下のような出力が得られます。

```
--- ユーザー別購買サマリー(購入回数順) ---
ユーザー: alice    合計金額: ¥790   購入回数: 4回
ユーザー: bob      合計金額: ¥330   購入回数: 3回
ユーザー: carol    合計金額: ¥480   購入回数: 2回

--- エラーハンドリングのテスト ---
エラー: ファイルが見つかりません: non_existent_file.json
エラー: ファイルのJSON形式が正しくありません: invalid.json
```

Gemini 2.5 Proは実際の実行結果まで出力してくれてますが、Opus 4.1の出力結果はありませんでした。

Opus 4.1を実際に実行した結果はこちら。

Opus 4.1の出力結果はこちら
テストファイルで実行:

============================================================
購買履歴サマリー(購入回数順)
============================================================

1. ユーザー: alice
   合計購入金額: ¥620
   購入回数: 3回
   平均購入金額: ¥207
   購入商品: apple, milk, cheese

2. ユーザー: bob
   合計購入金額: ¥380
   購入回数: 3回
   平均購入金額: ¥127
   購入商品: banana, eggs, yogurt

3. ユーザー: david
   合計購入金額: ¥500
   購入回数: 1回
   平均購入金額: ¥500
   購入商品: coffee

4. ユーザー: charlie
   合計購入金額: ¥150
   購入回数: 1回
   平均購入金額: ¥150
   購入商品: bread

============================================================
追加機能のテスト
============================================================

上位2ユーザー: ['alice', 'bob']

aliceの詳細統計:
  合計: ¥620
  回数: 3回

============================================================
エラーハンドリングのテスト
============================================================

1. 存在しないファイル:
エラー: ファイル 'nonexistent.json' が見つかりません。

2. 不正なJSON形式のテスト:
エラー: JSONファイルの解析に失敗しました。
詳細: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

3. 不正なデータ形式のテスト:
エラー: JSONデータはリスト形式である必要があります。

どちらも適切にユーザー指示を守ってくれていますが、Opus 4.1の方が詳細にコードを書いてくれていますね。ここの好みは人によって変わってきそうです。

なお、Claude最新AIエージェントの使い方・作り方を徹底解説について詳しく知りたい方は、下記の記事を合わせてご確認ください。

まとめ

本記事では、Opus 4.1の概要から使い方、実際に使ってみた所感をお伝えしました。

Gemini 2.5ProやSonnet 4と比較してみましたが、コーディングについては処理が丁寧という印象を受けました。

また、推論に関してはモデルが最新だからか最新のニュースにも触れて推論を行ってくれていました。使用制限がなければOpus 4.1を使うのが良いなと感じます。

ぜひ皆さんも本記事を参考にOpus 4.1を使ってみてください!

最後に

いかがだったでしょうか?

自社業務や開発環境に最適な導入方法について、専門スタッフが無料でご相談を承ります。お気軽にどうぞ。

株式会社WEELは、自社・業務特化の効果が出るAIプロダクト開発が強みです!

開発実績として、

・新規事業室での「リサーチ」「分析」「事業計画検討」を70%自動化するAIエージェント
・社内お問い合わせの1次回答を自動化するRAG型のチャットボット
・過去事例や最新情報を加味して、10秒で記事のたたき台を作成できるAIプロダクト
・お客様からのメール対応の工数を80%削減したAIメール
・サーバーやAI PCを活用したオンプレでの生成AI活用
・生徒の感情や学習状況を踏まえ、勉強をアシストするAIアシスタント

などの開発実績がございます。

生成AIを活用したプロダクト開発の支援内容は、以下のページでも詳しくご覧いただけます。
➡︎株式会社WEELのサービスを詳しく見る。

まずは、「無料相談」にてご相談を承っておりますので、ご興味がある方はぜひご連絡ください。
➡︎生成AIを使った業務効率化、生成AIツールの開発について相談をしてみる。

大規模言語モデル(LLM)比較レポート
LLM比較レポート

「生成AIを社内で活用したい」「生成AIの事業をやっていきたい」という方に向けて、生成AI社内セミナー・勉強会をさせていただいております。

セミナー内容や料金については、ご相談ください。

また、大規模言語モデル(LLM)を対象に、言語理解能力、生成能力、応答速度の各側面について比較・検証した資料も配布しております。この機会にぜひご活用ください。

投稿者

  • WEEL Media部

    株式会社WEELが運営する生成系AI関連メディア「生成AI Media」は、AIの専門家によるWebメディアです。 AIに特化した編集部がAIの活用方法、導入事例、ニュース、トレンド情報を発信しています。

  • URLをコピーしました!
  • URLをコピーしました!
目次