Skip to main content

Conversational

This walkthrough demonstrates how to use an agent optimized for conversation. Other agents are often optimized for using tools to figure out the best response, which is not ideal in a conversational setting where you may want the agent to be able to chat with the user as well.

This example shows how to construct an agent using LCEL. Constructing agents this way allows for customization beyond what previous methods like using initializeAgentExecutorWithOptions allow.

Using LCEL

npm install @langchain/openai
import { ChatOpenAI } from "@langchain/openai";
import { AgentExecutor } from "langchain/agents";
import { Calculator } from "@langchain/community/tools/calculator";
import { pull } from "langchain/hub";
import { BufferMemory } from "langchain/memory";
import { formatLogToString } from "langchain/agents/format_scratchpad/log";
import { renderTextDescription } from "langchain/tools/render";
import { ReActSingleInputOutputParser } from "langchain/agents/react/output_parser";
import { PromptTemplate } from "@langchain/core/prompts";
import { RunnableSequence } from "@langchain/core/runnables";
import { AgentStep } from "@langchain/core/agents";
import { BaseMessage } from "@langchain/core/messages";
import { SerpAPI } from "@langchain/community/tools/serpapi";

/** Define your chat model */
const model = new ChatOpenAI({ model: "gpt-4" });
/** Bind a stop token to the model */
const modelWithStop = model.bind({
stop: ["\nObservation"],
});
/** Define your list of tools */
const tools = [
new SerpAPI(process.env.SERPAPI_API_KEY, {
location: "Austin,Texas,United States",
hl: "en",
gl: "us",
}),
new Calculator(),
];
/**
* Pull a prompt from LangChain Hub
* @link https://smith.langchain.com/hub/hwchase17/react-chat
*/
const prompt = await pull<PromptTemplate>("hwchase17/react-chat");
/** Add input variables to prompt */
const toolNames = tools.map((tool) => tool.name);
const promptWithInputs = await prompt.partial({
tools: renderTextDescription(tools),
tool_names: toolNames.join(","),
});

const runnableAgent = RunnableSequence.from([
{
input: (i: {
input: string;
steps: AgentStep[];
chat_history: BaseMessage[];
}) => i.input,
agent_scratchpad: (i: {
input: string;
steps: AgentStep[];
chat_history: BaseMessage[];
}) => formatLogToString(i.steps),
chat_history: (i: {
input: string;
steps: AgentStep[];
chat_history: BaseMessage[];
}) => i.chat_history,
},
promptWithInputs,
modelWithStop,
new ReActSingleInputOutputParser({ toolNames }),
]);
/**
* Define your memory store
* @important The memoryKey must be "chat_history" for the chat agent to work
* because this is the key this particular prompt expects.
*/
const memory = new BufferMemory({ memoryKey: "chat_history" });
/** Define your executor and pass in the agent, tools and memory */
const executor = AgentExecutor.fromAgentAndTools({
agent: runnableAgent,
tools,
memory,
});

console.log("Loaded agent.");

const input0 = "hi, i am bob";
const result0 = await executor.invoke({ input: input0 });
console.log(`Got output ${result0.output}`);

const input1 = "whats my name?";
const result1 = await executor.invoke({ input: input1 });
console.log(`Got output ${result1.output}`);

const input2 = "whats the weather in pomfret?";
const result2 = await executor.invoke({ input: input2 });
console.log(`Got output ${result2.output}`);
/**
* Loaded agent.
* Got output Hello Bob, how can I assist you today?
* Got output Your name is Bob.
* Got output The current weather in Pomfret, CT is partly cloudy with a temperature of 59 degrees Fahrenheit. The humidity is at 52% and there is a wind speed of 8 mph. There is a 0% chance of precipitation.
*/

API Reference:

Using initializeAgentExecutorWithOptions

The example below covers how to create a conversational agent for a chat model. It will utilize chat specific prompts.

import { ChatOpenAI } from "@langchain/openai";
import { initializeAgentExecutorWithOptions } from "langchain/agents";
import { Calculator } from "@langchain/community/tools/calculator";
import { SerpAPI } from "@langchain/community/tools/serpapi";

export const run = async () => {
process.env.LANGCHAIN_HANDLER = "langchain";
const model = new ChatOpenAI({ temperature: 0 });
const tools = [
new SerpAPI(process.env.SERPAPI_API_KEY, {
location: "Austin,Texas,United States",
hl: "en",
gl: "us",
}),
new Calculator(),
];

// Passing "chat-conversational-react-description" as the agent type
// automatically creates and uses BufferMemory with the executor.
// If you would like to override this, you can pass in a custom
// memory option, but the memoryKey set on it must be "chat_history".
const executor = await initializeAgentExecutorWithOptions(tools, model, {
agentType: "chat-conversational-react-description",
verbose: true,
});
console.log("Loaded agent.");

const input0 = "hi, i am bob";

const result0 = await executor.invoke({ input: input0 });

console.log(`Got output ${result0.output}`);

const input1 = "whats my name?";

const result1 = await executor.invoke({ input: input1 });

console.log(`Got output ${result1.output}`);

const input2 = "whats the weather in pomfret?";

const result2 = await executor.invoke({ input: input2 });

console.log(`Got output ${result2.output}`);
};

API Reference:

Loaded agent.
Entering new agent_executor chain...
{
"action": "Final Answer",
"action_input": "Hello Bob! How can I assist you today?"
}
Finished chain.
Got output Hello Bob! How can I assist you today?
Entering new agent_executor chain...
{
"action": "Final Answer",
"action_input": "Your name is Bob."
}
Finished chain.
Got output Your name is Bob.
Entering new agent_executor chain...
```json
{
"action": "search",
"action_input": "weather in pomfret"
}
```
A steady rain early...then remaining cloudy with a few showers. High 48F. Winds WNW at 10 to 15 mph. Chance of rain 80%.
```json
{
"action": "Final Answer",
"action_input": "The weather in Pomfret is a steady rain early...then remaining cloudy with a few showers. High 48F. Winds WNW at 10 to 15 mph. Chance of rain 80%."
}
```
Finished chain.
Got output The weather in Pomfret is a steady rain early...then remaining cloudy with a few showers. High 48F. Winds WNW at 10 to 15 mph. Chance of rain 80%.

Help us out by providing feedback on this documentation page: