Creating the Agent

Now that you have a set of tools, you will need an agent to execute them.

The modules/agent/agent.ts file contains an async initAgent() function that the route handler calls with an input and sessionId and expects a string to be returned.

typescript
The initAgent function
Unresolved directive in lesson.adoc - include::https://raw.githubusercontent.com/neo4j-graphacademy/llm-chatbot-python/main/src/modules/agent/agent.ts[tag="function"]

The function should return a runnable sequence that:

  1. Uses the conversation history to rephrase the input into a standalone question

  2. Pass the rephrased question to an agent executor

  3. Return the output as a string

Open agent.ts

Creating a new Agent

First, inside the initAgent() function, use the the initTools() function from the previous lesson to create an array of tools for the agent to use.

typescript
Agent Tools
Unresolved directive in lesson.adoc - include::https://raw.githubusercontent.com/neo4j-graphacademy/llm-chatbot-python/main/src/solutions/modules/agent/agent.ts[tag="tools", indent=0]

Next, the agent will need a set of instructions to follow when processing the request.

You can use the pull() function from @langchain/hub package to pull a pre-written agent prompt from the LangChain Hub. In this case, we can use the hwchase17/openai-functions-agent prompt, a simple prompt designed to work with OpenAI Function agents.

typescript
Agent Tools
Unresolved directive in lesson.adoc - include::https://raw.githubusercontent.com/neo4j-graphacademy/llm-chatbot-python/main/src/solutions/modules/agent/agent.ts[tag="prompt", indent=0]

The llm, tools, and prompt arguments can be passed to the createOpenAIFunctionsAgent() function to create a new Agent instance.

typescript
Agent Tools
Unresolved directive in lesson.adoc - include::https://raw.githubusercontent.com/neo4j-graphacademy/llm-chatbot-python/main/src/solutions/modules/agent/agent.ts[tag="agent", indent=0]

OpenAI Functions Agent

The GPT 3.5-turbo and GPT-4 models are fine-tuned to select the appropriate tool from a list based on its metadata. As such, the OpenAI Functions Agent is an excellent choice for an agent with many tools or complex RAG requirements.

You can view a list of available agents in the LangChain documentation.

Agents are invoked through an instance of an Agent Executor. Use the agent and tools variables to create a new AgentExecutor instance.

typescript
Agent Executor
Unresolved directive in lesson.adoc - include::https://raw.githubusercontent.com/neo4j-graphacademy/llm-chatbot-python/main/src/solutions/modules/agent/agent.ts[tag="executor", indent=0]

Rephrasing the question

The chain must generate a rephrased question before being passed to the agent executor. Luckily, you built the functionality in the Conversation History module.

Use the initRephraseChain() function to create a new instance of the Rephrase Question Chain.

typescript
Rephrase Question Chain
Unresolved directive in lesson.adoc - include::https://raw.githubusercontent.com/neo4j-graphacademy/llm-chatbot-python/main/src/solutions/modules/agent/agent.ts[tag="rephrasechain", indent=0]

Runnable Sequence

Now you have everything you need to build your sequence. It is time to bring everything together.

Get History

Use the RunnablePassthrough.assign() method to get any conversation history from the database.

typescript
Get History
Unresolved directive in lesson.adoc - include::https://raw.githubusercontent.com/neo4j-graphacademy/llm-chatbot-python/main/src/solutions/modules/agent/agent.ts[tag="history", indent=0]

Configurable Options

The second parameter provides a configuration the chain can access and utilize throughout its execution.

This function extracts the sessionId from the config.configurable object, passed as the second argument.

Rephase the question

The chain input has both input and history keys, the expected inputs of the rephaseQuestionChain.

Call .assign() to assign the rephrased question to the rephrasedQuestion key.

typescript
Rephrasing the question
Unresolved directive in lesson.adoc - include::https://raw.githubusercontent.com/neo4j-graphacademy/llm-chatbot-python/main/src/solutions/modules/agent/agent.ts[tag="rephrase", indent=0]

Execute the agent

The agent now has all the information needed to decide which tool to use and generate an output.

Use the .pipe() method to pass the entire input and configuration to the executor.

typescript
Pipe to the executor
Unresolved directive in lesson.adoc - include::https://raw.githubusercontent.com/neo4j-graphacademy/llm-chatbot-python/main/src/solutions/modules/agent/agent.ts[tag="execute", indent=0]

Finally, the agent will return a structured output, including an input field.

Use the .pick() function to return the output value.

typescript
Pick the output
Unresolved directive in lesson.adoc - include::https://raw.githubusercontent.com/neo4j-graphacademy/llm-chatbot-python/main/src/solutions/modules/agent/agent.ts[tag="output", indent=0]

Completed function

If you have followed the steps, your initAgent() implementation should resemble the following.

typescript
Completed initAgent() function
Unresolved directive in lesson.adoc - include::https://raw.githubusercontent.com/neo4j-graphacademy/llm-chatbot-python/main/src/solutions/modules/agent/agent.ts[tag="function", indent=0]

Testing your changes

If you have followed the instructions, you should be able to run the following unit test to verify the response using the npm run test command.

sh
Running the Test
npm run test agent.test.ts
View Unit Test
typescript
agent.test.ts
Unresolved directive in ../../../../includes/test.adoc - include::https://raw.githubusercontent.com/neo4j-graphacademy/llm-chatbot-python/main/src/modules/agent/agent.test.ts[]

Verifying the Test

If every test in the test suite has passed, a new (:Session) node with a .id property of agent-rag-1 will have been created in your database.

The session should have atleast one (:Response) node, linked with a :CONTEXT relationship to a movie with the title Neo4j - Into the Graph.

Click the Check Database button below to verify the tests have succeeded.

Hint

You can compare your code with the solution in src/solutions/modules/agent/agent.ts and double-check that the conditions have been met in the test suite.

Solution

You can compare your code with the solution in src/solutions/modules/agent/agent.ts and double-check that the conditions have been met in the test suite.

You can also run the following Cypher statement to double-check that the index has been created in your database.

cypher
Session, response and context
MATCH (s:Session {id: 'agent-rag-1'})
RETURN s, [
  (s)-[:HAS_RESPONSE]->(r) | [r,
    [ (r) -[:CONTEXT]->(c) | c ]
  ]
]

Once you have verified your code and re-ran the tests, click Try again…​* to complete the challenge.

Summary

In this challenge, you wrote the code to create a chain that rephrases a user input into a standalone question and passes it on to an agent instance that then acts on the question.

In the next lesson, you will integrate the agent into the front end.

Chatbot

Hi, I am an Educational Learning Assistant for Intelligent Network Exploration. You can call me E.L.A.I.N.E.

How can I help you today?