LLMに時間変換を任せてはいけない:Findy AI+の開発で学んだ反省と改善策

こんにちは。

ファインディ株式会社でFindy AI+の開発をしているdanです。

今回は、プロンプトにどのようなデータや指示内容を与えるとLLMが誤った出力をしやすいのかについてお話しします。

プロンプトには何を書くべきで、何を書かないべきなのか。また、LLMに渡すデータはどのような形であるべきなのか。私自身が経験した実際の例をあげて解消までのアプローチ方法をご紹介します。

分析の精度をあげるにはここで紹介する内容では不十分ですが、入門編として参考になれば幸いです。

この記事はファインディエンジニア #3 Advent Calendar 2025 23日目の記事です。今月から、たくさんのアドベントカレンダー記事が執筆される予定ですので、ぜひ読んでみてください。

adventar.org

Findy AI+とは

Findy AI+は、GitHub連携やプロンプト指示を通じて生成AIアクティビティを可視化し、生成AIの利活用向上を支援するサービスです。

人と生成AIの協働を後押しし、開発組織の変革をサポートします。

Claude Code、GitHub Copilot、Codex、Devinなど様々なAIツールの利活用を横断的に分析しており、分析基盤にはLangChainを採用しています。また、日報やチーム分析などの機能でもLLMを活用しています。

こうした特性から、Findy AI+ では「何をどう分析するか」を定義するためのプロンプトが、サービスの価値を左右する重要な要素となります。

誤解していたプロンプト調整

良くない手法1: システムプロンプトにUTCから日本時間に変換する指示を与える

初期のシステムプロンプトは次の通りです。

# System Prompt
## Overview
You are expert of developer experience and developer productivity.

Your Timezone is Asia/Tokyo (UTC+9).
Your Language is Japanese.

The Timezone for the creation datetime of the Pull request is UTC.

上記はすごくシンプルなシステムプロンプトです。 このコードでは次のことを書いています。

  • LLMがどのような役割を担うのか
  • タイムゾーンはどこを使用するのか
  • どの言語で出力するのか
  • プルリクエストの作成日時がUTCであること

このシステムプロンプトを使用してプロダクトから分析ツールを実行すると次のような出力結果になりました。

指定した期間で取得されている画像 去年の日付で出力されている画像

システムプロンプトには使用してほしいタイムゾーンがUTC+9(日本時間)であることと、LLM分析に使用するデータはUTCであることを明記しています。

その結果、LLMは分析中に与えられたUTCのデータをJSTに変換する推論処理を行う必要があり、意図しない日付のズレが発生しました。

良くない手法2: 分析に使用するデータを加工する指示をシステムプロンプトに与える

ユーザーからの自由入力による追加分析を行うと実際とは異なる日時が分析結果として返ってきました。 そのため次のようにシステムプロンプトを調整しました。

# System Prompt
## Overview
You are expert of developer experience and developer productivity.

## Current Date
Today's date is {current_date} (YYYY-MM-DD format in UTC timezone).
When you see dates in the data provided, interpret them according to this current date.
For example, if today is 2025-10-08 and the data shows "2025-10-06 to 2025-10-12", this is the current week, not a future or past week.

Your Timezone is Asia/Tokyo (UTC+9).
Your Language is Japanese.

The Timezone for the creation datetime of the Pull request is UTC.

このコードでは次のことを書いています。

  • LLMがどのような役割を担うのか
  • 現在日時の明記
  • 現在日時は明記されたものを使用し過去を参照しないこと
  • タイムゾーンはどこを使用するのか
  • どの言語で出力するのか
  • プルリクエストの作成日時がUTCであること

このシステムプロンプトを使用してPRの分析を行った後、「日曜日に稼働したりしてないよね?」と追加で質問しました。LLMはGitの活動ログから曜日を判定して回答しますが、次のような出力結果になりました。

現実には存在しない日付を返している画像

実際の曜日とLLMが出力した曜日を比較すると、2025年11月17日は月曜日ですが日曜日で出力されてしまっていることが分かります。

システムプロンプトに現在日時の明記と過去を参照しない旨を明記しています。 また期間指定の範囲についても具体的に指示しています。

その結果LLMは現実と過去について言及されている部分で混乱し、誤った推論による出力ミスが起きてしまいました。

あるべき手法

システムプロンプトはどのような振る舞いで分析をしてほしいのかを書く

システムプロンプトにデータの加工、時間変換など処理の具体的な内容を書いてしまうと上記で紹介したような誤った推論を誘発してしまう可能性が高いです。

そのため、役割・言語・フォーマットなどシンプルな内容で最低限のみ書くのが良いです。

最終的には次のようなシンプルなシステムプロンプトになりました。

# System Prompt
## Overview
You are expert of developer experience and developer productivity.

## Current DateTime
Current datetime is {current_datetime_jst}

## Important Rules
- When data includes weekday information (e.g., "月曜日", "火曜日"), use it as-is. Do NOT recalculate weekdays yourself.

Your Language is Japanese.

このコードでは次のことを書いています。

  • LLMがどのような役割を担うのか
  • 現在日時は変換済みのJSTで渡す
  • 渡されたデータをそのまま使うよう指示する
  • どの言語で出力するのか

分析に使用するデータを加工してからLLMに渡す

分析に使用するデータは、システムプロンプトへ渡す前に加工済みのものを用意した方が良いです。

システムプロンプトにUTCからUTC+9(日本時間)の変換をするように書くべきではありません。 LLMに渡すデータは変換済みのデータにしておきましょう。

例えば、PRのデータをLLMに渡す場合を見てみましょう。 GitHubのPR情報をAPIから取得する場合、日時に関するレスポンスはUTCで返ってきます。

次の手順で、LLMに渡すデータを変換し分析を行います。

・GitHubのAPIから取得したPR作成日時をUTCからUTC+9(日本時間)に変換する

def format_datetime_jst(pr_utc_datetime: str) -> str:
  # UTCの日時文字列をJSTに変換
  utc_dt = datetime.fromisoformat(pr_utc_datetime.replace("Z", "+00:00"))
  jst_dt = utc_dt.astimezone(JST)
  # 曜日も付与してフォーマット
  weekday_jp = WEEKDAYS_JP[jst_dt.weekday()]
  return jst_dt.strftime(f"%Y/%m/%d ({weekday_jp}) %H:%M:%S UTC+9")

# 実行例
format_datetime_jst("2025-11-17T08:53:32Z")
# => "2025/11/17 (月曜日) 17:53:32 UTC+9"

・変換したデータを分析コンテンツに格納する

analysis_content = f"""
# Pull Request Analysis

- PR1 Created: {format_datetime_jst(pr1.get("created_at", ""))}
- PR2 Created: {format_datetime_jst(pr2.get("created_at", ""))}
- PR3 Created: {format_datetime_jst(pr3.get("created_at", ""))}
"""

・分析コンテンツを使用してLLMに分析を依頼する

llm.invoke([
  # 「システムプロンプトはどのような振る舞いで分析をしてほしいのかを書く」で紹介したシステムプロンプト
  {"role": "system", "content": system_prompt},
  {"role": "user", "content": analysis_content}
])

このように変換済みのデータをLLMに渡すことで、LLMが日時の計算や曜日の判定を行う必要がなくなり、誤った出力を防ぐことができます。

おわりに

今回は、LLMにデータ加工や時間変換を任せると誤った推論を誘発しやすいことをご紹介しました。システムプロンプトには役割や出力形式などシンプルな指示のみを書き、データはあらかじめ加工してから渡すことで、分析精度を向上させることができます。

プロンプトの書き方ひとつでLLMの出力は大きく変わります。この記事が、皆さんのLLM活用の参考になれば幸いです。

現在、ファインディでは一緒に働くメンバーを募集中です。

興味がある方はこちらからご応募ください。 herp.careers