agsamantha/node_modules/langchain/dist/agents/mrkl/index.js
2024-10-02 15:15:21 -05:00

132 lines
5.1 KiB
JavaScript

import { PromptTemplate, renderTemplate } from "@langchain/core/prompts";
import { LLMChain } from "../../chains/llm_chain.js";
import { Agent } from "../agent.js";
import { deserializeHelper } from "../helpers.js";
import { ZeroShotAgentOutputParser } from "./outputParser.js";
import { FORMAT_INSTRUCTIONS, PREFIX, SUFFIX } from "./prompt.js";
/**
* Agent for the MRKL chain.
* @augments Agent
* @example
* ```typescript
*
* const agent = new ZeroShotAgent({
* llmChain: new LLMChain({
* llm: new ChatOpenAI({ temperature: 0 }),
* prompt: ZeroShotAgent.createPrompt([new SerpAPI(), new Calculator()], {
* prefix: `Answer the following questions as best you can, but speaking as a pirate might speak. You have access to the following tools:`,
* suffix: `Begin! Remember to speak as a pirate when giving your final answer. Use lots of "Args"
* Question: {input}
* {agent_scratchpad}`,
* inputVariables: ["input", "agent_scratchpad"],
* }),
* }),
* allowedTools: ["search", "calculator"],
* });
*
* const result = await agent.invoke({
* input: `Who is Olivia Wilde's boyfriend? What is his current age raised to the 0.23 power?`,
* });
* ```
*
* @deprecated Use the {@link https://api.js.langchain.com/functions/langchain.agents.createReactAgent.html | createReactAgent method instead}.
*/
export class ZeroShotAgent extends Agent {
static lc_name() {
return "ZeroShotAgent";
}
constructor(input) {
const outputParser = input?.outputParser ?? ZeroShotAgent.getDefaultOutputParser();
super({ ...input, outputParser });
Object.defineProperty(this, "lc_namespace", {
enumerable: true,
configurable: true,
writable: true,
value: ["langchain", "agents", "mrkl"]
});
}
_agentType() {
return "zero-shot-react-description";
}
observationPrefix() {
return "Observation: ";
}
llmPrefix() {
return "Thought:";
}
/**
* Returns the default output parser for the ZeroShotAgent.
* @param fields Optional arguments for the output parser.
* @returns An instance of ZeroShotAgentOutputParser.
*/
static getDefaultOutputParser(fields) {
return new ZeroShotAgentOutputParser(fields);
}
/**
* Validates the tools for the ZeroShotAgent. Throws an error if any tool
* does not have a description.
* @param tools List of tools to validate.
*/
static validateTools(tools) {
const descriptionlessTool = tools.find((tool) => !tool.description);
if (descriptionlessTool) {
const msg = `Got a tool ${descriptionlessTool.name} without a description.` +
` This agent requires descriptions for all tools.`;
throw new Error(msg);
}
}
/**
* Create prompt in the style of the zero shot agent.
*
* @param tools - List of tools the agent will have access to, used to format the prompt.
* @param args - Arguments to create the prompt with.
* @param args.suffix - String to put after the list of tools.
* @param args.prefix - String to put before the list of tools.
* @param args.inputVariables - List of input variables the final prompt will expect.
*/
static createPrompt(tools, args) {
const { prefix = PREFIX, suffix = SUFFIX, inputVariables = ["input", "agent_scratchpad"], } = args ?? {};
const toolStrings = tools
.map((tool) => `${tool.name}: ${tool.description}`)
.join("\n");
const toolNames = tools.map((tool) => tool.name);
const formatInstructions = renderTemplate(FORMAT_INSTRUCTIONS, "f-string", {
tool_names: toolNames,
});
const template = [prefix, toolStrings, formatInstructions, suffix].join("\n\n");
return new PromptTemplate({
template,
inputVariables,
});
}
/**
* Creates a ZeroShotAgent from a Large Language Model and a set of tools.
* @param llm The Large Language Model to use.
* @param tools The tools for the agent to use.
* @param args Optional arguments for creating the agent.
* @returns A new instance of ZeroShotAgent.
*/
static fromLLMAndTools(llm, tools, args) {
ZeroShotAgent.validateTools(tools);
const prompt = ZeroShotAgent.createPrompt(tools, args);
const outputParser = args?.outputParser ?? ZeroShotAgent.getDefaultOutputParser();
const chain = new LLMChain({
prompt,
llm,
callbacks: args?.callbacks ?? args?.callbackManager,
});
return new ZeroShotAgent({
llmChain: chain,
allowedTools: tools.map((t) => t.name),
outputParser,
});
}
static async deserialize(data) {
const { llm, tools, ...rest } = data;
return deserializeHelper(llm, tools, rest, (llm, tools, args) => ZeroShotAgent.fromLLMAndTools(llm, tools, {
prefix: args.prefix,
suffix: args.suffix,
inputVariables: args.input_variables,
}), (args) => new ZeroShotAgent(args));
}
}