Conversations
This page assumes you are already familiar with how get hold of an api_key
and org_id
and how to install the Engage Smarter Python library. If not, turn to the Getting Started tutorial.
Conceptual overview
The Engage Smarter AI Conversations
API is the main API for interacting with agents on the platform.
Conversations are threads of messages between a user
and an AI agent
on the platform linked by a common conversation_id
. The platform contains a record of the conversation history, meaning the API is stateful. When a new user message is sent to an agent via the Conversations
API, the platform retrieves the previous conversation history and adds the latest user message. The agent then responds to the latest user message, using the existing conversation history as additional context.
The platform keeps track of which conversation a message is part of by enforcing that a conversation_id
be sent with every user
message to the Conversations
API.
There is also the Runs
API which expects a full message history between the User and the Agent to always be sent rather than just the latest user message. This is comparable to the OpenAI Chat Completion API. See the Runs section for more details.
Pre-requisites
First, we initialise the Engage Smarter Python Client
.
import os
from engagesmarter import Client
api_key = os.getenv("ENGAGE_SMARTER_API_KEY")
org_id = os.getenv("ENGAGE_SMARTER_ORG_ID")
client = Client(
api_key=api_key,
org_id=org_id,
)
Creating a new conversation
To have a conversation with an AI agent, we first need to request a conversation_id
to use with every subsequent request in the same conversation. To do this, we use the create
method which returns a ConversationReadFull
object with an id
field representing the conversation_id
.
conversation = client.conversations.create()
conversation_id = conversation.id
When we create a conversation, we may also want to pass in metadata to record additional information in the platform for us to refer to later. To do this we pass in a ConversationCreate
object to the create
method. We can use the data
field for additional metadata and the source
field to record where the API is being called from, for instance a particular chat integration.
When we get back the ConversationReadFull
object, we can see as well as the id
field, we also have a data
field and source
field with the data we passed in.
from engagesmarter import ConversationCreate
conversation_data = ConversationCreate(
data={"additional": "data", "can": "be", "added": "here"}, source="test_source"
)
conversation = client.conversations.create(conversation=conversation_data)
conversation_id = conversation.id
print(conversation.data)
print(conversation.source)
The additional data
and source
within a conversation may be useful for linking a conversation to a particular user or ticket in your system or from a particular system source.
The Engage Smarter AI Platform also has a tags mechanism for labelling either conversations or runs.
Interacting with an agent
Now that we have our conversation initialised with a conversation_id
, we can start to interact with an agent.
Let's send a first message to the agent. We'll speak to an agent which is an expert in pensions.
from engagesmarter import UserMessage
AGENT = "pensions-questions-latest"
user_message_1 = UserMessage(content="Hello, can you help me understand pensions?")
response = client.conversations.chat_with_agent(
conversation_id=conversation_id,
messages=[user_message_1],
agent=AGENT,
)
response
We get back a list of messages, in this case containing one agent message. We can see that its role
is "agent"
and the content
is the response from the agent.
agent_message_1 = response[0]
print(agent_message_1.role)
print(agent_message_1.content)
Since the Conversations API is stateful, to continue the conversation all we need to do is send another user message with the same conversation_id
as before. The agent on the platform knows what has already been said in the conversation and can respond to the user's latest message with that past context in mind.
user_message_2 = UserMessage(
content="Thanks, yes, I'd like some help understanding the options around transferring an old workplace pension."
)
replies = client.conversations.chat_with_agent(
conversation_id=conversation_id,
messages=[user_message_2],
agent=AGENT,
)
agent_message_2 = replies[0]
Notice that the user message is passed in as part of a list. This is because the API expects a list of messages to be sent in, even if there is only one message. You can in fact send multiple user messages at once to the API, and the agent will respond taking those message - plus the existing conversation history - into account.
Accessing the message history
If we want to see the full message history for a conversation, we can use the conversation_id
to access it via the get_conversation_message_history
method:
message_history = client.conversations.get_conversation_message_history(
conversation_id=conversation_id
)
for message in message_history:
print(f"{message.role}: {message.content[:50]} ...")
Searching your past conversations
You can search your conversations to find a specific conversation or a set of conversations that match a certain criteria. To do this, you can use the search_own_conversations
method. This will return a list of ConversationRead
objects that match the search criteria.
The results are paginated, meaning you will need to use the limit
and offset
parameters to page through the results. You can set the reversed
parameter to True
to reverse the order of the results.
The search_own_conversations
method will return conversations which you as a User have had either via the Platform UI or via the Conversations API. If you have shared an API key, for instance for use in a production system, then those conversations will be included in the search results.
results = client.conversations.search_own_conversations(limit=10, offset=0)
print(len(results))
Accessing or updating a conversation's metadata
We saw above that it is possible to add metadata to a conversation when it is created. We can also access conversation metadata at any time by requesting the ConversationReadFull
object. This object has a data
field which contains the metadata and a source
field for system source information, along with other fields such as the id
, created
timestamp and linked org_id
.
conversation_metadata = client.conversations.get_conversation_metadata(
conversation_id=conversation_id
)
print(conversation_metadata.data)
print(conversation_metadata.source)
We can also easily update this conversation metadata. Here we update only the data
field, but we could also update the source
field if we wanted to.
from engagesmarter import ConversationUpdate
conversation_update = ConversationUpdate(data={"different": "data"})
updated_conversation_metadata = client.conversations.update_conversation_metadata(
conversation_id=conversation_id,
conversation=conversation_update,
)
print(updated_conversation_metadata.data)
print(updated_conversation_metadata.source)