From 2b84c067591b9b631e305a5443412f1bbd384741 Mon Sep 17 00:00:00 2001 From: Meor Amer <92068895+mrmer1@users.noreply.github.com> Date: Fri, 24 Jan 2025 03:23:22 +0800 Subject: [PATCH 1/2] Update structured outputs docs (#287) * update structured outputs docs * add notes on nesting --------- Co-authored-by: trentfowlercohere <141260477+trentfowlercohere@users.noreply.github.com> --- .../text-generation/structured-outputs.mdx | 16 ++++----- fern/pages/text-generation/tools/tool-use.mdx | 12 ------- .../v2/text-generation/structured-outputs.mdx | 36 ++++++++++++------- .../tools/multi-step-tool-use.mdx | 13 +++++++ .../v2/text-generation/tools/tool-use.mdx | 14 +------- 5 files changed, 45 insertions(+), 46 deletions(-) diff --git a/fern/pages/text-generation/structured-outputs.mdx b/fern/pages/text-generation/structured-outputs.mdx index 74696d549..631d3b318 100644 --- a/fern/pages/text-generation/structured-outputs.mdx +++ b/fern/pages/text-generation/structured-outputs.mdx @@ -14,7 +14,7 @@ updatedAt: "Tue Jun 11 2024 02:43:00 GMT+0000 (Coordinated Universal Time)" ## Overview -Structured Outputs is a feature for forcing the LLM's output to follow a specified format 100% of the time. This increases the reliability of LLM in enterprise applications where downstream applications expect the LLM output to be correctly formatted. By forcing the model to follow a structured schema, hallucinated fields and entries in structured data can be reliably eliminated. +Structured Outputs is a feature that forces the LLM’s response to strictly follow a schema specified by the user. When Structured Outputs is turned on, the LLM will generate structured data that follows the desired schema, provided by the user, 100% of the time. This increases the reliability of LLMs in enterprise applications where downstream applications expect the LLM output to be correctly formatted. With Structured Outputs, hallucinated fields and entries in structured data can be reliably eliminated. Compatible models: - Command R 08 2024 @@ -75,8 +75,8 @@ By setting the `response_format` type to `"json_object"` in the Chat API, the ou When using `{ "type": "json_object" }` your `message` should always explicitly instruct the model to generate a JSON (eg: _"Generate a JSON ..."_) . Otherwise the model may end up getting stuck generating an infinite stream of characters and eventually run out of context length. - -This feature is currently not supported in RAG mode. + +This feature is currently not supported in [RAG](https://docs.cohere.com/v1/docs/retrieval-augmented-generation-rag) mode. #### JSON Schema mode @@ -125,15 +125,11 @@ In this schema, we defined three keys ("title," "author," "publication_year") an ``` - -Note: Each schema provided will incur a latency overhead required for processing the schema. This is only applicable for the first few requests. - - ## Specifying a schema ### Generating nested objects -The model can be configured to output objects with up to 5 levels of nesting. When a `schema` is specified, there are no limitations on the levels of nesting. +In JSON Schema mode, there are no limitations on the levels of nesting. However, in JSON mode (no schema specified), nesting is limited to 5 levels. ### Schema constraints @@ -164,3 +160,7 @@ We do not support the entirety of the [JSON Schema specification](https://json-s - Others: - `uniqueItems` - `additionalProperties` + + +Note: Using Structured Outputs (in JSON Schema mode) will incur a latency overhead required for processing the structured schema. This increase in latency only applies for the first few requests, since the schema is cached afterwards. + \ No newline at end of file diff --git a/fern/pages/text-generation/tools/tool-use.mdx b/fern/pages/text-generation/tools/tool-use.mdx index 0893cec7e..feb8e61cf 100644 --- a/fern/pages/text-generation/tools/tool-use.mdx +++ b/fern/pages/text-generation/tools/tool-use.mdx @@ -323,18 +323,6 @@ outputs = [{"number": 2343}] # Not Great outputs = [{"sum": 2343}] # Better ``` -## What's Next? - -Here, we'll preview some of the functionality we plan on adding in the coming months. - -### Cohere-hosted Tools - -The model can currently handle any tool provided by the developer. That having been said, Cohere has implemented some pre-defined tools that users can leverage out-of-the-box. - -Specifically we're going to roll out a **Python interpreter** tool and a **Web search** tool. - -Please [reach out](mailto:MAXIMEVOISIN@COHERE.COM) to join the beta. - ## Getting started Check out [this notebook](https://github.com/cohere-ai/cohere-developer-experience/blob/main/notebooks/agents/Vanilla_Tool_Use.ipynb) for a worked-out examples. diff --git a/fern/pages/v2/text-generation/structured-outputs.mdx b/fern/pages/v2/text-generation/structured-outputs.mdx index da3386383..768575f2a 100644 --- a/fern/pages/v2/text-generation/structured-outputs.mdx +++ b/fern/pages/v2/text-generation/structured-outputs.mdx @@ -15,7 +15,7 @@ updatedAt: "Tue Jun 11 2024 02:43:00 GMT+0000 (Coordinated Universal Time)" ## Overview -Structured Outputs is a feature for forcing the LLM's output to follow a specified format 100% of the time. This increases the reliability of LLM in enterprise applications where downstream applications expect the LLM output to be correctly formatted. By forcing the model to follow a structured schema, hallucinated fields and entries in structured data can be reliably eliminated. +Structured Outputs is a feature that forces the LLM’s response to strictly follow a schema specified by the user. When Structured Outputs is turned on, the LLM will generate structured data that follows the desired schema, provided by the user, 100% of the time. This increases the reliability of LLMs in enterprise applications where downstream applications expect the LLM output to be correctly formatted. With Structured Outputs, hallucinated fields and entries in structured data can be reliably eliminated. Compatible models: - Command R+ 08 2024 @@ -27,7 +27,7 @@ Compatible models: There are two ways to use Structured Outputs: - **Structured Outputs (JSON)**. This is primarily used in text generation use cases. -- **Structured Outputs (Tools)**. This is primarily used in tool use and agents use cases via function calling. +- **Structured Outputs (Tools)**. Structured Outputs (Tools). This is primarily used in [tool use (or function calling)](https://docs.cohere.com/docs/tool-use) and [agents](https://docs.cohere.com/docs/multi-step-tool-use) use cases. Structured Outputs with Tools are only supported in [Chat API V2](https://docs.cohere.com/reference/chat#request.body.strict_tools) via the `strict_tools` parameter. This parameter is not supported in Chat API V1. @@ -82,7 +82,7 @@ When using `{ "type": "json_object" }` your `message` should always explicitly -This feature is currently not supported in RAG mode. +This feature is currently not supported in [RAG](https://docs.cohere.com/docs/retrieval-augmented-generation-rag) mode. #### JSON Schema mode @@ -140,7 +140,7 @@ In this schema, we defined three keys ("title," "author," "publication_year") an Here's an example of a nested array. Note that the top level json structure must always be a json object. -```py +```python PYTHON cohere_api_key = os.getenv('cohere_api_key') co = cohere.ClientV2(cohere_api_key) response = co.chat( @@ -190,11 +190,13 @@ Note: Each schema provided (in both JSON and Tools modes) will incur a latency o ### Structured Outputs (Tools) -When you use the Chat API with `tools`, setting the `strict_tools` parameter to `True` will enforce that every generated tool call follows the specified tool schema. +When you use the Chat API with `tools` (see [tool use](https://docs.cohere.com/docs/tool-use) and [agents](https://docs.cohere.com/docs/multi-step-tool-use)), setting the `strict_tools` parameter to `True` will enforce that the tool calls generated by the mode strictly adhere to the tool descriptions you provided. - -`strict_tools` is currently an experimental parameter. We’ll be iterating on this feature and are looking for feedback. Share your experience with us in the `#api-discussions` channel on [discord](https://discord.gg/co-mmunity) or via [email](mailto:support@cohere.com). - +Concretely, this means: +- No hallucinated tool names +- No hallucinated tool parameters +- Every `required` parameter is included in the tool call +- All parameters produce the requested data types With `strict_tools` enabled, the API will ensure that the tool names and tool parameters are generated according to the tool definitions. This eliminates tool name and parameter hallucinations, ensures that each parameter matches the specified data type, and that all required parameters are included in the model response. @@ -233,10 +235,14 @@ response = co.chat(model="command-r-plus-08-2024", print(response.message.tool_calls) ``` +#### Important notes on using `strict_tools` +- This parameter is only supported in Chat API V2 via the strict_tools parameter (not API V1). +- You must specify at least one `required` parameter. Tools with only optional parameters are not supported in this mode. +- You can define a maximum of 200 fields across all tools in a single Chat API call. - -When `strict_tools` is enabled, tool definitions that have optional parameters must specify at least one `required` parameter as well. Tools with only optional parameters are not supported in this mode. - + +`strict_tools` is currently an experimental parameter. We’ll be iterating on this feature and are looking for feedback. Share your experience with us in the `#api-discussions` channel on [discord](https://discord.gg/co-mmunity) or via [email](mailto:tools_feedback@cohere.com). + ### When to Use Structured Outputs (JSON) vs. Structured Outputs (Tools) @@ -244,7 +250,7 @@ Structured Outputs (JSON) are ideal for text generation use cases where you want For example, when building a travel planner application, you might want the LLM to generate itineraries in a specific JSON format, allowing the application to use the output in the other parts of the application. -Structured Outputs (Tools) are ideal for function calling, tool use or agents use cases where you need the model to interact with external data or services. For instance, you can grant the model access to functions that interact with databases or other APIs. +Structured Outputs (Tools) are ideal for [tool use (or function calling)](https://docs.cohere.com/docs/tool-use) and [agents](https://docs.cohere.com/docs/multi-step-tool-use) use cases where you need the model to interact with external data or services. For instance, you can grant the model access to functions that interact with databases or other APIs. In summary, opt for: - Structured Outputs (JSON) when you need the model's response to follow a specific structure. @@ -255,7 +261,7 @@ In summary, opt for: ### Generating nested objects -The model can be configured to output objects with up to 5 levels of nesting. When a `schema` is specified, there are no limitations on the levels of nesting. +In JSON Schema mode, there are no limitations on the levels of nesting. However, in JSON mode (no schema specified), nesting is limited to 5 levels. ### Schema constraints @@ -342,3 +348,7 @@ We do not support the entirety of the [JSON Schema specification](https://json-s - `uuid` - `date` - `time` + + +Note: Using Structured Outputs (in both JSON Schema and Tools modes) will incur a latency overhead required for processing the structured schema. This increase in latency only applies for the first few requests, since the schema is cached afterwards. + \ No newline at end of file diff --git a/fern/pages/v2/text-generation/tools/multi-step-tool-use.mdx b/fern/pages/v2/text-generation/tools/multi-step-tool-use.mdx index 9d3e086de..170c258a9 100644 --- a/fern/pages/v2/text-generation/tools/multi-step-tool-use.mdx +++ b/fern/pages/v2/text-generation/tools/multi-step-tool-use.mdx @@ -181,6 +181,19 @@ Tool use is a natural extension of retrieval augmented generation (RAG). RAG is Tool use pushes this further, allowing Cohere models to go far beyond information retrieval, interact with search engines, APIs, functions, databases, and many other tools. +## Structured Outputs (Tools) + +Setting the `strict_tools` parameter to `True` will enforce each tool call to follow the specified tool schema. To learn more about this feature, visit the [Structured Outputs documentation](https://docs.cohere.com/v2/docs/structured-outputs). + +Note that `strict_tools` is currently an experimental feature. + +```python PYTHON {4} +response = co.chat(model="command-r-plus-08-2024", + messages=messages, + tools=tools, + strict_tools=True) +``` + ## A Further Example With Multiple Tools This section provides another example of multi-step tool use, this time with multiple tools. The notebook for this example can be [found here](https://github.com/cohere-ai/cohere-developer-experience/blob/main/notebooks/agents/Multi_Step_Tool_Use_Spotify_v2.ipynb). diff --git a/fern/pages/v2/text-generation/tools/tool-use.mdx b/fern/pages/v2/text-generation/tools/tool-use.mdx index 2d2d441ad..dedf43e0e 100644 --- a/fern/pages/v2/text-generation/tools/tool-use.mdx +++ b/fern/pages/v2/text-generation/tools/tool-use.mdx @@ -413,7 +413,7 @@ Start: 207 | End: 232 | Text: 'Tablet: $300, 25 in stock' ## Structured Outputs (Tools) -Setting the `strict_tools` parameter to True will enforce each tool call to follow the specified tool schema. To learn more about this feature, visit the [Structured Outputs documentation](https://docs.cohere.com/v2/docs/structured-outputs). +Setting the `strict_tools` parameter to `True` will enforce each tool call to follow the specified tool schema. To learn more about this feature, visit the [Structured Outputs documentation](https://docs.cohere.com/v2/docs/structured-outputs). Note that `strict_tools` is currently an experimental feature. @@ -435,18 +435,6 @@ outputs = [{"number": 2343}] # Not Great outputs = [{"sum": 2343}] # Better ``` -## What's Next? - -Here, we'll preview some of the functionality we plan on adding in the coming months. - -### Cohere-hosted Tools - -The model can currently handle any tool provided by the developer. That having been said, Cohere has implemented some pre-defined tools that users can leverage out-of-the-box. - -Specifically we're going to roll out a **Python interpreter** tool and a **Web search** tool. - -Please [reach out](mailto:MAXIMEVOISIN@COHERE.COM) to join the beta. - ## Getting started Check out [this notebook](https://github.com/cohere-ai/cohere-developer-experience/blob/main/notebooks/agents/Vanilla_Tool_Use_v2.ipynb) for a worked-out examples. From 60d68b876b312544e194fd95a44c0f0369b53271 Mon Sep 17 00:00:00 2001 From: Max Shkutnyk Date: Thu, 23 Jan 2025 21:31:20 +0200 Subject: [PATCH 2/2] apply black formatting to tutorials pages (#379) Co-authored-by: Max Shkutnyk --- .../tutorials/build-things-with-cohere.mdx | 7 +- .../building-a-chatbot-with-cohere.mdx | 37 ++-- .../building-an-agent-with-cohere.mdx | 190 ++++++++++-------- .../rag-with-cohere.mdx | 142 ++++++++----- .../reranking-with-cohere.mdx | 62 ++++-- .../semantic-search-with-cohere.mdx | 114 +++++++---- .../text-generation-tutorial.mdx | 51 +++-- .../cohere-on-azure/azure-ai-rag.mdx | 105 +++++----- .../cohere-on-azure/azure-ai-reranking.mdx | 89 +++++--- .../cohere-on-azure/azure-ai-sem-search.mdx | 55 ++--- .../azure-ai-text-generation.mdx | 38 ++-- .../cohere-on-azure/azure-ai-tool-use.mdx | 180 ++++++++++------- 12 files changed, 659 insertions(+), 411 deletions(-) diff --git a/fern/pages/tutorials/build-things-with-cohere.mdx b/fern/pages/tutorials/build-things-with-cohere.mdx index 59d97d40f..7c468a400 100644 --- a/fern/pages/tutorials/build-things-with-cohere.mdx +++ b/fern/pages/tutorials/build-things-with-cohere.mdx @@ -38,7 +38,8 @@ Next, we'll import the `cohere` library and create a client to be used throughou ```python PYTHON import cohere -co = cohere.Client(api_key="YOUR_COHERE_API_KEY") # Get your API key here: https://dashboard.cohere.com/api-keys +# Get your API key here: https://dashboard.cohere.com/api-keys +co = cohere.Client(api_key="YOUR_COHERE_API_KEY") ``` # Accessing Cohere from Other Platforms @@ -93,8 +94,8 @@ For further information, read this documentation on [Cohere on Azure](/docs/cohe import cohere co = cohere.Client( - api_key="...", - base_url="...", + api_key="...", + base_url="...", ) ``` diff --git a/fern/pages/tutorials/build-things-with-cohere/building-a-chatbot-with-cohere.mdx b/fern/pages/tutorials/build-things-with-cohere/building-a-chatbot-with-cohere.mdx index 15f9f5fb0..cf2ba42fa 100644 --- a/fern/pages/tutorials/build-things-with-cohere/building-a-chatbot-with-cohere.mdx +++ b/fern/pages/tutorials/build-things-with-cohere/building-a-chatbot-with-cohere.mdx @@ -30,7 +30,8 @@ To get started, first we need to install the `cohere` library and create a Coher import cohere -co = cohere.Client("COHERE_API_KEY") # Get your API key: https://dashboard.cohere.com/api-keys +# Get your API key: https://dashboard.cohere.com/api-keys +co = cohere.Client("COHERE_API_KEY") ``` ## Creating a custom preamble @@ -48,15 +49,14 @@ In the example below, the preamble provides context for the assistant's task (ta message = "I'm joining a new startup called Co1t today. Could you help me write a short introduction message to my teammates." # Create a custom preamble -preamble="""## Task and Context +preamble = """## Task and Context You are an assistant who assist new employees of Co1t with their first week. ## Style Guide Try to speak in rhymes as much as possible. Be professional.""" # Generate the response -response = co.chat(message=message, - preamble=preamble) +response = co.chat(message=message, preamble=preamble) print(response.text) ``` @@ -107,12 +107,11 @@ Here, we are also adding a custom preamble for generating concise response, just message = "I'm joining a new startup called Co1t today. Could you help me write a short introduction message to my teammates." # Create a custom preamble -preamble="""## Task & Context +preamble = """## Task & Context Generate concise responses, with maximum one-sentence.""" # Generate the response -response = co.chat(message=message, - preamble=preamble) +response = co.chat(message=message, preamble=preamble) print(response.text) ``` @@ -136,9 +135,11 @@ Looking at the response, we see that the model is able to get the context from t message = "Make it more upbeat and conversational." # Generate the response with the current chat history as the context -response = co.chat(message=message, - preamble=preamble, - chat_history=response.chat_history) +response = co.chat( + message=message, + preamble=preamble, + chat_history=response.chat_history, +) print(response.text) ``` @@ -157,12 +158,16 @@ You can continue doing this for any number of turns by passing the most recent ` ```python PYTHON # Add the user message -message = "Thanks. Could you create another one for my DM to my manager." +message = ( + "Thanks. Could you create another one for my DM to my manager." +) # Generate the response with the current chat history as the context -response = co.chat(message=message, - preamble=preamble, - chat_history=response.chat_history) +response = co.chat( + message=message, + preamble=preamble, + chat_history=response.chat_history, +) print(response.text) ``` @@ -178,8 +183,8 @@ To look at the current chat history, you can print the `response.chat_history` o ```python PYTHON # View the chat history for turn in response.chat_history: - print("Role:",turn.role) - print("Message:",turn.message,"\n") + print("Role:", turn.role) + print("Message:", turn.message, "\n") ``` ``` diff --git a/fern/pages/tutorials/build-things-with-cohere/building-an-agent-with-cohere.mdx b/fern/pages/tutorials/build-things-with-cohere/building-an-agent-with-cohere.mdx index 1eab305c8..c8dd2817a 100644 --- a/fern/pages/tutorials/build-things-with-cohere/building-an-agent-with-cohere.mdx +++ b/fern/pages/tutorials/build-things-with-cohere/building-an-agent-with-cohere.mdx @@ -35,7 +35,8 @@ To get started, first we need to install the `cohere` library and create a Coher import numpy as np import cohere -co = cohere.Client("COHERE_API_KEY") # Get your API key: https://dashboard.cohere.com/api-keys +# Get your API key: https://dashboard.cohere.com/api-keys +co = cohere.Client("COHERE_API_KEY") ``` ## Creating tools @@ -52,27 +53,48 @@ Here, we are defining a Python function for each tool, but more broadly, the too # Create the tools def search_faqs(query): faqs = [ - {"text": "Reimbursing Travel Expenses: Easily manage your travel expenses by submitting them through our finance tool. Approvals are prompt and straightforward."}, - {"text": "Working from Abroad: Working remotely from another country is possible. Simply coordinate with your manager and ensure your availability during core hours."} + { + "text": "Reimbursing Travel Expenses: Easily manage your travel expenses by submitting them through our finance tool. Approvals are prompt and straightforward." + }, + { + "text": "Working from Abroad: Working remotely from another country is possible. Simply coordinate with your manager and ensure your availability during core hours." + }, ] - return {"faqs" : faqs} + return {"faqs": faqs} + def search_emails(query): emails = [ - {"from": "it@co1t.com", "to": "david@co1t.com", "date": "2024-06-24", "subject": "Setting Up Your IT Needs", "text": "Greetings! To ensure a seamless start, please refer to the attached comprehensive guide, which will assist you in setting up all your work accounts."}, - {"from": "john@co1t.com", "to": "david@co1t.com", "date": "2024-06-24", "subject": "First Week Check-In", "text": "Hello! I hope you're settling in well. Let's connect briefly tomorrow to discuss how your first week has been going. Also, make sure to join us for a welcoming lunch this Thursday at noon—it's a great opportunity to get to know your colleagues!"} + { + "from": "it@co1t.com", + "to": "david@co1t.com", + "date": "2024-06-24", + "subject": "Setting Up Your IT Needs", + "text": "Greetings! To ensure a seamless start, please refer to the attached comprehensive guide, which will assist you in setting up all your work accounts.", + }, + { + "from": "john@co1t.com", + "to": "david@co1t.com", + "date": "2024-06-24", + "subject": "First Week Check-In", + "text": "Hello! I hope you're settling in well. Let's connect briefly tomorrow to discuss how your first week has been going. Also, make sure to join us for a welcoming lunch this Thursday at noon—it's a great opportunity to get to know your colleagues!", + }, ] - return {"emails" : emails} - + return {"emails": emails} + + def create_calendar_event(date: str, time: str, duration: int): # You can implement any logic here - return {"is_success": True, - "message": f"Created a {duration} hour long event at {time} on {date}"} - + return { + "is_success": True, + "message": f"Created a {duration} hour long event at {time} on {date}", + } + + functions_map = { "search_faqs": search_faqs, "search_emails": search_emails, - "create_calendar_event": create_calendar_event + "create_calendar_event": create_calendar_event, } ``` @@ -84,48 +106,48 @@ This schema informs the LLM about what the tool does, and the LLM decides whethe # Define the tools tools = [ { - "name": "search_faqs", - "description": "Given a user query, searches a company's frequently asked questions (FAQs) list and returns the most relevant matches to the query.", - "parameter_definitions": { - "query": { - "description": "The query from the user", - "type": "str", - "required": True - } - } - }, - { - "name": "search_emails", - "description": "Given a user query, searches a person's emails and returns the most relevant matches to the query.", - "parameter_definitions": { - "query": { - "description": "The query from the user", - "type": "str", - "required": True - } - } - }, + "name": "search_faqs", + "description": "Given a user query, searches a company's frequently asked questions (FAQs) list and returns the most relevant matches to the query.", + "parameter_definitions": { + "query": { + "description": "The query from the user", + "type": "str", + "required": True, + } + }, + }, { - "name": "create_calendar_event", - "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.", - "parameter_definitions": { - "date": { - "description": "the date on which the event starts, formatted as mm/dd/yy", - "type": "str", - "required": True + "name": "search_emails", + "description": "Given a user query, searches a person's emails and returns the most relevant matches to the query.", + "parameter_definitions": { + "query": { + "description": "The query from the user", + "type": "str", + "required": True, + } }, - "time": { - "description": "the time of the event, formatted using 24h military time formatting", - "type": "str", - "required": True + }, + { + "name": "create_calendar_event", + "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.", + "parameter_definitions": { + "date": { + "description": "the date on which the event starts, formatted as mm/dd/yy", + "type": "str", + "required": True, + }, + "time": { + "description": "the time of the event, formatted using 24h military time formatting", + "type": "str", + "required": True, + }, + "duration": { + "description": "the number of hours the event lasts for", + "type": "float", + "required": True, + }, }, - "duration": { - "description": "the number of hours the event lasts for", - "type": "float", - "required": True - } - } - } + }, ] ``` @@ -149,22 +171,21 @@ At its most basic, these four components interact in a workflow through four ste # Step 1: Get user message message = "Any messages about getting setup with IT?" -preamble="""## Task & Context +preamble = """## Task & Context You 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""" # Step 2: Tool planning and calling -response = co.chat( - message=message, - preamble=preamble, - tools=tools) +response = co.chat(message=message, preamble=preamble, tools=tools) if response.tool_calls: print("Tool plan:") - print(response.text,"\n") - + print(response.text, "\n") + print("Tool calls:") for call in response.tool_calls: - print(f"Tool name: {call.name} | Parameters: {call.parameters}") + print( + f"Tool name: {call.name} | Parameters: {call.parameters}" + ) ``` ``` @@ -189,7 +210,7 @@ for tc in response.tool_calls: tool_output = functions_map[tc.name](**tc.parameters) tool_results.append({"call": tool_call, "outputs": [tool_output]}) -print("Tool results:") +print("Tool results:") for result in tool_results: print(result) ``` @@ -204,17 +225,17 @@ Tool results: ```python PYTHON # Step 4: Response and citation generation response = co.chat( - message="", # In response generation, we set the message as empty + message="", # In response generation, we set the message as empty preamble=preamble, tools=tools, tool_results=tool_results, - chat_history=response.chat_history + chat_history=response.chat_history, ) # Print final response print("Final response:") print(response.text) -print("="*50) +print("=" * 50) # Print citations (if any) if response.citations: @@ -250,60 +271,65 @@ Let's create a function to called `run_assistant` to implement these steps, and ```python PYTHON model = "command-r-plus-08-2024" -preamble="""## Task & Context +preamble = """## Task & Context You are an assistant who assists 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""" + # A function that runs multi-step tool use def run_assistant(message, chat_history=[]): # Step 1: get user message print(f"Question:\n{message}") - print("="*50) + print("=" * 50) - # Step 2: Generate tool calls (if any) + # Step 2: Generate tool calls (if any) response = co.chat( message=message, model=model, preamble=preamble, tools=tools, - chat_history=chat_history + chat_history=chat_history, ) # Tool execution loop while response.tool_calls: tool_calls = response.tool_calls - + if response.text: print("Intermediate response:") - print(response.text,"\n") + print(response.text, "\n") print("Tool calls:") for call in tool_calls: - print(f"Tool name: {call.name} | Parameters: {call.parameters}") - print("="*50) - + print( + f"Tool name: {call.name} | Parameters: {call.parameters}" + ) + print("=" * 50) + # Step 3: Get tool results tool_results = [] for tc in tool_calls: tool_call = {"name": tc.name, "parameters": tc.parameters} tool_output = functions_map[tc.name](**tc.parameters) - tool_results.append({"call": tool_call, "outputs": [tool_output]}) - - # Step 4: Generate response and citations + tool_results.append( + {"call": tool_call, "outputs": [tool_output]} + ) + + # Step 4: Generate response and citations response = co.chat( message="", model=model, preamble=preamble, tools=tools, tool_results=tool_results, - chat_history=response.chat_history + chat_history=response.chat_history, ) chat_history = response.chat_history - + # Print final response print("Final response:") print(response.text) - print("="*50) - + print("=" * 50) + # Print citations (if any) if response.citations: print("\nCITATIONS:") @@ -313,7 +339,7 @@ def run_assistant(message, chat_history=[]): print("\nCITED REFERENCES:") for document in response.documents: print(document) - + return chat_history ``` @@ -327,7 +353,9 @@ This requires tasks to happen over multiple steps in a sequence. Here, we see th This is also an example of tool use enabling a write operation instead of just a read operation that we saw with RAG. ```python PYTHON -chat_history = run_assistant("Can you check if there are any lunch invites, and for those days, block an hour on my calendar from 12-1PM.") +chat_history = run_assistant( + "Can you check if there are any lunch invites, and for those days, block an hour on my calendar from 12-1PM." +) ``` ``` diff --git a/fern/pages/tutorials/build-things-with-cohere/rag-with-cohere.mdx b/fern/pages/tutorials/build-things-with-cohere/rag-with-cohere.mdx index 9e534c364..cbfdbd43a 100644 --- a/fern/pages/tutorials/build-things-with-cohere/rag-with-cohere.mdx +++ b/fern/pages/tutorials/build-things-with-cohere/rag-with-cohere.mdx @@ -37,7 +37,8 @@ To get started, first we need to install the `cohere` library and create a Coher import numpy as np import cohere -co = cohere.Client("COHERE_API_KEY") # Get your API key: https://dashboard.cohere.com/api-keys +# Get your API key: https://dashboard.cohere.com/api-keys +co = cohere.Client("COHERE_API_KEY") ``` ## Basic RAG @@ -49,10 +50,18 @@ In this example, each document is a dictionary with one field, `text`. But we ca ```python PYTHON # Define the documents faqs_short = [ - {"text": "Reimbursing Travel Expenses: Easily manage your travel expenses by submitting them through our finance tool. Approvals are prompt and straightforward."}, - {"text": "Working from Abroad: Working remotely from another country is possible. Simply coordinate with your manager and ensure your availability during core hours."}, - {"text": "Health and Wellness Benefits: We care about your well-being and offer gym memberships, on-site yoga classes, and comprehensive health insurance."}, - {"text": "Performance Reviews Frequency: We conduct informal check-ins every quarter and formal performance reviews twice a year."} + { + "text": "Reimbursing Travel Expenses: Easily manage your travel expenses by submitting them through our finance tool. Approvals are prompt and straightforward." + }, + { + "text": "Working from Abroad: Working remotely from another country is possible. Simply coordinate with your manager and ensure your availability during core hours." + }, + { + "text": "Health and Wellness Benefits: We care about your well-being and offer gym memberships, on-site yoga classes, and comprehensive health insurance." + }, + { + "text": "Performance Reviews Frequency: We conduct informal check-ins every quarter and formal performance reviews twice a year." + }, ] ``` @@ -71,22 +80,23 @@ query = "Are there fitness-related perks?" # Generate the response response = co.chat( - message=query, - model="command-r-plus-08-2024", - documents=faqs_short) + message=query, + model="command-r-plus-08-2024", + documents=faqs_short, +) # Display the response print(response.text) # Display the citations and source documents if response.citations: - print("\nCITATIONS:") - for citation in response.citations: - print(citation) + print("\nCITATIONS:") + for citation in response.citations: + print(citation) - print("\nDOCUMENTS:") - for document in response.documents: - print(document) + print("\nDOCUMENTS:") + for document in response.documents: + print(document) ``` ``` @@ -131,13 +141,12 @@ In the example below, the resulting queries breaks down the user message into tw query = "How to stay connected with the company and do you organize team events?" # Generate the search queries -response = co.chat(message=query, - search_queries_only=True) +response = co.chat(message=query, search_queries_only=True) queries = [] for r in response.search_queries: queries.append(r.text) - + print(queries) ``` @@ -152,13 +161,12 @@ And in the example below, the model decides that one query is sufficient. query = "How flexible are the working hours" # Generate the search queries -response = co.chat(message=query, - search_queries_only=True) +response = co.chat(message=query, search_queries_only=True) queries = [] for r in response.search_queries: queries.append(r.text) - + print(queries) ``` @@ -183,23 +191,44 @@ First, we need to embed the documents to search from. We call the Embed endpoint ```python PYTHON # Define the documents faqs_long = [ - {"text": "Joining Slack Channels: You will receive an invite via email. Be sure to join relevant channels to stay informed and engaged."}, - {"text": "Finding Coffee Spots: For your caffeine fix, head to the break room's coffee machine or cross the street to the café for artisan coffee."}, - {"text": "Team-Building Activities: We foster team spirit with monthly outings and weekly game nights. Feel free to suggest new activity ideas anytime!"}, - {"text": "Working Hours Flexibility: We prioritize work-life balance. While our core hours are 9 AM to 5 PM, we offer flexibility to adjust as needed."}, - {"text": "Side Projects Policy: We encourage you to pursue your passions. Just be mindful of any potential conflicts of interest with our business."}, - {"text": "Reimbursing Travel Expenses: Easily manage your travel expenses by submitting them through our finance tool. Approvals are prompt and straightforward."}, - {"text": "Working from Abroad: Working remotely from another country is possible. Simply coordinate with your manager and ensure your availability during core hours."}, - {"text": "Health and Wellness Benefits: We care about your well-being and offer gym memberships, on-site yoga classes, and comprehensive health insurance."}, - {"text": "Performance Reviews Frequency: We conduct informal check-ins every quarter and formal performance reviews twice a year."}, - {"text": "Proposing New Ideas: Innovation is welcomed! Share your brilliant ideas at our weekly team meetings or directly with your team lead."}, + { + "text": "Joining Slack Channels: You will receive an invite via email. Be sure to join relevant channels to stay informed and engaged." + }, + { + "text": "Finding Coffee Spots: For your caffeine fix, head to the break room's coffee machine or cross the street to the café for artisan coffee." + }, + { + "text": "Team-Building Activities: We foster team spirit with monthly outings and weekly game nights. Feel free to suggest new activity ideas anytime!" + }, + { + "text": "Working Hours Flexibility: We prioritize work-life balance. While our core hours are 9 AM to 5 PM, we offer flexibility to adjust as needed." + }, + { + "text": "Side Projects Policy: We encourage you to pursue your passions. Just be mindful of any potential conflicts of interest with our business." + }, + { + "text": "Reimbursing Travel Expenses: Easily manage your travel expenses by submitting them through our finance tool. Approvals are prompt and straightforward." + }, + { + "text": "Working from Abroad: Working remotely from another country is possible. Simply coordinate with your manager and ensure your availability during core hours." + }, + { + "text": "Health and Wellness Benefits: We care about your well-being and offer gym memberships, on-site yoga classes, and comprehensive health insurance." + }, + { + "text": "Performance Reviews Frequency: We conduct informal check-ins every quarter and formal performance reviews twice a year." + }, + { + "text": "Proposing New Ideas: Innovation is welcomed! Share your brilliant ideas at our weekly team meetings or directly with your team lead." + }, ] # Embed the documents doc_emb = co.embed( - model="embed-english-v3.0", - input_type="search_document", - texts=[doc['text'] for doc in faqs_long]).embeddings + model="embed-english-v3.0", + input_type="search_document", + texts=[doc["text"] for doc in faqs_long], +).embeddings ``` Next, we add a query, which asks about how to get to know the team. @@ -211,15 +240,15 @@ We choose `search_query` as the `input_type` to ensure the model treats this as query = "How to get to know my teammates" # Generate the search query -response = co.chat(message=query, - search_queries_only=True) +response = co.chat(message=query, search_queries_only=True) query_optimized = response.search_queries[0].text # Embed the search query query_emb = co.embed( model="embed-english-v3.0", input_type="search_query", - texts=[query_optimized]).embeddings + texts=[query_optimized], +).embeddings ``` Now, we want to search for the most relevant documents to the query. For this, we make use of the `numpy` library to compute the similarity between each query-document pair using the dot product approach. @@ -232,7 +261,9 @@ Here, we show the most relevant documents with their similarity scores. # Compute dot product similarity and display results n = 5 scores = np.dot(query_emb, np.transpose(doc_emb))[0] -scores_sorted = sorted(enumerate(scores), key=lambda x: x[1], reverse=True)[:n] +scores_sorted = sorted( + enumerate(scores), key=lambda x: x[1], reverse=True +)[:n] retrieved_documents = [faqs_long[item[0]] for item in scores_sorted] @@ -287,18 +318,22 @@ Here we select `top_n` to be 2, which will be the documents we will pass next fo ```python PYTHON # Rerank the documents -results = co.rerank(query=query_optimized, - documents=retrieved_documents, - top_n=2, - model='rerank-english-v3.0') +results = co.rerank( + query=query_optimized, + documents=retrieved_documents, + top_n=2, + model="rerank-english-v3.0", +) # Display the reranking results for idx, result in enumerate(results.results): - print(f"Rank: {idx+1}") + print(f"Rank: {idx+1}") print(f"Score: {result.relevance_score}") print(f"Document: {retrieved_documents[result.index]}\n") - -reranked_documents = [retrieved_documents[result.index] for result in results.results] + +reranked_documents = [ + retrieved_documents[result.index] for result in results.results +] ``` ``` @@ -330,22 +365,23 @@ RAG introduces additional objects in the Chat response. Here we display two: ```python PYTHON # Generate the response response = co.chat( - message=query_optimized, - model="command-r-plus-08-2024", - documents=reranked_documents) + message=query_optimized, + model="command-r-plus-08-2024", + documents=reranked_documents, +) # Display the response print(response.text) # Display the citations and source documents if response.citations: - print("\nCITATIONS:") - for citation in response.citations: - print(citation) + print("\nCITATIONS:") + for citation in response.citations: + print(citation) - print("\nDOCUMENTS:") - for document in response.documents: - print(document) + print("\nDOCUMENTS:") + for document in response.documents: + print(document) ``` ``` diff --git a/fern/pages/tutorials/build-things-with-cohere/reranking-with-cohere.mdx b/fern/pages/tutorials/build-things-with-cohere/reranking-with-cohere.mdx index ba9eb7792..28e5b67f5 100644 --- a/fern/pages/tutorials/build-things-with-cohere/reranking-with-cohere.mdx +++ b/fern/pages/tutorials/build-things-with-cohere/reranking-with-cohere.mdx @@ -32,7 +32,8 @@ To get started, first we need to install the `cohere` library and create a Coher import numpy as np import cohere -co = cohere.Client("COHERE_API_KEY") # Get your API key: https://dashboard.cohere.com/api-keys +# Get your API key: https://dashboard.cohere.com/api-keys +co = cohere.Client("COHERE_API_KEY") ``` ## Reranking lexical/semantic search results @@ -51,10 +52,18 @@ This is where Rerank can help. We call the endpoint using `co.rerank()` and pass ```python PYTHON # Define the documents faqs = [ - {"text": "Reimbursing Travel Expenses: Easily manage your travel expenses by submitting them through our finance tool. Approvals are prompt and straightforward."}, - {"text": "Working from Abroad: Working remotely from another country is possible. Simply coordinate with your manager and ensure your availability during core hours."}, - {"text": "Health and Wellness Benefits: We care about your well-being and offer gym memberships, on-site yoga classes, and comprehensive health insurance."}, - {"text": "Performance Reviews Frequency: We conduct informal check-ins every quarter and formal performance reviews twice a year."} + { + "text": "Reimbursing Travel Expenses: Easily manage your travel expenses by submitting them through our finance tool. Approvals are prompt and straightforward." + }, + { + "text": "Working from Abroad: Working remotely from another country is possible. Simply coordinate with your manager and ensure your availability during core hours." + }, + { + "text": "Health and Wellness Benefits: We care about your well-being and offer gym memberships, on-site yoga classes, and comprehensive health insurance." + }, + { + "text": "Performance Reviews Frequency: We conduct informal check-ins every quarter and formal performance reviews twice a year." + }, ] ``` @@ -64,7 +73,7 @@ query = "Are there fitness-related perks?" # Rerank the documents results = co.rerank( - model='rerank-v3.5', + model="rerank-v3.5", query=query, documents=faqs, top_n=1, @@ -79,12 +88,13 @@ id='9633b278-93ff-4664-a142-7d9dcf0ec0e5' results=[RerankResponseResultsItem(doc ```python PYTHON # Display the reranking results -def return_results(results, documents): +def return_results(results, documents): for idx, result in enumerate(results.results): - print(f"Rank: {idx+1}") + print(f"Rank: {idx+1}") print(f"Score: {result.relevance_score}") print(f"Document: {documents[result.index]}\n") - + + return_results(results, faqs_short) ``` @@ -119,9 +129,27 @@ To perform reranking over semi-structured data, we convert the documents to YAML ```python PYTHON # Define the documents emails = [ - {"from": "hr@co1t.com", "to": "david@co1t.com", "date": "2024-06-24", "subject": "A Warm Welcome to Co1t!", "text": "We are delighted to welcome you to the team! As you embark on your journey with us, you'll find attached an agenda to guide you through your first week."}, - {"from": "it@co1t.com", "to": "david@co1t.com", "date": "2024-06-24", "subject": "Setting Up Your IT Needs", "text": "Greetings! To ensure a seamless start, please refer to the attached comprehensive guide, which will assist you in setting up all your work accounts."}, - {"from": "john@co1t.com", "to": "david@co1t.com", "date": "2024-06-24", "subject": "First Week Check-In", "text": "Hello! I hope you're settling in well. Let's connect briefly tomorrow to discuss how your first week has been going. Also, make sure to join us for a welcoming lunch this Thursday at noon—it's a great opportunity to get to know your colleagues!"} + { + "from": "hr@co1t.com", + "to": "david@co1t.com", + "date": "2024-06-24", + "subject": "A Warm Welcome to Co1t!", + "text": "We are delighted to welcome you to the team! As you embark on your journey with us, you'll find attached an agenda to guide you through your first week.", + }, + { + "from": "it@co1t.com", + "to": "david@co1t.com", + "date": "2024-06-24", + "subject": "Setting Up Your IT Needs", + "text": "Greetings! To ensure a seamless start, please refer to the attached comprehensive guide, which will assist you in setting up all your work accounts.", + }, + { + "from": "john@co1t.com", + "to": "david@co1t.com", + "date": "2024-06-24", + "subject": "First Week Check-In", + "text": "Hello! I hope you're settling in well. Let's connect briefly tomorrow to discuss how your first week has been going. Also, make sure to join us for a welcoming lunch this Thursday at noon—it's a great opportunity to get to know your colleagues!", + }, ] ``` @@ -134,7 +162,7 @@ query = "Any email about check ins?" # Rerank the documents results = co.rerank( - model='rerank-v3.5', + model="rerank-v3.5", query=query, documents=yaml_docs, top_n=2, @@ -187,7 +215,7 @@ Below, we'll get results from the Rerank endpoint: ```python PYTHON # Define the documents -employees = df.to_dict('records') +employees = df.to_dict("records") # Convert the documents to YAML format yaml_docs = [yaml.dump(doc, sort_keys=False) for doc in employees] @@ -197,7 +225,7 @@ query = "Any full-time product designers who joined recently?" # Rerank the documents results = co.rerank( - model='rerank-v3.5', + model="rerank-v3.5", query=query, documents=yaml_docs, top_n=1, @@ -219,11 +247,11 @@ In the example below, we repeat the steps of performing reranking with one diffe ```python PYTHON # Define the query -query = "هل هناك مزايا تتعلق باللياقة البدنية؟" # Are there fitness benefits? +query = "هل هناك مزايا تتعلق باللياقة البدنية؟" # Are there fitness benefits? # Rerank the documents results = co.rerank( - model='rerank-v3.5', + model="rerank-v3.5", query=query, documents=faqs, top_n=1, diff --git a/fern/pages/tutorials/build-things-with-cohere/semantic-search-with-cohere.mdx b/fern/pages/tutorials/build-things-with-cohere/semantic-search-with-cohere.mdx index fc74f1c84..654b79c0c 100644 --- a/fern/pages/tutorials/build-things-with-cohere/semantic-search-with-cohere.mdx +++ b/fern/pages/tutorials/build-things-with-cohere/semantic-search-with-cohere.mdx @@ -35,7 +35,8 @@ To get started, first we need to install the `cohere` library and create a Coher import numpy as np import cohere -co = cohere.Client("COHERE_API_KEY") # Get your API key: https://dashboard.cohere.com/api-keys +# Get your API key: https://dashboard.cohere.com/api-keys +co = cohere.Client("COHERE_API_KEY") ``` ## Embedding the documents @@ -56,25 +57,46 @@ Right now, we are doing the former. We call the Embed endpoint using `co.embed() ```python PYTHON # Define the documents faqs_long = [ - {"text": "Joining Slack Channels: You will receive an invite via email. Be sure to join relevant channels to stay informed and engaged."}, - {"text": "Finding Coffee Spots: For your caffeine fix, head to the break room's coffee machine or cross the street to the café for artisan coffee."}, - {"text": "Team-Building Activities: We foster team spirit with monthly outings and weekly game nights. Feel free to suggest new activity ideas anytime!"}, - {"text": "Working Hours Flexibility: We prioritize work-life balance. While our core hours are 9 AM to 5 PM, we offer flexibility to adjust as needed."}, - {"text": "Side Projects Policy: We encourage you to pursue your passions. Just be mindful of any potential conflicts of interest with our business."}, - {"text": "Reimbursing Travel Expenses: Easily manage your travel expenses by submitting them through our finance tool. Approvals are prompt and straightforward."}, - {"text": "Working from Abroad: Working remotely from another country is possible. Simply coordinate with your manager and ensure your availability during core hours."}, - {"text": "Health and Wellness Benefits: We care about your well-being and offer gym memberships, on-site yoga classes, and comprehensive health insurance."}, - {"text": "Performance Reviews Frequency: We conduct informal check-ins every quarter and formal performance reviews twice a year."}, - {"text": "Proposing New Ideas: Innovation is welcomed! Share your brilliant ideas at our weekly team meetings or directly with your team lead."}, + { + "text": "Joining Slack Channels: You will receive an invite via email. Be sure to join relevant channels to stay informed and engaged." + }, + { + "text": "Finding Coffee Spots: For your caffeine fix, head to the break room's coffee machine or cross the street to the café for artisan coffee." + }, + { + "text": "Team-Building Activities: We foster team spirit with monthly outings and weekly game nights. Feel free to suggest new activity ideas anytime!" + }, + { + "text": "Working Hours Flexibility: We prioritize work-life balance. While our core hours are 9 AM to 5 PM, we offer flexibility to adjust as needed." + }, + { + "text": "Side Projects Policy: We encourage you to pursue your passions. Just be mindful of any potential conflicts of interest with our business." + }, + { + "text": "Reimbursing Travel Expenses: Easily manage your travel expenses by submitting them through our finance tool. Approvals are prompt and straightforward." + }, + { + "text": "Working from Abroad: Working remotely from another country is possible. Simply coordinate with your manager and ensure your availability during core hours." + }, + { + "text": "Health and Wellness Benefits: We care about your well-being and offer gym memberships, on-site yoga classes, and comprehensive health insurance." + }, + { + "text": "Performance Reviews Frequency: We conduct informal check-ins every quarter and formal performance reviews twice a year." + }, + { + "text": "Proposing New Ideas: Innovation is welcomed! Share your brilliant ideas at our weekly team meetings or directly with your team lead." + }, ] documents = faqs_long # Embed the documents doc_emb = co.embed( - model="embed-english-v3.0", - input_type="search_document", - texts=[doc['text'] for doc in documents]).embeddings + model="embed-english-v3.0", + input_type="search_document", + texts=[doc["text"] for doc in documents], +).embeddings ``` Further reading: @@ -96,9 +118,10 @@ query = "How do I stay connected to what's happening at the company?" # Embed the query query_emb = co.embed( - model="embed-english-v3.0", - input_type="search_query", - texts=[query]).embeddings + model="embed-english-v3.0", + input_type="search_query", + texts=[query], +).embeddings ``` ## Performing semantic search @@ -116,15 +139,16 @@ Here, we show the most relevant documents with their similarity scores. def return_results(query_emb, doc_emb, documents): n = 2 scores = np.dot(query_emb, np.transpose(doc_emb))[0] - scores_sorted = sorted(enumerate(scores), - key=lambda x: x[1], - reverse=True)[:n] + scores_sorted = sorted( + enumerate(scores), key=lambda x: x[1], reverse=True + )[:n] for idx, item in enumerate(scores_sorted): print(f"Rank: {idx+1}") print(f"Score: {item[1]}") print(f"Document: {documents[item[0]]}\n") - + + return_results(query_emb, doc_emb, documents) ``` @@ -153,28 +177,38 @@ In the example below, we repeat the steps of performing semantic search with one ```python PYTHON # Define the documents faqs_short_fr = [ - {"text" : "Remboursement des frais de voyage : Gérez facilement vos frais de voyage en les soumettant via notre outil financier. Les approbations sont rapides et simples."}, - {"text" : "Travailler de l'étranger : Il est possible de travailler à distance depuis un autre pays. Il suffit de coordonner avec votre responsable et de vous assurer d'être disponible pendant les heures de travail."}, - {"text" : "Avantages pour la santé et le bien-être : Nous nous soucions de votre bien-être et proposons des adhésions à des salles de sport, des cours de yoga sur site et une assurance santé complète."}, - {"text" : "Fréquence des évaluations de performance : Nous organisons des bilans informels tous les trimestres et des évaluations formelles deux fois par an."} + { + "text": "Remboursement des frais de voyage : Gérez facilement vos frais de voyage en les soumettant via notre outil financier. Les approbations sont rapides et simples." + }, + { + "text": "Travailler de l'étranger : Il est possible de travailler à distance depuis un autre pays. Il suffit de coordonner avec votre responsable et de vous assurer d'être disponible pendant les heures de travail." + }, + { + "text": "Avantages pour la santé et le bien-être : Nous nous soucions de votre bien-être et proposons des adhésions à des salles de sport, des cours de yoga sur site et une assurance santé complète." + }, + { + "text": "Fréquence des évaluations de performance : Nous organisons des bilans informels tous les trimestres et des évaluations formelles deux fois par an." + }, ] documents = faqs_short_fr # Embed the documents doc_emb = co.embed( - model="embed-multilingual-v3.0", - input_type="search_document", - texts=[doc['text'] for doc in documents]).embeddings + model="embed-multilingual-v3.0", + input_type="search_document", + texts=[doc["text"] for doc in documents], +).embeddings # Add the user query query = "What's your remote-working policy?" # Embed the query query_emb = co.embed( - model="embed-multilingual-v3.0", - input_type="search_query", - texts=[query]).embeddings + model="embed-multilingual-v3.0", + input_type="search_query", + texts=[query], +).embeddings # Compute dot product similarity and display results return_results(query_emb, doc_emb, documents) @@ -212,20 +246,22 @@ documents = faqs_long # Embed the documents with the given embedding types doc_emb = co.embed( - model="embed-english-v3.0", - embedding_types=["float","int8"], - input_type="search_document", - texts=[doc['text'] for doc in documents]).embeddings + model="embed-english-v3.0", + embedding_types=["float", "int8"], + input_type="search_document", + texts=[doc["text"] for doc in documents], +).embeddings # Add the user query query = "How do I stay connected to what's happening at the company?" # Embed the query query_emb = co.embed( - model="embed-english-v3.0", - embedding_types=["float","int8"], - input_type="search_query", - texts=[query]).embeddings + model="embed-english-v3.0", + embedding_types=["float", "int8"], + input_type="search_query", + texts=[query], +).embeddings ``` Here are the search results of using the `float` embeddings. diff --git a/fern/pages/tutorials/build-things-with-cohere/text-generation-tutorial.mdx b/fern/pages/tutorials/build-things-with-cohere/text-generation-tutorial.mdx index cb607641b..c13f42b13 100644 --- a/fern/pages/tutorials/build-things-with-cohere/text-generation-tutorial.mdx +++ b/fern/pages/tutorials/build-things-with-cohere/text-generation-tutorial.mdx @@ -30,7 +30,8 @@ To get started, first we need to install the `cohere` library and create a Coher import cohere -co = cohere.Client("COHERE_API_KEY") # Get your API key: https://dashboard.cohere.com/api-keys +# Get your API key: https://dashboard.cohere.com/api-keys +co = cohere.Client("COHERE_API_KEY") ``` ## Basic text generation @@ -98,10 +99,12 @@ Below, we want the response to be similar in style and length to the convention, ```python PYTHON # Add the user message -user_input = "Why can't I access the server? Is it a permissions issue?" +user_input = ( + "Why can't I access the server? Is it a permissions issue?" +) # Create a prompt containing example outputs -message=f"""Write a ticket title for the following user request: +message = f"""Write a ticket title for the following user request: User request: Where are the usual storage places for project files? Ticket title: Project File Storage Location @@ -218,28 +221,37 @@ The `response_format` parameter allows you to specify the schema the JSON object ```python PYTHON # Add the user message -user_input = "Why can't I access the server? Is it a permissions issue?" +user_input = ( + "Why can't I access the server? Is it a permissions issue?" +) # Generate the response multiple times by adding the JSON schema response = co.chat( - model="command-r-plus-08-2024", - message=f"""Create an IT ticket for the following user request. Generate a JSON object. + model="command-r-plus-08-2024", + message=f"""Create an IT ticket for the following user request. Generate a JSON object. {user_input}""", - response_format={ - "type": "json_object", - "schema": { - "type": "object", - "required": ["title", "category", "status"], - "properties": { - "title": { "type": "string"}, - "category": { "type" : "string", "enum" : ["access", "software"]}, - "status": { "type" : "string" , "enum" : ["open", "closed"]} - } - } - }, + response_format={ + "type": "json_object", + "schema": { + "type": "object", + "required": ["title", "category", "status"], + "properties": { + "title": {"type": "string"}, + "category": { + "type": "string", + "enum": ["access", "software"], + }, + "status": { + "type": "string", + "enum": ["open", "closed"], + }, + }, + }, + }, ) import json + json_object = json.loads(response.text) print(json_object) @@ -268,8 +280,7 @@ In streaming mode, the endpoint will generate a series of objects. To get the ac message = "I'm joining a new startup called Co1t today. Could you help me write a one-sentence introduction message to my teammates." # Generate the response by streaming it -response = co.chat_stream( - message=message) +response = co.chat_stream(message=message) for event in response: if event.event_type == "text-generation": diff --git a/fern/pages/tutorials/cohere-on-azure/azure-ai-rag.mdx b/fern/pages/tutorials/cohere-on-azure/azure-ai-rag.mdx index 41590a6ab..3b94d34b3 100644 --- a/fern/pages/tutorials/cohere-on-azure/azure-ai-rag.mdx +++ b/fern/pages/tutorials/cohere-on-azure/azure-ai-rag.mdx @@ -38,18 +38,18 @@ To create a client, you need to provide the API key and the model's base URL for import cohere co_chat = cohere.Client( - api_key="AZURE_API_KEY_CHAT", - base_url="AZURE_ENDPOINT_CHAT" # example: "https://cohere-command-r-plus-08-2024-xyz.eastus.models.ai.azure.com/" + api_key="AZURE_API_KEY_CHAT", + base_url="AZURE_ENDPOINT_CHAT", # example: "https://cohere-command-r-plus-08-2024-xyz.eastus.models.ai.azure.com/" ) co_embed = cohere.Client( - api_key="AZURE_API_KEY_EMBED", - base_url="AZURE_ENDPOINT_EMBED" # example: "https://cohere-embed-v3-multilingual-xyz.eastus.models.ai.azure.com/" + api_key="AZURE_API_KEY_EMBED", + base_url="AZURE_ENDPOINT_EMBED", # example: "https://cohere-embed-v3-multilingual-xyz.eastus.models.ai.azure.com/" ) co_rerank = cohere.Client( api_key="AZURE_API_KEY_RERANK", - base_url="AZURE_ENDPOINT_RERANK" # example: "https://cohere-rerank-v3-multilingual-xyz.eastus.models.ai.azure.com/" + base_url="AZURE_ENDPOINT_RERANK", # example: "https://cohere-rerank-v3-multilingual-xyz.eastus.models.ai.azure.com/" ) ``` @@ -66,13 +66,16 @@ We have seen how to use the Chat endpoint in the text generation chapter. To use documents = [ { "title": "Tall penguins", - "text": "Emperor penguins are the tallest."}, + "text": "Emperor penguins are the tallest.", + }, { "title": "Penguin habitats", - "text": "Emperor penguins only live in Antarctica."}, + "text": "Emperor penguins only live in Antarctica.", + }, { "title": "What are animals?", - "text": "Animals are different from plants."} + "text": "Animals are different from plants.", + }, ] ``` @@ -84,10 +87,7 @@ The model leverages the provided documents as context for its response. Specific ```python PYTHON message = "What are the tallest living penguins?" -response = co_chat.chat( - message=message, - documents=documents -) +response = co_chat.chat(message=message, documents=documents) print("\nRESPONSE:\n") print(response.text) @@ -140,16 +140,20 @@ Next, we’ll define the documents we’ll use for RAG. We’ll use a few pages raw_documents = [ { "title": "Crafting Effective Prompts", - "url": "https://docs.cohere.com/docs/crafting-effective-prompts"}, + "url": "https://docs.cohere.com/docs/crafting-effective-prompts", + }, { "title": "Advanced Prompt Engineering Techniques", - "url": "https://docs.cohere.com/docs/advanced-prompt-engineering-techniques"}, + "url": "https://docs.cohere.com/docs/advanced-prompt-engineering-techniques", + }, { "title": "Prompt Truncation", - "url": "https://docs.cohere.com/docs/prompt-truncation"}, + "url": "https://docs.cohere.com/docs/prompt-truncation", + }, { "title": "Preambles", - "url": "https://docs.cohere.com/docs/preambles"} + "url": "https://docs.cohere.com/docs/preambles", + }, ] ``` @@ -178,7 +182,6 @@ class Vectorstore: self.embed() self.index() - def load_and_chunk(self) -> None: """ Loads the text from the sources and chunks the HTML content. @@ -209,8 +212,7 @@ class Vectorstore: batch = self.docs[i : min(i + batch_size, self.docs_len)] texts = [item["text"] for item in batch] docs_embs_batch = co_embed.embed( - texts=texts, - input_type="search_document" + texts=texts, input_type="search_document" ).embeddings self.docs_embs.extend(docs_embs_batch) @@ -221,10 +223,16 @@ class Vectorstore: print("Indexing document chunks...") self.idx = hnswlib.Index(space="ip", dim=1024) - self.idx.init_index(max_elements=self.docs_len, ef_construction=512, M=64) - self.idx.add_items(self.docs_embs, list(range(len(self.docs_embs)))) + self.idx.init_index( + max_elements=self.docs_len, ef_construction=512, M=64 + ) + self.idx.add_items( + self.docs_embs, list(range(len(self.docs_embs))) + ) - print(f"Indexing complete with {self.idx.get_current_count()} document chunks.") + print( + f"Indexing complete with {self.idx.get_current_count()} document chunks." + ) def retrieve(self, query: str) -> List[Dict[str, str]]: """ @@ -239,21 +247,24 @@ class Vectorstore: # Dense retrieval query_emb = co_embed.embed( - texts=[query], - input_type="search_query" + texts=[query], input_type="search_query" ).embeddings - - doc_ids = self.idx.knn_query(query_emb, k=self.retrieve_top_k)[0][0] + + doc_ids = self.idx.knn_query( + query_emb, k=self.retrieve_top_k + )[0][0] # Reranking docs_to_rerank = [self.docs[doc_id] for doc_id in doc_ids] - yaml_docs = [yaml.dump(doc, sort_keys=False) for doc in docs_to_rerank] + yaml_docs = [ + yaml.dump(doc, sort_keys=False) for doc in docs_to_rerank + ] rerank_results = co_rerank.rerank( - query=query, - documents=yaml_docs, - top_n=self.rerank_top_k + query=query, documents=yaml_docs, top_n=self.rerank_top_k ) - doc_ids_reranked = [doc_ids[result.index] for result in rerank_results.results] + doc_ids_reranked = [ + doc_ids[result.index] for result in rerank_results.results + ] docs_retrieved = [] for doc_id in doc_ids_reranked: @@ -318,17 +329,17 @@ Here's what happens inside the function: ```python PYTHON def run_chatbot(message, chat_history=None): - + if chat_history is None: chat_history = [] - - # Generate search queries, if any + + # Generate search queries, if any response = co_chat.chat( message=message, search_queries_only=True, chat_history=chat_history, ) - + search_queries = [] for query in response.search_queries: search_queries.append(query.text) @@ -346,27 +357,26 @@ def run_chatbot(message, chat_history=None): response = co_chat.chat( message=message, documents=documents, - chat_history=chat_history + chat_history=chat_history, ) else: response = co_chat.chat( - message=message, - chat_history=chat_history + message=message, chat_history=chat_history ) - + # Print the chatbot response, citations, and documents print("\nRESPONSE:\n") print(response.text) - + if response.citations: - print("\nCITATIONS:\n") + print("\nCITATIONS:\n") for citation in response.citations: print(citation) - print("\nDOCUMENTS:\n") + print("\nDOCUMENTS:\n") for document in response.documents: print(document) - + chat_history = response.chat_history return chat_history @@ -387,7 +397,10 @@ Hello there! How can I help you today? ```python PYTHON -chat_history = run_chatbot("What's the difference between zero-shot and few-shot prompting", chat_history) +chat_history = run_chatbot( + "What's the difference between zero-shot and few-shot prompting", + chat_history, +) ``` ``` Retrieving information... @@ -409,7 +422,9 @@ DOCUMENTS: ```python PYTHON -chat_history = run_chatbot("What do you know about 5G networks?", chat_history) +chat_history = run_chatbot( + "What do you know about 5G networks?", chat_history +) ``` ```mdx Retrieving information... diff --git a/fern/pages/tutorials/cohere-on-azure/azure-ai-reranking.mdx b/fern/pages/tutorials/cohere-on-azure/azure-ai-reranking.mdx index 96a244252..224577eae 100644 --- a/fern/pages/tutorials/cohere-on-azure/azure-ai-reranking.mdx +++ b/fern/pages/tutorials/cohere-on-azure/azure-ai-reranking.mdx @@ -37,7 +37,7 @@ To create a client, you need to provide the API key and the model's base URL for # ! pip install cohere api_key_rerank = "AZURE_API_KEY_RERANK" -endpoint_rerank = "AZURE_ENDPOINT_RERANK" # example: "https://cohere-rerank-v3-multilingual-xyz.eastus.models.ai.azure.com/" +endpoint_rerank = "AZURE_ENDPOINT_RERANK" # example: "https://cohere-rerank-v3-multilingual-xyz.eastus.models.ai.azure.com/" ``` @@ -48,7 +48,6 @@ co = cohere.Client( api_key=api_key_rerank, base_url=endpoint_rerank, ) - ``` ## Retrieve documents @@ -60,15 +59,42 @@ Below is a list of nine documents representing the initial search results. Each ```python PYTHON documents = [ - {"Title":"Incorrect Password","Content":"Hello, I have been trying to access my account for the past hour and it keeps saying my password is incorrect. Can you please help me?"}, - {"Title":"Confirmation Email Missed","Content":"Hi, I recently purchased a product from your website but I never received a confirmation email. Can you please look into this for me?"}, - {"Title":"Questions about Return Policy","Content":"Hello, I have a question about the return policy for this product. I purchased it a few weeks ago and it is defective."}, - {"Title":"Customer Support is Busy","Content":"Good morning, I have been trying to reach your customer support team for the past week but I keep getting a busy signal. Can you please help me?"}, - {"Title":"Received Wrong Item","Content":"Hi, I have a question about my recent order. I received the wrong item and I need to return it."}, - {"Title":"Customer Service is Unavailable","Content":"Hello, I have been trying to reach your customer support team for the past hour but I keep getting a busy signal. Can you please help me?"}, - {"Title":"Return Policy for Defective Product","Content":"Hi, I have a question about the return policy for this product. I purchased it a few weeks ago and it is defective."}, - {"Title":"Wrong Item Received","Content":"Good morning, I have a question about my recent order. I received the wrong item and I need to return it."}, - {"Title":"Return Defective Product","Content":"Hello, I have a question about the return policy for this product. I purchased it a few weeks ago and it is defective."} + { + "Title": "Incorrect Password", + "Content": "Hello, I have been trying to access my account for the past hour and it keeps saying my password is incorrect. Can you please help me?", + }, + { + "Title": "Confirmation Email Missed", + "Content": "Hi, I recently purchased a product from your website but I never received a confirmation email. Can you please look into this for me?", + }, + { + "Title": "Questions about Return Policy", + "Content": "Hello, I have a question about the return policy for this product. I purchased it a few weeks ago and it is defective.", + }, + { + "Title": "Customer Support is Busy", + "Content": "Good morning, I have been trying to reach your customer support team for the past week but I keep getting a busy signal. Can you please help me?", + }, + { + "Title": "Received Wrong Item", + "Content": "Hi, I have a question about my recent order. I received the wrong item and I need to return it.", + }, + { + "Title": "Customer Service is Unavailable", + "Content": "Hello, I have been trying to reach your customer support team for the past hour but I keep getting a busy signal. Can you please help me?", + }, + { + "Title": "Return Policy for Defective Product", + "Content": "Hi, I have a question about the return policy for this product. I purchased it a few weeks ago and it is defective.", + }, + { + "Title": "Wrong Item Received", + "Content": "Good morning, I have a question about my recent order. I received the wrong item and I need to return it.", + }, + { + "Title": "Return Defective Product", + "Content": "Hello, I have a question about the return policy for this product. I purchased it a few weeks ago and it is defective.", + }, ] ``` @@ -88,15 +114,11 @@ When passing documents that contain multiple fields like in this case, for best ```python PYTHON import yaml -yaml_docs = [yaml.dump(doc, sort_keys=False) for doc in documents] +yaml_docs = [yaml.dump(doc, sort_keys=False) for doc in documents] -query = 'What emails have been about refunds?' +query = "What emails have been about refunds?" -results = co.rerank( - documents=yaml_docs, - query=query, - top_n=3 -) +results = co.rerank(documents=yaml_docs, query=query, top_n=3) ``` Since we set `top_n=3`, the response will return the three documents most relevant to our query. Each result includes both the document's original position (index) in our input list and a score indicating how well it matches the query. @@ -106,12 +128,13 @@ Let's examine the reranked results below. ```python PYTHON -def return_results(results, documents): +def return_results(results, documents): for idx, result in enumerate(results.results): - print(f"Rank: {idx+1}") + print(f"Rank: {idx+1}") print(f"Score: {result.relevance_score}") print(f"Document: {documents[result.index]}\n") - + + return_results(results, documents) ``` ```mdx @@ -144,9 +167,27 @@ The model will rerank based on order of the fields passed. ```python PYTHON # Define the documents emails = [ - {"from": "hr@co1t.com", "to": "david@co1t.com", "date": "2024-06-24", "subject": "A Warm Welcome to Co1t!", "text": "We are delighted to welcome you to the team! As you embark on your journey with us, you'll find attached an agenda to guide you through your first week."}, - {"from": "it@co1t.com", "to": "david@co1t.com", "date": "2024-06-24", "subject": "Setting Up Your IT Needs", "text": "Greetings! To ensure a seamless start, please refer to the attached comprehensive guide, which will assist you in setting up all your work accounts."}, - {"from": "john@co1t.com", "to": "david@co1t.com", "date": "2024-06-24", "subject": "First Week Check-In", "text": "Hello! I hope you're settling in well. Let's connect briefly tomorrow to discuss how your first week has been going. Also, make sure to join us for a welcoming lunch this Thursday at noon—it's a great opportunity to get to know your colleagues!"} + { + "from": "hr@co1t.com", + "to": "david@co1t.com", + "date": "2024-06-24", + "subject": "A Warm Welcome to Co1t!", + "text": "We are delighted to welcome you to the team! As you embark on your journey with us, you'll find attached an agenda to guide you through your first week.", + }, + { + "from": "it@co1t.com", + "to": "david@co1t.com", + "date": "2024-06-24", + "subject": "Setting Up Your IT Needs", + "text": "Greetings! To ensure a seamless start, please refer to the attached comprehensive guide, which will assist you in setting up all your work accounts.", + }, + { + "from": "john@co1t.com", + "to": "david@co1t.com", + "date": "2024-06-24", + "subject": "First Week Check-In", + "text": "Hello! I hope you're settling in well. Let's connect briefly tomorrow to discuss how your first week has been going. Also, make sure to join us for a welcoming lunch this Thursday at noon—it's a great opportunity to get to know your colleagues!", + }, ] yaml_emails = [yaml.dump(doc, sort_keys=False) for doc in emails] diff --git a/fern/pages/tutorials/cohere-on-azure/azure-ai-sem-search.mdx b/fern/pages/tutorials/cohere-on-azure/azure-ai-sem-search.mdx index 362add9f5..93d1cedfc 100644 --- a/fern/pages/tutorials/cohere-on-azure/azure-ai-sem-search.mdx +++ b/fern/pages/tutorials/cohere-on-azure/azure-ai-sem-search.mdx @@ -43,8 +43,8 @@ import re import cohere co = cohere.Client( - api_key="AZURE_API_KEY_EMBED", - base_url="AZURE_ENDPOINT_EMBED" # example: "https://cohere-embed-v3-multilingual-xyz.eastus.models.ai.azure.com/" + api_key="AZURE_API_KEY_EMBED", + base_url="AZURE_ENDPOINT_EMBED", # example: "https://cohere-embed-v3-multilingual-xyz.eastus.models.ai.azure.com/" ) ``` @@ -73,21 +73,24 @@ We'll perform several pre-processing steps: removing any duplicate entries, filt ```python PYTHON # Ensure there is no duplicated text in the headers def remove_duplicates(text): - return re.sub(r'((\b\w+\b.{1,2}\w+\b)+).+\1', r'\1', text, flags=re.I) + return re.sub( + r"((\b\w+\b.{1,2}\w+\b)+).+\1", r"\1", text, flags=re.I + ) -df ['text'] = df['text'].apply(remove_duplicates) + +df["text"] = df["text"].apply(remove_duplicates) # Keep only selected languages -languages = ['English', 'Spanish', 'Danish'] -df = df.loc[df['lang'].isin(languages)] +languages = ["English", "Spanish", "Danish"] +df = df.loc[df["lang"].isin(languages)] # Pick the top 80 longest articles -df['text_length'] = df['text'].str.len() -df.sort_values(by=['text_length'], ascending=False, inplace=True) +df["text_length"] = df["text"].str.len() +df.sort_values(by=["text_length"], ascending=False, inplace=True) top_80_df = df[:80] # Language distribution -top_80_df['lang'].value_counts() +top_80_df["lang"].value_counts() ``` @@ -113,17 +116,20 @@ Finally, we'll build a search index with the `hnsw` vector library to store thes ```python PYTHON # Embed documents -docs = top_80_df['text'].to_list() -docs_lang = top_80_df['lang'].to_list() -translated_docs = top_80_df['translation'].to_list() #for reference when returning non-English results +docs = top_80_df["text"].to_list() +docs_lang = top_80_df["lang"].to_list() +translated_docs = top_80_df[ + "translation" +].to_list() # for reference when returning non-English results doc_embs = co.embed( - texts=docs, - input_type='search_document' + texts=docs, input_type="search_document" ).embeddings # Create a search index -index = hnswlib.Index(space='ip', dim=1024) -index.init_index(max_elements=len(doc_embs), ef_construction=512, M=64) +index = hnswlib.Index(space="ip", dim=1024) +index.init_index( + max_elements=len(doc_embs), ef_construction=512, M=64 +) index.add_items(doc_embs, list(range(len(doc_embs)))) ``` @@ -137,20 +143,21 @@ Next, we build a function that takes a query as input, embeds it, and finds the def retrieval(query): # Embed query and retrieve results query_emb = co.embed( - texts=[query], - input_type="search_query" + texts=[query], input_type="search_query" ).embeddings - doc_ids = index.knn_query(query_emb, k=3)[0][0] # we will retrieve 3 closest neighbors - + doc_ids = index.knn_query(query_emb, k=3)[0][ + 0 + ] # we will retrieve 3 closest neighbors + # Print and append results print(f"QUERY: {query.upper()} \n") retrieved_docs, translated_retrieved_docs = [], [] - + for doc_id in doc_ids: # Append results retrieved_docs.append(docs[doc_id]) translated_retrieved_docs.append(translated_docs[doc_id]) - + # Print results print(f"ORIGINAL ({docs_lang[doc_id]}): {docs[doc_id]}") if docs_lang[doc_id] != "English": @@ -166,8 +173,8 @@ Let’s now try to query the index with a couple of examples, one each in Englis ```python PYTHON queries = [ - "Can data science help meet sustainability goals?", # English example - "Hvor kan jeg finde den seneste danske boligplan?" # Danish example - "Where can I find the latest Danish property plan?" + "Can data science help meet sustainability goals?", # English example + "Hvor kan jeg finde den seneste danske boligplan?", # Danish example - "Where can I find the latest Danish property plan?" ] for query in queries: diff --git a/fern/pages/tutorials/cohere-on-azure/azure-ai-text-generation.mdx b/fern/pages/tutorials/cohere-on-azure/azure-ai-text-generation.mdx index ccf3280cd..8c3eb8f18 100644 --- a/fern/pages/tutorials/cohere-on-azure/azure-ai-text-generation.mdx +++ b/fern/pages/tutorials/cohere-on-azure/azure-ai-text-generation.mdx @@ -38,8 +38,8 @@ To create a client, you need to provide the API key and the model's base URL for import cohere co = cohere.Client( - api_key="AZURE_API_KEY_CHAT", - base_url="AZURE_ENDPOINT_CHAT" # example: "https://cohere-command-r-plus-08-2024-xyz.eastus.models.ai.azure.com/" + api_key="AZURE_API_KEY_CHAT", + base_url="AZURE_ENDPOINT_CHAT", # example: "https://cohere-command-r-plus-08-2024-xyz.eastus.models.ai.azure.com/" ) ``` @@ -97,9 +97,7 @@ This function takes a user message and generates the response via the chat endpo ```python PYTHON def generate_text(message): - response = co.chat( - message=message - ) + response = co.chat(message=message) return response ``` @@ -149,7 +147,7 @@ Another type of use case is text summarization. Now, let's summarize the custome ```python PYTHON -prompt=f"""Summarize this customer inquiry into one short sentence. +prompt = f"""Summarize this customer inquiry into one short sentence. Inquiry: {inquiry}""" @@ -169,7 +167,7 @@ Let's look at an example where we convert a customer support chat response into ```python PYTHON -prompt=f"""Rewrite this customer support agent response into an email format, ready to send to the customer. +prompt = f"""Rewrite this customer support agent response into an email format, ready to send to the customer. If you're experiencing brief periods of slow data speeds or difficulty sending text messages and connecting to your mobile network, here are some troubleshooting steps you can follow: @@ -224,27 +222,28 @@ For this, we introduce a couple of additional parameters to the Chat endpoint: preamble = """## Task and Context You are a helpful customer support agent that assists customers of a mobile network service.""" + # Run the chatbot def run_chatbot(message, chat_history=None): if chat_history is None: chat_history = [] - + response = co.chat( - message=message, - preamble=preamble, - chat_history=chat_history + message=message, preamble=preamble, chat_history=chat_history ) - + print(response.text) - + chat_history = response.chat_history - + return chat_history ``` ```python PYTHON -chat_history = run_chatbot("Hi. I've noticed some fluctuations in my mobile network's performance recently.") +chat_history = run_chatbot( + "Hi. I've noticed some fluctuations in my mobile network's performance recently." +) ``` ```mdx Hello there! I'd be happy to assist you with this issue. Network performance fluctuations can be concerning, and it's important to identify the cause to ensure you have a smooth experience. @@ -256,7 +255,10 @@ We can work together to get to the bottom of this and find a solution to improve ```python PYTHON -chat_history = run_chatbot("At times, the data speed is very poor. What should I do?", chat_history) +chat_history = run_chatbot( + "At times, the data speed is very poor. What should I do?", + chat_history, +) ``` ```mdx Here are some steps you can take to address the issue of poor data speeds: @@ -284,7 +286,9 @@ If you've tried the basic troubleshooting steps and are still experiencing poor ```python PYTHON -chat_history = run_chatbot("Thanks. What else can I check?", chat_history) +chat_history = run_chatbot( + "Thanks. What else can I check?", chat_history +) ``` ```mdx You're welcome! Let's explore a few more advanced troubleshooting steps and potential factors: diff --git a/fern/pages/tutorials/cohere-on-azure/azure-ai-tool-use.mdx b/fern/pages/tutorials/cohere-on-azure/azure-ai-tool-use.mdx index 28c214598..c2b415e9e 100644 --- a/fern/pages/tutorials/cohere-on-azure/azure-ai-tool-use.mdx +++ b/fern/pages/tutorials/cohere-on-azure/azure-ai-tool-use.mdx @@ -29,7 +29,7 @@ To create a client, you need to provide the API key and the model's base URL for # ! pip install cohere api_key_chat = "AZURE_API_KEY_CHAT" -endpoint_chat = "AZURE_ENDPOINT_CHAT" # example: "https://cohere-command-r-plus-08-2024-xyz.eastus.models.ai.azure.com/" +endpoint_chat = "AZURE_ENDPOINT_CHAT" # example: "https://cohere-command-r-plus-08-2024-xyz.eastus.models.ai.azure.com/" ``` @@ -56,29 +56,58 @@ Here, we are defining a Python function for each tool, but more broadly, the too ```python PYTHON def search_faqs(query): 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."} + { + "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." + }, ] - return {"faqs" : faqs} + return {"faqs": faqs} + def search_emails(query): emails = [ - {"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."}, - {"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."}, - {"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!"}, + { + "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.", + }, + { + "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.", + }, + { + "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!", + }, ] - return {"emails" : emails} - + return {"emails": emails} + + def create_calendar_event(date: str, time: str, duration: int): # You can implement any logic here - return {"is_success": True, - "message": f"Created a {duration} hour long event at {time} on {date}"} - + return { + "is_success": True, + "message": f"Created a {duration} hour long event at {time} on {date}", + } + + functions_map = { "search_faqs": search_faqs, "search_emails": search_emails, - "create_calendar_event": create_calendar_event + "create_calendar_event": create_calendar_event, } ``` @@ -92,48 +121,48 @@ This schema informs the LLM about what the tool does, and the LLM decides whethe ```python PYTHON tools = [ { - "name": "search_faqs", - "description": "Given a user query, searches a company's frequently asked questions (FAQs) list and returns the most relevant matches to the query.", - "parameter_definitions": { - "query": { - "description": "The query from the user", - "type": "str", - "required": True - } - } - }, - { - "name": "search_emails", - "description": "Given a user query, searches a person's emails and returns the most relevant matches to the query.", - "parameter_definitions": { - "query": { - "description": "The query from the user", - "type": "str", - "required": True - } - } - }, + "name": "search_faqs", + "description": "Given a user query, searches a company's frequently asked questions (FAQs) list and returns the most relevant matches to the query.", + "parameter_definitions": { + "query": { + "description": "The query from the user", + "type": "str", + "required": True, + } + }, + }, { - "name": "create_calendar_event", - "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.", - "parameter_definitions": { - "date": { - "description": "the date on which the event starts, formatted as mm/dd/yy", - "type": "str", - "required": True + "name": "search_emails", + "description": "Given a user query, searches a person's emails and returns the most relevant matches to the query.", + "parameter_definitions": { + "query": { + "description": "The query from the user", + "type": "str", + "required": True, + } }, - "time": { - "description": "the time of the event, formatted using 24h military time formatting", - "type": "str", - "required": True + }, + { + "name": "create_calendar_event", + "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.", + "parameter_definitions": { + "date": { + "description": "the date on which the event starts, formatted as mm/dd/yy", + "type": "str", + "required": True, + }, + "time": { + "description": "the time of the event, formatted using 24h military time formatting", + "type": "str", + "required": True, + }, + "duration": { + "description": "the number of hours the event lasts for", + "type": "float", + "required": True, + }, }, - "duration": { - "description": "the number of hours the event lasts for", - "type": "float", - "required": True - } - } - } + }, ] ``` @@ -157,45 +186,50 @@ Let's create a function called `run_assistant` to implement these steps and prin ```python PYTHON -preamble="""## Task and Context +preamble = """## Task and Context You 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""" + def run_assistant(message, chat_history=None): - + if chat_history is None: chat_history = [] - + # Step 1: get user message print(f"Question:\n{message}") - print("="*50) + print("=" * 50) - # Step 2: Generate tool calls (if any) + # Step 2: Generate tool calls (if any) response = co.chat( message=message, preamble=preamble, tools=tools, chat_history=chat_history, - force_single_step=False + force_single_step=False, ) while response.tool_calls: tool_calls = response.tool_calls - + if response.text: print("Tool plan:") - print(response.text,"\n") + print(response.text, "\n") print("Tool calls:") for call in tool_calls: - print(f"Tool name: {call.name} | Parameters: {call.parameters}") - print("="*50) - + print( + f"Tool name: {call.name} | Parameters: {call.parameters}" + ) + print("=" * 50) + # Step 3: Get tool results tool_results = [] for tc in tool_calls: tool_call = {"name": tc.name, "parameters": tc.parameters} tool_output = functions_map[tc.name](**tc.parameters) - tool_results.append({"call": tool_call, "outputs": [tool_output]}) - + tool_results.append( + {"call": tool_call, "outputs": [tool_output]} + ) + # Step 4: Generate response and citations response = co.chat( message="", @@ -203,16 +237,16 @@ def run_assistant(message, chat_history=None): tools=tools, tool_results=tool_results, chat_history=response.chat_history, - force_single_step=False + force_single_step=False, ) chat_history = response.chat_history - + # Print final response print("RESPONSE:\n") print(response.text) - print("="*50) - + print("=" * 50) + # Print citations (if any) if response.citations: print("\nCITATIONS:\n") @@ -222,7 +256,7 @@ def run_assistant(message, chat_history=None): print("\nCITED REFERENCES:\n") for document in response.documents: print(document) - + return chat_history ``` @@ -236,7 +270,9 @@ Additionally, the model also generates fine-grained citations in tool use mode b ```python PYTHON -chat_history = run_assistant("Any doc on how do I submit travel expenses? Also, any emails about setting up IT access?") +chat_history = run_assistant( + "Any doc on how do I submit travel expenses? Also, any emails about setting up IT access?" +) ``` ```mdx Question: