Skip to content

Commit d8c0526

Browse files
baek54321baek54321DouweM
authored
Let additional instructions be provided at agent.run time. (#3309)
Co-authored-by: baek54321 <baekonbike@gmail.com> Co-authored-by: Douwe Maan <douwe@pydantic.dev>
1 parent 04a01ef commit d8c0526

File tree

8 files changed

+150
-6
lines changed

8 files changed

+150
-6
lines changed

docs/agents.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -904,14 +904,15 @@ You should use:
904904

905905
In general, we recommend using `instructions` instead of `system_prompt` unless you have a specific reason to use `system_prompt`.
906906

907-
Instructions, like system prompts, fall into two categories:
907+
Instructions, like system prompts, can be specified at different times:
908908

909909
1. **Static instructions**: These are known when writing the code and can be defined via the `instructions` parameter of the [`Agent` constructor][pydantic_ai.Agent.__init__].
910910
2. **Dynamic instructions**: These rely on context that is only available at runtime and should be defined using functions decorated with [`@agent.instructions`][pydantic_ai.Agent.instructions]. Unlike dynamic system prompts, which may be reused when `message_history` is present, dynamic instructions are always reevaluated.
911+
3. **Runtime instructions*: These are additional instructions for a specific run that can be passed to one of the [run methods](#running-agents) using the `instructions` argument.
911912

912-
Both static and dynamic instructions can be added to a single agent, and they are appended in the order they are defined at runtime.
913+
All three types of instructions can be added to a single agent, and they are appended in the order they are defined at runtime.
913914

914-
Here's an example using both types of instructions:
915+
Here's an example using a static instruction as well as dynamic instructions:
915916

916917
```python {title="instructions.py"}
917918
from datetime import date

pydantic_ai_slim/pydantic_ai/agent/__init__.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ def __init__(
238238
output_type: The type of the output data, used to validate the data returned by the model,
239239
defaults to `str`.
240240
instructions: Instructions to use for this agent, you can also register instructions via a function with
241-
[`instructions`][pydantic_ai.Agent.instructions].
241+
[`instructions`][pydantic_ai.Agent.instructions] or pass additional, temporary, instructions when executing a run.
242242
system_prompt: Static system prompts to use for this agent, you can also register system
243243
prompts via a function with [`system_prompt`][pydantic_ai.Agent.system_prompt].
244244
deps_type: The type used for dependency injection, this parameter exists solely to allow you to fully
@@ -418,6 +418,7 @@ def iter(
418418
message_history: Sequence[_messages.ModelMessage] | None = None,
419419
deferred_tool_results: DeferredToolResults | None = None,
420420
model: models.Model | models.KnownModelName | str | None = None,
421+
instructions: Instructions[AgentDepsT] = None,
421422
deps: AgentDepsT = None,
422423
model_settings: ModelSettings | None = None,
423424
usage_limits: _usage.UsageLimits | None = None,
@@ -436,6 +437,7 @@ def iter(
436437
message_history: Sequence[_messages.ModelMessage] | None = None,
437438
deferred_tool_results: DeferredToolResults | None = None,
438439
model: models.Model | models.KnownModelName | str | None = None,
440+
instructions: Instructions[AgentDepsT] = None,
439441
deps: AgentDepsT = None,
440442
model_settings: ModelSettings | None = None,
441443
usage_limits: _usage.UsageLimits | None = None,
@@ -454,6 +456,7 @@ async def iter(
454456
message_history: Sequence[_messages.ModelMessage] | None = None,
455457
deferred_tool_results: DeferredToolResults | None = None,
456458
model: models.Model | models.KnownModelName | str | None = None,
459+
instructions: Instructions[AgentDepsT] = None,
457460
deps: AgentDepsT = None,
458461
model_settings: ModelSettings | None = None,
459462
usage_limits: _usage.UsageLimits | None = None,
@@ -527,6 +530,7 @@ async def main():
527530
message_history: History of the conversation so far.
528531
deferred_tool_results: Optional results for deferred tool calls in the message history.
529532
model: Optional model to use for this run, required if `model` was not set when creating the agent.
533+
instructions: Optional additional instructions to use for this run.
530534
deps: Optional dependencies to use for this run.
531535
model_settings: Optional settings to use for this model's request.
532536
usage_limits: Optional limits on model request count or token usage.
@@ -580,7 +584,7 @@ async def main():
580584
model_settings = merge_model_settings(merged_settings, model_settings)
581585
usage_limits = usage_limits or _usage.UsageLimits()
582586

583-
instructions_literal, instructions_functions = self._get_instructions()
587+
instructions_literal, instructions_functions = self._get_instructions(additional_instructions=instructions)
584588

585589
async def get_instructions(run_context: RunContext[AgentDepsT]) -> str | None:
586590
parts = [
@@ -1330,9 +1334,15 @@ def _normalize_instructions(
13301334

13311335
def _get_instructions(
13321336
self,
1337+
additional_instructions: Instructions[AgentDepsT] = None,
13331338
) -> tuple[str | None, list[_system_prompt.SystemPromptRunner[AgentDepsT]]]:
13341339
override_instructions = self._override_instructions.get()
1335-
instructions = override_instructions.value if override_instructions else self._instructions
1340+
if override_instructions:
1341+
instructions = override_instructions.value
1342+
else:
1343+
instructions = self._instructions.copy()
1344+
if additional_instructions is not None:
1345+
instructions.extend(self._normalize_instructions(additional_instructions))
13361346

13371347
literal_parts: list[str] = []
13381348
functions: list[_system_prompt.SystemPromptRunner[AgentDepsT]] = []

pydantic_ai_slim/pydantic_ai/agent/abstract.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ async def run(
131131
message_history: Sequence[_messages.ModelMessage] | None = None,
132132
deferred_tool_results: DeferredToolResults | None = None,
133133
model: models.Model | models.KnownModelName | str | None = None,
134+
instructions: Instructions[AgentDepsT] = None,
134135
deps: AgentDepsT = None,
135136
model_settings: ModelSettings | None = None,
136137
usage_limits: _usage.UsageLimits | None = None,
@@ -150,6 +151,7 @@ async def run(
150151
message_history: Sequence[_messages.ModelMessage] | None = None,
151152
deferred_tool_results: DeferredToolResults | None = None,
152153
model: models.Model | models.KnownModelName | str | None = None,
154+
instructions: Instructions[AgentDepsT] = None,
153155
deps: AgentDepsT = None,
154156
model_settings: ModelSettings | None = None,
155157
usage_limits: _usage.UsageLimits | None = None,
@@ -168,6 +170,7 @@ async def run(
168170
message_history: Sequence[_messages.ModelMessage] | None = None,
169171
deferred_tool_results: DeferredToolResults | None = None,
170172
model: models.Model | models.KnownModelName | str | None = None,
173+
instructions: Instructions[AgentDepsT] = None,
171174
deps: AgentDepsT = None,
172175
model_settings: ModelSettings | None = None,
173176
usage_limits: _usage.UsageLimits | None = None,
@@ -201,6 +204,7 @@ async def main():
201204
message_history: History of the conversation so far.
202205
deferred_tool_results: Optional results for deferred tool calls in the message history.
203206
model: Optional model to use for this run, required if `model` was not set when creating the agent.
207+
instructions: Optional additional instructions to use for this run.
204208
deps: Optional dependencies to use for this run.
205209
model_settings: Optional settings to use for this model's request.
206210
usage_limits: Optional limits on model request count or token usage.
@@ -224,6 +228,7 @@ async def main():
224228
message_history=message_history,
225229
deferred_tool_results=deferred_tool_results,
226230
model=model,
231+
instructions=instructions,
227232
deps=deps,
228233
model_settings=model_settings,
229234
usage_limits=usage_limits,
@@ -250,6 +255,7 @@ def run_sync(
250255
message_history: Sequence[_messages.ModelMessage] | None = None,
251256
deferred_tool_results: DeferredToolResults | None = None,
252257
model: models.Model | models.KnownModelName | str | None = None,
258+
instructions: Instructions[AgentDepsT] = None,
253259
deps: AgentDepsT = None,
254260
model_settings: ModelSettings | None = None,
255261
usage_limits: _usage.UsageLimits | None = None,
@@ -269,6 +275,7 @@ def run_sync(
269275
message_history: Sequence[_messages.ModelMessage] | None = None,
270276
deferred_tool_results: DeferredToolResults | None = None,
271277
model: models.Model | models.KnownModelName | str | None = None,
278+
instructions: Instructions[AgentDepsT] = None,
272279
deps: AgentDepsT = None,
273280
model_settings: ModelSettings | None = None,
274281
usage_limits: _usage.UsageLimits | None = None,
@@ -287,6 +294,7 @@ def run_sync(
287294
message_history: Sequence[_messages.ModelMessage] | None = None,
288295
deferred_tool_results: DeferredToolResults | None = None,
289296
model: models.Model | models.KnownModelName | str | None = None,
297+
instructions: Instructions[AgentDepsT] = None,
290298
deps: AgentDepsT = None,
291299
model_settings: ModelSettings | None = None,
292300
usage_limits: _usage.UsageLimits | None = None,
@@ -319,6 +327,7 @@ def run_sync(
319327
message_history: History of the conversation so far.
320328
deferred_tool_results: Optional results for deferred tool calls in the message history.
321329
model: Optional model to use for this run, required if `model` was not set when creating the agent.
330+
instructions: Optional additional instructions to use for this run.
322331
deps: Optional dependencies to use for this run.
323332
model_settings: Optional settings to use for this model's request.
324333
usage_limits: Optional limits on model request count or token usage.
@@ -341,6 +350,7 @@ def run_sync(
341350
message_history=message_history,
342351
deferred_tool_results=deferred_tool_results,
343352
model=model,
353+
instructions=instructions,
344354
deps=deps,
345355
model_settings=model_settings,
346356
usage_limits=usage_limits,
@@ -361,6 +371,7 @@ def run_stream(
361371
message_history: Sequence[_messages.ModelMessage] | None = None,
362372
deferred_tool_results: DeferredToolResults | None = None,
363373
model: models.Model | models.KnownModelName | str | None = None,
374+
instructions: Instructions[AgentDepsT] = None,
364375
deps: AgentDepsT = None,
365376
model_settings: ModelSettings | None = None,
366377
usage_limits: _usage.UsageLimits | None = None,
@@ -380,6 +391,7 @@ def run_stream(
380391
message_history: Sequence[_messages.ModelMessage] | None = None,
381392
deferred_tool_results: DeferredToolResults | None = None,
382393
model: models.Model | models.KnownModelName | str | None = None,
394+
instructions: Instructions[AgentDepsT] = None,
383395
deps: AgentDepsT = None,
384396
model_settings: ModelSettings | None = None,
385397
usage_limits: _usage.UsageLimits | None = None,
@@ -399,6 +411,7 @@ async def run_stream( # noqa C901
399411
message_history: Sequence[_messages.ModelMessage] | None = None,
400412
deferred_tool_results: DeferredToolResults | None = None,
401413
model: models.Model | models.KnownModelName | str | None = None,
414+
instructions: Instructions[AgentDepsT] = None,
402415
deps: AgentDepsT = None,
403416
model_settings: ModelSettings | None = None,
404417
usage_limits: _usage.UsageLimits | None = None,
@@ -439,6 +452,7 @@ async def main():
439452
message_history: History of the conversation so far.
440453
deferred_tool_results: Optional results for deferred tool calls in the message history.
441454
model: Optional model to use for this run, required if `model` was not set when creating the agent.
455+
instructions: Optional additional instructions to use for this run.
442456
deps: Optional dependencies to use for this run.
443457
model_settings: Optional settings to use for this model's request.
444458
usage_limits: Optional limits on model request count or token usage.
@@ -468,6 +482,7 @@ async def main():
468482
deferred_tool_results=deferred_tool_results,
469483
model=model,
470484
deps=deps,
485+
instructions=instructions,
471486
model_settings=model_settings,
472487
usage_limits=usage_limits,
473488
usage=usage,
@@ -716,6 +731,7 @@ def run_stream_events(
716731
message_history: Sequence[_messages.ModelMessage] | None = None,
717732
deferred_tool_results: DeferredToolResults | None = None,
718733
model: models.Model | models.KnownModelName | str | None = None,
734+
instructions: Instructions[AgentDepsT] = None,
719735
deps: AgentDepsT = None,
720736
model_settings: ModelSettings | None = None,
721737
usage_limits: _usage.UsageLimits | None = None,
@@ -734,6 +750,7 @@ def run_stream_events(
734750
message_history: Sequence[_messages.ModelMessage] | None = None,
735751
deferred_tool_results: DeferredToolResults | None = None,
736752
model: models.Model | models.KnownModelName | str | None = None,
753+
instructions: Instructions[AgentDepsT] = None,
737754
deps: AgentDepsT = None,
738755
model_settings: ModelSettings | None = None,
739756
usage_limits: _usage.UsageLimits | None = None,
@@ -751,6 +768,7 @@ def run_stream_events(
751768
message_history: Sequence[_messages.ModelMessage] | None = None,
752769
deferred_tool_results: DeferredToolResults | None = None,
753770
model: models.Model | models.KnownModelName | str | None = None,
771+
instructions: Instructions[AgentDepsT] = None,
754772
deps: AgentDepsT = None,
755773
model_settings: ModelSettings | None = None,
756774
usage_limits: _usage.UsageLimits | None = None,
@@ -800,6 +818,7 @@ async def main():
800818
message_history: History of the conversation so far.
801819
deferred_tool_results: Optional results for deferred tool calls in the message history.
802820
model: Optional model to use for this run, required if `model` was not set when creating the agent.
821+
instructions: Optional additional instructions to use for this run.
803822
deps: Optional dependencies to use for this run.
804823
model_settings: Optional settings to use for this model's request.
805824
usage_limits: Optional limits on model request count or token usage.
@@ -824,6 +843,7 @@ async def main():
824843
message_history=message_history,
825844
deferred_tool_results=deferred_tool_results,
826845
model=model,
846+
instructions=instructions,
827847
deps=deps,
828848
model_settings=model_settings,
829849
usage_limits=usage_limits,
@@ -840,6 +860,7 @@ async def _run_stream_events(
840860
message_history: Sequence[_messages.ModelMessage] | None = None,
841861
deferred_tool_results: DeferredToolResults | None = None,
842862
model: models.Model | models.KnownModelName | str | None = None,
863+
instructions: Instructions[AgentDepsT] = None,
843864
deps: AgentDepsT = None,
844865
model_settings: ModelSettings | None = None,
845866
usage_limits: _usage.UsageLimits | None = None,
@@ -865,6 +886,7 @@ async def run_agent() -> AgentRunResult[Any]:
865886
message_history=message_history,
866887
deferred_tool_results=deferred_tool_results,
867888
model=model,
889+
instructions=instructions,
868890
deps=deps,
869891
model_settings=model_settings,
870892
usage_limits=usage_limits,
@@ -893,6 +915,7 @@ def iter(
893915
message_history: Sequence[_messages.ModelMessage] | None = None,
894916
deferred_tool_results: DeferredToolResults | None = None,
895917
model: models.Model | models.KnownModelName | str | None = None,
918+
instructions: Instructions[AgentDepsT] = None,
896919
deps: AgentDepsT = None,
897920
model_settings: ModelSettings | None = None,
898921
usage_limits: _usage.UsageLimits | None = None,
@@ -911,6 +934,7 @@ def iter(
911934
message_history: Sequence[_messages.ModelMessage] | None = None,
912935
deferred_tool_results: DeferredToolResults | None = None,
913936
model: models.Model | models.KnownModelName | str | None = None,
937+
instructions: Instructions[AgentDepsT] = None,
914938
deps: AgentDepsT = None,
915939
model_settings: ModelSettings | None = None,
916940
usage_limits: _usage.UsageLimits | None = None,
@@ -930,6 +954,7 @@ async def iter(
930954
message_history: Sequence[_messages.ModelMessage] | None = None,
931955
deferred_tool_results: DeferredToolResults | None = None,
932956
model: models.Model | models.KnownModelName | str | None = None,
957+
instructions: Instructions[AgentDepsT] = None,
933958
deps: AgentDepsT = None,
934959
model_settings: ModelSettings | None = None,
935960
usage_limits: _usage.UsageLimits | None = None,
@@ -1003,6 +1028,7 @@ async def main():
10031028
message_history: History of the conversation so far.
10041029
deferred_tool_results: Optional results for deferred tool calls in the message history.
10051030
model: Optional model to use for this run, required if `model` was not set when creating the agent.
1031+
instructions: Optional additional instructions to use for this run.
10061032
deps: Optional dependencies to use for this run.
10071033
model_settings: Optional settings to use for this model's request.
10081034
usage_limits: Optional limits on model request count or token usage.

pydantic_ai_slim/pydantic_ai/agent/wrapper.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ def iter(
7676
message_history: Sequence[_messages.ModelMessage] | None = None,
7777
deferred_tool_results: DeferredToolResults | None = None,
7878
model: models.Model | models.KnownModelName | str | None = None,
79+
instructions: Instructions[AgentDepsT] = None,
7980
deps: AgentDepsT = None,
8081
model_settings: ModelSettings | None = None,
8182
usage_limits: _usage.UsageLimits | None = None,
@@ -94,6 +95,7 @@ def iter(
9495
message_history: Sequence[_messages.ModelMessage] | None = None,
9596
deferred_tool_results: DeferredToolResults | None = None,
9697
model: models.Model | models.KnownModelName | str | None = None,
98+
instructions: Instructions[AgentDepsT] = None,
9799
deps: AgentDepsT = None,
98100
model_settings: ModelSettings | None = None,
99101
usage_limits: _usage.UsageLimits | None = None,
@@ -112,6 +114,7 @@ async def iter(
112114
message_history: Sequence[_messages.ModelMessage] | None = None,
113115
deferred_tool_results: DeferredToolResults | None = None,
114116
model: models.Model | models.KnownModelName | str | None = None,
117+
instructions: Instructions[AgentDepsT] = None,
115118
deps: AgentDepsT = None,
116119
model_settings: ModelSettings | None = None,
117120
usage_limits: _usage.UsageLimits | None = None,
@@ -185,6 +188,7 @@ async def main():
185188
message_history: History of the conversation so far.
186189
deferred_tool_results: Optional results for deferred tool calls in the message history.
187190
model: Optional model to use for this run, required if `model` was not set when creating the agent.
191+
instructions: Optional additional instructions to use for this run.
188192
deps: Optional dependencies to use for this run.
189193
model_settings: Optional settings to use for this model's request.
190194
usage_limits: Optional limits on model request count or token usage.
@@ -202,6 +206,7 @@ async def main():
202206
message_history=message_history,
203207
deferred_tool_results=deferred_tool_results,
204208
model=model,
209+
instructions=instructions,
205210
deps=deps,
206211
model_settings=model_settings,
207212
usage_limits=usage_limits,

0 commit comments

Comments
 (0)