Skip to content

Commit 87180f1

Browse files
Onboarding General and API Spec Review channels (#12801)
1 parent 44f3c6f commit 87180f1

File tree

41 files changed

+1684
-259
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1684
-259
lines changed

tools/sdk-ai-bots/azure-sdk-qa-bot-backend/CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# Release History
22

3+
## 0.7.0 (unreleased)
4+
5+
### Features Added
6+
7+
* Add new tenants General, API Review, JS, Java and .Net
8+
* Add new knowledge sources from JS, Java and .Net
9+
* Support routing tenant based on question domain
10+
11+
## Other changes
12+
13+
* Refine prompt for onboarding channel to improve answer accuracy
14+
* Refactor post process of merging and sorting and complete chunk logic, to give more better context to LLM
15+
316
## 0.6.0 (2025-12-16)
417

518
### Features Added

tools/sdk-ai-bots/azure-sdk-qa-bot-backend/config/env.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,21 @@ const (
2323
)
2424

2525
type Config struct {
26-
AOAI_CHAT_REASONING_MODEL string
27-
AOAI_CHAT_COMPLETIONS_MODEL string
28-
AOAI_CHAT_COMPLETIONS_TOP_P float32
29-
AOAI_CHAT_MAX_TOKENS int
30-
AOAI_CHAT_CONTEXT_MAX_TOKENS int
31-
AOAI_CHAT_COMPLETIONS_ENDPOINT string
26+
AOAI_CHAT_REASONING_MODEL string
27+
AOAI_CHAT_REASONING_MODEL_TEMPERATURE float32
28+
AOAI_CHAT_COMPLETIONS_MODEL string
29+
AOAI_CHAT_COMPLETIONS_TEMPERATURE float32
30+
AOAI_CHAT_MAX_TOKENS int
31+
AOAI_CHAT_CONTEXT_MAX_TOKENS int
32+
AOAI_CHAT_COMPLETIONS_ENDPOINT string
3233

3334
AI_SEARCH_BASE_URL string
3435
AI_SEARCH_INDEX string
3536
AI_SEARCH_AGENT string
3637
AI_SEARCH_KNOWLEDGE_BASE string
3738
AI_SEARCH_KNOWLEDGE_SOURCE string
3839
AI_SEARCH_KNOWLEDGE_BASE_API string
40+
AI_SEARCH_TOPK int
3941

4042
STORAGE_BASE_URL string
4143
STORAGE_KNOWLEDGE_CONTAINER string

tools/sdk-ai-bots/azure-sdk-qa-bot-backend/config/tenant.go

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ type TenantConfig struct {
99
AgenticSearchPrompt string
1010
IntentionPromptTemplate string
1111
KeywordReplaceMap map[string]string
12+
EnableRouting bool
1213
}
1314

1415
var typespecSources = []model.Source{
@@ -41,18 +42,48 @@ var tenantConfigMap = map[model.TenantID]TenantConfig{
4142
IntentionPromptTemplate: "language_python/intention.md",
4243
AgenticSearchPrompt: "language_python/agentic_search.md",
4344
},
45+
model.TenantID_DotnetChannelQaBot: {
46+
Sources: append([]model.Source{model.Source_AzureSDKForNetDocs, model.Source_AzureSDKGuidelines, model.Source_AzureSDKDocsEng}, typespecSources...),
47+
SourceFilter: map[model.Source]string{
48+
model.Source_AzureSDKGuidelines: "search.ismatch('dotnet_*', 'title')",
49+
},
50+
PromptTemplate: "language_channel/qa.md",
51+
IntentionPromptTemplate: "language_channel/intention.md",
52+
AgenticSearchPrompt: "language_channel/agentic_search.md",
53+
},
4454
model.TenantID_GolangChannelQaBot: {
45-
Sources: append([]model.Source{model.Source_AzureSDKForGo, model.Source_AzureSDKGuidelines}, typespecSources...),
55+
Sources: append([]model.Source{model.Source_AzureSDKForGo, model.Source_AzureSDKGuidelines, model.Source_AzureSDKDocsEng}, typespecSources...),
4656
SourceFilter: map[model.Source]string{
4757
model.Source_AzureSDKGuidelines: "search.ismatch('golang_*', 'title')",
4858
},
49-
PromptTemplate: "common/language_channel.md",
50-
IntentionPromptTemplate: "prompt_template/intention.md",
51-
AgenticSearchPrompt: "common/agentic_search.md",
59+
PromptTemplate: "language_channel/qa.md",
60+
IntentionPromptTemplate: "language_channel/intention.md",
61+
AgenticSearchPrompt: "language_channel/agentic_search.md",
62+
},
63+
model.TenantID_JavaChannelQaBot: {
64+
Sources: append([]model.Source{model.Source_AzureSDKForJava, model.Source_AzureSDKForJavaWiki, model.Source_AzureSDKGuidelines, model.Source_AutorestJava, model.Source_AzureSDKDocsEng}, typespecSources...),
65+
SourceFilter: map[model.Source]string{
66+
model.Source_AzureSDKGuidelines: "search.ismatch('java_*', 'title')",
67+
},
68+
PromptTemplate: "language_channel/qa.md",
69+
IntentionPromptTemplate: "language_channel/intention.md",
70+
AgenticSearchPrompt: "language_channel/agentic_search.md",
71+
},
72+
model.TenantID_JavaScriptChannelQaBot: {
73+
Sources: append([]model.Source{model.Source_AzureSDKForJavaScript, model.Source_AzureSDKForJavaScriptWiki, model.Source_AzureSDKGuidelines, model.Source_AzureSDKDocsEng}, typespecSources...),
74+
SourceFilter: map[model.Source]string{
75+
model.Source_AzureSDKGuidelines: "search.ismatch('typescript_*', 'title')",
76+
},
77+
PromptTemplate: "language_channel/qa.md",
78+
IntentionPromptTemplate: "language_channel/intention.md",
79+
AgenticSearchPrompt: "language_channel/agentic_search.md",
5280
},
5381
model.TenantID_AzureSDKQaBot: {
54-
PromptTemplate: "typespec/qa.md",
55-
Sources: typespecSources,
82+
PromptTemplate: "typespec/qa.md",
83+
Sources: append(typespecSources, model.Source_AzureSDKDocsEng),
84+
SourceFilter: map[model.Source]string{
85+
model.Source_AzureSDKDocsEng: "search.ismatch('design*', 'title')",
86+
},
5687
IntentionPromptTemplate: "typespec/intention.md",
5788
AgenticSearchPrompt: "typespec/agentic_search.md",
5889
},
@@ -62,6 +93,22 @@ var tenantConfigMap = map[model.TenantID]TenantConfig{
6293
AgenticSearchPrompt: "azure_sdk_onboarding/agentic_search.md",
6394
IntentionPromptTemplate: "azure_sdk_onboarding/intention.md",
6495
},
96+
model.TenantID_GeneralQaBot: {
97+
PromptTemplate: "general/qa.md",
98+
IntentionPromptTemplate: "general/intention.md",
99+
AgenticSearchPrompt: "general/agentic_search.md",
100+
EnableRouting: true,
101+
},
102+
model.TenantID_APISpecReviewBot: {
103+
PromptTemplate: "api_spec_review/qa.md",
104+
Sources: []model.Source{model.Source_StaticAzureDocs, model.Source_AzureRestAPISpec, model.Source_AzureSDKDocsEng},
105+
SourceFilter: map[model.Source]string{
106+
model.Source_AzureSDKDocsEng: "search.ismatch('design*', 'title')",
107+
},
108+
IntentionPromptTemplate: "api_spec_review/intention.md",
109+
AgenticSearchPrompt: "api_spec_review/agentic_search.md",
110+
EnableRouting: true,
111+
},
65112
}
66113

67114
func GetTenantConfig(tenantID model.TenantID) (TenantConfig, bool) {

tools/sdk-ai-bots/azure-sdk-qa-bot-backend/model/completion.go

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,16 @@ package model
33
type TenantID string
44

55
const (
6-
TenantID_AzureSDKQaBot TenantID = "azure_sdk_qa_bot" // default as TypeSpec QA bot
7-
TenantID_TypeSpecExtension TenantID = "typespec_extension"
8-
TenantID_PythonChannelQaBot TenantID = "python_channel_qa_bot"
9-
TenantID_AzureSDKOnboarding TenantID = "azure_sdk_onboarding"
10-
TenantID_GolangChannelQaBot TenantID = "golang_channel_qa_bot"
6+
TenantID_AzureSDKQaBot TenantID = "azure_sdk_qa_bot" // default as TypeSpec QA bot
7+
TenantID_TypeSpecExtension TenantID = "typespec_extension"
8+
TenantID_PythonChannelQaBot TenantID = "python_channel_qa_bot"
9+
TenantID_DotnetChannelQaBot TenantID = "dotnet_channel_qa_bot"
10+
TenantID_AzureSDKOnboarding TenantID = "azure_sdk_onboarding"
11+
TenantID_GolangChannelQaBot TenantID = "golang_channel_qa_bot"
12+
TenantID_JavaChannelQaBot TenantID = "java_channel_qa_bot"
13+
TenantID_JavaScriptChannelQaBot TenantID = "javascript_channel_qa_bot"
14+
TenantID_GeneralQaBot TenantID = "general_qa_bot"
15+
TenantID_APISpecReviewBot TenantID = "api_spec_review_bot"
1116
)
1217

1318
type Source string
@@ -29,6 +34,12 @@ const (
2934
Source_AzureSDKForGo Source = "azure_sdk_for_go_docs"
3035
Source_StaticAzureDocs Source = "static_azure_docs"
3136
Source_StaticTypeSpecToSwaggerMapping Source = "static_typespec_to_swagger_mapping"
37+
Source_AzureSDKForJava Source = "azure_sdk_for_java_docs"
38+
Source_AzureSDKForJavaWiki Source = "azure_sdk_for_java_wiki"
39+
Source_AutorestJava Source = "autorest_java_docs"
40+
Source_AzureSDKForJavaScript Source = "azure_sdk_for_js_docs"
41+
Source_AzureSDKForJavaScriptWiki Source = "azure_sdk_for_js_wiki"
42+
Source_AzureSDKForNetDocs Source = "azure_sdk_for_net_docs"
3243
)
3344

3445
type Role string
@@ -85,6 +96,7 @@ type CompletionResp struct {
8596
FullContext *string `json:"full_context" jsonschema:"omitempty,description=The full context used to generate the answer"`
8697
Intention *IntentionResult `json:"intention" jsonschema:"omitempty,description=The intention of the question"`
8798
ReasoningProgress *string `json:"reasoning_progress,omitempty" jsonschema:"omitempty,description=The reasoning progress of generating the answer"`
99+
RouteTenant *TenantID `json:"route_tenant,omitempty" jsonschema:"omitempty,description=The tenant ID the question is routed to"`
88100
}
89101

90102
type QuestionScope string
@@ -102,3 +114,7 @@ type IntentionResult struct {
102114
Scope QuestionScope `json:"scope,omitempty" jsonschema:"omitempty,description=The scope of the question"`
103115
NeedsRagProcessing bool `json:"needs_rag_processing" jsonschema:"required,description=Whether to invoke RAG workflow"`
104116
}
117+
118+
type TenantRoutingResult struct {
119+
RouteTenant TenantID `json:"route_tenant" jsonschema:"required,description=The tenant ID to route the question to"`
120+
}

tools/sdk-ai-bots/azure-sdk-qa-bot-backend/model/search.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,32 @@ import (
44
"strings"
55
)
66

7+
// ExpansionType defines how a chunk should be expanded
8+
type ExpansionType int
9+
10+
const (
11+
ExpansionNone ExpansionType = iota // No expansion needed - use chunk as-is
12+
ExpansionHierarchical // Expand based on header hierarchy
13+
ExpansionQA // Expand based on Q&A pairs
14+
ExpansionMapping // Expand based on TypeSpec to Swagger mapping
15+
)
16+
17+
// ChunkWithExpansion wraps a chunk with its expansion strategy
18+
type ChunkWithExpansion struct {
19+
Chunk Index
20+
Expansion ExpansionType
21+
}
22+
23+
// ChunkHierarchy represents the header level of a chunk
24+
type ChunkHierarchy int
25+
26+
const (
27+
HierarchyHeader3 ChunkHierarchy = iota // Full chunk with header3 (most specific)
28+
HierarchyHeader2 // Chunk with header1 and header2
29+
HierarchyHeader1 // Chunk with only header1
30+
HierarchyUnknown // Unknown or no headers
31+
)
32+
733
type AgenticSearchRequest struct {
834
Messages []KnowledgeAgentMessage `json:"messages"`
935
KnowledgeSourceParams []KnowledgeSourceParams `json:"knowledgeSourceParams,omitempty"`
@@ -247,11 +273,25 @@ func GetIndexLink(chunk Index) string {
247273
return "https://azure.github.io/typespec-azure/docs/migrate-swagger/faq/breakingchange"
248274
case Source_AzureSDKForGo:
249275
return "https://github.com/Azure/azure-sdk-for-go/blob/main/documentation/" + path
276+
case Source_AzureSDKForJava:
277+
return "https://github.com/Azure/azure-sdk-for-java/blob/main/" + path
278+
case Source_AzureSDKForJavaWiki:
279+
path = TrimFileFormat(path)
280+
return "https://github.com/Azure/azure-sdk-for-java/wiki/" + path
281+
case Source_AutorestJava:
282+
return "https://github.com/Azure/autorest.java/blob/main/" + path
250283
case Source_StaticAzureDocs:
251284
if chunk.Title == "Azure Versioning and Breaking Changes Policy V1.3.2" {
252285
return "http://aka.ms/azbreakingchangespolicy"
253286
}
254287
return ""
288+
case Source_AzureSDKForJavaScript:
289+
return "https://github.com/Azure/azure-sdk-for-js/blob/main/" + path
290+
case Source_AzureSDKForJavaScriptWiki:
291+
path = TrimFileFormat(path)
292+
return "https://github.com/Azure/azure-sdk-for-js/wiki/" + path
293+
case Source_AzureSDKForNetDocs:
294+
return "https://github.com/Azure/azure-sdk-for-net/blob/main/" + path
255295
default:
256296
return ""
257297
}

0 commit comments

Comments
 (0)