Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions infra/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -1676,6 +1676,7 @@ module searchService 'br/public:avm/res/search/search-service:0.11.1' = {
managedIdentities: {
systemAssigned: true
}
semanticSearch: 'standard'

// Enabled the Public access because other services are not able to connect with search search AVM module when public access is disabled

Expand Down
33 changes: 29 additions & 4 deletions infra/scripts/index_datasets.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
from azure.identity import AzureCliCredential
from azure.search.documents import SearchClient
from azure.search.documents.indexes import SearchIndexClient
from azure.search.documents.indexes.models import SearchIndex, SimpleField, SearchableField, SearchFieldDataType
from azure.search.documents.indexes.models import (
SearchIndex,
SimpleField,
SearchableField,
SearchFieldDataType,
SemanticConfiguration,
SemanticField,
SemanticPrioritizedFields,
SemanticSearch
)
from azure.storage.blob import BlobServiceClient
import sys

Expand Down Expand Up @@ -114,12 +123,28 @@ def extract_docx_text(docx_bytes):
SearchableField(name="content", type=SearchFieldDataType.String, searchable=True),
SearchableField(name="title", type=SearchFieldDataType.String, searchable=True, filterable=True)
]
index = SearchIndex(name=ai_search_index_name, fields=index_fields)

# Configure semantic search for better natural language understanding
semantic_config = SemanticConfiguration(
name="default",
prioritized_fields=SemanticPrioritizedFields(
title_field=SemanticField(field_name="title"),
content_fields=[SemanticField(field_name="content")]
)
)

semantic_search = SemanticSearch(configurations=[semantic_config])

index = SearchIndex(
name=ai_search_index_name,
fields=index_fields,
semantic_search=semantic_search
)

print("Creating or updating Azure Search index...")
print("Creating or updating Azure Search index with semantic configuration...")
search_index_client = SearchIndexClient(endpoint=ai_search_endpoint, credential=credential)
search_index_client.create_or_update_index(index=index)
print(f"Index '{ai_search_index_name}' created or updated successfully.")
print(f"Index '{ai_search_index_name}' created or updated successfully with semantic search enabled.")
except Exception as e:
print(f"Error creating/updating index: {e}")
sys.exit(1)
Expand Down
96 changes: 95 additions & 1 deletion src/backend/v4/magentic_agents/foundry_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ async def _create_azure_search_enabled_client(self, chatClient=None) -> Optional

desired_connection_name = getattr(self.search, "connection_name", None)
index_name = getattr(self.search, "index_name", "")
query_type = getattr(self.search, "search_query_type", "simple")
# Use semantic search for better natural language understanding and document retrieval
query_type = getattr(self.search, "search_query_type", "semantic")

if not index_name:
self.logger.error(
Expand Down Expand Up @@ -175,6 +176,98 @@ async def _create_azure_search_enabled_client(self, chatClient=None) -> Optional
self.logger.error("Failed to enumerate connections: %s", ex)
return None

# Build search query guidance based on scenario (Contract vs RFP) and agent type (summary/risk/compliance)
index_name_lower = index_name.lower()

# Detect scenario and agent type from index name
is_contract = "contract" in index_name_lower
is_rfp = "rfp" in index_name_lower
is_summary = "summary" in index_name_lower
is_risk = "risk" in index_name_lower
is_compliance = "compliance" in index_name_lower

if is_contract and is_summary:
# Contract Summary Agent
search_query_guidance = """

IMPORTANT - Azure AI Search Query Guidelines:
When searching for documents, ALWAYS use multiple comma-separated search terms to maximize retrieval success.

Example of a GOOD search query:
- Instead of: "NDA summary"
Use: "Contoso NDA, non-disclosure agreement, NDA summary, Contoso agreement, confidentiality obligations, term, governing law, parties involved, effective date, notable clauses, NDA key points, Contoso contract summary, NDA restrictions, NDA termination, NDA obligations"

ALWAYS search with at least 6-8 related terms. Include company names (Contoso), document types (NDA, contract, agreement), and topic variations.
"""
elif is_contract and is_risk:
# Contract Risk Agent
search_query_guidance = """

IMPORTANT - Azure AI Search Query Guidelines:
When searching for documents, ALWAYS use multiple comma-separated search terms to maximize retrieval success.

Example of a GOOD search query:
- Instead of: "NDA risks"
Use: "Contoso NDA risk assessment, Contoso NDA risks, NDA clauses, NDA liability, NDA confidentiality, NDA jurisdiction, NDA termination, NDA data handling, NDA dispute resolution, NDA definitions, risk analysis, legal risks, compliance risks, Contoso contract risks"

ALWAYS search with at least 6-8 related terms. Include company names (Contoso), document types (NDA, contract), and risk-related terms.
"""
elif is_contract and is_compliance:
# Contract Compliance Agent
search_query_guidance = """

IMPORTANT - Azure AI Search Query Guidelines:
When searching for documents, ALWAYS use multiple comma-separated search terms to maximize retrieval success.

Example of a GOOD search query:
- Instead of: "NDA compliance"
Use: "Contoso NDA, NDA compliance, NDA policy, NDA audit, NDA gaps, NDA violations, NDA corrective actions, NDA internal policy, NDA legal requirements, NDA clauses, Confidentiality clause, Termination clause, Governing Law clause, Non-Assignment clause, Entire Agreement clause, NDA liability protections, NDA dispute resolution, NDA data protection obligations"

ALWAYS search with at least 6-8 related terms. Include company names (Contoso), document types (NDA, contract), and compliance-related terms.
"""
elif is_rfp and is_summary:
# RFP Summary Agent
search_query_guidance = """

IMPORTANT - Azure AI Search Query Guidelines:
When searching for documents, ALWAYS use multiple comma-separated search terms to maximize retrieval success.

Example of a GOOD search query:
- Instead of: "RFP summary"
Use: "Woodgrove Bank RFP, Contoso response, objectives, technical solution, pricing, timeline, compliance, regulatory requirements, proposal summary, contract terms, deliverables, evaluation criteria, RFP overview, RFP document, proposal details"

ALWAYS search with at least 6-8 related terms. Include company names (Woodgrove Bank, Contoso), document types (RFP, proposal, response), and topic variations.
"""
elif is_rfp and is_risk:
# RFP Risk Agent
search_query_guidance = """

IMPORTANT - Azure AI Search Query Guidelines:
When searching for documents, ALWAYS use multiple comma-separated search terms to maximize retrieval success.

Example of a GOOD search query:
- Instead of: "RFP risks"
Use: "Woodgrove Bank RFP response, Contoso RFP response, RFP risks, proposal risks, risk assessment, risk analysis, RFP risk evaluation, proposal concerns, financial risks, technical risks, compliance risks, delivery risks, contract risks, liability risks"

ALWAYS search with at least 6-8 related terms. Include company names (Woodgrove Bank, Contoso), document types (RFP, proposal), and risk-related terms.
"""
elif is_rfp and is_compliance:
# RFP Compliance Agent
search_query_guidance = """

IMPORTANT - Azure AI Search Query Guidelines:
When searching for documents, ALWAYS use multiple comma-separated search terms to maximize retrieval success.

Example of a GOOD search query:
- Instead of: "RFP compliance"
Use: "Woodgrove Bank RFP response, Contoso RFP response, banking regulations compliance, internal policy alignment, contract best practices, compliance gaps analysis, Woodgrove Bank proposal, Contoso proposal compliance, regulatory adherence banking RFP"

ALWAYS search with at least 6-8 related terms. Include company names (Woodgrove Bank, Contoso), document types (RFP, proposal), and compliance-related terms.
"""
else:
# No specific guidance for other scenarios
search_query_guidance = ""

# Create agent with raw tool
try:
azure_agent = await self.client.create_agent(
Expand All @@ -183,6 +276,7 @@ async def _create_azure_search_enabled_client(self, chatClient=None) -> Optional
instructions=(
f"{self.agent_instructions} "
"Always use the Azure AI Search tool and configured index for knowledge retrieval."
f"{search_query_guidance}"
),
tools=[{"type": "azure_ai_search"}],
tool_resources={
Expand Down
Loading