Skip to content

Commit

Permalink
further docs improvements (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelcolvin authored Nov 12, 2024
1 parent 234cde8 commit 5882769
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 71 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ typecheck-mypy:
.PHONY: typecheck # Run static type checking
typecheck: typecheck-pyright

.PHONY: typecheck-both # Run static type checking with both Pyright and Mypy
typecheck-both: typecheck-pyright typecheck-mypy

.PHONY: test # Run tests and collect coverage data
test:
uv run coverage run -m pytest
Expand Down
8 changes: 6 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

You can think of PydanticAI as an Agent Framework or a shim to use Pydantic with LLMs — they're the same thing.

PydanticAI ties to make working with LLMs feel similar to building a web application.
PydanticAI tries to make working with LLMs feel similar to building a web application.

!!! example "In Beta"
PydanticAI is in early beta, the API is subject to change and there's a lot more to do.
[Feedback](https://github.com/pydantic/pydantic-ai/issues) is very welcome!

## Example — Retrievers

Expand Down Expand Up @@ -42,7 +46,7 @@ print(result.all_messages()) # (10)!
2. Here we configure the agent to use OpenAI's GPT-4o model, you can also customise the model when running the agent.
3. We specify a dependency for the agent, in this case an HTTP client, which retrievers will use to make requests to external services. PydanticAI's system of dependency injection provides a powerful, type safe way to customise the behaviour of your agents, including for unit tests and evals.
4. Static system prompts can be registered as key word arguments to the agent, dynamic system prompts can be registered with the `@agent.system_prompot` decorator and benefit from dependency injection.
5. Retrievers let you register "tools" which the LLM can call while trying to respond to a user. You inject dependencies into the retriever with `CallContext`, any other arguments become the tool schema passed to the LLM, Pydantic is used to validate these arguments, errors are passed back to the LLM so it can retry.
5. Retrievers let you register "tools" which the LLM may call while to respond to a user. You inject dependencies into the retriever with `CallContext`, any other arguments become the tool schema passed to the LLM, Pydantic is used to validate these arguments, errors are passed back to the LLM so it can retry.
6. This docstring is also passed to the LLM as a description of the tool.
7. Multiple retrievers can be registered with the same agent, the LLM can choose which (if any) retrievers to call in order to respond to a user.
8. Run the agent synchronously, conducting a conversation with the LLM until a final response is reached. (internally agents are all async, `run_sync` is a helper using `asyncio.run` to call `run()`)
Expand Down
38 changes: 37 additions & 1 deletion docs/install.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,39 @@
# Installation

TODO
PydanticAI is available [on PyPI](https://pypi.org/project/pydantic-ai/) so installation is as simple as:

=== "pip"

```bash
pip install pydantic-ai
```

=== "uv"

```bash
uv add pydantic-ai
```

It requires Python 3.9+.

## Use with Pydantic Logfire

PydanticAI has an excellent (but completely optional) integration with [Pydantic Logfire](https://pydantic.dev/logfire) to help you view and understand agent runs.

To use Logfire, install PydanticAI with the `logfire` optional group:

=== "pip"

```bash
pip install 'pydantic-ai[logfire]'
```

=== "uv"

```bash
uv add 'pydantic-ai[logfire]'
```

From there, follow the [Logfire documentation](https://logfire.pydantic.dev/docs/) to configure Logfire.

TODO screenshot of Logfire with PydanticAI in action.
66 changes: 0 additions & 66 deletions preview.README.md

This file was deleted.

14 changes: 12 additions & 2 deletions pydantic_ai/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@
_logfire = logfire_api.Logfire(otel_scope='pydantic-ai')


class Unset:
"""A sentinel value to indicate that a parameter was not set."""

pass


UNSET = Unset()


@final
@dataclass(init=False)
class Agent(Generic[AgentDeps, ResultData]):
Expand Down Expand Up @@ -62,8 +71,7 @@ def __init__(
result_type: type[ResultData] = str,
*,
system_prompt: str | Sequence[str] = (),
# type here looks odd, but it's required os you can avoid "partially unknown" type errors with `deps=None`
deps: AgentDeps | tuple[()] = (),
deps: AgentDeps | Unset = UNSET,
retries: int = 1,
result_tool_name: str = 'final_result',
result_tool_description: str | None = None,
Expand All @@ -79,6 +87,8 @@ def __init__(
prompts via a function with [`system_prompt`][pydantic_ai.Agent.system_prompt].
deps: The type used for dependency injection, this parameter exists solely to allow you to fully
parameterize the agent, and therefore get the best out of static type checking.
If you're not using deps, but want type checking to pass, you can set `deps=None` to satisfy Pyright
or add a type hint `: Agent[None, <return type>]`.
retries: The default number of retries to allow before raising an error.
result_tool_name: The name of the tool to use for the final result.
result_tool_description: The description of the final result tool.
Expand Down
4 changes: 4 additions & 0 deletions tests/typed_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,7 @@ def foo_result(response: Union[Foo, Bar]) -> str:
def run_sync3() -> None:
result: RunResult[Union[Foo, Bar]] = union_agent.run_sync('testing')
foo_result(result.data)


agent_unknown_deps = Agent() # type: ignore[var-annotated]
agent_known_deps: Agent[None, str] = Agent()

0 comments on commit 5882769

Please sign in to comment.