Pepabo Tech Portal

https://tech.pepabo.com/

GMOペパボのエンジニア・デザイナーによる技術情報のポータルサイト

フィード

記事のアイキャッチ画像
プロンプトのtypoをCIで弾く ── TypeScriptの型でAIへの指示を守る
はてなブックマークアイコン 1
Pepabo Tech Portal
はじめにこんにちは。ロリポップ・ムームードメイン事業部でエンジニアリングリードをしています kinosuke01 といいます。先日ゴジラ-0.0のティザー映像が解禁されましたね。公開が楽しみです。さて、GMOペパボでは、ユーザーとの対話をもとにWebサイトをまるごと自動生成するAIサイトエージェントを提供しています。ユーザーが「カフェのサイトを作りたい」「コーポレートサイトがほしい」と伝えるだけで、ページ構成からデザインテーマ、コンテンツまでを一括で生成し、すぐに公開できるWebサイトを作り上げます。この仕組みの裏側では、Webサイトの構造をすべてJSONで表現しています。生成AIに対して「このJSONを埋めてください」と指示し、Structured Outputでフォーマットを固定することで、安定した出力を得ています。しかし、JSONの構造を固定するだけでは不十分でした。各プロパティに何を入れるべきかを正しく伝えるために、システムプロンプトでフィールドごとの説明を与えています。ここで問題になったのが、プロンプトに書いたプロパティ名と実際のコードの型定義がズレるリスクです。この記事では、TypeScriptの型システムを活用してプロンプトの正しさをコンパイル時に保証する仕組みを紹介します。サイト生成の仕組みJSONでWebサイトを表現する私たちのシステムでは、Webサイトを「セクション」の組み合わせで表現しています。ヒーローセクション、特徴紹介セクション、料金表セクションなど、複数のセクションを用意しており、それぞれがJSON構造を持ちます。たとえば、ヒーローセクションはこのような構造です。{ "component": "HeroSection", "props": { "headline": { "text": "想いを、かたちに。" }, "title": { "text": "あなたの「やりたい」を実現するために" }, "primaryButton": { "label": "お問い合わせ", "href": "/contact" }, "layout": "split-content-image", "image": { "imageId": "hero-1", "alt": "メインビジュアル" } }}3つのエージェントによる段階的な生成サイト生成は、
15時間前
記事のアイキャッチ画像
flaky testの原因は、無関係なファイルの1行にあった
はてなブックマークアイコン 1
Pepabo Tech Portal
SUZURI Webアプリケーションエンジニアのarumaです。昨日の記事では、SUZURIで遭遇したflaky testの事例をいくつかご紹介しました。本記事では、その中でも特に原因の特定が難しかった1件を深掘りします。発生していた現象手がかり1: 自前のメソッドが呼ばれていない手がかり2: フレームワークに同名メソッドが追加されていた手がかり3: ancestorsチェーンの順序が変わっている手がかり4: トップレベルでのinclude真相おわりに発生していた現象ApplicationHelper に定義された画像表示用のヘルパーメソッド picture_tag のテストが、時々failしていました。fail時のログを確認すると、picture_tag が期待と異なるHTMLを生成していました。CIの実行ログからpass時とfail時それぞれのseed値を確認し、ローカルで同じseedを指定して実行してみると、seed値に応じてpassとfailが再現しました。手がかり1: 自前のメソッドが呼ばれていない試しに ApplicationHelper#picture_tag の中身に raise を加えてそれぞれのseedで実行してみると、passしていたseedで実行 → 例外が発生failしていたseedで実行 → 例外は発生せず、同じようにfailという結果になりました。つまり、failするseedでは、テスト対象 ApplicationHelper#picture_tag がそもそも呼ばれていないということです。では、代わりに何が呼ばれているのでしょうか?手がかり2: フレームワークに同名メソッドが追加されていたpicture_tag で検索してみると、Rails 7.1で ActionView::Helpers::AssetTagHelper に同名の picture_tag メソッドが新規追加されていたことがわかりました。ApplicationHelper#picture_tag とは異なる動作をするメソッドです。fail時の出力は、この AssetTagHelper#picture_tag の動作と一致していました。failするseedでは、ApplicationHelper#picture_tag ではなく AssetTagHelper#pictur
3日前
記事のアイキャッチ画像
シニアエンジニア所信表明 — レバレッジと横断性で事業やサービスが向かうべき先に未来を作る
はてなブックマークアイコン 1
Pepabo Tech Portal
こんにちは!ロリポップ・ムームードメイン事業部ムームードメイングループのはるおつ(@haruotsu_hy)です。2026年4月1日にシニアエンジニアになりました。このエントリーでは、シニアエンジニアとしてこれから何をしていくのかを、ここに至るまでの経緯とあわせて書きます。所信表明シニアエンジニアとして、レバレッジの効く開発と横断的な行動を武器に、目の前の課題を技術構造ごと解き、事業やサービスが向かうべき先に未来を作る。その成果を全社・業界を動かすレベルまで広げていきます。レバレッジの効く開発とは、一つの技術投資が時間軸・組織軸・技術軸で複数の価値を生む開発です。個別の問題を個別に解くのではなく、構造的に解く。目の前のタスクの背後にある構造を変えることで、まだ見えていない未来の課題まで同時に解決する。横断的な行動とは、価値を届けるために自分から境界を越えに行くということです。技術領域も、組織も、職域も関係ない。価値があるなら自分のチームに閉じさせず、どこまでも持っていく。境界を一つ越えるたびに、同じ投資の効果が倍になっていく。レバレッジで一つの投資の価値を最大化し、横断性でその価値の届く範囲を最大化する。この掛け算で、事業が向かうべき方向に対して技術の力で道を作る。それが私のエンジニアリングです。ペパボのエンジニア職位制度GMOペパボのエンジニア職位制度は立候補制です。「作り上げる力」「先を見通す力」「影響を広げる力」の3軸で評価され、基準を超えた人が立候補資料を提出して昇格の判断を受けます(詳細)。判断は「追認制」、つまりすでに実質その等級として振る舞えている人だけが昇格します。これまで私は2024年4月、新卒年収710万プログラムのエンジニアとしてペパボに入社しました。プログラムの導入背景にあるように、尖った技術力や専門性を幹にしながら複数の枝を生やし、すべてを自分ごと化しながら高いモチベーションと覚悟でチャレンジしていくことが求められる採用枠です。その期待に応えるべく、ペパボの「やっていき・のっていき」文化の「いいじゃん!」に背中を押されながら、同期や先輩パートナーとともに、速度感をもってありとあらゆることに挑戦し時には職種を超えて社内外で注目される活動を重ねてきたように思います。しかし、2025年8月に行った1度目の立候補では、シニアエンジニアになることは叶
3日前
記事のアイキャッチ画像
SUZURIで遭遇したflaky testの事例集
Pepabo Tech Portal
SUZURI Webアプリケーションエンジニアのarumaです。SUZURIにはRSpecによるテストコードが多数ありますが、一時期flaky testが増えてCIが不安定になってしまったことがありました。まとめて調査・対処した際の記録から、いくつかの事例をピックアップしてご紹介します。なお、記事中のコードは説明のために簡略化したものです。事例1: 2026年になると失敗するテスト事例2: 深夜0時ちょうどにのみ失敗するテスト事例3: 保証のない順序に依存していたテスト事例4: 不正なテストデータが作られていたテスト事例5: 偶然の一致で失敗するテスト番外編: そもそも実行されていなかったテストおわりに事例1: 2026年になると失敗するテストこれは厳密にはflaky testというより「ある時点から必ず失敗するようになったテスト」ですが、テストの書き方に共通する教訓があるので紹介します。クレジットカード決済に関するテストのセットアップ内で、カードの有効期限がハードコードされていました。let(:credit_card) do create( :credit_card, expire_year: 2025, expire_month: 12 )endこのコードが書かれたのは2020年。5年間は問題なく動いていましたが、2026年を迎えた途端に有効期限切れの無効なカードとなり、テストの検証対象とは無関係な理由でエラーが発生するようになってしまいました。対処として、有効期限が常に未来の日付となるよう、現在の日付から算出する形に変更しました。let(:credit_card) do create( :credit_card, expire_year: Time.zone.today.year + 1, expire_month: 12 )end似た話として、travel_to で固定した時刻がSQLの now() には反映されないために、テストとDBで時刻がずれていたケースもありました。travel_to はRubyプロセス内の時刻を差し替えるだけなので、DBの now() には効きません。これも月をまたいで初めて顕在化しました。時間の経過でテストの前提が崩れないようにすることが大切です。事例2: 深夜0時ちょうどにのみ失敗するテスト夜間に自動作成されるPRだけなぜか時々
4日前
記事のアイキャッチ画像
「技術で事業の成長曲線を変える」── 事業成長を軸に働くエンジニアがGMOペパボを選んだ理由
はてなブックマークアイコン 1
Pepabo Tech Portal
2026年3月、SREチームに新しいメンバーが加わりました。事業会社で約5年間、バックエンド開発からアーキテクチャ設計、開発リードまで幅広く経験してきたtokaiさん。技術力だけでなく「事業と数字に向き合う姿勢」を自身の核に据えるエンジニアがなぜ次の活躍の場としてGMOペパボを選んだのか、そのキャリア観はどのように形成されたのか。これまでの歩みとともにお話を伺いました。偶然から始まったエンジニア人生──エンジニアを目指そうと思ったきっかけを教えてください大学4年のとき、1年間休学して海外でインターンをしていました。オフショア企業で日本人のPMと現地エンジニアをつなぐブリッジのような役割を担っていたのですが、そこで初めてコードに触れたのがきっかけです。もともと親族が建築会社を経営していたこともあり「ものづくり」への漠然とした憧れはずっとありました。プログラミングはそこに通じる感覚があって、一気にのめり込んでいきました。競技プログラミングにも触れていて、問題を解いていくゲーム性も相まって、どんどん面白くなっていった記憶があります。小さな組織で、全部やる──新卒の際、どのような軸(基準)で会社を選ばれたのですか?正直に言うと、当時業界軸ではあまり考えておらず、当時は事業ドメインへの関心もほとんどなくて、使っている技術スタックが面白そうだな、くらいの感覚で企業を見ていました。ただ「エンジニア組織が小さいところで、何でもやれる環境がいい」という軸は明確にありました。内定をいくつかいただいた中で、エンジニアが最も少ない会社を選んでいます。実際、入社した企業は、当時エンジニアは20人に満たず、私は新卒エンジニアの第1期生でした。バックエンド担当として入りましたが、インフラもやればフロントも触る。必要なら事業部との折衝まで――とにかく自走するしかない環境でした。最初の3年間は正直、自身の力不足もあって事業への手触り感はほとんどなかったです。ただ、とにかくいろんなことをやらせてもらえました。振り返れば、あの環境が今のエンジニアとしての土台になっています。転機になった「事業の早期撤退」──新卒として入社した企業には5年近く在籍されたと思うのですが、その中で印象的なエピソードはありますか?2年目に新規プロジェクトのアーキテクチャ設計からアプリケーション開発までゼロベースで任せてもらいまし
5日前
記事のアイキャッチ画像
シニアエンジニア所信表明 — AIを使うから、AIに使ってもらうへ
はてなブックマークアイコン 1
Pepabo Tech Portal
SUZURI・minne事業部の渡辺(@ae14watanabe)です。2026年4月にシニアエンジニアとなりました。自己紹介を兼ねてこれまでの自分の取り組みを簡単に紹介します。その上で、これから何をしていくのかを述べ、所信表明とします。これまで:サービスがAIを使う私は自身の専門領域を「AIが関わるサービスの開発」とし、これまでSUZURI byGMOペパボにおいて、AI(LLMをはじめとする機械学習モデル)を導入した機能の開発を複数行ってきました。具体的な取り組みについてはこちらの資料にまとめていますが、一例を挙げると、商品の規約違反チェックをAIで自動化するプロジェクトをリードしてきました。AIを導入した機能開発と、そうでない開発の根本的な違いは、不確実性の有無にあります。従来のソフトウェアは書いた通りに動きます。バグがなければ期待通りの結果を決定的に返します。一方でAIは、入力のわずかな違いで出力が変わりうる、複雑な判断を求められるほど完璧な結果は期待できない、といった性質があり、不確実性が常につきまといます。この不確実性をハンドリングすることが自分の仕事だと考えています。ハンドリングとしてやってきたことは大きく2つあります。1つ目はAIへの入力を設計し、評価し、改善するサイクルを回すことです。規約違反チェックの例でいえば、違反ジャンルを網羅したデータセットを構築してAIの判断を定量評価しました。さらに、CSチームが現場で見つけた誤判定のフィードバックも踏まえて改善サイクルを回してきました。2つ目は、AIの誤りを許容できるフローの構築です。AIは間違える前提で、ユーザ・サービス・運営者それぞれのレイヤーで誤りを吸収できる仕組みを設計してきました。これから:AIにサービスを使ってもらうしかし最近、自分が「AIが関わるサービス」をかなり狭く捉えていたのではないか、と思うようになりました。自分がやってきたのは「サービスがAIを使うこと」でした。構造としては「ユーザ ↔ サービス ↔ AI」——サービスがAIを呼び出し、その結果をサービスが受け取ってユーザに届ける形です。一方で、もうひとつの構造があります。「ユーザ ↔ AI ↔ サービス」——AIエージェントがMCPやCLIを通じてサービスをツールとして使う形です。たとえば今、Claude Codeのようなコーディ
8日前
記事のアイキャッチ画像
シニアエンジニア所信表明 - 不変条件を見極めて、システムを組み替える
はてなブックマークアイコン 1
Pepabo Tech Portal
EC事業部の古殿(@furudono2)です。ペパボでシニアエンジニアに昇格しました。この記事では、私がどのような関心を持ち、今後どのように取り組んでいくかを紹介します。これまで学生の頃はプログラミング言語の意味論を研究していました。どのようなプログラミング言語の定義をすると、どのような不変条件がプログラムに生まれ、プログラミングを頑強にするかを議論してきました。この頃の関心と今の仕事には共通するものがあると考えています。どちらも、あるシステムの上で期待される営みを見定め、それがうまく進むための制約を設計する仕事です。私はこの種の問題を解くことに楽しさと価値を感じています。2023年に入社してからは、この関心に沿った仕事をしてきました。新規サービスの立ち上げ、サービス間で共通するID・決済機能の基盤設計、大規模メールリレーシステムの移設など、いずれも特定のレイヤに閉じず横断的に課題を捉える仕事です。議論の対象は技術の話からそれを用いたソフトウェアや、ソフトウェアを組み合わせて提供するサービスへと広がってきました。所信EC事業部のシステムには、長年の積み重ねによる制約がいくつかあります。たとえばサービスを支える複数のロール(管理画面とAPI)の責務境界が歴史的に曖昧になっていたり、古い文字コードへの依存が広範に残っていたりします。こうした制約は、提供できる機能の幅や日々の開発速度に影響を与えています。これらが今日まで解きほぐされずに残っているのには理由があると考えています。何が本当に守らなければならない制約なのかを見抜くことは難しく、見抜いた上でそれを実際のコードやデータに反映させるには膨大な労力が要るからです。過去に取り組んだ人がいなかったのではなく、取り組むコストが割に合いづらい性質の課題だったのだと考えています。生成AIエージェントの登場によって、広範囲にわたるコードやデータの変更、あるいは依存関係や情報の欠落を洗い出す調査といった、かつて膨大な手作業を要した仕事を、現実的なコストで進められるようになってきたのではないかと考えています。もっとも、AIを使えば何でも解けるわけではありません。システムに何が本当に守らなければならない不変条件があるのかは、まだ人間が見抜く必要があるように感じています。そして、その不変条件を満たし続けるようにシステムの変更を組み立ててい
8日前
記事のアイキャッチ画像
minneリワードを支えるマルチクラウドアーキテクチャ
はてなブックマークアイコン 1
Pepabo Tech Portal
はじめにminneでは、アプリでミッションを達成したり、広告を見ることでminneコインが無料で貯まる機能「minneリワード」をリリースしました。minneリワードには昨年リリースされた作家・ブランドへの応援ミッションの他に、「アプリを起動する」「注目の特集をチェック」といったデイリーミッション、応援・購入回数に応じた累積ミッションが用意されています。ミッションを達成し動画広告を視聴すると、minneコインが付与される仕組みです。【予告】お買い物がちょっとお得になる「minneリワード」が3月に登場✨アプリでミッションを達成し、広告を見るとコインがもらえます🎁貯めたコインは、ポイントに交換してお買い物に使えます!… pic.twitter.com/xp955ifPQ9— minne byGMOペパボ(ミンネ) (@minnecom) February 20, 2026本記事では、マルチクラウド構成でのゲーミフィケーション機能を実現するにあたっての設計判断と、実際に運用する上で直面した課題・解決策を紹介します。はじめにminneリワードの全体像クライアント起点の実績集計を採用しなかった理由なぜマルチクラウドになったのか設計判断のポイント 1. Firestoreのドキュメント構造:ユーザー起点 vs 日付起点2. DynamoDB GSIシャーディングによるホットパーティション回避3. SQSを介した非同期書き込み4. 2フェーズコイン付与による不正防止5. GraphQLにおけるインターフェース分離パターン累積ミッションの設計:新しいデータストアを作らない判断見積もりと開発体制まとめminneリワードの全体像minneリワードは、大きく二種類のミッションで構成されています。デイリーミッション: 毎日リセットされ、「アプリを起動する」「注目の特集をチェック」といったタスクをこなすと達成されるミッション累積ミッション: 「作品を10回購入する」「応援スタンプを10回送る」のように、長期的な利用で達成されるミッションミッション達成後にユーザーが動画広告を視聴すると、minneコインが付与されます。このコインはminneでのお買い物に利用できるminneポイントに変換することができます。全体の処理は大きく4つのフェーズに分かれます。ミッション進捗の記録: ユーザーの行動...
8日前
記事のアイキャッチ画像
RubyKaigi 2026が近いのでローカルオーガナイザーが函館のご飯を紹介します
はてなブックマークアイコン 24
Pepabo Tech Portal
RubyKaigi 2026の開催が近づいてまいりましたが、皆様いかがお過ごしでしょうか。EC事業部のakatsuuraです。インターネットでは@UVB_76として生きています。私は生まれてから学生のころまで函館で過ごしており、その縁で今年のRubyKaigiのローカルオーガナイザーとして活動をしています。去年の年末辺りから何度か函館に帰りつつ、地元のローカルオーガナイザーと顔を合わせたり、会場の下見や現地の業者さまと打ち合わせを行って来ました。そしてその合間で様々な飲食店に行って食べ歩きをしてきました。この記事では直近函館に帰った際に自腹で食べ歩きをした飲食店を紹介していきます。RubyKaigi会期中の昼食、夜の野良ドリンクアップや夕食、After Partyの帰りの夜食やDay4以降など、それぞれの場面で参考にしていただければ幸いです。夜に行きたいたちか屋下見の際に地元の方に紹介してもらったお店です。五稜郭のエリアに存在していて、店内にはカウンターと座敷席が用意されています。私が行ったときにはおすすめとしてホッキ貝のお刺身とごっこの唐揚げがメニューにあり、日本酒と合わせて美味しくいただきました。煙が目にしみる五稜郭の繁華街の奥にあるダイニングバーです。料理のメニューが豊富で二次会以降に食べたりなかった場合にも便利かもしれません。個人的にはラーメンサラダがおすすめです。締めに行きたいらーめん ひらき家いくつか店舗があるのですが、私が行ったのは五稜郭、本町の元祖 ひらき家でした。深夜までやっているので締めにどうぞ。笑てん函館駅前で締めを探して行き着いたのがこのお店でした。塩ラーメンは函館の塩らしいスッキリしたスープで、私はかなり好みでした。深夜でも地元の人が店の外に待ち列を作る人気店のようです。赤い風車通称「赤風」。今回の下見で初めてお店の存在を知ったのですが、なかなかインパクトがあるお店でした。メニューが豊富で、ハンバーグやパスタなどの洋食メニューは一通り揃っています。30時までやっているので、いつ行っても安心ですね(寝坊には気をつけましょう)。お昼に行きたいコーヒーショップきくちRubyKaigiの会場から徒歩15分程度でいける昭和の香りが残る喫茶店です。某北海道ローカル番組のソフトクリーム3本勝負の舞台で、現在もテイクアウトをやっているようです。ランチブレイ
8日前
記事のアイキャッチ画像
ビジネスロジックのSQL化——セール進捗管理をdbtで再設計する
Pepabo Tech Portal
技術部データ基盤チームの新飼(shinkai)です。データ基盤チームでは、技術部の「Agent Ready」方針に基づき、事業部が意思決定に集中できるデータ環境の整備を進めています。今回はその実践として、オリジナルグッズの作成・販売サービス「SUZURI」のセール運用において、スプレッドシートに閉じていたビジネスロジックをdbtで構造化し、CSV1行の入力で目標・実績の全指標を自動算出できるようにした取り組みを紹介します。背景SUZURIでは年間を通じて複数回のセールを実施しています。セール期間中は目標に対する進捗(売上・流通額等)を毎日確認する必要があります。データはBigQueryにありますが、売上の算出ロジックはスプレッドシートの関数に組まれていました。そのため毎日の数値確認には「BIツールからCSVエクスポート → スプレッドシートに転記 → 関数で再計算」という手作業が必要でした。何を自動化し、何を残すか最初に考えたのは、事業部とデータ基盤の役割分担です。スプレッドシートで行われていた作業のうち、確定した目標値に基づく算出処理(日別配分、KPI概算、実績集計、目標との突合)はロジックが固定されておりSQLに書き起こせます。一方、セール企画時の試算プロセス(アイテムの選定、割引額の設定、目標数量の決定)はセールごとに変数と判断基準が変わるため、スプレッドシートに残しました。この線引きにより、事業部との接合点を「CSVに1行追加してPull Requestを出す」という1つのアクションに集約しています。確定した目標値(流通額と売上)だけをデータ基盤に渡せば、残りはすべて自動で算出されます。設計方針精度より実用性を優先するKPI目標の概算には前年同日の注文単価やCVRをそのまま使っています。最初から完璧な精度を目指すより、まず使える状態にして、運用しながら必要に応じて精度を上げていく方針です。比較セールが存在しない場合、KPI目標はNULLとし、無理に算出しない設計にしています。表示ロジックはBIツールに委ねるマートテーブルには日別の目標値と実績値だけを持たせています。累積値や達成率の計算はBIツール側に委ねました。マートの責務を「正確な基礎数値の提供」に限定することで、ダッシュボードの見せ方を事業部が自由に変えられるようにしています。BIツール側で計算式を誤る
9日前
記事のアイキャッチ画像
シニア・プリンシパルエンジニア所信表明 - なめらかなシステムの実現に向けて
Pepabo Tech Portal
CTO室研究開発チーム(ペパボ研究所)の三宅(@monochromegane)です。2026年4月より、シニア・プリンシパルエンジニアになりました。このエントリーでは、昇格にあたっての所信表明と、その背景にあるペパボのエンジニア評価制度について書きます。所信表明シニア・プリンシパルとして、AI前提のサービスの実現に尽力していきます。サービスの中にAIや機械学習が自然に組み込まれ、利用者の体験がそれによって継続的に良くなっていく。そういうサービスのあり方を各サービスで具現化することに加え、それが自分一人の力ではなくプロダクト開発のあり方として定着する仕組みを築いていくことが自分の役割だと考えています。サービスそのものだけでなく、それを支える開発の営みも含めた全体が適応的に動いていく。これはペパボ研究所が掲げる「なめらかなシステム」の体現に他なりません。この目標に向かう中で、大切にしていることがあります。会社の外にある基準を知った上で、会社の中で生かすということです。ここでいう外の基準とは、学術研究に限った話ではありません。国際会議やジャーナルで議論されている最先端の手法、OSSコミュニティで共有されている設計思想、業界全体の技術トレンド。世界がいまどこまで進んでいて、どういう原理で動いているかを知ることです。一方で、それを生かす「中」とは、自社のサービスが持つ歴史、利用者の行動、蓄積されたデータ、運用上の制約、事業としての文脈です。どちらか一方だけでは足りないと考えています。会社に長くいて業務に精通していても、外を見なければ既存の枠内で最適化するにとどまります。逆に、新しい技術や方式をよく知っていても、サービスの文脈を理解していなければ、提案は着地しないまま終わります。両方を自分の中で統合して初めて、その会社でしか生み出せない、事業を差別化する技術になります。その統合の先に、継続的に学習し適応していく仕組みが選択肢として自然に検討される土壌をつくること。研究と開発の両面から、この橋渡しを担っていきます。ペパボのエンジニア評価制度ペパボのエンジニア専門職にはシニアエンジニア、プリンシパルエンジニア、シニア・プリンシパルエンジニアの3段階があります。評価は「作り上げる力」「先を見通す力」「影響を広げる力」の3軸で行われます。特徴的なのは、立候補制であることです。候補者自身
17日前