The useAgent
hook is a Agent AI tool for simulating the cognitive steps someone might take when answering a question.
Importing the Hook
To use the useAgent
hook, first, ensure that it's imported into your React component.
import { useAgent } from 'polyfire-js/hooks;
Actions
To enable the agent to perform specific tasks, you need to define the actions
that the agent will use. Each action is represented as an object with a name
, description
, callback
, and example
, all are required.
The action type is:
{
name: string, // Action name
description: string, // Description of what the action does
callback: (param: string) => Promise<string | undefined>, // This is the function that'll be executed for this action
example: {
question: string,
process: [
{
thought: string,
action: string,
observation: string,
}
]
}
}
Writing the Examples
Each action will need to have some examples of how it is used. This is necessary for the LLM to understand what the action actually does.
For example, a basic search function that allows the Agent to search on the web could have these examples:
[
{
question:
'Musician and satirist Allie Goertz wrote a song about the "The Simpsons" character Milhouse, who Matt Groening named after who?',
process: [
{
thought:
'The question simplifies to "The Simpsons" character Milhouse is named after who. I only need to search Milhouse and find who it is named after.',
action: "Search[Milhouse]",
observation:
"Milhouse Mussolini Van Houten is a recurring character in the Fox animated television series The Simpsons voiced by Pamela Hayden and created by Matt Groening.",
},
{
thought:
'The paragraph does not tell who Milhouse is named after, maybe I can look up "The Simpsons Milhouse named after".',
action: "Search[The Simpsons Milhouse named after]",
observation:
"Milhouse was named after U.S. president Richard Nixon, whose middle name was Milhous.",
},
{
thought:
"Milhouse was named after U.S. president Richard Nixon, so the answer is Richard Nixon.",
action: "Finish[Richard Nixon]",
observation: "",
},
],
}
]
UseAgent
Now that we have the actions defined, we can call useAgent with the action list. The second parameter is a GenerationOptions
as defined in generate
NOTE:
In our tests, the agents were not working correctly if we didn't use GPT-4. Using GPT-3.5 will make them hallucinate or forget actions as well as getting stuck in endless loops.
You can still test it with other models but you've been warned.
const { start, stop } = useAgent(actions, {
model: "gpt-4",
provider: "openai",
});
Start the agent
After the agent has been initialized with all its action, you can use the start
function to give it a task to accomplish.
function start(question: string, progress?: (step: number, result: string) => void): Promise<string>
If you want to log/use the reasoning of the agent, you can use the progress function.
If you want to stop the agent early you can call the function stop()
.
Example Usage
Here's how you might use the useAgent
hook in a component:
import { useState } from "react";
import { usePolyfire, useAgent, DefinitionAction } from "polyfire-js/hooks";
export const examples = [
{
question:
'Musician and satirist Allie Goertz wrote a song about the "The Simpsons" character Milhouse, who Matt Groening named after who?',
process: [
{
thought:
'The question simplifies to "The Simpsons" character Milhouse is named after who. I only need to search Milhouse and find who it is named after.',
action: "Search[Milhouse]",
observation:
"Milhouse Mussolini Van Houten is a recurring character in the Fox animated television series The Simpsons voiced by Pamela Hayden and created by Matt Groening.",
},
{
thought:
'The paragraph does not tell who Milhouse is named after, maybe I can look up "The Simpsons Milhouse named after".',
action: "Search[The Simpsons Milhouse named after]",
observation:
"Milhouse was named after U.S. president Richard Nixon, whose middle name was Milhous.",
},
{
thought:
"Milhouse was named after U.S. president Richard Nixon, so the answer is Richard Nixon.",
action: "Finish[Richard Nixon]",
observation: "",
},
],
}
];
export default function App() {
const { auth: { login }, models } = usePolyfire();
const search = async (request: string) => {
const page = await models?.generate(request, {
web: true,
});
return page;
};
const actions: DefinitionAction[] = [
{
name: "Search",
description: "Use this action if you have to search on the web",
callback: search,
example: examples[0],
}
];
const { start, stop } = useAgent(actions, {
provider: "openai",
model: "gpt-4",
});
const [answer, setAnswer] = useState<string | null>(null);
const [status, setStatus] = useState("idle"); // 'idle', 'processing', 'completed'
const getAnswer = async () => {
setStatus("processing");
try {
const response = await start(
"How is jean-baptiste dutrou-bordier ?",
(step, result) => {
console.log(`Step: ${step}, Result: ${result}`);
}
);
setAnswer(response);
setStatus("completed");
} catch (error) {
console.error("An error occurred:", error);
setStatus("idle");
}
};
const loginButton = login && (
<button onClick={() => login({ provider: "google" })} className="login-btn">
Login with Google
</button>
);
const agentBox = (
<div>
<button onClick={getAnswer}>Get Answer</button>
{status === "processing" && <p>Processing...</p>}
{status === "completed" && answer && <p>Answer: {answer}</p>}
<button onClick={stop}>Stop</button>
</div>
);
return <div>{login ? loginButton : agentBox}</div>;
}