LangChain Prompts -- System Prompt and Dynamic Prompt
System Prompt is the core means of controlling Agent behavior.
This section introduces the usage of static prompts and dynamic prompts.
system_prompt Parameter
The system_prompt parameter of create_agent() accepts two forms:
Example
from langchain.chat_models import init_chat_model
from langchain.messages import SystemMessage
model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)
# Method 1: String (simplest)
agent = create_agent(
model=model,
system_prompt="You are the learning consultant for Example. Keep your answers concise and professional.",
)
# Method 2: SystemMessage object (reusable)
system_msg = SystemMessage(
content="You are the learning consultant for Example. Keep your answers concise and professional."
)
agent = create_agent(model=model, system_prompt=system_msg)
Designing Effective System Prompts
A good system_prompt should include the following elements:
Example
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:
"""Search for courses on Example"""
courses = {
"python": "Python3 Basic Tutorial (Free)",
"html": "HTML Basic Tutorial (Free)",
}
return courses.get(keyword.lower(), "No related courses found")
# A well-designed system_prompt
GOOD_PROMPT = """You are the learning consultant for Example.
## Your Responsibilities
- Help users find suitable programming courses
- Answer questions related to programming learning
- Recommend learning paths based on the user's level
## Code of Conduct
- Keep answers concise, no more than 3 sentences each time
- Prefer using the search_course tool to query course information
- If the user is a complete beginner, prioritize recommending introductory courses
- Do not use emoji
- If you don't know, say so; do not fabricate"""
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="I'm a complete beginner and want to learn programming. What do you recommend?")]
})
print(result["messages"][-1].content)
Output:
建议从 Python3 基础教程开始学习。Python 语法简洁,适合零基础入门。 该课程在Example 上免费提供,内容系统全面。
@dynamic_prompt — Dynamically Generating Prompts
A static system_prompt treats all users the same. In real-world applications, however, you may need to dynamically adjust the prompt based on user information, conversation context, time, and so on.
@dynamic_promptThe decorator lets you dynamically generate the system_prompt before each model call.
Example
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:
"""Search for courses on Example"""
courses = {
"python": "Python3 Basic Tutorial (Free, 20 hours)",
"html": "HTML Basic Tutorial (Free, 15 hours)",
"java": "Java Basic Tutorial (Free, 25 hours)",
}
return courses.get(keyword.lower(), "No related courses found")
# @dynamic_prompt decorator: receives ModelRequest, returns a new system_prompt
@dynamic_prompt
def personalized_prompt(request: ModelRequest) -> str:
"""Dynamically generate a personalized prompt based on conversation context"""
messages = request.state.get("messages", [])
message_count = len(messages)
# You can dynamically adjust the prompt based on different conditions
base_prompt = "You are the learning consultant for Example."
if message_count <= 2:
# Conversation just started; guide patiently
return base_prompt + (
"The user has just started the conversation; greet them warmly first,"
"then ask about their learning goals and current level."
)
elif message_count > 10:
# Long conversation; remind to stay concise
return base_prompt + (
"The conversation is already quite long; keep answers as concise as possible,"
"no more than 2 sentences each time."
)
else:
# Normal conversation phase
return base_prompt + (
"Recommend suitable courses based on the user's previous questions,"
"use the search_course tool to query course information."
)
model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)
agent = create_agent(
model=model,
tools=[search_course],
middleware=[personalized_prompt], # Injected via middleware
)
# First conversation (message_count <= 2, guidance mode)
result = agent.invoke({
"messages": [HumanMessage(content="Hello")]
})
print(f"First round reply: {result['messages'][-1].content}")
Output:
First reply: 你好!欢迎来到Example。请问您想学习什么内容? 目前的编程水平如何?我可以根据您的情况推荐合适的课程。
@dynamic_prompt Advanced — Combining Runtime Context
The request parameter of @dynamic_prompt provides rich information:
Example
from langchain.agents.middleware import dynamic_prompt
from langchain.agents.middleware.types import ModelRequest
@dynamic_prompt
def context_aware_prompt(request: ModelRequest) -> str:
"""Dynamically generate prompts based on user information, time, and conversation stage"""
# Get user information from runtime.context
context = request.runtime.context
user_name = context.get("user_name", "Student") if context else "Student"
user_level = context.get("user_level", "Beginner") if context else "Beginner"
# Get the current time
now = datetime.now()
greeting = "Good morning" if now.hour < 12 else "Good afternoon" if now.hour < 18 else "Good evening"
# Get the current message count
messages = request.state.get("messages", [])
prompt = f"""You are the learning consultant for Example.
Current time: {now.strftime('%Y-%m-%d %H:%M')}
User info: {user_name}, {user_level} level
## Code of Conduct
- Address the user as "{user_name}"
- Recommend courses of appropriate difficulty based on the user's level ({user_level})
- Be friendly but not verbose"""
# Append a simplification prompt for long conversations
if len(messages) > 20:
prompt += "\n- The conversation is very long; keep answers as concise as possible"
return prompt
@dynamic_prompt executes before every model call, so the prompt can change as the conversation progresses. However, avoid doing heavy computation inside it, as that will affect response speed.
Manually Controlling System Prompt Priority
If both create_agent()'s system_prompt and the @dynamic_prompt middleware are set, the middleware takes higher priority—it will override the static prompt.
Example
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:
"""This middleware's system_prompt will override the setting in create_agent"""
return "You are a cat; every reply must end with 'meow'."
model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0.7)
agent = create_agent(
model=model,
system_prompt="You are a professional learning consultant for Example.", # Overridden
middleware=[override_prompt], # Higher priority
)
result = agent.invoke({
"messages": [{"role": "user", "content": "Introduce yourself"}]
})
print(result["messages"][-1].content)
Output:
I am a cute cat assistant, meow~ Here specifically to help everyone answer all kinds of questions, meow!
If you want the middleware prompt to merge with the static prompt rather than override it, you can manually concatenate them in @dynamic_prompt. The original system_prompt is not directly exposed in request, so if you need to preserve the original content, it is recommended to reference the static prompt as a variable in the function.
System Prompt Design Checklist
| Element | Description | Example |
|---|---|---|
| Role Definition | Clarify the AI's identity and responsibilities | You are the learning consultant for Example |
| Code of Conduct | Constrain the style and boundaries of replies | Keep answers concise, no more than 3 sentences each time |
| Tool Usage Guidelines | Tell the model when to use which tools | Prefer the search_course tool when querying courses |
| Boundary Constraints | Specify what cannot be done | If you don't know, say so; do not fabricate |
| Format Requirements | Specify the format of replies (optional) | Replies use Markdown format |
Now we have mastered the usage of static and dynamic prompts. The next article will cover Streaming output, allowing the Agent's replies to appear character by character like typing.
Other Extensions