Skip to content

Commit

Permalink
docs[patch]: Update tool concepts docs (#6134)
Browse files Browse the repository at this point in the history
* Update tool concepts docs

* Fix typo
  • Loading branch information
jacoblee93 authored Jul 18, 2024
1 parent 8ef6465 commit ec89a7b
Showing 1 changed file with 45 additions and 45 deletions.
90 changes: 45 additions & 45 deletions docs/core_docs/docs/concepts.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ This is where information like log-probs and token usage may be stored.
These represent a decision from an language model to call a tool. They are included as part of an `AIMessage` output.
They can be accessed from there with the `.tool_calls` property.

This property returns an array of objects. Each object has the following keys:
This property returns a list of `ToolCall`s. A `ToolCall` is an object with the following arguments:

- `name`: The name of the tool that should be called.
- `args`: The arguments to that tool.
Expand Down Expand Up @@ -558,72 +558,72 @@ A tool consists of:
When a tool is bound to a model, the name, description and JSON schema are provided as context to the model.

Given a list of tools and a set of instructions, a model can request to call one or more tools with specific inputs.
Once the chosen tools are invoked, the results can be passed back to the model so that it can complete whatever task
it's performing.

#### Tool inputs

A tool can take arbitrary arguments as input. At runtime, these arguments can be passed in either:

1. As just the raw arguments.
2. As a `ToolCall`, which contains the arguments along with other metadata like the tool call ID.
Typical usage may look like the following:

```ts
const tool = ...
// Define a list of tools
const tools = [...];
const llmWithTools = llm.bindTools([tool]);
const aiMessage = await llmWithTools.invoke("do xyz...");

const aiMessage = await llmWithTools.invoke("do xyz...");
// AIMessage(tool_calls=[ToolCall(...), ...], ...)
```

const toolCall = aiMessage.tool_calls[0];
The `AIMessage` returned from the model MAY have `tool_calls` associated with it.
Read [this guide](/docs/concepts/#aimessage) for more information on what the response type may look like.

// ToolCall(args={...}, id=..., ...)
Once the tools are chosen, you will usually want to invoke them and then pass the results back to the model so that it can complete whatever task
it's performing.

// 1. pass in args directly
await tool.invoke(toolCall.args);
There are generally two different ways to invoke the tool and pass back the response:

// 2. pass in the whole ToolCall
await tool.invoke(toolCall);
```
#### Invoke with just the arguments

A tool also has access to the `RunnableConfig` that's passed into whatever chain the tool is a part of. This allows you to write tool logic that can be parameterized by the chain config.
When you invoke a tool with just the arguments, you will get back the raw tool output (usually a string).
Here's what this looks like:

```ts
const config = { configurable: { tool_param_foo: ... }};
await tool.invoke(toolCall, config);
import { ToolMessage } from "@langchain/core/messages";

const toolCall = aiMessage.tool_calls[0]; // ToolCall(args={...}, id=..., ...)
const toolOutput = await tool.invoke(toolCall.args);
const toolMessage = new ToolMessage({
content: toolOutput,
name: toolCall.name,
tool_call_id: toolCall.id,
});
```

See the how-to guide for [passing in configs here](/docs/how_to/tool_configure/).

#### Tool outputs

The format of a tool's output depends on the format of the input. If a tool is called:

1. With a dict of its arguments then it will produce an arbitrary output that we assume can be passed to a model as the `ToolMessage.content` field,
2. A `ToolCall` then it will produce a `ToolMessage(content=..., ...)` where the tool output has already been assigned to the `ToolMessage.content` field.
Note that the `content` field will generally be passed back to the model.
If you do not want the raw tool response to be passed to the model, but you still want to keep it around,
you can transform the tool output but also pass it as an artifact (read more about [`ToolMessage.artifact` here](/docs/concepts/#toolmessage))

```ts
// 1. pass in args directly

tool.invoke(toolCall.args);
// -> "tool result foobar..."

// 2. pass in the whole ToolCall

await tool.invoke(toolCall);
// -> ToolMessage(content="tool result foobar...", tool_call_id=..., name="tool_name")
// Same code as above
const responseForModel = someTransformation(response);
const toolMessage = new ToolMessage({
content: responseForModel,
tool_call_id: toolCall.id,
name: toolCall.name,
artifact: response,
});
```

A tool can also be defined to include an artifact when invoked with a `ToolCall`. An artifact is some element of the
tool's execution which is useful to return but shouldn't be sent to the model. The artifact can _only_ be returned
when the tool input is a `ToolCall`:
#### Invoke with `ToolCall`

The other way to invoke a tool is to call it with the full `ToolCall` that was generated by the model.
When you do this, the tool will return a `ToolMessage`.
The benefits of this are that you don't have to write the logic yourself to transform the tool output into a ToolMessage.
Here's what this looks like:

```ts
await toolWithArtifact.invoke(toolCall);
// -> ToolMessage(content="tool result foobar...", tool_call_id=..., name="tool_name", artifact=...).
const toolCall = aiMessage.tool_calls[0];
const toolMessage = await tool.invoke(toolCall);
```

Learn about [`ToolMessage.artifact` here](/docs/concepts/#toolmessage) and about [defining tools that return artifacts here](/docs/how_to/tool_artifacts/).
If you are invoking the tool this way and want to include an [artifact](/docs/concepts/#toolmessage) for the `ToolMessage`, you will need to have the tool return a tuple
with two items: the `content` and the `artifact`.
Read more about [defining tools that return artifacts here](/docs/how_to/tool_artifacts/).

#### Best practices

Expand Down

0 comments on commit ec89a7b

Please sign in to comment.