
Do niedawna praca z systemem CRM kojarzyła się z ekranem, klawiaturą i dziesiątkami ekranów oraz kliknięć. Dziś, dzięki zastosowaniu modeli językowych oraz mechanizmów sztucznej inteligencji, realny staje się scenariusz, w którym handlowiec w drodze ze spotkania może dyktować notatkę, technik serwisu pytać o historię zgłoszeń klienta, a dyrektor jednym zdaniem sprawdzać stan lejka sprzedażowego bez otwierania jakiejkolwiek aplikacji. Kluczem do takiego podejścia jest idea headless CRM. W klasycznym modelu system CRM stanowi nierozerwalną całość: dane, logika biznesowa i interfejs użytkownika tworzą jeden produkt, z którego korzysta się przez dedykowaną aplikację. W omawianym podejściu warstwa prezentacji zostaje oddzielona oddanych, reguł biznesowych, uprawnień i procesów. CRM staje się usługą dostępną przez API, a interfejs do komunikacji może stanowić formularz webowy, aplikacja mobilna, agent AI albo głos użytkownika. Dane i zasady ich przetwarzania pozostają te same, natomiast zmienia się sposób interakcji człowieka z systemem.
Warto podkreślić, że omawiany temat, mimo odniesienia do Dynamics 365 CE (Customer Engagement) w tytule, nie ogranicza się do jednego produktu. Fundamentem jest w tym przypadku Microsoft Dataverse, czyli usługa chmurowa na której zbudowane są aplikacje firmy Microsoft (Dynamics 365 Sales, Customer Service, Field Service i Customer Insights), a także niestandardowe rozwiązania stworzone na platformie Power Platform. Omawiana usługa udostępnia ujednolicone API, model bezpieczeństwa i mechanizmy automatyzacji, a także serwer protokołu MCP (Model Context Protocol) – otwartego standardu, za pomocą którego agenci AI komunikują się z zewnętrznymi źródłami danych i narzędziami. W związku z tym Dataverse stanowi idealny przykład technologii, która może być wykorzystana w podejściu headless CRM.
W kolejnych częściach artykułu opiszę możliwe podejścia do tematu implementacji systemu typu Voice Chat umożliwiającego interakcję zdanymi w repozytorium Dataverse. Ponieważ treść artykułu opiera się na naszych rzeczywistych doświadczeniach z implementacją omawianego rozwiązania, wymienione zostaną w nim również „ślepe uliczki”, na które natrafiliśmy przy projektowaniu aplikacji. Omówimy także podejście do bezpieczeństwa danych w systemach, które są konsumowane przez agentów sztucznej inteligencji.
Rozdział 1: Copilot ponad wszystko!
Ponieważ jesteśmy firmą, która od wielu lat specjalizuje się w dostarczaniu rozwiązań biznesowych w oparciu o Microsoft Power Platform, naturalnym pierwszym wyborem technologicznym był dla nas agent stworzony w narzędziu Microsoft Copilot Studio. Do komunikacji z repozytorium Dataverse (która w omawianym przypadku użycia polegać miała na rejestrowaniu aktywności handlowców w systemie) wykorzystywaliśmy protokół MCP oraz serwer dostępny natywnie w ramach usługi Dataverse. Inicjalna wersja architektury rozwiązania miała przedstawiać się następująco:
Niestety, już na etapie prototypowania powyższe podejście ujawniło swoją podstawową słabość. Żaden z domyślnych kanałów, w których możemy opublikować agenta stworzonego za pomocą Copilot Studio, nie daje możliwości komunikacji za pomocą czatu głosowego. Aplikacja mobilna oraz interfejs portalu Microsoft 365 dają co prawda możliwość zamiany komunikatów głosowych na tekst, co uznaliśmy jednak za mało wygodny półśrodek. Z kolei w przypadku komunikacji z agentem w aplikacji mobilnej Microsoft Teams jedyną wspieraną formą konwersacji okazała się komunikacja tekstowa, co zupełnie przekreśliło możliwość zastosowanie tego klienta w omawianym przypadku użycia. Jest to o tyle ciekawe, że w przypadku domyślnego agenta Microsoft Copilot funkcjonalność czatu głosowego jest dostępna „z pudełka”.
Rozdział 2: Może coś niestandardowego?
Opisaną powyżej niedogodność spróbowaliśmy rozwiązać za pomocą niestandardowej aplikacji dostępowej oraz usługi Azure Speech pozwalającej w prosty sposób zamieniać mowę na tekst (speech-to-text) oraz tekst na mowę(text-to-speech). Na początku próbowaliśmy zbudować omawianą funkcjonalność za pomocą aplikacji typu Canvas z zagnieżdżonymi kontrolkami do rejestrowania i odtwarzania dźwięku.
Niestety komunikacja z usługą odpowiedzialną za dwustronne przekształcanie tekstu i głosu za pomocą protokołu HTTP okazała się obarczona zbyt dużymi opóźnieniami. O ile w przypadku komunikacji jednokierunkowej rozwiązanie to może się nieźle sprawdzić, o tyle w przypadku komunikacji dwukierunkowej trudno było mówić o jakiejkolwiek płynnej rozmowie z agentem. Aplikacje tego typu niestety nie wspierają natywnie komunikacji za pomocą protokołów WebSocket lub WebRTC, które – w przeciwieństwie do pojedynczych zapytań HTTP – utrzymują stałe, dwukierunkowe połączenie i pozwalają przesyłać dźwięk strumieniowo, w czasie rzeczywistym. Oczywiście problem ten moglibyśmy łatwo obejść za pomocą niestandardowego kodu wyszliśmy jednak z założenia, że skoro miałby on stanowić główny i w praktyce jedyny element interfejsu użytkownika, równie dobrze możemy stworzyć do tego celu niestandardową aplikację.
Rozdział 3: Jednak platforma
Z uwagi na fakt, że mechanizmy low-code dostępne w modelu SaaS nie spełniły w omawianym przypadku naszych oczekiwań, postanowiliśmy zweryfikować możliwości wykorzystania usług dostępnych w ramach Microsoft Foundry (do niedawna Azure AI Foundry). W ramach omawianej usługi skonfigurowany został agent z włączoną możliwością komunikacji głosowej (Interaction Mode = Voice). Dodatkowo stworzona została usługa sieciowa w technologii .NET 10, dająca możliwość ukrycia szczegółów agenta przed klientem oraz potencjalnie rozszerzająca możliwości zarządzania dostępem i konfiguracją aplikacji lub reguł biznesowych dla poszczególnych kont użytkowników bez konieczności „dotykania” zasobów Azure. Zastosowanie dodatkowej warstwy pośredniczącej w komunikacji umożliwia również potencjalną wymianę agenta w przyszłości bez konieczności zmian w konfiguracji aplikacji klienckiej.
Jako warstwę front-end zdecydowaliśmy się w tym przypadku na stworzenie kontrolki PCF (Power Apps Component Framework). Wspomniana technologia umożliwia łatwe osadzenie stworzonego kodu (ReactJS, Vite) wewnątrz różnych typów aplikacji Power Platform (Canvas, Model-Driven Apps, Power Pages) lub dość prostą konwersję do Power Platform Code App.
Dodatkowo wstępne estymacje implementacji omawianej funkcjonalności w oparciu o wspomniane usługi wykazały potencjalnie niższy koszt użytkowania niż w przypadku analogicznego rozwiązania zbudowanego w oparciu o komponenty low-code. No i co najważniejsze w końcu udało nam się uzyskać pożądany rezultat, czyli płynną rozmowę z niestandardowym agentem umożliwiającym tworzenie rekordów w Microsoft Dataverse z poziomu aplikacji mobilnej.
Rozdział 4: Czy to bezpieczne?
W kontekście bezpieczeństwa prezentowanego powyżej rozwiązania ważnymi kwestiami są na pewno uwierzytelnianie użytkowników oraz autoryzacja dostęp do danych w Microsoft Dataverse. W przypadku komunikacji aplikacji klienckiej z back-endem wykorzystaliśmy uwierzytelnianie oparte na Microsoft Entra ID oraz bibliotekę MSAL.js (Microsoft Authentication Library),która odpowiada za logowanie użytkownika i pozyskiwanie tokenów dostępu. Podejście to daje możliwość kontroli dostępu do zasobu z poziomu katalogu chmurowego, uniemożliwia dostęp do aplikacji użytkownikom spoza organizacji, a także zapewnia funkcjonalność jednokrotnego logowania (SSO). Z kolei usługa sieciowa stworzona w technologii .NET komunikuje się z agentem z wykorzystaniem zarządzanej tożsamości Azure (Azure Managed Identity). Konfiguracja dostępu oraz uprawnień pozostaje w tym przypadku po stronie zasobów sieciowych Azure oraz mechanizmu kontroli dostępu opartej na rolach (Azure RBAC).
Osobnym zagadnieniem pozostaje dostęp agenta do repozytorium Dataverse oraz znajdujących się w nim danych. Zapewne chcielibyśmy uniknąć sytuacji, w której agent głosowy dokonuje odczytu danych kolejnych klientów, nawet takich, do których nominalnie nie mamy dostępu. W naszym przypadku agent łączył się z Dataverse w kontekście własnej tożsamości (ponownie wykorzystującej mechanizm Azure Managed Identity) o ograniczonych uprawnieniach. Możemy wyobrazić sobie jednak scenariusz, w którym dostęp do rekordów Dataverse jest warunkowany faktycznymi uprawnieniami użytkownika uruchamiającego aplikację. W takim przypadku wymagane będzie zastosowanie uwierzytelniania „OAuth Identity Passthrough” oraz przekazywanie informacji o tożsamości użytkownika z aplikacji klienckiej poprzez back-end aż do agenta. Jest to na pewno kolejny scenariusz, który będziemy weryfikować w ramach prac nad omawianym rozwiązaniem.
Podsumowanie
Komunikacja głosowa z systemem CRM przestaje być wizją przyszłości i staje się realną alternatywą dla tradycyjnego interfejsu graficznego. Podejście headless CRM, w którym Microsoft Dataverse pełni rolę usługi udostępniającej dane, logikę biznesową i model bezpieczeństwa, pozwala swobodnie dobierać kanał interakcji – w tym agenta AI obsługującego głos.
Nasze doświadczenia pokazują jednak, że droga do działającego rozwiązania nie zawsze prowadzi przez najbardziej oczywiste narzędzia. Agent zbudowany w Copilot Studio nie oferował w dostępnych kanałach publikacji wygodnej rozmowy głosowej, a aplikacja Canvas zintegrowana z usługą Azure Speech okazała się zbyt wolna z powodu opóźnień komunikacji opartej na protokole HTTP. Ostatecznie najlepiej sprawdziło się połączenie agenta głosowego w Microsoft Foundry oraz niestandardowych aplikacji stworzonych w technologiach .NET i JavaScript/PCF. Omawiane rozwiązanie zapewniło pożądaną płynność rozmowy i elastyczność przy ewentualnej wymianie agenta, a według wstępnych estymacji także niższy koszt użytkowania niż rozwiązanie low-code.
Równie istotnym elementem projektu pozostaje bezpieczeństwo. Uwierzytelnianie oparte na Microsoft Entra ID, wykorzystanie Azure Managed Identity oraz ograniczone uprawnienia agenta w Dataverse stanowią solidną podstawę. Docelowo warto jednak rozważyć przekazywanie tożsamości użytkownika aż do agenta (OAuth Identity Passthrough), tak aby dostęp do danych odzwierciedlał faktyczne uprawnienia osoby korzystającej z aplikacji. Jest to kierunek, który będziemy rozwijać w kolejnych etapach prac.
Płynną rozmowę głosową z danymi w Microsoft Dataverse zapewniło dopiero połączenie agenta głosowego w Microsoft Foundry z niestandardową usługą .NET i kontrolką PCF, bo Copilot Studio nie obsługuje czatu głosowego w swoich kanałach, a aplikacja Canvas z Azure Speech działała ze zbyt dużymi opóźnieniami. Przy wyborze architektury równie ważne jak płynność rozmowy jest bezpieczeństwo: uwierzytelnianie w Microsoft Entra ID, ograniczone uprawnienia agenta, a docelowo przekazywanie tożsamości użytkownika aż do agenta (OAuth Identity Passthrough).
Masz podobne wyzwanie?

Jeden mail miesięcznie, tylko konkrety
Co się dzieje w Dynamics, Power Platform i Copilot — bez marketingowego ozdobnika.

