LINEヤフー Tech Blog

LINEヤフー株式会社のサービスを支える、技術・開発文化を発信しています。

This post is also available in the following languages. English, Korean

AI時代の開発は「検証力」で決まる:Flava API Gateway が学んだ高速な動作検証と環境戦略

LINEヤフーの技術カンファレンス「Tech-Verse 2026」の公式記事です。

エージェントがコードを書く時代に

コーディングエージェントを使い始めると、最初に気づくのはその速さです。その試行錯誤の速さに驚かされる一方で、他の開発工程の遅さが気になり始めました。CI を経由するたびに発生する待ち時間や、構築に半日かかる環境などが、ボトルネックとして見えてきます。

また、エージェントとの開発には、当たり外れがありました。うまくいくときは申し分ありませんが、そうでないことも少なくありません。コンパイルが通らないコードを書いたり、存在しない API を参照したり、事前に詰め切れていない設計をその場で勝手に判断してしまったりすることが、何度もありました。

これは私たちだけの話ではありません。同じプロンプトでも、実行のたびに異なる出力が返ってくることがあります[1]。出力は不安定で、エージェントの能力について一般化して語るのが難しいとされています[2]。同じツールを使っていても、開発者によって体験が大きく異なるという報告もあります[3]。AI はコーディングを高速化する一方で[4]、開発者がしっかりレビューできる速度を超えてコードが生成されているという指摘もあります[5]。そもそも、エージェントの出力の良し悪しをどう測るかという問い自体、いまだに研究上の課題として残っています[6, 7]。

では、AI が書くコードが増えるなかで、ソフトウェアの信頼性をどう保てばよいのでしょうか。これまで信頼性を支えてきた基本こそ、いっそう重要になると考えています。要となるのは開発者の知見と細部への注意です。テスト・リンター・高速なローカル環境・事前の設計がそれを支えます。これらがなければ、本来もっと早く表面化していたはずの問題でエージェントが立ち往生してしまいます。

本記事では、Flava API Gateway の開発を通じて、こうした課題に対処するために取り入れた実践をご紹介します。

Flava API Gateway とは

LINEヤフー株式会社では、LINE株式会社とヤフー株式会社の合併以降、社内向けのプライベートクラウドである Flava の開発を進めてきました。Flava API Gateway はそのエコシステムを構成するプロダクトのひとつです。各チームが Web API を作成・公開・監視できる仕組みを提供します。

アーキテクチャの全体像を下図に示します。データプレーンには Kong[8] を採用しています。コントロールプレーンはマルチテナントの RESTful API を提供しており、各チームが独立して API を設定・デプロイできます。

Flava API Gateway architecture

Flava API Gateway チームは 2025年半ばに結成されました。当時、社内ではエージェントによるコーディングが急速に広がりつつありました。そこで、AI の落とし穴を避けつつ、その恩恵をチームがどう活かせるかを検討しました。検討の結果、次の 3 つの実践が不可欠だという結論に行き着きました。

  • 仕様駆動開発(spec-driven development)により、エージェントが 1 行目のコードを書く前に認識を合わせる
  • 自動化された検証により、エージェントが自身のミスを段階的に見つけて修正できるようにする
  • 高速で再現性のある(hermetic)ローカル環境により、CI を経由せずに数秒で検証ループ全体を回せるようにする

以降のセクションで、それぞれを順に説明していきます。

最初の 1 行を書く前に認識を合わせる

前述のとおり、エージェント開発における大きな課題は出力品質のばらつきです。開発の初期から、この問題には何度も直面しました。設計が固まらないうちにエージェントが実装に取りかかり、その場の判断で設計を進めてしまうことで、出力のばらつきがさらに大きくなっていました。

ここで役立つのが仕様駆動開発です。設計・進め方・各変更で取り組むタスクを明示的に書き出すことで、曖昧さを減らし、出力の予測可能性を高めます。

コントロールプレーンの開発を例に、もう少し踏み込んで説明します。まず、コードを書き始める前に OpenAPI 仕様を書き、全体設計を先に固めました。そこから機能単位に分割し、それぞれを OpenSpec[9] を使って実装していきました。OpenSpec はエージェントと連携して仕様駆動開発を支援するツールです。

OpenAPI

OpenAPI[10] は REST API の仕様を記述するための業界標準です。コントロールプレーンの定義にも、これを採用しました。仕様があることで、エージェントの出力には明確な基準が与えられ、生成されたレスポンスが設計から外れたときに、具体的に捉えられるようになります。ただし、仕様自体が実装と乖離してしまえば、エージェントを縛るものはなくなります。素の OpenAPI YAML は記述量が多く、エンドポイント間で同じパターンが繰り返されます。直接書き続けると仕様が実態に追いつかなくなりがちです[11]。

そこで、OpenAPI YAML を直接編集するのではなく、Nickel[12] を使用しました。Nickel はデータ検証とボイラープレートの削減に長けた設定言語です。これを用い、簡潔な宣言的記述から API リソースの CRUD エンドポイントの仕様一式を生成するコードを書きました。たとえば、以下のスニペットは path リソースを記述しています。

resources.path = {
  description = "URL routes exposed by API Gateway.",
  parent = "API",
  editable = 'none,    # 更新エンドポイントなし。path は作成と削除のみで、更新はしない
  timestamped = true,  # created_at と updated_at を自動生成
  properties = {
    id = { schema = lib.uuid_for "path", sortable = true },
    path = {
      schema = lib.ref "#/components/schemas/PathTemplate",
      create = 'required,      # POST リクエストのボディに必須
      sortable = true,         # list クエリで ?sort=path を有効化
      filterable = true,       # ?path=<value> による完全一致フィルタを有効化
      filter_contains = true,  # ?path.contains=<value> による部分一致フィルタを有効化
    },
  },
}

これをもとに、CRUD ジェネレータが listPaths、createPath、getPath、deletePath のエンドポイント一式を生成します。いずれにも、ページネーション、ソートとフィルタのパラメータ、楽観的ロック用の ETag ヘッダー、そして一貫したエラーレスポンス一式が備わっています。

生成された仕様の一部を以下に示します。

/v1/projects/{project}/apis/{api_id}/paths:
  get:
    summary: List paths
    operationId: listPaths
    parameters:
      - $ref: '#/components/parameters/Page'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/SortPaths'
      - $ref: '#/components/parameters/Order'
      - name: path
        in: query
        description: Filter by exact path
      - name: path.contains
        in: query
        description: Filter by path (substring match)
    responses:
      '200':
        description: Paths listed
      '400':
        $ref: '#/components/responses/BadRequest'
      '401':
        $ref: '#/components/responses/Unauthorized'
      # ...

OpenSpec

OpenSpec を使うと、機能変更のたびに振る舞いの仕様を先に固めてから実装に進みます。これを支えるのが次の 4 つの成果物です。

  • 提案(Proposal):変更の意図と内容
  • 設計(Design):技術的な意思決定とトレードオフ
  • 差分仕様(delta spec):変更ごとの振る舞いの要件を Given-When-Then[13] 形式のシナリオで記述したもの
  • タスク(Tasks):実装手順をチェックリストに分解したもの

OpenSpec での開発は、4 つのフェーズに分かれます。

まず、開発者がエージェントと一緒に機能を検討します。このとき、エージェントは決めきれていない詳細やエッジケース、設計の選択肢を開発者から引き出します。次に、エージェントが 4 つの成果物すべてを生成します。続いて、実装に入ります。エージェントはタスクを階層ごとに進めながら、項目にチェックを入れていきます。最後に、すべてのタスクが完了したら、変更をアーカイブします。つまり、差分仕様がメインの仕様にマージされ、API の振る舞いがバージョン管理された記録として残ります。こうした差分仕様が時間とともに積み重なり、システム全体の生きた仕様を形作っていきます。

OpenSpec workflow

エージェント自身にミスを見つけさせる

エージェントが一発で正しく書けることは、そう多くありませんでした。コードがビルドできない、存在しない API を呼び出してしまう、といった場面が頻繁にありました。最初に試したのは、避けるべき落とし穴をプロンプトに事細かく書き連ねるという対処法です。ところが、これは効果がないどころか、かえって事態を悪化させているようにすら感じました。研究でも、出力への制約を増やすほど品質が低下していくことが示されています[14]。最終的にうまくいったのは、エージェント自身にミスを見つけて修正させるやり方でした。鍵となるのは、検証です。

Flava API Gateway の開発を通じて気づいたのは、自動テストとリンターがエージェント開発と特に相性がよいということでした。これは、LLM によるコード生成に TDD の原則を適用した研究でも指摘されています[15]。要件を最初にまとめてエージェントに渡すのではなく、テストとリンターが問題を段階的に明らかにしていきます。テストが失敗すれば、どこで何が壊れたのかを正確に伝えてくれます。エージェントはその問題を修正し、再びテストを走らせて、次の失敗へと進みます。こうして、エージェントへのフィードバックは必要なときに必要な分だけ届きます

同じ考え方を、エージェントが検証ループを呼び出す仕組みにも適用しています。テスト、リンター、フォーマッタの使い方を 1 つのプロジェクトスキルにまとめ、それをいつ読み込むかを AGENTS.md[16] でエージェントに伝えています。スキルの指示は、関係ある場面でだけエージェントに届き、毎ターン読み込まれることはありません。

もちろん、自動テストとリンターがコード品質に重要であることは、いまに始まった話ではありません。しかし現実には、納期に追われたときに真っ先に削られがちな項目でもあります。エージェント開発では、これらはもはや任意の選択肢ではないと考えています。実際、開発のなかで AI が実装中にこれらのチェックに引っかかる場面は何度もありました。自動チェックがなければ、これらを見つけ出すのにより多くの時間がかかり、AI による生産性の向上は打ち消されていたでしょう。

これまでの多くのプロジェクトでは、テストを CI と共有テスト環境に頼ってきました。社内の依存関係をローカルに用意するのは手間がかかり、不安定になりがちだったためです。人手でコードを書いているうちは、この不便さは我慢できる範囲でした。開発者はプッシュ前にコードを正しい状態に仕上げることで、CI を何度も回さなくて済むようにしていました。しかし、エージェントには同じやり方は通用しません。試行錯誤のスピードが速く、毎回リモートのパイプラインを経由するのは現実的ではありません。待ち時間が長く、その間にエージェントはコンテキストを失ってしまいます。完全にローカルで動く環境に投資すれば、この両方の問題が解消します。エージェントは即座にフィードバックを得られ、作業の流れを途切れさせることなく連続したループに留まれます。さらに、依存関係がローカルにあれば、ログや状態を直接確認できるため、失敗の原因を突き止めるのがはるかに楽になります。

現在、テストは合計 2,754 件あり、次の 3 つの層にまたがっています。統合テストと E2E テストでは、依存サービスをモックせず、実際のインスタンスを使用します。

  • 単体(Unit):ビジネスロジックを単独で検証
  • 統合(Integration):PostgreSQL(制約、トリガー、論理削除のカスケード、トランザクション)、プロセス内の HTTP スタック全体、レスポンスごとの OpenAPI 仕様準拠
  • E2E(エンドツーエンド):Athenz 認証、Kong データプレーン、API キー、マルチテナント分離を含むシステム全体

エージェントが試行のたびに気兼ねなく実行できるよう、テストは高速である必要がありました。開発者マシンでは、テスト全体が約 15 秒で完了します。この速度を出すには、並列化への意識的な投資が欠かせません。テストケースは可能なかぎり互いに干渉しないよう設計しています。たとえば、テーブルを共有して実行のたびに TRUNCATE するのではなく、テストパッケージごとにテーブルの入れ物となる専用の PostgreSQL スキーマを新しく作成するようにしています。

エージェントが生成するコードは、気づきにくい形で仕様から逸脱することがあります。これを検出するため、統合テストでは、テスト対象の HTTP サーバーをすべて薄いハンドラでラップしています。このハンドラが、通常のテスト実行のなかで仕様準拠を検証します。以下はそのラッパーを簡略化したものです。

type specValidatingHandler struct {
    t       testing.TB // 実行中の Go テストへの参照
    handler http.Handler
}

// ServeHTTP はリクエストごとに呼び出されます。内部ハンドラに処理を委譲し、
// 記録したレスポンスを呼び出し元へ転送したうえで、仕様に照らして検証します。
func (s *specValidatingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
    rec := httptest.NewRecorder()
    s.handler.ServeHTTP(rec, req)
    // レスポンスを実際の writer に転送 ...
    validateSpecResponse(s.t, specRouter, req, rec.Code, rec.Header(), rec.Body.Bytes())
}

func validateSpecResponse(t testing.TB, router routers.Router,
    req *http.Request, code int, header http.Header, body []byte) {
    t.Helper()

    route, pathParams, err := router.FindRoute(req)
    if err != nil {
        return // 仕様に存在しないルート。スキップ
    }
    err = openapi3filter.ValidateResponse(req.Context(), &openapi3filter.ResponseValidationInput{
        RequestValidationInput: &openapi3filter.RequestValidationInput{
            Request: req, PathParams: pathParams, Route: route,
        },
        Status:  code,
        Header:  header,
        Body:    io.NopCloser(bytes.NewReader(body)),
        Options: &openapi3filter.Options{IncludeResponseStatus: true}, // 仕様にないステータスコードも失敗扱いに
    })
    if err != nil {
        t.Fatalf("response does not conform to OpenAPI spec: %v", err)
    }
}

// setupTestServer は、すべての統合テストがセットアップで
// http.Handler を取得するために呼び出すコンストラクタです。
// 常にラップされたハンドラを返します。
func setupTestServer(tb testing.TB /* , ... */) http.Handler {
    appHandler := buildAppHandler(/* ... */)
    return &specValidatingHandler{t: tb, handler: appHandler}
}

各テストはセットアップで setupTestServer から http.Handler を取得し、その ServeHTTP を介してリクエストを処理します。返されるハンドラはラッパーなので、すべてのテストレスポンスが OpenAPI 仕様に照らして検証され、ステータスコード・ヘッダー・ボディスキーマのいずれかに逸脱があればテストは失敗します。

エージェント開発ではテストに加えて、リンターも従来の人手による開発以上に重要になります。人間のチームは、コードレビューの文化、チーム内の共通認識、明文化されていないルールといった非公式の慣行に頼って品質を保っています。しかし、エージェントにはそれらを知る術がなく、こうした暗黙の規範に沿わない出力を生み出します[17]。明示的な自動チェックだけが、エージェントが従える唯一の規範です。そこで Flava API Gateway では、できるかぎり多くの自動チェックを設けています。具体的には、Go コードには golangci-lint[18]、SQL とマイグレーションには専用のリンター[19, 20]、コード全般には組み込みおよびカスタムルールを備えた Semgrep[21] を導入しています。golangci-lint は、デフォルトで全ルールを有効にしたうえで、不要なものを除外する opt-out 方式で運用しています。これにより、エージェントは通常のループのなかでこれらの制約についてのフィードバックを得られます。

全体像

仕様駆動開発ループ

すべての変更は、設計フェーズから始まります。開発者はエージェントと一緒に機能を検討し、エッジケースや設計の選択肢を洗い出します。そのうえで、エージェントが 4 つの OpenSpec 成果物を生成します。次は実装フェーズです。エージェントはタスクを順に進めながら、変更のたびにテストとリンターを走らせます。失敗した場合は、その結果がそのまま次の試行に活かされます。すべてのチェックを通過したら、差分仕様をメインの仕様に取り込み、API の振る舞いを記録として残します。こうして、検証がすべてのステップに組み込まれた、素早いフィードバックループが生まれます。

すべてをローカルで完結させる

こうした検証を支える重要な前提が、ローカルの開発者環境です。網羅的な検証を続けるには、それを動かす環境のセットアップと変更が容易であることが欠かせません。セットアップに手間がかかりすぎる環境は、使われなくなります。変更しにくい環境は、プロジェクトの進化に追いつけなくなります。次第に新しいツールが入らない、サービスのバージョンがずれる、開発者が環境を活用するのではなく回避して作業するようになる、といったことが起こります。ローカルでテスト全体を動かすには、PostgreSQL、Athenz 認証サービス、各種リンターやコードジェネレータを、互いに互換性のあるバージョンで連携させる必要があります。これらすべてを管理するローカルの開発者環境は、できるかぎり手間のかからないものにしなければなりませんでした。

これを解決してくれるのが Nix[22] をベースにした Devenv[23] です。Devenv はプロジェクトごとに、専用の開発環境となるシェルを用意します。devenv shell というコマンドひとつで、すべての開発者と CI ランナーが同じツールを同じバージョンで揃えられます。しかも、macOS と Linux のどちらでも同じように動きます。このシェルは、コンテナや VM のようにホスト環境を置き換えるのではなく、その上に重ねる形で動作します。そのため、開発者は普段使っているエディタ・dotfiles・ワークフローをそのまま使い続けられます。direnv[24] と組み合わせれば、プロジェクトディレクトリに移動するたびに自動的にこのシェルに入れるようになります。

direnv がプロジェクトディレクトリへの移動を検知し、自動的に開発シェルを読み込んでいる様子

特に便利だったのは、Nix がパッケージ、サービス、設定(環境変数や生成ファイルなど)を単一の言語で記述できることです。たとえば、本プロジェクトのコントロールプレーンは Go で実装しています。エディタやエージェントは補完・コードナビゲーション・診断のために Go の LSP である gopls[25] を呼び出します。gopls は通常、各開発者がエディタやエージェントに合わせてインストールと設定を済ませる必要があります。Devenv ではこのインストールと設定をリポジトリにまとめて記述できるため、どの開発者の手元でも同じ状態が再現されます。

以下のスニペットでは、gopls のラッパーを Nix パッケージとして組み立て、Devenv の languages.go モジュールに組み込んでいます。これだけで開発シェル内の PATH に gopls が乗ります。ラッパーが実際の gopls バイナリにプロジェクト固有のフラグを渡すため、各開発者が個別に設定をしなくても、エディタやエージェントから適切な gopls を呼び出せます。

# 既存の gopls パッケージを引数として受け取り、-tags=extdep を常に
# 注入したカスタム gopls バイナリを含む、ラップ済み gopls パッケージを返す関数です。
wrapGopls = gopls: pkgs.runCommand gopls.name
  {
    nativeBuildInputs = [ pkgs.makeWrapper ];

    # ここは概要の把握に必須ではありません。languages.go の期待に合わせるために
    # 含めています。
    passthru.override = lib.setFunctionArgs (args: wrapGopls (gopls.override args))
      (lib.functionArgs gopls.override);
  }
  ''
    mkdir -p "$out/bin"
    makeWrapper ${lib.getExe gopls} "$out/bin/gopls" \
      --suffix GOFLAGS ' ' -tags=extdep
  '';

languages.go.lsp.package = wrapGopls pkgs.gopls;

設定の各部分は互いに参照し合うこともできます。コントロールプレーンのサーバーは、ランタイムの設定を Devenv が生成する YAML ファイルから読み込みます。以下の例では、PostgreSQL の設定にあるポート番号がサーバーの設定に直接渡されている様子が分かります。

providerCfg.database.port = config.services.postgres.settings.port;

PostgreSQL のサービスポートが変わると、生成される YAML が自動的にその値を反映します。

また、Devenv は 120,000 を超えるパッケージを揃えた Nixpkgs[26] を活用しています。通常、新しいツールを追加するには、開発者ごとのマシンと CI でそれぞれインストールする必要があり、バージョンがずれていきがちです。Nix と Nixpkgs を使えば、すべてのパッケージがピン留めされ、どの環境でも完全に同じものが得られます。たった 1 行追加するだけで、新しいツールをどこでも同じように使えるようになります。

packages = [
  pkgs.openspec
  pkgs.semgrep
  pkgs.sqlc
  pkgs.squawk
  pkgs.yaml-language-server

  # OpenAPI
  pkgs.nickel
  pkgs.nls
  pkgs.redocly
  json-schema-to-nickel
];

Devenv にはモジュールシステムがあり、設定を自己完結したユニットとしてまとめられます。これにより、サービスの再利用・拡張・組み合わせが容易になります。PostgreSQL を有効にするのはわずか数行で済みます。データベースの作成・ユーザー設定・起動まで、すべて自動的に処理されます。

services.postgres = {
  enable = true;
  initialDatabases = [
    { name = "flava-api-gateway"; user = "flava-api-gateway"; }
  ];
};

一般的なツール向けにはモジュールが豊富に用意されており、多くの場合、デフォルトと異なる部分だけを設定すれば済みます。たとえば言語モジュールには、その言語のコンパイラ、フォーマッタ、LSP、その他の標準ツールが揃っています。ここで独自に設定しているのは先ほどの gopls のラッパーを組み込む部分だけです。

languages = {
  nix.enable = true;
  go = {
    enable = true;
    lsp.package = wrapGopls pkgs.gopls;
  };
};

同じ原則はより複雑なサービスにも当てはまります。たとえば、Flava API Gateway が大きく依存しているアクセス制御システム、Athenz[27] です。これをローカルで動かせるよう設定するには、相当な労力が必要でした。ただし、Devenv が環境構築の基盤周りや依存関係の管理を引き受けてくれたため、周辺のインフラと格闘する必要はなく、その労力を Athenz そのものの理解に費やせました。

Athenz をローカルで動かす

E2E テストはモックではなく本物の Athenz 認証に依存しています。モックにするのは現実的ではありません。Athenz は複雑な認証モデルを持っており、サービスは証明書で認証され、アクセスはドメイン・ロール・ポリシーの階層によって制御されます[28]。忠実にモックしようとすると、相当な量のロジックを再実装することになります。しかも、テストできるのは Athenz そのものではなく、こちらの Athenz 理解にすぎません。そのため、ローカルで動かす必要がありました。

認証モデル全体は、サービスの定義と一緒に宣言します。サービスのアイデンティティ・ドメイン階層・ロール・ポリシーは、すべて起動時にプロビジョニングされます。以下がその設定です。

services.athenz = {
  enable = true;
  provisionDomains = {
    # Athenz サービスを登録
    devenv.services =
      lib.genAttrs
        ["provider" "apiadminrw" "apiadminro"]
        (svcName: {
          pubkey = "${credentialsDir}/devenv/${svcName}.pub.pem";
          key = "${credentialsDir}/devenv/${svcName}.key";
          cert = "${credentialsDir}/devenv/${svcName}.cert.pem";
        });

    # Athenz の TLD を作成
    flava-api-gateway.admins = [ "devenv.provider" ];

    # Athenz のサブドメインを作成
    "flava-api-gateway.local" = {
      admins = [ "devenv.provider" ];
      roles = {
        apigateway_admin = {
          members = [ "devenv.apiadminrw" ];
          policies.grant_api_admin = {
            grant = "*";
            on = "apigateway.api.*";
          };
        };
        apigateway_readonly = {
          members = [ "devenv.apiadminro" ];
          policies = {
            grant_readonly_1 = {
              grant = "GET";
              on = "apigateway.api.*";
            };
            grant_readonly_2 = {
              grant = "GET";
              on = "apigateway.api";
            };
          };
        };
      };
    };
  };
};

従来の実践がいっそう重要になる時代に

AI が生成するコードのスピードによる恩恵は、その出力が十分に信頼できる水準で安定しなければ得られません。これを可能にするのが、検証です。そこに到達するには、いくつかの土台が必要でした。素早くミスを捉えられるテスト、それを手間なく走らせられるローカル環境、そしてエージェントがコードを書き始める前に認識を合わせる仕組みです。

エージェントにとって検証が役立つには、速さが欠かせません。高速なローカル環境がなければ、確認のたびに CI を回さなければなりません。仕様の認識合わせを欠いた検証では、テストは通っても設計から外れたコードができてしまいます。両方が揃って初めて、エージェントが自力で進められるほど素早いフィードバックループが生まれます。

QA チームの方からは、システムの複雑さの割にバグが少なかったとの意見をいただきました。本記事で実践したことだけが要因かは定かではありませんが、私たちが開発を進めていたときの手応えとも一致しています。

本記事で取り上げた多くのことは以前から有用なものでした。AI が変えるのはこうした実践の重みです。AI は品質向上の努力も手抜きも増幅して結果に反映します。

一緒に作りませんか

こうした課題に一緒に取り組んでくださる方を募集しています

参考文献

[1] Ouyang, S. et al. 2025. An Empirical Study of the Non-Determinism of ChatGPT in Code Generation. ACM Transactions on Software Engineering and Methodology. 34, 2 (Jan. 2025), 1–28. https://doi.org/10.1145/3697010.
[2] Larbi, M. et al. 2025. When Prompts Go Wrong: Evaluating Code Model Robustness to Ambiguous, Contradictory, and Incomplete Task Descriptions. arXiv. https://doi.org/10.48550/arXiv.2507.20439.
[3] Tomaz, R. et al. 2026. Impacts of Generative AI on Agile Teams’ Productivity: A Multi-Case Longitudinal Study. arXiv. https://doi.org/10.48550/arXiv.2602.13766.
[4] Peng, S. et al. 2023. The Impact of AI on Developer Productivity: Evidence from GitHub Copilot. arXiv. https://doi.org/10.48550/arXiv.2302.06590.
[5] Afroz, S. et al. 2025. The Fast and Spurious: Developer Productivity with GenAI. arXiv. https://doi.org/10.48550/arXiv.2510.24265.
[6] METR. Measuring the Impact of Early-2025 AI on Experienced Open-Source Developer Productivity. Retrieved from https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/.
[7] Wang, X. et al. 2025. CodeVisionary: An Agent-based Framework for Evaluating Large Language Models in Code Generation. arXiv. https://doi.org/10.48550/arXiv.2504.13472.
[8] Kong. Retrieved from https://github.com/Kong/kong.
[9] OpenSpec — A lightweight spec‑driven framework. Retrieved from https://openspec.dev.
[10] OpenAPI Initiative. Retrieved from https://www.openapis.org.
[11] Huang, R. et al. 2024. Generating REST API Specifications through Static Analysis. Proceedings of the IEEE/ACM 46th International Conference on Software Engineering. ACM. https://doi.org/10.1145/3597503.3639137.
[12] Nickel. Retrieved from https://nickel-lang.org.
[13] Given When Then. Retrieved from https://martinfowler.com/bliki/GivenWhenThen.html.
[14] Dente, F. et al. 2026. Constraint Decay: The Fragility of LLM Agents in Backend Code Generation. arXiv. https://doi.org/10.48550/arXiv.2605.06445.
[15] Mathews, N.S. and Nagappan, M. 2024. Test-Driven Development and LLM-based Code Generation. Proceedings of the 39th IEEE/ACM International Conference on Automated Software Engineering. ACM. https://doi.org/10.1145/3691620.3695527.
[16] AGENTS.md. Retrieved from https://agents.md.
[17] Wang, Y. et al. 2025. Beyond Functional Correctness: Investigating Coding Style Inconsistencies in Large Language Models. Proceedings of the ACM on Software Engineering. 2, FSE (June 2025), 690–712. https://doi.org/10.1145/3715749.
[18] Golangci-lint. Retrieved from https://golangci-lint.run.
[19] SQLFluff. Retrieved from https://www.sqlfluff.com.
[20] Squawk — a linter for Postgres migrations. Retrieved from https://squawkhq.com.
[21] Semgrep. Retrieved from https://semgrep.dev.
[22] Nix & NixOS. Retrieved from https://nixos.org.
[23] devenv. Retrieved from https://devenv.sh.
[24] direnv. Retrieved from https://direnv.net.
[25] Gopls: The language server for Go - The Go Programming Language. Retrieved from https://go.dev/gopls/.
[26] NixOS Search. Retrieved from https://search.nixos.org/packages.
[27] Athenz IO - Home. Retrieved from https://www.athenz.io.
[28] Athenz IO - Explore. Retrieved from https://www.athenz.io/explore.html#model.

Tech-Verse 2026 を開催します(6月29日)

image

この記事は、イベントの公式記事として公開されました。
Tech-Verse 2026は、LINEヤフーが開催する技術カンファレンスです。
最先端の挑戦や積み重ねてきた知識を共有します。

YouTube LIVEでの配信をぜひご覧ください。
https://tech-verse.lycorp.co.jp/2026/ja/