Skip to content

Commit

Permalink
langchain[minor],docs[minor]: openai formatted tools in create agent …
Browse files Browse the repository at this point in the history
…funcs (#5871)

* langchain[minor]: openai formatted tools in create agent funcs

* add oai formatted tool support to others

* chore: lint files

* docs

* fix build

* update langchain version in doc tips
  • Loading branch information
bracesproul committed Jun 28, 2024
1 parent 4f545f1 commit 056b871
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 15 deletions.
8 changes: 7 additions & 1 deletion docs/core_docs/docs/how_to/chatbots_tools.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,13 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Great! Now let’s assemble our agent:\n"
"Great! Now let’s assemble our agent:\n",
"\n",
"```{=mdx}\n",
":::tip\n",
"As of `langchain` version `0.2.8`, the `createOpenAIToolsAgent` function now supports [OpenAI-formatted tools](https://api.js.langchain.com/interfaces/langchain_core_language_models_base.ToolDefinition.html).\n",
":::\n",
"```\n"
]
},
{
Expand Down
4 changes: 4 additions & 0 deletions docs/core_docs/docs/how_to/generative_ui.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ export const agentExecutor = new AgentExecutor({
});
```

:::tip
As of `langchain` version `0.2.8`, the `createToolCallingAgent` function now supports [OpenAI-formatted tools](https://api.js.langchain.com/interfaces/langchain_core_language_models_base.ToolDefinition.html).
:::

```tsx agent.tsx
async function agent(inputs: { input: string }) {
"use server";
Expand Down
4 changes: 4 additions & 0 deletions docs/core_docs/docs/how_to/stream_agent_client.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ Next, lets define our async function inside which contains the agent logic:
});
```
:::tip
As of `langchain` version `0.2.8`, the `createToolCallingAgent` function now supports [OpenAI-formatted tools](https://api.js.langchain.com/interfaces/langchain_core_language_models_base.ToolDefinition.html).
:::
Here you can see we're doing a few things:
The first is we're defining our list of tools (in this case we're only using a single tool) and pulling in our prompt from the LangChain prompt hub.
Expand Down
8 changes: 7 additions & 1 deletion docs/core_docs/docs/how_to/tools_prompting.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,13 @@
"source": [
"## Creating our prompt\n",
"\n",
"We'll want to write a prompt that specifies the tools the model has access to, the arguments to those tools, and the desired output format of the model. In this case we'll instruct it to output a JSON blob of the form `{\"name\": \"...\", \"arguments\": {...}}`."
"We'll want to write a prompt that specifies the tools the model has access to, the arguments to those tools, and the desired output format of the model. In this case we'll instruct it to output a JSON blob of the form `{\"name\": \"...\", \"arguments\": {...}}`.\n",
"\n",
"```{=mdx}\n",
":::tip\n",
"As of `langchain` version `0.2.8`, the `renderTextDescription` function now supports [OpenAI-formatted tools](https://api.js.langchain.com/interfaces/langchain_core_language_models_base.ToolDefinition.html).\n",
":::\n",
"```"
]
},
{
Expand Down
2 changes: 1 addition & 1 deletion langchain/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -888,7 +888,7 @@
}
},
"dependencies": {
"@langchain/core": "~0.2.0",
"@langchain/core": ">=0.2.9 <0.3.0",
"@langchain/openai": ">=0.1.0 <0.3.0",
"@langchain/textsplitters": "~0.0.0",
"binary-extensions": "^2.2.0",
Expand Down
3 changes: 2 additions & 1 deletion langchain/src/agents/openai_tools/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { ChatPromptTemplate } from "@langchain/core/prompts";
import { RunnablePassthrough } from "@langchain/core/runnables";
import { OpenAIClient } from "@langchain/openai";
import { convertToOpenAITool } from "@langchain/core/utils/function_calling";
import { ToolDefinition } from "@langchain/core/language_models/base";
import { formatToOpenAIToolMessages } from "../format_scratchpad/openai_tools.js";
import {
OpenAIToolsAgentOutputParser,
Expand Down Expand Up @@ -35,7 +36,7 @@ export type CreateOpenAIToolsAgentParams = {
}
>;
/** Tools this agent has access to. */
tools: StructuredToolInterface[];
tools: StructuredToolInterface[] | ToolDefinition[];
/** The prompt to use, must have an input key of `agent_scratchpad`. */
prompt: ChatPromptTemplate;
/**
Expand Down
22 changes: 17 additions & 5 deletions langchain/src/agents/structured_chat/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { zodToJsonSchema, JsonSchema7ObjectType } from "zod-to-json-schema";
import type { StructuredToolInterface } from "@langchain/core/tools";
import type {
BaseLanguageModel,
BaseLanguageModelInterface,
import {
isOpenAITool,
type BaseLanguageModel,
type BaseLanguageModelInterface,
type ToolDefinition,
} from "@langchain/core/language_models/base";
import { RunnablePassthrough } from "@langchain/core/runnables";
import type { BasePromptTemplate } from "@langchain/core/prompts";
Expand All @@ -14,6 +16,7 @@ import {
PromptTemplate,
} from "@langchain/core/prompts";
import { AgentStep } from "@langchain/core/agents";
import { isStructuredTool } from "@langchain/core/utils/function_calling";
import { LLMChain } from "../../chains/llm_chain.js";
import { Optional } from "../../types/type-utils.js";
import {
Expand Down Expand Up @@ -239,7 +242,7 @@ export type CreateStructuredChatAgentParams = {
/** LLM to use as the agent. */
llm: BaseLanguageModelInterface;
/** Tools this agent has access to. */
tools: StructuredToolInterface[];
tools: (StructuredToolInterface | ToolDefinition)[];
/**
* The prompt to use. Must have input keys for
* `tools`, `tool_names`, and `agent_scratchpad`.
Expand Down Expand Up @@ -324,7 +327,16 @@ export async function createStructuredChatAgent({
)}`
);
}
const toolNames = tools.map((tool) => tool.name);
let toolNames: string[] = [];
if (tools.every(isOpenAITool)) {
toolNames = tools.map((tool) => tool.function.name);
} else if (tools.every(isStructuredTool)) {
toolNames = tools.map((tool) => tool.name);
} else {
throw new Error(
"All tools must be either OpenAI or Structured tools, not a mix."
);
}
const partialedPrompt = await prompt.partial({
tools: renderTextDescriptionAndArgs(tools),
tool_names: toolNames.join(", "),
Expand Down
3 changes: 2 additions & 1 deletion langchain/src/agents/tool_calling/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { BaseChatModel } from "@langchain/core/language_models/chat_models";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { StructuredToolInterface } from "@langchain/core/tools";
import { RunnablePassthrough } from "@langchain/core/runnables";
import { ToolDefinition } from "@langchain/core/language_models/base";
import { AgentRunnableSequence } from "../agent.js";
import {
ToolCallingAgentOutputParser,
Expand All @@ -20,7 +21,7 @@ export type CreateToolCallingAgentParams = {
*/
llm: BaseChatModel;
/** Tools this agent has access to. */
tools: StructuredToolInterface[];
tools: StructuredToolInterface[] | ToolDefinition[];
/** The prompt to use, must have an input key of `agent_scratchpad`. */
prompt: ChatPromptTemplate;
/**
Expand Down
34 changes: 30 additions & 4 deletions langchain/src/tools/render.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { zodToJsonSchema, JsonSchema7ObjectType } from "zod-to-json-schema";
import { StructuredToolInterface } from "@langchain/core/tools";
import {
ToolDefinition,
isOpenAITool,
} from "@langchain/core/language_models/base";

/**
* Render the tool name and description in plain text.
Expand All @@ -13,9 +17,21 @@ import { StructuredToolInterface } from "@langchain/core/tools";
* @returns a string of all tools and their descriptions
*/
export function renderTextDescription(
tools: StructuredToolInterface[]
tools: StructuredToolInterface[] | ToolDefinition[]
): string {
return tools.map((tool) => `${tool.name}: ${tool.description}`).join("\n");
if ((tools as unknown[]).every(isOpenAITool)) {
return (tools as ToolDefinition[])
.map(
(tool) =>
`${tool.function.name}${
tool.function.description ? `: ${tool.function.description}` : ""
}`
)
.join("\n");
}
return (tools as StructuredToolInterface[])
.map((tool) => `${tool.name}: ${tool.description}`)
.join("\n");
}

/**
Expand All @@ -30,9 +46,19 @@ export function renderTextDescription(
* @returns a string of all tools, their descriptions and a stringified version of their schemas
*/
export function renderTextDescriptionAndArgs(
tools: StructuredToolInterface[]
tools: StructuredToolInterface[] | ToolDefinition[]
): string {
return tools
if ((tools as unknown[]).every(isOpenAITool)) {
return (tools as ToolDefinition[])
.map(
(tool) =>
`${tool.function.name}${
tool.function.description ? `: ${tool.function.description}` : ""
}, args: ${JSON.stringify(tool.function.parameters)}`
)
.join("\n");
}
return (tools as StructuredToolInterface[])
.map(
(tool) =>
`${tool.name}: ${tool.description}, args: ${JSON.stringify(
Expand Down
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -29532,7 +29532,7 @@ __metadata:
"@gomomento/sdk-core": ^1.51.1
"@jest/globals": ^29.5.0
"@langchain/cohere": ^0.0.8
"@langchain/core": ~0.2.0
"@langchain/core": ">=0.2.9 <0.3.0"
"@langchain/openai": ">=0.1.0 <0.3.0"
"@langchain/scripts": ~0.0.14
"@langchain/textsplitters": ~0.0.0
Expand Down

0 comments on commit 056b871

Please sign in to comment.