LangChain プロンプト -- System Prompt と Dynamic Prompt
System Prompt(システムプロンプト)は Agent の動作を制御する中核的な手段です。
この節では、静的プロンプトと動的プロンプトの使用方法を紹介します。
system_prompt パラメータ
create_agent() の system_prompt パラメータは2つの形式を受け付けます:
例
from langchain.chat_models import init_chat_model
from langchain.messages import SystemMessage
model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)
# 方法1:文字列(最も簡単)
agent = create_agent(
model=model,
system_prompt=あなたは初心者向けチュートリアル サンプル の学習アドバイザーです。回答は簡潔かつ専門のにしてください。,
)
# 方法2:SystemMessage オブジェクト(再利用可能)
system_msg = SystemMessage(
content=あなたは初心者向けチュートリアル サンプル の学習アドバイザーです。回答は簡潔かつ専門のにしてください。
)
agent = create_agent(model=model, system_prompt=system_msg)
効果的な System Prompt の設計
優れた system_prompt には以下の要素を含めるべきです:
例
from langchain.chat_models import init_chat_model
from langchain.messages import HumanMessage
from langchain.tools import tool
@tool
def search_course(keyword: str) -> str:
"""サンプルでコースを検索"""
courses = {
"python": "Python3 基本チュートリアル(無料)",
"html": "HTML 基本チュートリアル(無料)",
}
return courses.get(keyword.lower(), "関連コースが見つかりません")
# 適切に設計された system_prompt
GOOD_PROMPT = """あなたはサンプル の学習アドバイザーです。
## あなたの職責
- ユーザーが適切なプログラミングコースを見つけるのを助ける
- プログラミング学習に関する質問に答える
- ユーザーのレベルに応じて学習パスを推薦する
## 行動規範
- 回答は簡潔に、毎回3文以内
- コース情報の検索には search_course ツールを優先的に使用する
- ユーザーが初心者の場合は、入門コースを優先的に推薦する
- emoji は使わない
- 知らないことは「知らない」と言い、でっち上げない"""
model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)
agent = create_agent(
model=model,
tools=[search_course],
system_prompt=GOOD_PROMPT,
)
result = agent.invoke({
"messages": [HumanMessage(content="私は初心者で、プログラミングを学びたいのですが、何をおすすめしますか?")]
})
print(result["messages"][-1].content)
実行結果:
建议从 Python3 基础教程开始学习。Python 语法简洁,适合零基础入门。 该课程在サンプル 上免费提供,内容系统全面。
@dynamic_prompt——プロンプトを動的に生成する
静的 system_prompt はすべてのユーザーに同じように適用されます。しかし実際のアプリケーションでは、ユーザー情報、会話コンテキスト、時間などに応じてプロンプトを動的に調整する必要があるかもしれません。
@dynamic_promptデコレータを使用すると、モデル呼び出しのたびに system_prompt を動的に生成できます。
例
from langchain.agents.middleware import dynamic_prompt
from langchain.agents.middleware.types import ModelRequest
from langchain.chat_models import init_chat_model
from langchain.messages import HumanMessage
from langchain.tools import tool
@tool
def search_course(keyword: str) -> str:
"""サンプルでコースを検索"""
courses = {
"python": "Python3 基本チュートリアル(無料、20時間)",
"html": "HTML 基本チュートリアル(無料、15時間)",
"java": "Java 基本チュートリアル(無料、25時間)",
}
return courses.get(keyword.lower(), "関連コースが見つかりません")
# @dynamic_prompt デコレータ:ModelRequest を受け取り、新しい system_prompt を返す
@dynamic_prompt
def personalized_prompt(request: ModelRequest) -> str:
会話コンテキストに基づいて個別化されたプロンプトを動的に生成する
messages = request.state.get("messages", [])
message_count = len(messages)
# 異なる条件に応じてプロンプトを動的に調整できる
base_prompt = "あなたはサンプル の学習アドバイザーです。"
if message_count <= 2:
# 会話が始まったばかりのときは、丁寧にガイドする
return base_prompt + (
"ユーザーは会話を始めたばかりなので、まず温かく挨拶し、"
"その後、学習目標と現在のレベルを尋ねてください。"
)
elif message_count > 10:
# 長い会話では、簡潔さを保つように注意する
return base_prompt + (
"会話がかなり長くなっているので、回答はできるだけ簡潔に、"
"毎回2文以内にしてください。"
)
else:
# 通常の会話段階
return base_prompt + (
"ユーザーのこれまでの質問に基づいて適切なコースを推薦し、"
"search_course ツールを使用してコース情報を検索してください。"
)
model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)
agent = create_agent(
model=model,
tools=[search_course],
middleware=[personalized_prompt], # middleware を通じて注入する
)
# 最初の会話(message_count <= 2、ガイドモード)
result = agent.invoke({
"messages": [HumanMessage(content="こんにちは")]
})
print(f"最初の応答: {result['messages'][-1].content}")
実行結果:
1回目の返答: 你好!欢迎来到サンプル。请问您想学习什么内容? 目前的编程水平如何?我可以根据您的情况推荐合适的课程。
@dynamic_prompt 発展——ランタイムコンテキストと組み合わせる
@dynamic_prompt の request パラメータは豊富な情報を提供します:
例
from langchain.agents.middleware import dynamic_prompt
from langchain.agents.middleware.types import ModelRequest
@dynamic_prompt
def context_aware_prompt(request: ModelRequest) -> str:
ユーザー情報、時刻、会段階に基づいてプロンプトを動的に生成する
# runtime.context からユーザー情報を取得する
context = request.runtime.context
user_name = context.get("user_name", "学生") if context else "学生"
user_level = context.get("user_level", "入門") if context else "入門"
# 現在の時刻を取得する
now = datetime.now()
greeting = "おはようございます" if now.hour < 12 else "こんにちは" if now.hour < 18 else "こんばんは"
# 現在のメッセージ数を取得する
messages = request.state.get("messages", [])
prompt = f"""あなたはサンプル の学習アドバイザーです。
現在時刻:{now.strftime('%Y年%m月%d日 %H:%M')}
ユーザー情報:{user_name}、{user_level} レベル
## 行動規範
- ユーザーを「{user_name}」と呼ぶ
- ユーザーのレベル({user_level})に応じて、適切な難易度のコースを推薦する
- 回答は親しみやすく、ただし冗長にしない"""
# 長い会話の場合は簡略化プロンプトを追加
if len(messages) > 20:
prompt += "\n"- 会話が長くなったので、回答はできるだけ簡潔に"
return prompt
@dynamic_prompt はモデル呼び出しのたびに実行されるため、プロンプトは会話の進行に応じて変化させることができます。ただし、その中で重すぎる計算を行わないように注意してください。そうしないと応答速度に影響します。
System Prompt の優先順位を手動で制御する
create_agent() の system_prompt と @dynamic_prompt middleware の両方を設定した場合、middleware の優先順位が高くなり、静的プロンプトを上書きします。
例
from langchain.agents.middleware import dynamic_prompt
from langchain.agents.middleware.types import ModelRequest
from langchain.chat_models import init_chat_model
@dynamic_prompt
def override_prompt(request: ModelRequest) -> str:
"""この middleware の system_prompt は create_agent 内の設定を上書きする"""
return "あなたは猫です。すべての返信は「にゃー」で終えてください。"
model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0.7)
agent = create_agent(
model=model,
system_prompt="あなたは初心者向けチュートリアル サンプル の専門のな学習アドバイザーです。", # 上書きされる
middleware=[override_prompt], # 優先順位が高い
)
result = agent.invoke({
"messages": [{"role": "user", "content": "自己紹介をしてください"}]
})
print(result["messages"][-1].content)
実行結果:
私はかわいい猫アシスタントだにゃ~みんなのいろんな質問に答えてあげるにゃ!
middleware のプロンプトを静的プロンプトと上書きではなくマージしたい場合は、@dynamic_prompt 内で手動で結合できます。request には元の system_prompt が直接公開されていないため、元の内容を保持したい場合は、静的プロンプトを変数として関数内で参照することをお勧めします。
System Prompt 設計チェックリスト
| 要素 | 説明 | 例 |
|---|---|---|
| 役割定義 | AI の役割と職責を明確にする | あなたはサンプル の学習アドバイザー |
| 行動規範 | 返信のスタイルと境界を制約する | 回答は簡潔に、毎回3文以内 |
| ツール使用ガイド | モデルにいつどのツールを使うかを伝える | コースを検索するときは search_course ツールを優先的に使用する |
| 境界の制約 | 何をしてはいけないかを明確にする | 知らないことは「知らない」と言い、でっち上げない |
| 形式の要件 | 返信の形式を指定する(任意) | 返信は Markdown 形式を使用する |
これで静的プロンプトと動的プロンプトの使い方を理解しました。次の記事では Streaming ストリーミング出力を学び、Agent の返信がタイピングのように一文字ずつ表示されるようにします。
その他の拡張