Skip to content

Commit 9d7114f

Browse files
authored
fix broken links and add type checking function (#97)
1 parent 1f0e225 commit 9d7114f

File tree

8 files changed

+76
-14
lines changed

8 files changed

+76
-14
lines changed

docs/agents.md

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ but multiple agents can also interact to embody more complex workflows.
88
The [`Agent`][pydantic_ai.Agent] class has full API documentation, but conceptually you can think of an agent as a container for:
99

1010
* A [system prompt](#system-prompts) — a set of instructions for the LLM written by the developer
11-
* One or more [retrieval tool](#tools) — functions that the LLM may call to get information while generating a response
11+
* One or more [retrieval tool](#function-tools) — functions that the LLM may call to get information while generating a response
1212
* An optional structured [result type](results.md) — the structured datatype the LLM must return at the end of a run
1313
* A [dependency](dependencies.md) type constraint — system prompt functions, tools and result validators may all use dependencies when they're run
1414
* Agents may optionally also have a default [LLM model](api/models/base.md) associated with them; the model to use can also be specified when running the agent
1515

16-
In typing terms, agents are generic in their dependency and result types, e.g., an agent which required dependencies of type `#!python Foobar` and returned results of type `#!python list[str]` would have type `#!python Agent[Foobar, list[str]]`.
16+
In typing terms, agents are generic in their dependency and result types, e.g., an agent which required dependencies of type `#!python Foobar` and returned results of type `#!python list[str]` would have type `cAgent[Foobar, list[str]]`. In practice, you shouldn't need to care about this, it should just mean your IDE can tell you when you have the right type, and if you choose to use [static type checking](#static-type-checking) it should work well with PydanticAI.
1717

1818
Here's a toy example of an agent that simulates a roulette wheel:
1919

@@ -394,9 +394,9 @@ If a tool has a single parameter that can be represented as an object in JSON sc
394394

395395
## Reflection and self-correction
396396

397-
Validation errors from both tool parameter validation and [structured result validation](results.md#structured-result-validation) can be passed back to the model with a request to retry.
397+
Validation errors from both function tool parameter validation and [structured result validation](results.md#structured-result-validation) can be passed back to the model with a request to retry.
398398

399-
You can also raise [`ModelRetry`][pydantic_ai.exceptions.ModelRetry] from within a [tool](#tools) or [result validator function](results.md#result-validators-functions) to tell the model it should retry generating a response.
399+
You can also raise [`ModelRetry`][pydantic_ai.exceptions.ModelRetry] from within a [tool](#function-tools) or [result validator function](results.md#result-validators-functions) to tell the model it should retry generating a response.
400400

401401
- The default retry count is **1** but can be altered for the [entire agent][pydantic_ai.Agent.__init__], a [specific tool][pydantic_ai.Agent.tool], or a [result validator][pydantic_ai.Agent.__init__].
402402
- You can access the current retry count from within a tool or result validator via [`ctx.retry`][pydantic_ai.dependencies.CallContext].
@@ -518,3 +518,64 @@ else:
518518
1. Define a tool that will raise `ModelRetry` repeatedly in this case.
519519

520520
_(This example is complete, it can be run "as is")_
521+
522+
## Static Type Checking
523+
524+
PydanticAI is designed to work well with static type checkers, like mypy and pyright.
525+
526+
!!! tip "mypy vs. pyright"
527+
[mypy](https://github.com/python/mypy) and [pyright](https://github.com/microsoft/pyright) are both static type checkers for Python.
528+
529+
Mypy was the first and is still generally considered the default, in part because it was developed parly by Guido van Rossum, the creator of Python.
530+
531+
Pyright is generally faster and more sophisticated. It is develoepd by Eric Trout for use in VSCode, since that's its primary use case, it's terminal output is more verbose and harder to read than that of mypy.
532+
533+
In particular, agents are generic in both the type of their dependencies and the type of results they return, so you can use the type hints to ensure you're using the right types.
534+
535+
Consider the following script with type mistakes:
536+
537+
```py title="type_mistakes.py" hl_lines="18 28"
538+
from dataclasses import dataclass
539+
540+
from pydantic_ai import Agent, CallContext
541+
542+
543+
@dataclass
544+
class User:
545+
name: str
546+
547+
548+
agent = Agent(
549+
'test',
550+
deps_type=User, # (1)!
551+
result_type=bool,
552+
)
553+
554+
555+
@agent.system_prompt
556+
def add_user_name(ctx: CallContext[str]) -> str: # (2)!
557+
return f"The user's name is {ctx.deps}."
558+
559+
560+
def foobar(x: bytes) -> None:
561+
pass
562+
563+
564+
result = agent.run_sync('Does their name start with "A"?', deps=User('Adam'))
565+
foobar(result.data) # (3)!
566+
```
567+
568+
1. The agent is defined as expecting an instance of `User` as `deps`.
569+
2. But here `add_user_name` is defined as taking a `str` as the dependency, not a `User`.
570+
3. Since the agent is defined as returning a `bool`, this will raise a type error since `foobar` expects `bytes`.
571+
572+
Running `mypy` on this will give the following output:
573+
574+
```bash
575+
➤ uv run mypy type_mistakes.py
576+
type_mistakes.py:18: error: Argument 1 to "system_prompt" of "Agent" has incompatible type "Callable[[CallContext[str]], str]"; expected "Callable[[CallContext[User]], str]" [arg-type]
577+
type_mistakes.py:28: error: Argument 1 to "foobar" has incompatible type "bool"; expected "bytes" [arg-type]
578+
Found 2 errors in 1 file (checked 1 source file)
579+
```
580+
581+
Running `pyright` would identify the same issues.

docs/dependencies.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Dependencies
22

3-
PydanticAI uses a dependency injection system to provide data and services to your agent's [system prompts](agents.md#system-prompts), [tools](agents.md#tools) and [result validators](results.md#result-validators-functions).
3+
PydanticAI uses a dependency injection system to provide data and services to your agent's [system prompts](agents.md#system-prompts), [tools](agents.md#function-tools) and [result validators](results.md#result-validators-functions).
44

55
Matching PydanticAI's design philosophy, our dependency system tries to use existing best practice in Python development rather than inventing esoteric "magic", this should make dependencies type-safe, understandable easier to test and ultimately easier to deploy in production.
66

@@ -158,7 +158,7 @@ _(This example is complete, it can be run "as is")_
158158

159159
## Full Example
160160

161-
As well as system prompts, dependencies can be used in [tools](agents.md#tools) and [result validators](results.md#result-validators-functions).
161+
As well as system prompts, dependencies can be used in [tools](agents.md#function-tools) and [result validators](results.md#result-validators-functions).
162162

163163
```py title="full_example.py" hl_lines="27-35 38-48"
164164
from dataclasses import dataclass

docs/examples/bank-support.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Demonstrates:
44

55
* [dynamic system prompt](../agents.md#system-prompts)
66
* [structured `result_type`](../results.md#structured-result-validation)
7-
* [tools](../agents.md#tools)
7+
* [tools](../agents.md#function-tools)
88

99
## Running the Example
1010

docs/examples/rag.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ RAG search example. This demo allows you to ask question of the [logfire](https:
44

55
Demonstrates:
66

7-
* [tools](../agents.md#tools)
7+
* [tools](../agents.md#function-tools)
88
* [agent dependencies](../dependencies.md)
99
* RAG search
1010

docs/examples/weather-agent.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Example of PydanticAI with multiple tools which the LLM needs to call in turn to
22

33
Demonstrates:
44

5-
* [tools](../agents.md#tools)
5+
* [tools](../agents.md#function-tools)
66
* [agent dependencies](../dependencies.md)
77

88
In this case the idea is a "weather" agent — the user can ask for the weather in multiple locations,

docs/index.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,11 @@ async def main():
124124

125125
1. This [agent](agents.md) will act as first-tier support in a bank. Agents are generic in the type of dependencies they accept and the type of result they return. In this case, the support agent has type `#!python Agent[SupportDependencies, SupportResult]`.
126126
2. Here we configure the agent to use [OpenAI's GPT-4o model](api/models/openai.md), you can also set the model when running the agent.
127-
3. The `SupportDependencies` dataclass is used to pass data, connections, and logic into the model that will be needed when running [system prompt](agents.md#system-prompts) and [tool](agents.md#tools) functions. PydanticAI's system of dependency injection provides a type-safe way to customise the behavior of your agents, and can be especially useful when running unit tests and evals.
127+
3. The `SupportDependencies` dataclass is used to pass data, connections, and logic into the model that will be needed when running [system prompt](agents.md#system-prompts) and [tool](agents.md#function-tools) functions. PydanticAI's system of dependency injection provides a type-safe way to customise the behavior of your agents, and can be especially useful when running unit tests and evals.
128128
4. Static [system prompts](agents.md#system-prompts) can be registered with the [`system_prompt` keyword argument][pydantic_ai.Agent.__init__] to the agent.
129129
5. Dynamic [system prompts](agents.md#system-prompts) can be registered with the [`@agent.system_prompt`][pydantic_ai.Agent.system_prompt] decorator, and can make use of dependency injection. Dependencies are carried via the [`CallContext`][pydantic_ai.dependencies.CallContext] argument, which is parameterized with the `deps_type` from above. If the type annotation here is wrong, static type checkers will catch it.
130-
6. [Tools](agents.md#tools) let you register "tools" which the LLM may call while responding to a user. Again, dependencies are carried via [`CallContext`][pydantic_ai.dependencies.CallContext], and any other arguments become the tool schema passed to the LLM. Pydantic is used to validate these arguments, and errors are passed back to the LLM so it can retry.
131-
7. The docstring of a tool is also passed to the LLM as the description of the tool. Parameter descriptions are [extracted](agents.md#tools-tools-and-schema) from the docstring and added to the tool schema sent to the LLM.
130+
6. [Tools](agents.md#function-tools) let you register "tools" which the LLM may call while responding to a user. Again, dependencies are carried via [`CallContext`][pydantic_ai.dependencies.CallContext], and any other arguments become the tool schema passed to the LLM. Pydantic is used to validate these arguments, and errors are passed back to the LLM so it can retry.
131+
7. The docstring of a tool is also passed to the LLM as the description of the tool. Parameter descriptions are [extracted](agents.md#function-tools-and-schema) from the docstring and added to the tool schema sent to the LLM.
132132
8. [Run the agent](agents.md#running-agents) asynchronously, conducting a conversation with the LLM until a final response is reached. Even in this fairly simple case, the agent will exchange multiple messages with the LLM as tools are called to retrieve a result.
133133
9. The response from the agent will, be guaranteed to be a `SupportResult`, if validation fails [reflection](agents.md#reflection-and-self-correction) will mean the agent is prompted to try again.
134134
10. The result will be validated with Pydantic to guarantee it is a `SupportResult`, since the agent is generic, it'll also be typed as a `SupportResult` to aid with static type checking.

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ validation:
9393
omitted_files: warn
9494
absolute_links: warn
9595
unrecognized_links: warn
96+
anchors: warn
9697

9798
extra_css:
9899
- 'extra/tweaks.css'

pydantic_ai_slim/pydantic_ai/agent.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ def tool(
448448
Can decorate a sync or async functions.
449449
450450
The docstring is inspected to extract both the tool description and description of each parameter,
451-
[learn more](../agents.md#tools-tools-and-schema).
451+
[learn more](../agents.md#function-tools-and-schema).
452452
453453
We can't add overloads for every possible signature of tool, since the return type is a recursive union
454454
so the signature of functions decorated with `@agent.tool` is obscured.
@@ -506,7 +506,7 @@ def tool_plain(self, func: ToolPlainFunc[ToolParams] | None = None, /, *, retrie
506506
Can decorate a sync or async functions.
507507
508508
The docstring is inspected to extract both the tool description and description of each parameter,
509-
[learn more](../agents.md#tools-tools-and-schema).
509+
[learn more](../agents.md#function-tools-and-schema).
510510
511511
We can't add overloads for every possible signature of tool, since the return type is a recursive union
512512
so the signature of functions decorated with `@agent.tool` is obscured.

0 commit comments

Comments
 (0)