-
Notifications
You must be signed in to change notification settings - Fork 5.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New agents tutorial using AgentWorkflow #17926
base: main
Are you sure you want to change the base?
Conversation
|
||
To get a human in the loop, we'll get our tool to emit an event that isn't received by any other step in the workflow. We'll then tell our tool to wait until it receives a specific "reply" event. | ||
|
||
We have built-in `InputRequiredEvent` and `HumanResponseEvent` events to use for this purpose. If you want to capture different forms of human input, you can subclass these events to match your own preferences. Let's import them: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically, any event type is supported here, not just these or subclasses of these (these do however, have special handling for workflow validation when used as step inputs and outputs)
) | ||
``` | ||
|
||
Next we'll create a tool that performs a hypothetical dangerous task. There are a couple ofnew things happening here: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Next we'll create a tool that performs a hypothetical dangerous task. There are a couple ofnew things happening here: | |
Next we'll create a tool that performs a hypothetical dangerous task. There are a couple of new things happening here: | |
As you can see, these are regular vanilla Python functions. The docstring comments provide metadata to the agent about what the tool does: if your LLM is having trouble figuring out which tool to use, these docstrings are what you should tweak first. | ||
|
||
After each function is defined we create `FunctionTool` objects from these functions, which wrap them in a way that the agent can understand. | ||
As you can see, these are regular Python functions. When deciding what tool to use, your agent will use the tool's name, parameters, and docstring to determine what the tool does and whether it's appropriate for the task at hand. So it's important to make sure the docstrings are descriptive and helpful. It will also use the type hints to determine the expected parameters and return type. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be unneeded complexity, but we can also use the Annotated
type in python to give the params themselves text descriptions, beyond just the types
|
||
As usual, you can see the [full code of this example](https://github.com/run-llama/python-agents-tutorial/blob/main/5_human_in_the_loop.py). | ||
|
||
You can do anything you want to capture the input; you could use a GUI, or audio input, or even get another, separate agent involved. Which brings us to our next section, [multi-agent systems](./multi_agent.md). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could also be a good spot to point to the context serialization section
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We maybe don't have to include this yet, but technically we are still using our memory modules (they get stored in the context). You can even pass in memory
into the workflow.run(..., memory=memory)
call, or you can manage it completely outside of the worklfow. Without it, it defaults to an in-memory ChatMemoryBuffer
chat_history = memory.get()
workflow.run(user_msg="...", chat_history=chat_history)
I think I actually prefer the latter, since then you don't have to worry about the memory
object being serializable
Anyways, yea, just realizing I never properly documented that initially
return a + b | ||
|
||
|
||
add_tool = FunctionTool.from_defaults(fn=add) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should still mention FunctionTool here, since it lets your override the tool name/description, and even override the entire schema
The `Settings` is a bundle of configuration data that you pass into different parts of LlamaIndex. You can [learn more about Settings](../../module_guides/supporting_modules/settings.md) and how to customize it. | ||
`stream_complete` is also available as an async method, `astream_complete`. | ||
|
||
## Chat interface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could also detail manual function calling, kind of like this tidbit hidden in the openai notebook
https://docs.llamaindex.ai/en/stable/examples/llm/openai/#manual-tool-calling
This is nice for when you are writing workflows from scratch (although this could also be its own section honestly in another PR someday)
No description provided.