-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
index.ts
122 lines (118 loc) · 3.72 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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 { AgentRunnableSequence } from "../agent.js";
import {
ToolCallingAgentOutputParser,
ToolsAgentStep,
} from "./output_parser.js";
import { formatToToolMessages } from "../format_scratchpad/tool_calling.js";
/**
* Params used by the createOpenAIToolsAgent function.
*/
export type CreateToolCallingAgentParams = {
/**
* LLM to use as the agent. Should work with OpenAI tool calling,
* so must either be an OpenAI model that supports that or a wrapper of
* a different model that adds in equivalent support.
*/
llm: BaseChatModel;
/** Tools this agent has access to. */
tools: StructuredToolInterface[];
/** The prompt to use, must have an input key of `agent_scratchpad`. */
prompt: ChatPromptTemplate;
/**
* Whether to invoke the underlying model in streaming mode,
* allowing streaming of intermediate steps. Defaults to true.
*/
streamRunnable?: boolean;
};
/**
* Create an agent that uses tools.
* @param params Params required to create the agent. Includes an LLM, tools, and prompt.
* @returns A runnable sequence representing an agent. It takes as input all the same input
* variables as the prompt passed in does. It returns as output either an
* AgentAction or AgentFinish.
* @example
* ```typescript
* import { ChatAnthropic } from "@langchain/anthropic";
* import { ChatPromptTemplate, MessagesPlaceholder } from "@langchain/core/prompts";
* import { AgentExecutor, createToolCallingAgent } from "langchain/agents";
*
* const prompt = ChatPromptTemplate.fromMessages(
* [
* ["system", "You are a helpful assistant"],
* ["placeholder", "{chat_history}"],
* ["human", "{input}"],
* ["placeholder", "{agent_scratchpad}"],
* ]
* );
*
*
* const llm = new ChatAnthropic({
* modelName: "claude-3-opus-20240229",
* temperature: 0,
* });
*
* // Define the tools the agent will have access to.
* const tools = [...];
*
* const agent = createToolCallingAgent({ llm, tools, prompt });
*
* const agentExecutor = new AgentExecutor({ agent, tools });
*
* const result = await agentExecutor.invoke({input: "what is LangChain?"});
*
* // Using with chat history
* import { AIMessage, HumanMessage } from "@langchain/core/messages";
*
* const result2 = await agentExecutor.invoke(
* {
* input: "what's my name?",
* chat_history: [
* new HumanMessage({content: "hi! my name is bob"}),
* new AIMessage({content: "Hello Bob! How can I assist you today?"}),
* ],
* }
* );
* ```
*/
export function createToolCallingAgent({
llm,
tools,
prompt,
streamRunnable,
}: CreateToolCallingAgentParams) {
if (!prompt.inputVariables.includes("agent_scratchpad")) {
throw new Error(
[
`Prompt must have an input variable named "agent_scratchpad".`,
`Found ${JSON.stringify(prompt.inputVariables)} instead.`,
].join("\n")
);
}
if (llm.bindTools === undefined) {
throw new Error(
`This agent requires that the "bind_tools()" method be implemented on the input model.`
);
}
const modelWithTools = llm.bindTools(tools);
const agent = AgentRunnableSequence.fromRunnables(
[
RunnablePassthrough.assign({
agent_scratchpad: (input: { steps: ToolsAgentStep[] }) =>
formatToToolMessages(input.steps),
}),
prompt,
modelWithTools,
new ToolCallingAgentOutputParser(),
],
{
name: "ToolCallingAgent",
streamRunnable,
singleAction: false,
}
);
return agent;
}