Tool Use & Agents

Open in GitHub

Tool use enhances retrieval-augmented generation (RAG) capabilities by enabling applications to both answer questions and automate tasks.

Tools provide a broader access to external systems compared to traditional RAG. This approach leverages LLMs’ inherent ability to reason and make decisions. By incorporating tools, developers can create agent-like applications that interact with external systems through both read and write operations.

In this chapter, we’ll explore how to build an agentic application by building an agent that can answer questions and automate tasks, enabled by a number of tools.

Setup

First, you will need to deploy the Command model on Azure via Azure AI Foundry. The deployment will create a serverless API with pay-as-you-go token based billing. You can find more information on how to deploy models in the Azure documentation.

In the example below, we are deploying the Command R+ (August 2024) model.

Once the model is deployed, you can access it via Cohere’s Python SDK. Let’s now install the Cohere SDK and set up our client.

To create a client, you need to provide the API key and the model’s base URL for the Azure endpoint. You can get these information from the Azure AI Foundry platform where you deployed the model.

PYTHON
1# ! pip install cohere
2
3api_key_chat = "AZURE_API_KEY_CHAT"
4endpoint_chat = "AZURE_ENDPOINT_CHAT" # example: "https://cohere-command-r-plus-08-2024-xyz.eastus.models.ai.azure.com/"
PYTHON
1import cohere
2
3co = cohere.Client(
4 api_key=api_key_chat,
5 base_url=endpoint_chat,
6)

Create tools

The pre-requisite, before we can run a tool use workflow, is to set up the tools. Let’s create three tools:

  • search_faqs: A tool for searching the FAQs of a company. For simplicity, we’ll not implement any retrieval logic, but we’ll simply pass a list of three predefined documents. In practice, we would set up a retrieval system as we did in Chapters 4, 5, and 6.
  • search_emails: A tool for searching the emails. Same as above, we’ll simply pass a list of predefined emails.
  • create_calendar_event: A tool for creating new calendar events. Again, for simplicity, we’ll only return mock successful event creations without actual implementation. In practice, we can connect to a calendar service API and implement all the necessary logic here.

Here, we are defining a Python function for each tool, but more broadly, the tool can be any function or service that can receive and send objects.

PYTHON
1def search_faqs(query):
2 faqs = [
3 {"text" : "Submitting Travel Expenses:\nSubmit your expenses through our user-friendly finance tool."},
4 {"text" : "Side Projects Policy:\nWe encourage you to explore your passions! Just ensure there's no conflict of interest with our business."},
5 {"text" : "Wellness Benefits:\nTo promote a healthy lifestyle, we provide gym memberships, on-site yoga classes, and health insurance."}
6 ]
7 return {"faqs" : faqs}
8
9def search_emails(query):
10 emails = [
11 {"from": "hr@co1t.com", "to": "david@co1t.com", "date": "2024-06-24", "subject": "A Warm Welcome to Co1t, David!", "text": "We are delighted to have you on board. Please find attached your first week's agenda."},
12 {"from": "it@co1t.com", "to": "david@co1t.com", "date": "2024-06-24", "subject": "Instructions for IT Setup", "text": "Welcome, David! To get you started, please follow the attached guide to set up your work accounts."},
13 {"from": "john@co1t.com", "to": "david@co1t.com", "date": "2024-06-24", "subject": "First Week Check-In", "text": "Hi David, let's chat briefly tomorrow to discuss your first week. Also, come join us for lunch this Thursday at noon to meet everyone!"},
14 ]
15 return {"emails" : emails}
16
17def create_calendar_event(date: str, time: str, duration: int):
18 # You can implement any logic here
19 return {"is_success": True,
20 "message": f"Created a {duration} hour long event at {time} on {date}"}
21
22functions_map = {
23 "search_faqs": search_faqs,
24 "search_emails": search_emails,
25 "create_calendar_event": create_calendar_event
26}

Define tool schemas

The next step is to define the tool schemas in a format that can be accepted by the Chat endpoint. The schema must contain the following fields: name, description, and parameter_definitions.

This schema informs the LLM about what the tool does, and the LLM decides whether to use a particular tool based on it. Therefore, the more descriptive and specific the schema, the more likely the LLM will make the right tool call decisions.

PYTHON
1tools = [
2 {
3 "name": "search_faqs",
4 "description": "Given a user query, searches a company's frequently asked questions (FAQs) list and returns the most relevant matches to the query.",
5 "parameter_definitions": {
6 "query": {
7 "description": "The query from the user",
8 "type": "str",
9 "required": True
10 }
11 }
12 },
13 {
14 "name": "search_emails",
15 "description": "Given a user query, searches a person's emails and returns the most relevant matches to the query.",
16 "parameter_definitions": {
17 "query": {
18 "description": "The query from the user",
19 "type": "str",
20 "required": True
21 }
22 }
23 },
24 {
25 "name": "create_calendar_event",
26 "description": "Creates a new calendar event of the specified duration at the specified time and date. A new event cannot be created on the same time as an existing event.",
27 "parameter_definitions": {
28 "date": {
29 "description": "the date on which the event starts, formatted as mm/dd/yy",
30 "type": "str",
31 "required": True
32 },
33 "time": {
34 "description": "the time of the event, formatted using 24h military time formatting",
35 "type": "str",
36 "required": True
37 },
38 "duration": {
39 "description": "the number of hours the event lasts for",
40 "type": "float",
41 "required": True
42 }
43 }
44 }
45]

Run agent

Now, let’s set up the agent using Cohere’s tool use feature. We can think of a tool use system as consisting of four components:

  • The user
  • The application
  • The LLM
  • The tools

At its most basic, these four components interact in a workflow through four steps:

  • Step 1: Get user message. The LLM gets the user message (via the application).
  • Step 2: Generate tool calls. The LLM makes a decision on the tools to call (if any) and generates the tool calls.
  • Step 3: Get tool results. The application executes the tools and sends the tool results to the LLM.
  • Step 4: Generate response and citations. The LLM generates the response and citations and sends them back to the user.

Let’s create a function called run_assistant to implement these steps and print out the key events and messages along the way. This function also optionally accepts the chat history as an argument to keep the state in a multi-turn conversation.

PYTHON
1preamble="""## Task and Context
2You are an assistant who assist new employees of Co1t with their first week. You respond to their questions and assist them with their needs. Today is Monday, June 24, 2024"""
3
4def run_assistant(message, chat_history=None):
5
6 if chat_history is None:
7 chat_history = []
8
9 # Step 1: get user message
10 print(f"Question:\n{message}")
11 print("="*50)
12
13 # Step 2: Generate tool calls (if any)
14 response = co.chat(
15 message=message,
16 preamble=preamble,
17 tools=tools,
18 chat_history=chat_history,
19 force_single_step=False
20 )
21
22 while response.tool_calls:
23 tool_calls = response.tool_calls
24
25 if response.text:
26 print("Tool plan:")
27 print(response.text,"\n")
28 print("Tool calls:")
29 for call in tool_calls:
30 print(f"Tool name: {call.name} | Parameters: {call.parameters}")
31 print("="*50)
32
33 # Step 3: Get tool results
34 tool_results = []
35 for tc in tool_calls:
36 tool_call = {"name": tc.name, "parameters": tc.parameters}
37 tool_output = functions_map[tc.name](**tc.parameters)
38 tool_results.append({"call": tool_call, "outputs": [tool_output]})
39
40 # Step 4: Generate response and citations
41 response = co.chat(
42 message="",
43 preamble=preamble,
44 tools=tools,
45 tool_results=tool_results,
46 chat_history=response.chat_history,
47 force_single_step=False
48 )
49
50 chat_history = response.chat_history
51
52 # Print final response
53 print("RESPONSE:\n")
54 print(response.text)
55 print("="*50)
56
57 # Print citations (if any)
58 if response.citations:
59 print("\nCITATIONS:\n")
60 for citation in response.citations:
61 print(citation)
62
63 print("\nCITED REFERENCES:\n")
64 for document in response.documents:
65 print(document)
66
67 return chat_history

Let’s now run the agent. We’ll use an example of a new hire asking about IT access and the travel expense process.

Given three tools to choose from, the model is able to pick the right tools (in this case, search_faqs and search_emails) based on what the user is asking for.

Also, notice that the model first generates a plan about what it should do (“I will …”) before actually generating the tool call(s).

Additionally, the model also generates fine-grained citations in tool use mode based on the tool results it receives, the same way we saw with RAG.

PYTHON
1chat_history = run_assistant("Any doc on how do I submit travel expenses? Also, any emails about setting up IT access?")
1Question:
2Any doc on how do I submit travel expenses? Also, any emails about setting up IT access?
3==================================================
4Tool plan:
5I will search for 'how to submit travel expenses' and 'setting up IT access'.
6
7Tool calls:
8Tool name: search_faqs | Parameters: {'query': 'how to submit travel expenses'}
9Tool name: search_emails | Parameters: {'query': 'setting up IT access'}
10==================================================
11RESPONSE:
12
13You can submit your travel expenses through the user-friendly finance tool.
14
15There is an email from IT with the subject 'Instructions for IT Setup'. It says:
16> Welcome, David! To get you started, please follow the attached guide to set up your work accounts.
17==================================================
18
19CITATIONS:
20
21start=48 end=75 text='user-friendly finance tool.' document_ids=['search_faqs:0:2:0']
22start=100 end=102 text='IT' document_ids=['search_emails:1:2:0']
23start=120 end=147 text="'Instructions for IT Setup'" document_ids=['search_emails:1:2:0']
24start=160 end=258 text='Welcome, David! To get you started, please follow the attached guide to set up your work accounts.' document_ids=['search_emails:1:2:0']
25
26CITED REFERENCES:
27
28{'faqs': '[{"text":"Submitting Travel Expenses:\\nSubmit your expenses through our user-friendly finance tool."},{"text":"Side Projects Policy:\\nWe encourage you to explore your passions! Just ensure there\'s no conflict of interest with our business."},{"text":"Wellness Benefits:\\nTo promote a healthy lifestyle, we provide gym memberships, on-site yoga classes, and health insurance."}]', 'id': 'search_faqs:0:2:0', 'tool_name': 'search_faqs'}
29{'emails': '[{"date":"2024-06-24","from":"hr@co1t.com","subject":"A Warm Welcome to Co1t, David!","text":"We are delighted to have you on board. Please find attached your first week\'s agenda.","to":"david@co1t.com"},{"date":"2024-06-24","from":"it@co1t.com","subject":"Instructions for IT Setup","text":"Welcome, David! To get you started, please follow the attached guide to set up your work accounts.","to":"david@co1t.com"},{"date":"2024-06-24","from":"john@co1t.com","subject":"First Week Check-In","text":"Hi David, let\'s chat briefly tomorrow to discuss your first week. Also, come join us for lunch this Thursday at noon to meet everyone!","to":"david@co1t.com"}]', 'id': 'search_emails:1:2:0', 'tool_name': 'search_emails'}

Conclusion

In this tutorial, we learned about:

  • How to set up tools with parameter definitions for the Cohere chat API
  • How to define tools for building agentic applications
  • How to set up the agent
  • How to run a tool use workflow involving the user, the application, the LLM, and the tools
Built with