Czterowarstwowa architektura dla agenta przekazywania informacji kierownictwu w Azure
Jak agent służący do przygotowywania raportów w sposób deterministyczny dzieli pracę pomiędzy Fabric, procedury przechowywane w SQL, FastAPI w Azure Functions oraz Copilot Studio w celu tworzenia dokumentów dla kierownictwa.
Każdy, kto przygotowuje kadry kierownicze do spotkań z klientami, wie, jak rozproszone są surowe dane. Informacje z CRM znajdują się w jednym systemie, dane o przychodach w innym, a informacje o wykorzystaniu produktów w trzecim; historię strategiczną trzeba ręcznie składać z tych wszystkich źródeł. Narzędzie do przygotowywania informacji dla „szefa sztabu” jest właśnie przeznaczone do rozwiązania tego problemu: osoba prosi w prostym języku o streszczenie, a platforma zwraca dokument gotowy do użycia przez kadrę kierowniczą, stworzony na podstawie fragmentarycznych danych operacyjnych, finansowych oraz dotyczących wdrażania sztucznej inteligencji.
To, co sprawia, że ten projekt warto badać, to to, jak mało polega na przypadku. Zamiast prosić model o napisanie informacji wstępnych na podstawie instrukcji, zastępuje to ręczne agregowanie orkiestracją regulowaną umowami. Dane są konsolidowane w ramach określonych zasad, agregowane za pomocą deterministycznego SQL, przekazywane przez usługi bez stanu i dostarczane poprzez kontrolowany przepływ konwersacyjny. Architektura wyznacza ścisłe granice wykonania pomiędzy czterema warstwami: podstawową, danych, usług i doświadczenia, dzięki czemu wyniki można odtworzyć, sprawdzić i dostarczyć z prędkością typową dla przedsiębiorstw w ramach ścisłych ograniczeń bezpieczeństwa.
Ten projekt powstał w ramach wewnętrznego programu inkubacji sztucznej inteligencji w ekosystemie Microsoft, a podane poniżej informacje na temat wydajności i efektywności pochodzą od samych twórców, a nie zostały sprawdzone niezależnie. Jest szczególnie przydatny dla architektów przedsiębiorstw, inżynierów sztucznej inteligencji oraz kierowników platform, którzy potrzebują deterministycznych systemów AI umożliwiających konsolidację danych, agregację w SQL, orkiestrację bez stanu oraz prace w formie konwersacji.
Czterowarstwowy projekt
Agent opiera się na modelu orkiestracji czterowarstwowej, przy którym każda warstwa pełni określoną funkcję i obejmuje kilka usług Azure oraz granic bezpieczeństwa:
- Fundament: Microsoft Fabric Lakehouse, który konsoliduje dane pod kontrolą zasad zarządzania.
- Dane: Fabric SQL (Warehouse lub endpoint SQL) zawierający procedury przechowywane do wykonywania zapytań operacyjnych i agregacji.
Razem tworzą jednokierunkowy pipeline inteligencji. Dane są kuratowane i zarządzane na poziomie bazowym, agregowane w sposób deterministyczny w SQL, przetwarzane przez logikę domenową na poziomie usługi, a ostatecznie prezentowane poprzez interakcję w języku naturalnym. Każda warstwa ma wyraźną umowę z sąsiednimi warstwami, dzięki czemu element AI wspomaga podejmowanie decyzji, a nie je utrudnia.
Warstwa podstawowa: zintegrowane zarządzanie danymi
Microsoft Fabric pełni rolę zintegrowanej platformy analitycznej oraz jedynego źródła prawdy dotyczącego szczegółów kont, danych finansowych, wskaźników wykorzystania oraz trendów historycznych. Zasada działania jest prosta: dane przechowuje się raz i wykorzystuje je wielokrotnie, dzięki czemu nic nie jest duplikowane pomiędzy systemami.
Kanał przesyłu aktualizuje się codziennie, pobierając i łącząc dane przedsiębiorstwa z Dynamics 365, systemów finansowych oraz zewnętrznych API. Taki harmonogram zapewnia przewidywalne okna przetwarzania i gwarantuje, że każdy system źródłowy zakończy swoją codzienną pracę przed rozpoczęciem konsolidacji. Lakehouse przechowuje dane w ich oryginalnym formacie wraz ze standardami śledzenia pochodzenia i zarządzania, a następnie udoskonalone zbiory danych trafiają do Fabric SQL – szybkiego warstwy zapytań operacyjnych, której struktury są dostosowane do potrzeb tworzenia raportów dla kierownictwa.
Warstwa danych: silnik operacyjny stworzony do dostępu przez API
To warstwa przekształca starannie przygotowane dane podstawowe w deterministyczne, o niskiej opóźnieniu kontrakty zapytań służące do generowania raportów. Określa ona ścisłe granice agregacji oraz gwarancje wydajności, których oczekują kierownicy od narzędzia o szybkiej reakcji.
Architektura. Fabric SQL Warehouse to interfejs relacyjny, który umieszcza każdą operację z danymi związanymi z raportowaniem w procedurach przechowywanych. Warstwa usługowa nigdy nie wysyła zapytań bezpośrednio do tabel. Złożone łączenia między tabelami, znaczenie każdej agregacji oraz logika biznesowa są realizowane wewnątrz bazy danych, a nie w kodzie aplikacji, co zapewnia przewidywalne czasy odpowiedzi przy dużych objętościach danych. SQL jest dostosowany do zapytań operacyjnych, a nie do analizy, a projekt ma na celu realizację deterministycznych łączeń dających spójne wyniki, planów zapytań nadających się do ponownego użycia dla stabilnej wydajności, wykonywania z parametrami dla bezpieczeństwa oraz agregacji zamkniętych, które są łatwiejsze w utrzymaniu.
Filozofia schematu: zapytanie na pierwszym miejscu. Schemat opiera się na wzorcach zapytań, a nie na standardowej normalizacji z podręczników. Entytą główną jest struktura klasterowania Account, a tabele pomocnicze są ułożone tak, aby połączenia odbywały się efektywnie na podstawie identyfikatora biznesowego, czyli TPID.
--Accounts Table - Primary Business Entity
CREATE TABLE [aieo].[Accounts] (
[Id] INT IDENTITY(1,1) PRIMARY KEY,
[TPID] BIGINT NOT NULL,
[AccountName] NVARCHAR(255) NOT NULL,
[AccountNumber] NVARCHAR(50),
[SearchTokens] NVARCHAR(500),
[Segment] NVARCHAR(100),
[Industry] NVARCHAR(100),
[ACR_FY25] DECIMAL(15,2),
[RevenueRank] INT,
[CreatedDate] DATETIME2 DEFAULT GETUTCDATE(),
[LastSync] DATETIME2,
[IsActive] BIT DEFAULT 1
);
CREATE CLUSTERED INDEX IX_Accounts_TPID ON [aieo].[Accounts]([TPID]);
CREATE NONCLUSTERED INDEX IX_Accounts_Name ON [aieo].[Accounts](
Tabela Accounts stanowi centralną jednostkę, a jej kluczem do grupowania jest TPID. Dzięki temu uzyskuje się mniej więcej liniową szybkość wyszukiwania najczęściej używanych zapytań dotyczących konkretnych kont, a tabela obsługuje zarówno bezpośrednie zapytania oparte na TPID, jak i wyszukiwanie według nazwy.
Tabele pomocnicze. Kilka tabel pomocniczych pokazuje, w jaki sposób obsługiwane są wskaźniki finansowe, informacje o wykorzystaniu AI oraz wzbogacanie danych międzysystemowe.
-- Revenue Table - Historical and Forecast Data
CREATE TABLE [aieo].[Revenue] (
[TPID] BIGINT,
[FiscalYear] NVARCHAR(10),
[RevenueType] NVARCHAR(20),
[Amount] DECIMAL(15,2),
[LastUpdated] DATETIME2
);
CREATE INDEX IX_Revenue_TPID_FY ON [aieo].[Revenue]([TPID], [FiscalYear]);
Tabela przychodów przechowuje dane finansowe z kilku lat oraz wykorzystuje indeksy złożone, które nadają się do obliczania serii czasowych i trendów.
-- AI Usage Table - Product Adoption Metrics
CREATE TABLE [aieo].[AIUsage] (
[TPID] BIGINT,
[ProductCategory] NVARCHAR(50),
[UsageLevel] NVARCHAR(20),
[SeatCount] INT,
[AdoptionRate] DECIMAL(5,2),
[LastUpdated] DATETIME2
);
CREATE INDEX IX_AIUsage_TPID_Product ON [aieo].[AIUsage]([TPID], [ProductCategory]);
Tabela wykorzystania AI odnotowuje przyjęcie produktów według kategorii, co umożliwia analizę wzorców zaangażowania oraz stopnia wdrażania technologii, które mają znaczenie przy planowaniu kont.
Strategia procedur przechowywanych: logika biznesowa znajduje się w bazie danych. Trzy podstawowe procedury odpowiadają za generowanie wszystkich informacji. SearchAccounts znajduje konta i sortuje je według przychodów, GetAccountDetails agreguje dane z różnych źródeł, tworząc kompletny obraz dla kierownictwa, a GetBriefingTemplate zarządza uprawnieniami do szablonów w zależności od roli, aby tylko odpowiednie osoby miały dostęp. Warstwa usługowa wywołuje jedynie te procedury i nic więcej, a tworzenie dynamicznego SQL nie jest dozwolone.
--Account Search Procedure - Revenue-Prioritized Discovery
CREATE OR ALTER PROCEDURE [aieo].[SearchAccounts]
@searchTerm NVARCHAR(255),
@top INT = 5
AS
BEGIN
SET NOCOUNT ON;
DECLARE @likeTerm NVARCHAR(257) = '%' + REPLACE(REPLACE(@searchTerm, '[', '[[]'), '%', '[%]') + '%'
SELECT TOP (@top)
a.TPID,
a.AccountName,
a.AccountNumber,
ISNULL(acr.ACR_YTD, 0) as ACR_YTD
FROM [aieo].[Accounts] a
LEFT JOIN [aieo].[ACR] acr ON a.TPID = acr.TPID
WHERE
a.AccountName LIKE @likeTerm
OR CAST(a.TPID AS NVARCHAR) = @searchTerm
OR a.AccountNumber LIKE @likeTerm
ORDER BY
ISNULL(acr.ACR_YTD, 0) DESC,
a.AccountName ASC
FOR JSON PATH;
END;
--Account Details Retrieval Procedure - Comprehensive Intelligence Aggregation
CREATE PROCEDURE [aieo].[GetAccountDetails]
(@TPID int)
AS
BEGIN
SET NOCOUNT ON;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT TOP 1
JSON_QUERY(ap.[AccountProfile]) AS [Account],
JSON_QUERY(ai.[AIUsage]) AS [AI],
JSON_QUERY(acr.[Data]) AS [ACR],
deal.[Deals.AgreementValue],
deal.[Deals.DealType],
deal.[Deals.Term],
deal.[Deals.Remaining],
deal.[Deals.EndDate],
ecif.[ECIF.Committed],
aco.[ACO.IncrementalRevenue],
aco.[ACO.Discount],
aco.[ACO.ACO],
JSON_QUERY(bot.[Data]) AS [BoT],
JSON_QUERY(inv.[Data]) AS [Investments],
JSON_QUERY(rev.[Data]) AS [Revenue]
FROM [dbo].[vw_Customer] P
OUTER APPLY (
SELECT TOP 1
a.[TPID],
a.[CRMAccountName] AS [AccountName],
a.[Segment],
a.[Industry],
a.[EOU],
a.[OU],
LOWER(TRIM(c.[Value])) AS [ATU_Manager.Alias],
aau.[Mail] AS [ATU_Manager.Email],
[dbo].[RemoveJobTitle](aau.[DisplayName]) AS [ATU_Manager.DisplayName],
NULLIF(TRIM(aau.[BusinessPhone]), '') AS [ATU_Manager.PhoneNumber],
JSON_QUERY([am].[Data]) AS [AM],
JSON_QUERY([atum].[Data]) AS [ATUM]
FROM [dbo].[vw_Customer] A
OUTER APPLY STRING_SPLIT(a.[AM], ',', 1) C
LEFT JOIN [cm].[vw_AAD_User] AAU ON LOWER(TRIM(C.[Value])) = LOWER(AAU.[UserPrincipalName])
WHERE A.TPID = P.TPID
) ap
WHERE P.TPID = @TPID;
END;
--Template Management Procedure - Role-Based Access Control
CREATE OR ALTER PROCEDURE [aieo].[GetBriefingTemplate]
(
@UserAlias NVARCHAR(200),
@BriefingType NVARCHAR(200)
)
AS
BEGIN
SET @UserAlias = IIF(CHARINDEX('@', @UserAlias) > 0,
LEFT(@UserAlias, CHARINDEX('@', @UserAlias) - 1),
@UserAlias)
SELECT DISTINCT
[BriefingTemplateId],[TemplateDescription],[BriefingType],
[UserAlias],FullName,[Filename],[FileType],[PreviewFilename]
FROM [hr].[DimPerson] p
INNER JOIN [aieo].[ExecutiveOfficeMember] eom ON eom.[PersonnelNumber] = p.[PersonnelNumber]
INNER JOIN [aieo].[ExecutiveOffice] o ON o.[ExecutiveOfficeId] = eom.[ExecutiveOfficeId]
INNER JOIN [aieo].[BriefingTemplate] bt ON bt.[ExecutiveOfficeId] = o.[ExecutiveOfficeId]
UNION
SELECT DISTINCT
[BriefingTemplateId],[TemplateDescription],[BriefingType],
p.EmailName As UserAlias,p.FullName,[Filename],[FileType],[PreviewFilename]
FROM [aieo].[BriefingTemplate] bt
CROSS JOIN [hr].[DimPerson] p
WHERE bt.[UserAlias] = 'ALL' AND p.EmailName = @UserAlias
AND bt.BriefingType = @BriefingType;
END;
Wydajność i bezpieczeństwo. Transakcje wykorzystują SET NOCOUNT ON dla lepszej wydajności oraz SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED przy operacjach odczytu, aby nie blokować innych transakcji. Obsługa JSON opiera się na wbudowanych funkcjach SQL Servera, takich jak JSON_QUERY i FOR JSON PATH, które efektywnie przetwarzają dane i serializują je bezpośrednio z bazy danych. Dozwolona jest wyłącznie eksploatacja z użyciem parametrów, a tożsamość usługi aplikacji ma uprawnienia do wykonywania procedur przechowywanych, bez możliwości bezpośredniego dostępu do tabel.
GRANT EXECUTE ON SCHEMA::[aieo] TO [service_identity];
- No direct table access permitted
Szczegóły warstwy usługowej: orkiestracja bez stanu i granice wykonywania
Warstwa usługowa zajmuje się wyłącznie orkiestracją danych. Pobiera dane, renderuje szablony i nie stosuje żadnych własnych reguł biznesowych. Każda usługa ma jedną funkcję i jest luźno powiązana z innymi, co zapewnia czyste oddzielenie warstwy danych od warstwy prezentacji.
Powierzchnia API i walidacja. Aplikacja FastAPI udostępnia wyraźne punkty końcowe typu REST z silnie skategoryzowanymi kontraktami zdefiniowanymi jako modele Pydantic:
POST /api/briefing/generateto główny punkt końcowy służący do generowania raportów, z pełną walidacją danych wejściowych.GET /api/healthinformuje o stanie systemu.GET /api/templateswyświetla listę dostępnych szablonów dla użytkownika, który wysyła żądanie.
from pydantic import BaseModel
from typing import Optional
class BriefingRequest(BaseModel):
account_name_or_tpid: str
meeting_datetime: Optional[str] = None
meeting_objective: Optional[str] = None
ms_attendees: Optional[str] = None
template_type: Optional[str] = None
Model zapewnia ścisłą weryfikację i bezpieczeństwo typów, automatycznie generuje dokumentację OpenAPI oraz koryguje strukturę każdej żądania. Żaden nieuporządkowany wprowadzony danych nie może przejść przez tę barierę.
Model wykonywania. Usługa uruchamia określoną pięciostopniową sekwencję:
- Weryfikacja żądania. Modele Pydantic sprawdzają, czy typy i dane wejściowe są dopuszczalne.
- Rozwiązywanie problemu konta. Format danych wejściowych decyduje o tym, czy szukać TPID bezpośrednio, czy wywołać
SearchAccountsw celu wyszukiwania po nazwie. - Pobieranie danych równoczesne. Funkcje
GetAccountDetailsiGetBriefingTemplatesą wykonywane jednocześnie za pomocąasyncio.gather(). - Kompletowanie kontekstu. Wyniki procedur są bezpośrednio przekształcane w obiekty gotowe do użycia w szablonie, bez żadnej dodatkowej obróbki pośredniej.
Asynchroniczna eksploatacja oraz gromadzenie połączeń za pomocą abstrakcji DatabaseService oznaczają, że identyczne dane wejściowe dają identyczne wyniki wyjściowe.
Zasady kierujące. Warstwę usługową rządzi pięć zasad. Nie zawiera ona logiki biznesowej, ponieważ przetwarzanie informacji odbywa się wyłącznie w procedurach przechowywanych, co chroni warstwę usługową przed zasadami utrudniającymi testowanie i konserwację. Pełni ona jedynie funkcję orkiestracji danych, koordynując ich pobieranie i wyświetlanie bez żadnych transformacji czy obliczeń. Mapowanie kontekstu jest bezpośrednie, więc wyniki procedur trafiają do struktur szablonów bez żadnych odchyleń, co zmniejsza ryzyko różnic w znaczeniu pomiędzy danymi a prezentacją. Przetwarzanie jest deterministyczne – daje to ten sam wynik dla tego samego wejścia, niezależnie od czasu wykonywania lub stanu infrastruktury. Ponadto wszystkie aspekty są czysto oddzielone: logika danych znajduje się w procedurach SQL, orkiestracja w usługach Python FastAPI, a prezentacja w szablonach Jinja2.
Warstwa doświadczeń: Copilot Studio jako silnik rozmowy
Na górze framework AdaptiveDialog w Microsoft Copilot Studio przekształca prośbę w języku naturalnym w deterministyczny proces pracy. Zajmuje się rozwiązywaniem problemów z kontem, autoryzacją szablonów, integracją danych z zewnętrznych źródeł, generowaniem dokumentów oraz ich dostarczaniem przez różne kanały. Proces przebiega sekwencyjnie – od pierwszej prośby, przez rozwiązanie problemów z kontem i autoryzację szablonów, aż po zbieranie danych z zewnętrznych źródeł i ich przesyłkę do SharePoint, przy czym na każdej drodze rozmowy znajdują się punkty decyzyjne oraz kroki weryfikacji.
Główna rozmowa. Ta część automatycznie zbiera identyfikator konta, określa frazy wyzwalające rozpoczęcie rozmowy i ustala główny punkt wejścia do konwersacji:
kind: AdaptiveDialog
inputs:
- kind: AutomaticTaskInput
propertyName: Account_Name_or_TPID
name: Account Name or TPID
description: The account/customer TPID (unique identifier) or name
shouldPromptUser: true
modelDescription: Create briefing document to prepare for meeting with customer
beginDialog:
kind: OnRecognizedIntent
intent:
displayName: Topic for creating briefing document to prepare for meeting with customer
triggerQueries:
- Generate a briefing document for account Accenture
- I need a briefing for Amazon
- Create briefing for Apple
- I have a meeting with JPMorgan Chase at 4PM
Rozwiązywanie problemów z kontem. Sprawdzenie IsNumeric() klasyfikuje wprowadzony tekst jako bezpośredni TPID lub nazwę konta wymagającą wyszukiwania. Unikanie wyszukiwania, gdy to możliwe, zmniejsza liczbę wywołań API i przyspiesza odpowiedź:
- kind: SetVariable
id: setVariable_IsNumeric
variable: Topic.IsNumeric
value: =IsNumeric(Topic.UserInput)
- kind: ConditionGroup
id: conditionGroup_InputType
conditions:
- id: condition_IsTPID
condition: =Topic.IsNumeric
actions:
- kind: SetVariable
variable: Topic.Account_TPID
value: =Topic.UserInput
Wywołanie do wyszukiwania konta. W przypadku imion proces wywołuje punkt końcowy wyszukiwania warstwy usługowej przez REST. Koduje specjalne znaki w formacie URL, autoryzuje się za pomocą klucza subskrypcji i określa schemat odpowiedzi, dzięki czemu dane są automatycznie weryfikowane:
- kind: HttpRequestAction
id: httpRequest_SearchAccounts
displayName: Search Accounts by Name
url: =Global.ApiBaseUrl & "/api/mssales/search/" & EncodeUrl(Topic.UserInput)
headers:
Ocp-Apim-Subscription-Key: =Global.ApiKey
response: Topic.SearchResults
responseSchema:
kind: Record
properties:
accounts:
type:
kind: Table
properties:
account_name: String
tpid: String
total_count: Number
Karta rozróżniająca. Jeśli wyszukiwanie znajdzie kilka kont, karta adaptacyjna pokazuje dynamiczną listę opcji utworzoną za pomocą ForAll() na podstawie wyników, przy czym każda pozycja wyświetla swój TPID. Dzięki temu niejasny wpis nie blokuje dalszej rozmowy:
- kind: AdaptiveCardPrompt
id: adaptiveCard_SelectAccount
card: "=Concatenate('{
\"$schema\":\"https://adaptivecards.io/schemas/adaptive-card.json\",
\"type\":\"AdaptiveCard\",\"version\":\"1.5\",
\"body\":[
{\"type\":\"TextBlock\",\"text\":\"Multiple accounts found\",\"weight\":\"Bolder\"},
{\"type\":\"Input.ChoiceSet\",\"id\":\"selectedAccount\",\"isRequired\":true,
\"choices\":',
JSON(ForAll(Topic.SearchResults.accounts,
{title: Concatenate(account_name, \" (TPID: \", tpid, \")\"), value: tpid})),
'}],
\"actions\":[{\"type\":\"Action.Submit\",\"title\":\"Continue\"}]
}')"
Uzyskanie uprawnień do szablonu. Za pomocą funkcji GetBriefingTemplate system sprawdza, czy użytkownik ma prawo korzystać ze szablonów kierowniczych, w oparciu o swoją rolę organizacyjną oraz przynależność do zarządu. Nazwa głównego użytkownika służy do weryfikacji tożsamości, typ informacji filtruje wyniki, a zarządzanie szablonami jest domyślnie zabezpieczone:
- kind: HttpRequestAction
id: httpRequest_GetUserTemplates
url: =Global.ApiBaseUrl & "/api/briefings/templates?user_alias=" &
EncodeUrl(System.User.PrincipalName) & "&briefing_type=Customer"
headers:
Ocp-Apim-Subscription-Key: =Global.ApiKey
response: Topic.UserTemplates
Karta z informacjami o spotkaniu. Następna karta wykorzystuje zasadę stopniowego ujawniania informacji – pola obowiązkowe są pokazywane od razu, natomiast opcjonalne znajdują się za przyciskiem do ich wyboru. To zmniejsza obciążenie poznawcze, przy jednoczesnym zebraniu wszystkich niezbędnych informacji do krótkiego przeglądu:
- kind: AdaptiveCardPrompt
id: adaptiveCard_MeetingDetails
card: "=Concatenate('{
\"$schema\":\"https://adaptivecards.io/schemas/adaptive-card.json\",
\"type\":\"AdaptiveCard\",\"version\":\"1.5\",
\"body\":[
{\"type\":\"TextBlock\",\"text\":\"Create Executive Briefing Document\",
\"weight\":\"Bolder\",\"size\":\"Large\",\"color\":\"Accent\"},
{\"type\":\"Input.Date\",\"id\":\"meetingDate\",\"isRequired\":true,
\"label\":\"Meeting Date\"},
{\"type\":\"Input.Time\",\"id\":\"meetingTime\",\"value\":\"09:00\"},
{\"type\":\"Input.Text\",\"id\":\"msAttendees\",\"isVisible\":false,
\"label\":\"Microsoft Attendees\"}
],
\"actions\":[
{\"type\":\"Action.ToggleVisibility\",\"title\":\"Additional Options ▼\",
\"targetElements\":[\"msAttendees\"]},
{\"type\":\"Action.Submit\",\"title\":\"Generate Briefing\"}
]
}')"
Równoczesne zbieranie danych i generowanie dokumentów. Warstwa doświadczeń wywołuje jednocześnie API Account Details oraz Azure AI Foundry, przy czym każde z tych wywołań ma 60 sekund czasu oczekiwania. Gdy oba zwrócą odpowiedź, tworzy się jeden ustrukturyzowany payload w formacie JSON na podstawie wszystkich źródeł, który jest następnie przekazywany do API do generowania dokumentów. Proces weryfikacji i kompletowania danych jest zintegrowany, dzięki czemu dokument powstaje w sposób deterministyczny.
Azure AI Foundry: inteligencja organizacyjna
Integracja z Foundry rozszerza zakres działania agenta poza dane rynkowe o kontekst pochodzący z wnętrza organizacji, wykorzystując komponent „M365 Researcher”. Dzięki uprawnieniom Microsoft Graph agent może przeszukiwać e-maile w Outlooku oraz rozmowy w Teams, przy czym cała operacja odbywa się w ramach zasad bezpieczeństwa przedsiębiorstwa i zasady zerowego zaufania.
Dostęp do Microsoft Graph poprzez delegację bez przechowywanych sekretów. Badacz polega na autoryzacji delegowanej, która całkowicie eliminuje przechowywanie sekretów klienta. Wykorzystuje ona łączniki zarządzane przez Azure Logic Apps – aplikacje firmy Microsoft z uprzednio zatwierdzonymi zakresami uprawnień delegowanych. Dzięki temu unika się konieczności zarządzania rejestracjami aplikacji, ponieważ Azure zajmuje się cyklem życia tokenów oraz ich automatycznym odświeżaniem.
Ponadto krótkotrwałe instancje Logic Apps zabezpieczają dostęp do danych użytkownika za pomocą wyzwalaczy HTTP chronionych kluczami SAS. Każde wyszukiwanie uruchamia nową instancję Logic App, pobiera dane z Microsoft Graph równolegle i natychmiast ją usuwa, dzięki czemu adres URL z kluczem SAS nie może być ponownie użyty, a żaden trwały token nie pozostaje dostępny.
// Ephemeral Logic App Security Pattern
const createSearchLogicApp = async (userAlias, searchQuery) => {
const logicAppName = `Researcher-${userAlias}`;
// Create Logic App with SAS trigger
const logicApp = await armClient.logicApps.createOrUpdate({
resourceGroupName: 'Azure_OpenAI',
workflowName: logicAppName,
definition: buildResearchWorkflow(userAlias)
});
// Execute search via SAS URL
const searchResults = await triggerLogicApp(logicApp.triggerUrl, searchQuery);
// Immediate cleanup for security
await armClient.logicApps.delete(logicAppName);
return searchResults;
};
Równoległe pobieranie danych i optymalizacja Graph. Dane z e-maili oraz Teams są zbierane jednocześnie, przy czym stosuje się ograniczenia dotyczące równoczesności, aby sesje wielu użytkowników nie powodowały spowolnień. W przypadku e-maili connector Office 365 pobiera maksymalnie 250 najnowszych wiadomości na użytkownika, a filtrowanie odbywa się na stronie klienta, aby obejść ograniczenia Graph dotyczące wyszukiwania treści wiadomości. W przypadku Teams stosuje się podejście dwufazowe: najpierw identyfikowane są rozmowy za pomocą żądań paginowanych, a następnie pobierane są wiadomości z poszczególnych wątków rozmowy przy zachowaniu konfigurowalnego limitu równoczesności.
# Logic App Parallel Execute Pattern
HTTP_Trigger_SAS_Secured:
Email_Branch:
- Get_Emails: Office365_Connector.Mail (top=250)
Teams_Branch_Parallel:
- Get_Teams_Chats_Page1: Teams_Connector.Chats (top=50)
- Get_Teams_Chats_Page2: Teams_Connector.Chats (skip=50, top=50)
- For_Each_Chat:
concurrency: 10
actions:
- Get_Chat_Messages: Teams_Connector.Messages (top=50)
- Append_Chat_Data: Variable_Accumulation
Response_Assembly:
- Combine: Email_Results + Teams_Results + Metadata
- Return: JSON_Structured_Response
Zwykłe wyszukiwanie polega na około 101 wywołaniach Graph API: jednym do przeglądania maili, dwóch do wyliczania rozmów w Teams oraz średnio 98 do pobierania wiadomości z rozmów. Dzięki temu uzyskuje się dużą ilość danych, przy jednoczesnym przestrzeganiu ograniczeń równoczesności Graph API oraz, zgodnie z projektem, utrzymywaniu czasu odpowiedzi poniżej 60 sekund.
Połączenia i tokeny na użytkownika. Każdy użytkownik potrzebuje dwóch zarządzanych połączeń, które przechowują delegowane tokeny OAuth w trakcie sesji wyszukiwania: office365-{alias} do obsługi poczty z zakresem Mail.ReadWrite oraz teams-{alias} do czatu z zakresem Chat.Read. Infrastruktura zarządzanych połączeń Azure automatycznie odnawia tokeny i zapewnia zgodność z wymogami. Proces konfiguracji odbywa się według schematu opartego na zgodzie użytkownika – ten loguje się raz poprzez interfejs OAuth firmy Microsoft, a delegowane uprawnienia pozostają w mocy do chwili ich cofnięcia. Aplikacja Function App zarządza cyklem życia połączeń za pomocą API Azure Resource Manager pod kierownictwem tożsamości zarządzanej, dzięki czemu żadne dane uwierzytelniające klienta nie są przechowywane w warstwie aplikacji.
// Per-User Connection Provisioning
const provisionUserConnections = async (userAlias) => {
const connections = [
{
name: `office365-${userAlias}`,
api: '/providers/Microsoft.PowerApps/apis/shared_office365',
scopes: ['Mail.ReadWrite']
},
{
name: `teams-${userAlias}`,
api: '/providers/Microsoft.PowerApps/apis/shared_teams',
scopes: ['Chat.Read']
}
];
for (const conn of connections) {
await armClient.connections.createOrUpdate({
resourceGroupName: 'Azure_OpenAI',
connectionName: conn.name,
properties: {
displayName: conn.name,
api: { id: conn.api },
parameterValues: {}
}
});
}
return generateConsentUrls(connections);
};
Synteza za pomocą modelu GPT. Surowe komunikaty są przekształcane w gotowe do użycia informacje strategiczne za pomocą modelu z usługi Azure OpenAI Service (opisanego jako GPT-4.1, chociaż przykładowy kod wskazuje na wersję GPT-4 preview). Ten proces przekształca filtrowane e-maile oraz treści z Teams w ustrukturyzowane wnioski obejmujące analizę interesariuszy, wzorce komunikacji oraz działania istotne dla spotkania. Pytania zadawane modelowi odpowiadają na potrzeby kierownictwa, takie jak mapowanie relacji, status projektu i tematy strategiczne, a model zwraca ustrukturyzowany plik JSON, który można wstawić do istniejących szablonów Jinja2, zapewniając spójny format we wszystkich dokumentach.
# Organizational Intelligence Synthesis
async def synthesize_organizational_context(filtered_data, account_context):
synthesis_prompt = """
Analyze the following organizational communications for executive briefing preparation:
Account Context: {account_name}
Email Communications: {email_count} relevant messages
Teams Discussions: {chat_count} relevant conversations
Generate executive intelligence focusing on:
Financial performance, earnings trends, and capital allocation signals.
Corporate strategy, market positioning, and competitive landscape.
AI strategy, digital transformation initiatives, and cloud ecosystem alignment.
Recent material developments (≤ 90 days) with actionable insights for executive engagement.
Format as structured JSON with executive_summary, stakeholder_analysis, recent_activities, and recommended_actions.
"""
response = await azure_openai_client.chat.completions.create(
model="gpt-4-1106-preview",
messages=[{
"role": "system",
"content": "You are an executive intelligence analyst."
}, {
"role": "user",
"content": synthesis_prompt.format(**filtered_data, **account_context)
}],
temperature=0.1,
max_tokens=2000
)
return parse_structured_intelligence(response.choices[0].message.content)
Integracja z dialogiem. Badacz łączy się z procesem pracy Copilot Studio równocześnie z pobieraniem standardowych danych konta oraz informacji z zewnętrznych źródeł analityki rynkowej, dzięki czemu dodatkowy kontekst organizacyjny nie powinien spowolnić ogólnej generacji raportów.
# Enhanced Copilot Studio Parallel Execution
- kind: ParallelExecution
id: parallelExecution_ComprehensiveIntelligence
branches:
- account_data:
kind: HttpRequestAction
url: =Global.ApiBaseUrl & "/api/accounts/" & Topic.Account_TPID
- organizational_intelligence:
kind: HttpRequestAction
url: =Global.ApiBaseUrl & "/api/search?q=" & EncodeUrl(Topic.Account_Name) & "&alias=" & System.User.PrincipalName
requestTimeoutInMilliseconds: 60000
continueOnError: true
- market_intelligence:
kind: HttpRequestAction
url: =Global.FoundryBaseUrl & "/bingnews/api/AgentFunction"
- kind: SetVariable
id: setVariable_CombinedIntelligence
variable: Topic.BriefingContext
value: ={
account_details: Topic.AccountData,
organizational_context: Topic.OrganizationalIntelligence,
market_insights: Topic.MarketIntelligence
}
Zarządzanie i zgodność. Użytkownicy mogą przeszukiwać wyłącznie swoją własną pocztę oraz wiadomości w Teams za pomocą uprawnień delegowanych, co zapobiega dostępowi między użytkownikami i utrzymuje ścisłe granice danych. Każda wywołanie Graph API jest rejestrowane wraz z kontekstem użytkownika, parametrami wyszukiwania oraz metadanymi wyników. Okres przechowywania danych jest konfigurowalny, a połączenia, które nie są używane przez określony czas – zazwyczaj 80 dni – są automatycznie usuwane. Przetwarzanie odbywa się wewnątrz tenantu Azure, a mechanizmy kontroli lokalizacji danych wspierają polityki zarządzania organizacją.
// Enterprise Governance and Cleanup
const implementGovernanceControls = async () => {
// Automated stale connection cleanup
const staleThreshold = 80; // days
const allConnections = await listManagedConnections();
const staleConnections = allConnections.filter(connection => {
const lastUsed = parseISO(connection.properties.lastConnection);
const daysSinceUse = differenceInDays(new Date(), lastUsed);
return daysSinceUse > staleThreshold;
});
// Compliance audit logging
for (const connection of staleConnections) {
await auditLogger.log({
action: 'CONNECTION_CLEANUP',
userAlias: connection.userAlias,
reason: 'AUTOMATED_GOVERNANCE',
retentionPolicy: `${staleThreshold}_DAYS_INACTIVE`,
timestamp: new Date().toISOString()
});
await deleteUserResources(connection.userAlias);
}
};
Wydajność i tolerancja na awarie. System przechowuje w pamięci tymczasowej stan połączenia użytkownika i sprawdza jego sprawność przed wykonywaniem kosztownych operacji Graph. Jeśli dostęp do Graph jest ograniczony lub chwilowo niedostępny, system funkcjonuje dalej w sposób uporządkowany, stosując eksponencjalne opóźnienia przy tymczasowych awariach oraz ścisłe limity czasowe, aby generowanie raportów nie zostało zatrzymane. Gdy wyszukiwanie w organizacji zawiedzie lub wygaśnie czas oczekiwania, raport nadal jest wysyłany wraz z danymi konta i informacjami rynkowymi z zewnętrznych źródeł, dzięki czemu kierownicy otrzymują spójne doświadczenie niezależnie od dostępności Microsoft 365.
// Fault-Tolerant Execution Pattern
const executeOrganizationalIntelligence = async (searchQuery, userAlias) => {
const executionTimeout = 60000; // 60 second maximum
const fallbackResponse = { summary: "Organizational context unavailable", status: "fallback" };
try {
// Health check before expensive operations
const connectionsHealthy = await verifyConnectionHealth(userAlias);
if (!connectionsHealthy) {
return fallbackResponse;
}
// Execute with timeout boundary
const intelligencePromise = gatherOrganizationalIntelligence(searchQuery, userAlias);
const timeoutPromise = new Promise((_, reject) =>
setTimeout(() => reject(new Error('TIMEOUT')), executionTimeout)
);
return await Promise.race([intelligencePromise, timeoutPromise]);
} catch (error) {
// Graceful degradation logging
await logger.warn(`M365 Researcher fallback: ${error.message}`, {
userAlias,
searchQuery,
fallbackMode: true
});
return fallbackResponse;
}
};
Gdy badacz jest już przygotowany, agent przechodzi od informacji rynkowych pochodzących z zewnątrz do kompleksowego obrazu, który obejmuje również wgląd w sytuację wewnętrznych interesariuszy, co ma na celu wspieranie lepszych decyzji strategicznych bez osłabiania standardów bezpieczeństwa, zarządzania czy wydajności.
Zawołanie do generowania dokumentu. W tym kroku tworzone jest ostateczne zestawienie informacji poprzez połączenie wszystkiego, co zostało zebrane podczas rozmowy, w jedną paczkę danych przeznaczoną dla warstwy usługowej. Zawiera ona kontekst użytkownika, szczegóły spotkania oraz opcjonalne informacje uzyskane za pomocą sztucznej inteligencji z zewnątrz, przy czym całkowity proces tworzenia dokumentu ma czas wykonywania 60 sekund:
- kind: HttpRequestAction
id: p4tceX
method: Post
url: =Global.ApiBaseUrl & "/api/briefings/" & Topic.templateId & "/accounts/" & Topic.Account_TPID
body:
kind: JsonRequestContent
content: "={
user_alias: Topic.SenderEmail,
MeetingDateTime: Topic.MeetingDateTime,
msAttendees: Topic.msAttendees,
FoundryResponse: Topic.FoundryResponse
}"
requestTimeoutInMilliseconds: 60000
response: Topic.BriefingDocument
Dostawa do SharePoint. Wszystkie utworzone dokumenty trafiają do centralnego repozytorium za pośrednictwem łącznika SharePoint w Power Platform z zarządzaną autoryzacją, dzięki czemu każdy dokument jest przechowywany i dostępny niezależnie od sposobu drugorzędnej dostawy, co spełnia wymagania związane z zarządzaniem. Strona docelowa oraz folder w poniższym przykładzie są tylko placeholderami.
- kind: InvokeConnectorAction
id: invokeConnectorAction_YKkMK4
input:
binding:
dataset: https://microsoft.sharepoint.com/teams/MCAPSAIIncubationHub
folderPath: /Shared Documents/General/AI Prototypes & Solutions/AI Executive Office Use Cases/Published Cust Template/
name: =Topic.CustomFilename
file: =Global.File
Nazwy plików są generowane w taki sposób, aby były czytelne, łącząc nazwę konta, identyfikator kierownika oraz datę spotkania. Funkcja Substitute() zapewnia bezpieczeństwo tych nazw w systemie plików oraz utrzymuje spójność ich formatowania we wszystkich procesach pracy kierowników:
- kind: SetVariable
id: setVariable_CustomFilename
variable: Topic.CustomFilename
value: =Concatenate(
Substitute(Topic.Account_Name, " ", "_"), "_",
Topic.ExecutiveName, "_Brief_",
Text(Topic.meetingDate, "yyyy-MM-dd"), ".docx"
)
Zarządzanie błędami i stanem. Niepowodzenia przy dostępie do szablonu powodują pokazanie wskazówek kontekstowych w karcie adaptacyjnej o stylu ostrzeżenia, a nie ogólnego błędu. System sprawdza konkretne kody błędów z API usługi, informuje użytkownika o braku uprawnień i ukrywa wrażliwe dane systemowe:
- kind: ConditionGroup
id: conditionGroup_CheckBriefingError
conditions:
- condition: =!IsBlank(Topic.BriefingDocument.error) && Topic.BriefingDocument.error.error_code = "TEMPLATE_ACCESS_DENIED"
actions:
- kind: AdaptiveCardPrompt
card: ={
"$schema":"https://adaptivecards.io/schemas/adaptive-card.json",
"type":"AdaptiveCard","version":"1.5",
"body":[{
"type":"Container","style":"warning",
"items":[{
"type":"TextBlock","text":"Template Access Required",
"weight":"Bolder","color":"Attention"
},{
"type":"TextBlock","wrap":true,
"text": Topic.BriefingDocument.error.user_message
}]
}]
}
Walidacja biznesowa odbywa się na stronie klienta, dzięki czemu nieprawidłowe dane nigdy nie trafiają do usług backendowych, co poprawia doświadczenie użytkownika i unika niepotrzebnych wywołań API. Na przykład data spotkania z przeszłości jest natychmiast odrzucana wraz z wskazówkami co robić:
- kind: ConditionGroup
id: conditionGroup_ValidateInputs
conditions:
- condition: =Topic.meetingDate < Today()
actions:
- kind: SendActivity
activity: The meeting date cannot be in the past. Please start over and enter a future date.
- kind: EndConversation
Krok czyszczenia o charakterze bezpieczeństwa usuwa wszystkie zmienne przechowujące dane konta, odpowiedzi API oraz dane wprowadzone przez użytkownika po zakończeniu rozmowy. Dzięki temu spełniane są wymagania dotyczące prywatności, a także unikane jest gromadzenie się danych w pamięci w usługach rozmów długotrwałych, które przetwarzają poufne informacje biznesowe:
- kind: SetVariable
id: setVariable_ClearUserInput
variable: Topic.UserInput
value: =Blank()
- kind: SetVariable
id: setVariable_ClearAccountDetails
variable: Topic.AccountDetails
value: =Blank()
- kind: SetVariable
id: setVariable_ClearFoundryResponse
variable: Topic.FoundryResponse
value: =Blank()
- kind: SetVariable
id: setVariable_ClearBriefingDocument
variable: Topic.BriefingDocument
value: =Blank()
W połączeniu warstwa doświadczeń użytkownika zapewnia orkiestrację rozmów przy użyciu deterministycznych schematów pracy, rozbudowaną obsługę błędów, odporne na awarie połączenia z usługami zewnętrznymi, autoryzację opartą na rolach oraz dostarczanie treści przez kilka kanałów dzięki frameworkowi AdaptiveDialog.
Bезpieczeństwo i szczegóły implementacji
Tożsamość i uwierzytelnianie federowane
System wykorzystuje kredencjały tożsamości federowanej Azure, dzięki czemu żadne sekrety nie są przechowywane, a logowanie jest spójne we wszystkich środowiskach. Wybieracz kredencjałów określa, w jakim środowisku uruchamiany jest kod, i wybiera odpowiedni mechanizm:
# Environment-aware authentication pattern
def get_credential():
if is_azure_environment():
return ManagedIdentityCredential(client_id=os.getenv('AZURE_CLIENT_ID'))
else:
return AzureCliCredential()
W Azure wykorzystuje zarządzaną tożsamość, przy której dane uwierzytelniające są automatycznie dostarczane i rotowane, natomiast przy lokalnym rozwoju stosuje się dane uwierzytelniające z Azure CLI. Tokeny są przechowywane w sposób bezpieczny pod względem wątków, a ich wygaśnięcie jest obsługiwane automatycznie.
Struktura usługi i zarządzanie zależnościami
Szczegóły funkcjonowania usługi opierają się na iniekcji zależności, co umożliwia uruchamianie tego samego kodu zarówno z użyciem symulacji w testach, jak i w pełni skonfigurowanych instancji w środowisku produkcyjnym. Kwestie wspólne dla wszystkich komponentów usługi, takie jak obsługa błędów i zarządzanie konfiguracją, są dzielone pomiędzy nimi, a każdy z komponentów (SharePoint, baza danych, Power BI) przyjmuje opcjonalne zależności poprzez swój konstruktor, pozostając przy tym luźno powiązanym z zewnętrznymi API i zasobami Azure. Dzięki temu możliwe jest dokładne testowanie za pomocą symulowanych implementacji, a także niezawodne działanie w środowisku produkcyjnym dzięki odpowiedniej abstrakcji.
Orkiestracja jest asynchroniczna, aby maksymalnie wykorzystać równoległe zbieranie danych. Gdy generowana jest informacja wstępna, kilka źródeł jest wyświetlanych jednocześnie za pomocą mechanizmu async/await oraz starannego obsługi błędów, dzięki czemu system funkcjonuje prawidłowo nawet w przypadku awarii jednego z elementów.
Połączenia z bazą danych i wydajność
Szczegółowa warstwa bazodanowa wykorzystuje zarządzanie połączeniami poprzez mechanizm engine management w SQLAlchemy, z użyciem singletona w celu efektywnego wykorzystania zasobów. Zapytania są gromadzone w procedurach przechowywanych, które zawierają logikę biznesową wewnątrz bazy danych, co zmniejsza ruch sieciowy i upraszcza kod aplikacji. Duże zbiory wyników są przetwarzane poprzez inteligentną rekonstrukcję formatu JSON, obejście ograniczeń pyodbc przy dużych odpowiedziach, dzięki czemu przetwarzanie pozostaje niezawodne niezależnie od rozmiaru wyników, a zużycie pamięci pozostaje umiarkowane.
Integracja z zewnętrznymi usługami
Integracja z SharePoint i Microsoft Graph przechowuje dane w pamięci podręcznej w sposób opóźniony, aby ograniczyć liczbę wywołań API przy jednoczesnym utrzymywaniu aktualności informacji. ID stron i folderów są przechowywane w pamięci podręcznej z odpowiednią logiką unieważniania danych oraz dynamicznym wybieraniem bibliotek, co zapewnia niezawodność przesyłania plików. Integracja z Dynamics 365 analizuje odpowiedzi z Search v2.0 i przekształca surowe wyniki w struktury mające znaczenie biznesowe, wykorzystując logikę ponawiania prób w przypadku ograniczeń szybkości oraz staranną obsługę błędów.
Generowanie dokumentów
Proces generowania łączy przetwarzanie szablonów Jinja2 z budową kontekstu, który przekształca surowe dane w gotowe do użycia wnioski. Kontekst szablonu zawiera surowe dane, obliczone metryki, narzędzia do formatowania oraz informacje uzyskane z analizy międzysystemowej. Zarządzanie szablonami weryfikuje składnię i radzi sobie z błędami, dzięki czemu proces generowania pozostaje niezawodny nawet po edycji szablonów, a kilka formatów wyjściowych jest obsługiwanych dzięki konfiguracji typów MIME dla elastycznej dostawy.
Błędy i wyjątki
Aplikacja posiada ustrukturyzowaną hierarchię wyjątków, która dostarcza szczegółowych informacji o błędach przy jednoczesnym przestrzeganiu zasad bezpieczeństwa. Dostosowane klasy wyjątków zawierają kontekst, który ułatwia debugowanie bez ujawniania wewnętrznych mechanizmów systemu:
Structured exception hierarchy
class AIExecutiveOfficeError(Exception):
def __init__(self, message: str, error_code: str = None, details: dict = None):
self.message = message
self.error_code = error_code or self.__class__.__name__
self.details = details or {}
self.timestamp = datetime.utcnow()
Globalny obsługa wyjątków przekształca błędy techniczne w ustrukturyzowane odpowiedzi API, które pomagają użytkownikowi, nie ujawniając przy tym zbyt wielu szczegółów.
Ocena i weryfikacja jakości
System jest oceniany za pomocą ustrukturyzowanego frameworku testowego, który sprawdza wydajność techniczną oraz jakość informacji w różnych kontach firmowych. Metody ilościowe i jakościowe są łączone w procesie oceny opartym na kilku notatnikach, który testuje każdy komponent architektoniczny partiami.
Z punktu widzenia aspektu ilościowego kluczowa jest dokładność danych. Wskaźniki w gotowych, wypełnionych szablonach raportów są porównywane z danymi źródłowymi z warstwy podstawowej, a proces oblicza wyniki dokładności oraz średnią bezwzględną błąd procentowy (MAPE). Pokazują one, w jakim stopniu warstwa usługowa przekazuje dane przez cały proces, od wyników procedur przechowywanych aż do ostatecznego dokumentu. Wykonania partiami obejmują wiele kont i dostarczają zintegrowanego notatnika wydajności, stanowiącgo statystyczne potwierdzenie, że projekt oparty wyłącznie na orkiestracji zachowuje wierność danych, nie wprowadzając błędów obliczeniowych ani odchyleń semantycznych pomiędzy warstwą podstawową a warstwą użytkownika.
Cecha jakościowa mierzy pojedynczą cechę – biegłość w komunikacji z firmą, czyli to, na jak dobrą stopę materiał informacyjny pokazuje rzeczywiste zrozumienie organizacji docelowej i w odpowiedni sposób o niej mówi. Sędzia wykorzystujący LLM ocenia każdy materiał według pięciu standardowych kryteriów: trafność (czy treść jest odpowiednia do podejmowania decyzji kierowniczych), spójność (logiczny tok i struktura), dokładność (poprawność faktograficzna i zgodność z danymi źródłowymi), klarowność (język i forma prezentacji dostosowane do kierowników) oraz kompletność (objęcie strategicznych obszarów). Ten podejście zapewnia spójną, skalowalną ocenę z obiektywnymi wynikami w różnych typach kont i branżach, chociaż, podobnie jak we wszystkich systemach oceniania opartych na LLM, przenosi ono uprzedzenia samego modelu sędziego.
Kolejne kroki: przejście na Microsoft Agent Framework
Zespół postrzega architekturę czterowarstwową jako solidną podstawę do migracji na Microsoft Agent Framework (MAF), co wzmocni orkiestrację sztucznej inteligencji przy jednoczesnym zachowaniu zasad deterministycznych. MAF w większości wejdzie w grę na warstwie usług, zastępując logikę orkiestracji FastAPI agentami MAF, które stosują te same wzorce czystej orkiestracji danych. Warstwa doświadczeń użytkownika ulegnie całkowitej zmianie: Copilot Studio zostanie zastąpione natywną integracją z Microsoft 365, która umieszcza procesy biznesowe w Outlooku, Teams i SharePoint, wykorzystując rozumienie języka MAF do lepszej identyfikacji intencji i rozmów wieloetapowych, przy jednoczesnym korzystaniu z tych samych procedur przechowywanych do analizy danych biznesowych.
wbudowana możliwość obserwacji, zarządzanie komunikacjami oraz narzędzia do zarządzania cyklem życia agentów w MAF pozwoliłyby na eliminację konieczności stosowania specjalistycznej infrastruktury oraz umożliwiłyby monitorowanie i wdrażanie na poziomie przedsiębiorstwa. Ścieżka migracji zachowuje istniejące inwestycje w procedury przechowywane, szablony Jinja2 oraz integrację z SharePoint, jednocześnie dodając funkcjonalności do trudniejszych scenariuszy, takich jak briefingi obejmujące kilka kont, syntezę analiz konkurencyjnych oraz szablony generowane dynamicznie na podstawie kontekstu spotkania i uczestników. Dzięki integracji z Microsoft 365 generowanie briefingów stałoby się funkcją wbudowaną w istniejące procesy produktywności, a nie oddzielną interfejsem czatowym, przy czym warstwy danych i usług pozostałyby deterministyczne.
Co pokazuje projekt
Agent przekształca przygotowanie informacji szkoleniowych z ręcznej koordynacji w automatyczną generację danych wywiadowczych za pomocą czterech warstw, które odpowiadają za konsolidację danych, agregację operacyjną, orkiestrację biznesową oraz interakcję w języku naturalnym. Mówi się, że ten deterministyczny podejście w ramach zintegrowanego ekosystemu Microsoft umożliwia szybką generację informacji szkoleniowych (twierdzi się, że w czasie „poniżej sekundy”, chociaż własne limity czasowe procesu wynoszą 60 sekund, więc najprawdopodobniej chodzi o kroki związane z bazą danych i usługami), a także zapewnia bezpieczeństwo, zarządzanie oraz możliwości audytu, których systemy oparte wyłącznie na pytaniach mają trudności z zagwarantowaniem.
Podstawowa lekcja polega na tym, że skuteczne aplikacje AI w przedsiębiorstwach stawiają rozwiązanie problemów biznesowych ponad zaawansowanie techniczne i przynoszą wartość dzięki solidnej integracji danych oraz automatyzacji procesów, a nie dzięki zaawansowanym technikom uczenia maszynowego. Warstwowa separacja zadań, iniekcja zależności oraz określone granice wykonywania sprawiają, że taki projekt stanowi wzorzec nadający się do ponownego użycia w automatyzacji obsługi klienta, pracach związanych z analizą finansową oraz w systemach inteligencji operacyjnej w innych organizacjach.