Skip to content

Commit

Permalink
feat: implement chat history (#106)
Browse files Browse the repository at this point in the history
* feat: add chat history apis

* feat: chat history ui initial implementation

* chore: switch model to gpt-4o-mini

* refactor: migrate cosmos db infra to AVM

* fix: missing or incorrect sessionId

* chore: update dependencies

* fix: chat message format

* fix: querying user id

* fix: get chat sessions

* feat: complete history component

* feat: connect chat component with history

* docs: update docs
  • Loading branch information
sinedied authored Dec 16, 2024
1 parent 8d40bbd commit ecf53a3
Show file tree
Hide file tree
Showing 27 changed files with 1,249 additions and 748 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ This application is made from multiple components:

- A serverless API built with [Azure Functions](https://learn.microsoft.com/azure/azure-functions/functions-overview?pivots=programming-language-javascript) and using [LangChain.js](https://js.langchain.com/) to ingest the documents and generate responses to the user chat queries. The code is located in the `packages/api` folder.

- A database to store the text extracted from the documents and the vectors generated by LangChain.js, using [Azure Cosmos DB for NoSQL](https://learn.microsoft.com/azure/cosmos-db/nosql/).
- A database to store chat sessions and the text extracted from the documents and the vectors generated by LangChain.js, using [Azure Cosmos DB for NoSQL](https://learn.microsoft.com/azure/cosmos-db/nosql/).

- A file storage to store the source documents, using [Azure Blob Storage](https://learn.microsoft.com/azure/storage/blobs/storage-blobs-introduction).

Expand All @@ -54,6 +54,7 @@ We use the [HTTP protocol for AI chat apps](https://aka.ms/chatprotocol) to comm

- **Serverless Architecture**: Utilizes Azure Functions and Azure Static Web Apps for a fully serverless deployment.
- **Retrieval-Augmented Generation (RAG)**: Combines the power of Azure Cosmos DB and LangChain.js to provide relevant and accurate responses.
- **Chat Sessions History**: Maintains a personal chat history for each user, allowing them to revisit previous conversations.
- **Scalable and Cost-Effective**: Leverages Azure's serverless offerings to provide a scalable and cost-effective solution.
- **Local Development**: Supports local development using Ollama for testing without any cloud costs.

Expand Down
Binary file modified docs/images/architecture-local.drawio.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/architecture.drawio.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions docs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ This application is made from multiple components:

- A serverless API built with [Azure Functions](https://learn.microsoft.com/azure/azure-functions/functions-overview?pivots=programming-language-javascript) and using [LangChain.js](https://js.langchain.com/) to ingest the documents and generate responses to the user chat queries. The code is located in the `packages/api` folder.

- A database to store the text extracted from the documents and the vectors generated by LangChain.js, using [Azure Cosmos DB for NoSQL](https://learn.microsoft.com/azure/cosmos-db/nosql/).
- A database to store chat sessions and the text extracted from the documents and the vectors generated by LangChain.js, using [Azure Cosmos DB for NoSQL](https://learn.microsoft.com/azure/cosmos-db/nosql/).

- A file storage to store the source documents, using [Azure Blob Storage](https://learn.microsoft.com/azure/storage/blobs/storage-blobs-introduction).

Expand Down Expand Up @@ -77,9 +77,9 @@ You can now open the web app in your browser and start chatting with the bot.

Our API is composed of two main endpoints:

- `/documents`: This endpoint allows to upload a PDF documents in the database. Using LangChain.js, we extract the text from the PDF file, split it into smaller chunks, and generate vectors for each chunk. We store the text and the vectors in the database for later use.
- `POST /documents`: This endpoint allows to upload a PDF documents in the database. Using LangChain.js, we extract the text from the PDF file, split it into smaller chunks, and generate vectors for each chunk. We store the text and the vectors in the database for later use.

- `/chat`: This endpoint receives a list of messages, the last being the user query and returns a response generated by the LLM. It uses the documents stored in the database to generate the response. We use LangChain.js components to connect to the database, load the documents and perform a vector search after vectorizing the user query. After that, the most relevant documents are injected into the prompt, and we generate the response. While this process seems complex, LangChain.js does all the heavy lifting for us so we can focus on the application flow.
- `POST /chats`: This endpoint receives a list of messages, the last being the user query and returns a response generated by the LLM. It uses the documents stored in the database to generate the response. We use LangChain.js components to connect to the database, load the documents and perform a vector search after vectorizing the user query. After that, the most relevant documents are injected into the prompt, and we generate the response. While this process seems complex, LangChain.js does all the heavy lifting for us so we can focus on the application flow.

The `/documents` endpoint is used to ingest the documents after the application is deployed by uploading the PDFs, using either `curl` commands or the Node.js script we built (have a look at the `postup` hook in the `azure.yaml` file).

Expand Down
40 changes: 0 additions & 40 deletions infra/core/database/cosmos/cosmos-account.bicep

This file was deleted.

21 changes: 0 additions & 21 deletions infra/core/database/cosmos/sql/cosmos-sql-account.bicep

This file was deleted.

73 changes: 0 additions & 73 deletions infra/core/database/cosmos/sql/cosmos-sql-db.bicep

This file was deleted.

69 changes: 55 additions & 14 deletions infra/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ module openAi 'core/ai/cognitiveservices.bicep' = if (empty(openAiUrl)) {
version: chatModelVersion
}
sku: {
name: 'Standard'
name: 'GlobalStandard'
capacity: chatDeploymentCapacity
}
}
Expand All @@ -237,22 +237,63 @@ module openAi 'core/ai/cognitiveservices.bicep' = if (empty(openAiUrl)) {
}
}

module cosmosDb './core/database/cosmos/sql/cosmos-sql-db.bicep' = {
module cosmosDb 'br/public:avm/res/document-db/database-account:0.9.0' = {
name: 'cosmosDb'
scope: resourceGroup
params: {
accountName: !empty(cosmosDbServiceName) ? cosmosDbServiceName : '${abbrs.documentDBDatabaseAccounts}${resourceToken}'
location: location
name: !empty(cosmosDbServiceName) ? cosmosDbServiceName : '${abbrs.documentDBDatabaseAccounts}${resourceToken}'
tags: tags
containers: [
locations: [
{
name: 'vectorSearchContainer'
id: 'vectorSearchContainer'
partitionKey: '/id'
locationName: location
failoverPriority: 0
isZoneRedundant: false
}
]
databaseName: 'vectorSearchDB'
disableLocalAuth: true
managedIdentities: {
systemAssigned: true
}
capabilitiesToAdd: [
'EnableServerless'
'EnableNoSQLVectorSearch'
]
networkRestrictions: {
ipRules: []
virtualNetworkRules: []
publicNetworkAccess: 'Enabled'
}
sqlDatabases: [
{
containers: [
{
name: 'vectorSearchContainer'
paths: [
'/id'
]
}
]
name: 'vectorSearchDB'
}
{
containers: [
{
name: 'chatHistoryContainer'
paths: [
'/userId'
]
}
]
name: 'chatHistoryDB'
}
]
}
}

module dbRoleDefinition './core/database/cosmos/sql/cosmos-sql-role-def.bicep' = {
scope: resourceGroup
name: 'db-contrib-role-definition'
params: {
accountName: cosmosDb.outputs.name
}
}

Expand Down Expand Up @@ -287,10 +328,10 @@ module dbContribRoleUser './core/database/cosmos/sql/cosmos-sql-role-assign.bice
scope: resourceGroup
name: 'db-contrib-role-user'
params: {
accountName: cosmosDb.outputs.accountName
accountName: cosmosDb.outputs.name
principalId: principalId
// Cosmos DB Data Contributor
roleDefinitionId: cosmosDb.outputs.roleDefinitionId
roleDefinitionId: dbRoleDefinition.outputs.id
}
}

Expand Down Expand Up @@ -321,10 +362,10 @@ module dbContribRoleApi './core/database/cosmos/sql/cosmos-sql-role-assign.bicep
scope: resourceGroup
name: 'db-contrib-role-api'
params: {
accountName: cosmosDb.outputs.accountName
accountName: cosmosDb.outputs.name
principalId: api.outputs.identityPrincipalId
// Cosmos DB Data Contributor
roleDefinitionId: cosmosDb.outputs.roleDefinitionId
roleDefinitionId: dbRoleDefinition.outputs.id
}
}

Expand Down
4 changes: 2 additions & 2 deletions infra/main.parameters.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
"value": "${AZURE_OPENAI_API_VERSION=2024-02-01}"
},
"chatModelName": {
"value": "${AZURE_OPENAI_API_MODEL=gpt-4}"
"value": "${AZURE_OPENAI_API_MODEL=gpt-4o-mini}"
},
"chatModelVersion": {
"value": "${AZURE_OPENAI_API_MODEL_VERSION=turbo-2024-04-09}"
"value": "${AZURE_OPENAI_API_MODEL_VERSION=2024-07-18}"
},
"embeddingsModelName": {
"value": "${AZURE_OPENAI_API_EMBEDDINGS_MODEL=text-embedding-ada-002}"
Expand Down
Loading

0 comments on commit ecf53a3

Please sign in to comment.