Skip to content

Commit 0ac80d7

Browse files
committed
[DERCBOT-919] Add condenseQuestion LLM and Prompt
1 parent 75f7c08 commit 0ac80d7

File tree

39 files changed

+257
-154
lines changed

39 files changed

+257
-154
lines changed

bot/admin/server/src/main/kotlin/BotAdminService.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1156,7 +1156,9 @@ object BotAdminService {
11561156
// delete the RAG configuration
11571157
ragConfigurationDAO.findByNamespaceAndBotId(app.namespace, app.name)?.let { config ->
11581158
ragConfigurationDAO.delete(config._id)
1159-
config.llmSetting.apiKey?.let { SecurityUtils.deleteSecret(it) }
1159+
config.questionCondensingLlmSetting?.apiKey?.let { SecurityUtils.deleteSecret(it) }
1160+
config.questionAnsweringLlmSetting?.apiKey?.let { SecurityUtils.deleteSecret(it) }
1161+
config.llmSetting?.apiKey?.let { SecurityUtils.deleteSecret(it) }
11601162
config.emSetting.apiKey?.let { SecurityUtils.deleteSecret(it) }
11611163
}
11621164

bot/admin/server/src/main/kotlin/model/BotRAGConfigurationDTO.kt

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package ai.tock.bot.admin.model
1818

1919
import ai.tock.bot.admin.bot.rag.BotRAGConfiguration
2020
import ai.tock.bot.admin.service.VectorStoreService
21+
import ai.tock.genai.orchestratorclient.requests.PromptTemplate
2122
import ai.tock.genai.orchestratorcore.mappers.EMSettingMapper
2223
import ai.tock.genai.orchestratorcore.mappers.LLMSettingMapper
2324
import ai.tock.genai.orchestratorcore.models.Constants
@@ -34,26 +35,39 @@ data class BotRAGConfigurationDTO(
3435
val namespace: String,
3536
val botId: String,
3637
val enabled: Boolean = false,
37-
val llmSetting: LLMSettingDTO,
38+
val questionCondensingLlmSetting: LLMSettingDTO? = null,
39+
val questionCondensingPrompt: PromptTemplate? = null,
40+
val questionAnsweringLlmSetting: LLMSettingDTO,
41+
val questionAnsweringPrompt: PromptTemplate,
3842
val emSetting: EMSettingDTO,
3943
val indexSessionId: String? = null,
4044
val indexName: String? = null,
4145
val noAnswerSentence: String,
4246
val noAnswerStoryId: String? = null,
4347
val documentsRequired: Boolean = true,
48+
val debugEnabled: Boolean,
49+
val maxDocumentsRetrieved: Int,
50+
val maxMessagesFromHistory: Int,
4451
) {
4552
constructor(configuration: BotRAGConfiguration) : this(
4653
id = configuration._id.toString(),
4754
namespace = configuration.namespace,
4855
botId = configuration.botId,
4956
enabled = configuration.enabled,
50-
llmSetting = configuration.llmSetting.toDTO(),
57+
questionCondensingLlmSetting = configuration.questionCondensingLlmSetting?.toDTO(),
58+
questionCondensingPrompt = configuration.questionCondensingPrompt,
59+
questionAnsweringLlmSetting = configuration.getQuestionAnsweringLLMSetting().toDTO(),
60+
questionAnsweringPrompt = configuration.questionAnsweringPrompt
61+
?: configuration.initQuestionAnsweringPrompt(),
5162
emSetting = configuration.emSetting.toDTO(),
5263
indexSessionId = configuration.indexSessionId,
5364
indexName = configuration.generateIndexName(),
5465
noAnswerSentence = configuration.noAnswerSentence,
5566
noAnswerStoryId = configuration.noAnswerStoryId,
5667
documentsRequired = configuration.documentsRequired,
68+
debugEnabled = configuration.debugEnabled,
69+
maxDocumentsRetrieved = configuration.maxDocumentsRetrieved,
70+
maxMessagesFromHistory = configuration.maxMessagesFromHistory,
5771
)
5872

5973
fun toBotRAGConfiguration(): BotRAGConfiguration =
@@ -62,12 +76,20 @@ data class BotRAGConfigurationDTO(
6276
namespace = namespace,
6377
botId = botId,
6478
enabled = enabled,
65-
llmSetting = LLMSettingMapper.toEntity(
79+
questionCondensingLlmSetting = LLMSettingMapper.toEntity(
80+
namespace = namespace,
81+
botId = botId,
82+
feature = Constants.GEN_AI_RAG_QUESTION_CONDENSING,
83+
dto = questionCondensingLlmSetting!!
84+
),
85+
questionCondensingPrompt = questionCondensingPrompt,
86+
questionAnsweringLlmSetting = LLMSettingMapper.toEntity(
6687
namespace = namespace,
6788
botId = botId,
6889
feature = Constants.GEN_AI_RAG_QUESTION_ANSWERING,
69-
dto = llmSetting
90+
dto = questionAnsweringLlmSetting
7091
),
92+
questionAnsweringPrompt = questionAnsweringPrompt,
7193
emSetting = EMSettingMapper.toEntity(
7294
namespace = namespace,
7395
botId = botId,
@@ -78,6 +100,9 @@ data class BotRAGConfigurationDTO(
78100
noAnswerSentence = noAnswerSentence,
79101
noAnswerStoryId = noAnswerStoryId,
80102
documentsRequired = documentsRequired,
103+
debugEnabled = debugEnabled,
104+
maxDocumentsRetrieved = maxDocumentsRetrieved,
105+
maxMessagesFromHistory = maxMessagesFromHistory,
81106
)
82107
}
83108

@@ -87,6 +112,7 @@ private fun BotRAGConfiguration.generateIndexName(): String? {
87112
namespace,
88113
botId,
89114
it,
115+
maxDocumentsRetrieved,
90116
VectorStoreService.getVectorStoreConfiguration(namespace, botId, enabled = true)
91117
?.setting
92118
).second

bot/admin/server/src/main/kotlin/model/BotSentenceGenerationConfigurationDTO.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package ai.tock.bot.admin.model
1818

1919
import ai.tock.bot.admin.bot.sentencegeneration.BotSentenceGenerationConfiguration
20+
import ai.tock.genai.orchestratorclient.requests.PromptTemplate
2021
import ai.tock.genai.orchestratorcore.mappers.LLMSettingMapper
2122
import ai.tock.genai.orchestratorcore.models.Constants
2223
import ai.tock.genai.orchestratorcore.models.llm.LLMSettingDTO
@@ -32,6 +33,7 @@ data class BotSentenceGenerationConfigurationDTO(
3233
val enabled: Boolean = false,
3334
val nbSentences: Int,
3435
val llmSetting: LLMSettingDTO,
36+
val prompt: PromptTemplate,
3537
) {
3638
constructor(configuration: BotSentenceGenerationConfiguration) : this(
3739
id = configuration._id.toString(),
@@ -40,6 +42,7 @@ data class BotSentenceGenerationConfigurationDTO(
4042
enabled = configuration.enabled,
4143
nbSentences = configuration.nbSentences,
4244
llmSetting = configuration.llmSetting.toDTO(),
45+
prompt = configuration.prompt ?: configuration.initPrompt()
4346
)
4447

4548
fun toSentenceGenerationConfiguration(): BotSentenceGenerationConfiguration =
@@ -54,7 +57,8 @@ data class BotSentenceGenerationConfigurationDTO(
5457
botId = botId,
5558
feature = Constants.GEN_AI_COMPLETION_SENTENCE_GENERATION,
5659
dto = llmSetting
57-
)
60+
),
61+
prompt = prompt
5862
)
5963
}
6064

bot/admin/server/src/main/kotlin/model/GenerateSentencesRequest.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616

1717
package ai.tock.bot.admin.model
1818

19+
import ai.tock.genai.orchestratorclient.requests.PromptTemplate
1920
import java.util.Locale
2021

2122
data class SentenceGenerationRequest(
23+
val prompt: PromptTemplate,
2224
val llmTemperature: String,
2325
val sentences: List<String>,
2426
val locale: Locale,

bot/admin/server/src/main/kotlin/service/CompletionService.kt

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,18 +75,11 @@ object CompletionService {
7575
)
7676
)
7777

78-
// Create a Jinja2 prompt template
79-
val prompt = PromptTemplate(
80-
formatter = Formatter.JINJA2.id,
81-
template = llmSetting.prompt,
82-
inputs = inputs
83-
)
84-
8578
// call the completion service to generate sentences
8679
return completionService
8780
.generateSentences(
8881
SentenceGenerationQuery(
89-
llmSetting, prompt,
82+
llmSetting, request.prompt.copy(inputs = inputs),
9083
ObservabilityService.getObservabilityConfiguration(namespace, botId, enabled = true)?.setting
9184
)
9285
)

bot/admin/server/src/main/kotlin/service/RAGService.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,11 @@ object RAGService {
6464
logger.info { "Deleting the RAG Configuration [namespace: $namespace, botId: $botId]" }
6565
ragConfigurationDAO.delete(ragConfig._id)
6666

67-
logger.info { "Deleting the LLM secret ..." }
68-
ragConfig.llmSetting.apiKey?.let { SecurityUtils.deleteSecret(it) }
67+
logger.info { "Deleting the question condensing LLM secret ..." }
68+
ragConfig.questionCondensingLlmSetting?.apiKey?.let { SecurityUtils.deleteSecret(it) }
69+
logger.info { "Deleting the question answering LLM secret ..." }
70+
ragConfig.questionAnsweringLlmSetting?.apiKey?.let { SecurityUtils.deleteSecret(it) }
71+
ragConfig.llmSetting?.apiKey?.let { SecurityUtils.deleteSecret(it) }
6972
logger.info { "Deleting the Embedding secret ..." }
7073
ragConfig.emSetting.apiKey?.let { SecurityUtils.deleteSecret(it) }
7174
}

bot/admin/server/src/main/kotlin/service/RAGValidationService.kt

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,24 @@ object RAGValidationService {
3737
private val vectorStoreProviderService: VectorStoreProviderService get() = injector.provide()
3838

3939
fun validate(ragConfig: BotRAGConfiguration): Set<ErrorMessage> {
40+
val observabilitySetting = ObservabilityService.getObservabilityConfiguration(
41+
ragConfig.namespace, ragConfig.botId, enabled = true
42+
)?.setting
43+
4044
return mutableSetOf<ErrorMessage>().apply {
41-
val llmErrors = llmProviderService.checkSetting(
45+
val questionCondensingLlmErrors = llmProviderService.checkSetting(
46+
LLMProviderSettingStatusQuery(
47+
ragConfig.questionCondensingLlmSetting!!,
48+
observabilitySetting
49+
)
50+
).getErrors("LLM setting check failed (for question condensing)")
51+
52+
val questionAnsweringLlmErrors = llmProviderService.checkSetting(
4253
LLMProviderSettingStatusQuery(
43-
ragConfig.llmSetting,
44-
ObservabilityService.getObservabilityConfiguration(
45-
ragConfig.namespace, ragConfig.botId, enabled = true
46-
)?.setting
54+
ragConfig.questionAnsweringLlmSetting!!,
55+
observabilitySetting
4756
)
48-
).getErrors("LLM setting check failed")
57+
).getErrors("LLM setting check failed (for question answering)")
4958

5059
val embeddingErrors = emProviderService.checkSetting(
5160
EMProviderSettingStatusQuery(ragConfig.emSetting)
@@ -59,7 +68,11 @@ object RAGValidationService {
5968
)?.setting
6069

6170
val (_, indexName) = VectorStoreUtils.getVectorStoreElements(
62-
ragConfig.namespace, ragConfig.botId, ragConfig.indexSessionId!!, vectorStoreSetting
71+
ragConfig.namespace,
72+
ragConfig.botId,
73+
ragConfig.indexSessionId!!,
74+
ragConfig.maxDocumentsRetrieved,
75+
vectorStoreSetting
6376
)
6477

6578
vectorStoreProviderService.checkSetting(
@@ -71,7 +84,7 @@ object RAGValidationService {
7184
).getErrors("Vector store setting check failed")
7285
} ?: emptySet()
7386

74-
addAll(llmErrors + embeddingErrors + indexSessionIdErrors + vectorStoreErrors)
87+
addAll(questionCondensingLlmErrors + questionAnsweringLlmErrors + embeddingErrors + indexSessionIdErrors + vectorStoreErrors)
7588
}
7689
}
7790

bot/admin/server/src/test/kotlin/service/RAGServiceTest.kt

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import ai.tock.bot.test.TFunction
3030
import ai.tock.bot.test.TRunnable
3131
import ai.tock.bot.test.TSupplier
3232
import ai.tock.bot.test.TestCase
33+
import ai.tock.genai.orchestratorclient.requests.PromptTemplate
3334
import ai.tock.genai.orchestratorclient.responses.ProviderSettingStatusResponse
3435
import ai.tock.genai.orchestratorclient.services.EMProviderService
3536
import ai.tock.genai.orchestratorclient.services.LLMProviderService
@@ -65,25 +66,36 @@ class RAGServiceTest : AbstractTest() {
6566
const val INDEX_SESSION_ID = "1010101"
6667

6768
private val DEFAULT_RAG_CONFIG = BotRAGConfigurationDTO(
68-
id = "ragId",
69+
id = "ragId",
6970
namespace = NAMESPACE,
7071
botId = BOT_ID,
7172
enabled = false,
72-
llmSetting = OpenAILLMSettingDTO(
73+
questionCondensingLlmSetting = OpenAILLMSettingDTO(
7374
apiKey = "apikey",
7475
model = MODEL,
75-
prompt = PROMPT,
7676
temperature = TEMPERATURE,
7777
baseUrl = "https://api.openai.com/v1"
7878
),
79+
questionCondensingPrompt = PromptTemplate(template = PROMPT),
80+
questionAnsweringLlmSetting = OpenAILLMSettingDTO(
81+
apiKey = "apikey",
82+
model = MODEL,
83+
temperature = TEMPERATURE,
84+
baseUrl = "https://api.openai.com/v1"
85+
),
86+
questionAnsweringPrompt = PromptTemplate(template = PROMPT),
7987
emSetting = AzureOpenAIEMSettingDTO(
8088
apiKey = "apiKey",
8189
apiVersion = "apiVersion",
8290
deploymentName = "deployment",
8391
model = "model",
8492
apiBase = "url"
8593
),
86-
noAnswerSentence = "No answer sentence"
94+
noAnswerSentence = "No answer sentence",
95+
documentsRequired = true,
96+
debugEnabled = false,
97+
maxDocumentsRetrieved = 2,
98+
maxMessagesFromHistory = 2,
8799
)
88100

89101
private val DEFAULT_BOT_CONFIG = aApplication.copy(namespace = NAMESPACE, botId = BOT_ID)
@@ -186,9 +198,9 @@ class RAGServiceTest : AbstractTest() {
186198
Assertions.assertEquals(BOT_ID, captured.botId)
187199
Assertions.assertEquals(true, captured.enabled)
188200
Assertions.assertEquals(NAMESPACE, captured.namespace)
189-
Assertions.assertEquals(PROVIDER, captured.llmSetting.provider.name)
190-
Assertions.assertEquals(TEMPERATURE, captured.llmSetting.temperature)
191-
Assertions.assertEquals(PROMPT, captured.llmSetting.prompt)
201+
Assertions.assertEquals(PROVIDER, captured.questionAnsweringLlmSetting!!.provider.name)
202+
Assertions.assertEquals(TEMPERATURE, captured.questionAnsweringLlmSetting!!.temperature)
203+
Assertions.assertEquals(PROMPT, captured.questionAnsweringPrompt!!.template)
192204
Assertions.assertEquals(null, captured.noAnswerStoryId)
193205
}
194206

bot/admin/server/src/test/kotlin/service/RAGValidationServiceTest.kt

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package ai.tock.bot.admin.service
1919
import ai.tock.bot.admin.bot.observability.BotObservabilityConfigurationDAO
2020
import ai.tock.bot.admin.bot.vectorstore.BotVectorStoreConfigurationDAO
2121
import ai.tock.bot.admin.model.BotRAGConfigurationDTO
22+
import ai.tock.genai.orchestratorclient.requests.PromptTemplate
2223
import ai.tock.genai.orchestratorclient.responses.ErrorInfo
2324
import ai.tock.genai.orchestratorclient.responses.ErrorResponse
2425
import ai.tock.genai.orchestratorclient.responses.ProviderSettingStatusResponse
@@ -63,7 +64,7 @@ class RAGValidationServiceTest {
6364
}
6465

6566
private val openAILLMSetting = OpenAILLMSetting(
66-
apiKey = "123-abc", model = "unavailable-model", temperature = "0.4", prompt = "How to bike in the rain",
67+
apiKey = "123-abc", model = "unavailable-model", temperature = "0.4",
6768
baseUrl = "https://api.openai.com/v1",
6869
)
6970

@@ -78,9 +79,16 @@ class RAGValidationServiceTest {
7879
private val ragConfiguration = BotRAGConfigurationDTO(
7980
namespace = "namespace",
8081
botId = "botId",
81-
llmSetting = openAILLMSetting,
82+
questionCondensingLlmSetting = openAILLMSetting,
83+
questionCondensingPrompt = PromptTemplate(template = "test"),
84+
questionAnsweringLlmSetting = openAILLMSetting,
85+
questionAnsweringPrompt = PromptTemplate(template = "How to bike in the rain"),
8286
emSetting = azureOpenAIEMSetting,
8387
noAnswerSentence = " No answer sentence",
88+
documentsRequired = true,
89+
debugEnabled = false,
90+
maxDocumentsRetrieved = 2,
91+
maxMessagesFromHistory = 2,
8492
)
8593

8694
@Test
@@ -163,7 +171,7 @@ class RAGValidationServiceTest {
163171
fun `validation of the RAG configuration when the Orchestrator returns 2 errors for LLM and 1 for Embedding model, the RAG function has not been activated`() {
164172

165173
// GIVEN
166-
// - 3 errors returned by Generative AI Orchestrator for LLM (2) and EM (1)
174+
// - 3 errors returned by Generative AI Orchestrator for LLM (4 = 2 for condensing + 2 for answering) and EM (1)
167175
// - RAG is not enabled
168176
every {
169177
llmProviderService.checkSetting(any())
@@ -187,11 +195,13 @@ class RAGValidationServiceTest {
187195
)
188196

189197
// THEN :
190-
// Check that 3 errors have been found
191-
assertEquals(2, errors.size)
198+
// Check that 3 groups of errors have been found
199+
assertEquals(3, errors.size)
192200
assertEquals("10", (((errors.elementAt(0).params) as List<*>)[0] as ErrorResponse).code)
193201
assertEquals("20", (((errors.elementAt(0).params) as List<*>)[1] as ErrorResponse).code)
194-
assertEquals("30", (((errors.elementAt(1).params) as List<*>)[0] as ErrorResponse).code)
202+
assertEquals("10", (((errors.elementAt(1).params) as List<*>)[0] as ErrorResponse).code)
203+
assertEquals("20", (((errors.elementAt(1).params) as List<*>)[1] as ErrorResponse).code)
204+
assertEquals("30", (((errors.elementAt(2).params) as List<*>)[0] as ErrorResponse).code)
195205
}
196206

197207
private fun createFakeErrorResponse(code: String) = ErrorResponse(

0 commit comments

Comments
 (0)