SharePoint-Listen als Wissensquelle in Copilot Studio nutzen

Andreas Nigg
Andreas Nigg · Mitgründer, Pondhouse Data
Veröffentlicht Aktualisiert 10 Min. Lesezeit
SharePoint-Listen als Wissensquelle in Copilot Studio nutzen
Inhalt

Microsoft Copilot Studio unterstützt SharePoint als Wissensquelle, SharePoint-Listen aber nur sehr eingeschränkt: Eine Liste lässt sich nur als Ganzes laden. Der Workaround in diesem Tutorial: Der Agent bekommt zwei Tools vom Typ Agent-Flow. Das erste liest die internen Spaltennamen der Liste über die SharePoint-REST-API. Das zweite führt eine OData-Abfrage aus, die der Agent selbst formuliert, und liefert nur die Listenelemente und Spalten, die er zur Beantwortung der Frage braucht.

Warum nicht einfach die ganze Liste laden? Hat Ihre Liste Tausende Einträge, lädt der Agent sie alle in seinen Kontext, und das führt höchstwahrscheinlich zu schlechten Antworten. Noch schlimmer: Ist die Liste zu groß, schneidet Copilot Studio sie ab, damit der Kontext des Agenten nicht überläuft, und dabei gehen viele Informationen verloren.

In den folgenden Schritten zeige ich, wie Sie beide Agent-Flows bauen, mit einem Agenten in Copilot Studio verbinden und testen, ob der Agent Fragen aus dem Inhalt der Liste beantwortet.

Voraussetzungen

Sie brauchen nur eine SharePoint-Liste. Viel mehr gibt es nicht vorzubereiten.

Für diesen Leitfaden habe ich eine Liste mit Maschinenalarmen angelegt: die häufigsten Alarme eines Maschinentyps und ihre Lösungen.

Die Liste machine_alarms_1000 mit Alarm-ID, Alarmtext, Maschinenteil und Lösung

Tutorial: SharePoint-Listen als Wissensquelle für Agenten in Copilot Studio

Vor den eigentlichen Schritten kurz die Grundidee. SharePoint-Listen bringen einen API-gesteuerten Abfrage- und Filtermechanismus mit, mit dem Sie gezielt einzelne Elemente einer Liste abrufen. Technisch gesprochen unterstützt SharePoint OData-Abfrageparameter, um Listenelemente zu filtern und abzufragen. Um einen Ausschnitt einer Liste abzurufen, brauchen wir nur:

  1. die ID oder den Namen der Liste

  2. die ID der SharePoint-Website, auf der die Liste liegt

  3. die internen Spalten-IDs der Liste

Mit diesen drei Angaben kann eine HTTP-Anfrage in einem Agent-Flow von Copilot Studio gezielt Elemente der Liste abrufen und sie dem Agenten als Wissen übergeben.

Einen Haken gibt es: Die internen Spalten-IDs einer Liste zu erraten ist ziemlich mühsam, und ändert sich die Liste einmal, müssten Sie alle Ihre Agenten von Hand anpassen. Zum Glück gibt es dafür einen praktischen Trick. Der Endpunkt /fields der SharePoint-API liefert alle Felder einer Liste samt ihren internen IDs, und mit diesem Ergebnis kann der Agent die eigentliche Datenabfrage zusammenbauen.

Zwei HTTP-Anfragen: zuerst die Felder der Liste abrufen, dann die per OData gefilterten Listenelemente

Wie das Diagramm zeigt, verwenden wir zwei HTTP-Anfragen:

  1. Die erste Anfrage ruft die Felder der Liste und ihre internen IDs ab.
  2. Die zweite Anfrage nutzt diese Feld-IDs, um die eigentlichen Listenelemente abzurufen, gefiltert nach dem, was der Agent braucht.

So kann der Agent dynamisch filtern und nur die Zeilen und Spalten abrufen, die er wirklich braucht.

Noch ein Punkt: Wir führen nicht beide HTTP-Anfragen in einem Flow aus, sondern legen zwei Tools an:

  • Das erste Tool ruft die Feld-IDs (Spalten-IDs) ab.
  • Das zweite Tool nutzt sie, um die eigentlichen Daten abzurufen.

Warum zwei Tools statt einem? Weil der Agent dann die Abfrage des zweiten Tools ändern kann, wenn er keine Ergebnisse bekommt. Hat er zum Beispiel eine falsche Filterabfrage geschrieben, führt er das zweite Tool einfach mit einer anderen noch einmal aus.

Ein Tool, das die internen Namen und IDs der Listenspalten abruft

Zuerst richten wir das erste Tool ein.

  1. Legen Sie einen neuen Agenten an und geben Sie Titel, Beschreibung und Anweisungen ein. Orientieren Sie sich am Screenshot unten.

    Einen neuen Agenten in Copilot Studio anlegen

  2. Fügen Sie ein Tool hinzu und wählen Sie Agent Flow (in der deutschen Oberfläche "Agent-Flow").

    Agent Flow als Typ des neuen Tools auswählen

  3. Klicken Sie im Designer des Agent-Flows auf die erste Karte und fügen Sie eine Texteingabe hinzu:

    Texteingaben hinzufügen (Hinweis: Sie brauchen nur die Eingabe list-name)

    • list-name: der Name der SharePoint-Liste, die wir abfragen wollen. Haben Sie nur eine Liste, können Sie diese Eingabe weglassen und den Listennamen unten fest in die HTTP-Anfragen schreiben. Ich würde ihn trotzdem konfigurierbar halten, weil der Agent dadurch flexibler und wiederverwendbar wird.

    Im Screenshot sehen Sie eine zweite Eingabe, natural-language-query. Der Flow verwendet sie nie, Sie können sie also weglassen. Im Screenshot zur Berechtigungsabfrage im Abschnitt zum Testen taucht sie trotzdem als Eingabe des Tools auf, weil mein Test-Flow sie hatte.

  4. Klicken Sie unten auf das Symbol + und wählen Sie die Aktion Send HTTP Request to SharePoint (deutsch "HTTP-Anforderung an SharePoint senden"). Klicken Sie auf Sign In ("Anmelden") und melden Sie sich mit Ihrem Konto für Microsoft 365 an.

  5. In dieser Karte für die HTTP-Anfrage legen Sie drei Dinge fest:

    • die Adresse der SharePoint-Website (Websiteadresse)
    • die Methode der Anfrage
    • den URI des Endpunkts

    Wählen Sie als Websiteadresse im Dropdown die Website aus, auf der Ihre Liste liegt. Als Methode wählen Sie GET. Als URI des Endpunkts tragen Sie Folgendes ein:

     _api/web/lists/getbytitle('@{triggerBody()?['text']}')/fields?$select=Title,InternalName,TypeAsString&$filter=CanBeDeleted eq true or InternalName eq 'ID'
    

    Hinweis: text verweist auf die Texteingabe aus Schritt 3, die den Namen der Liste enthält. Haben Sie diese Eingabe weggelassen, schreiben Sie den Listennamen stattdessen fest in den URI:

     _api/web/lists/getbytitle('My List Name')/fields?$select=Title,InternalName,TypeAsString&$filter=CanBeDeleted eq true or InternalName eq 'ID'
    

    Legen Sie weitere Texteingaben an, heißt die zweite text_1 und so weiter.

    Diese erste Anfrage ruft alle Felder der angegebenen SharePoint-Liste ab. Die Antwort sieht so aus:

    1{
    2 "d": {
    3 "results": [
    4 {
    5 "__metadata": {
    6 "id": "https://pondhousedataog.sharepoint.com/_api/Web/Lists(guid'dd00d367-461f-402a-b954-6c1127917e3c')/Fields(guid'286a5897-dcd7-41a3-a6bb-e9943e9f339c')",
    7 "uri": "https://pondhousedataog.sharepoint.com/_api/Web/Lists(guid'dd00d367-461f-402a-b954-6c1127917e3c')/Fields(guid'286a5897-dcd7-41a3-a6bb-e9943e9f339c')",
    8 "type": "SP.FieldText"
    9 },
    10 "InternalName": "field_1",
    11 "Title": "Alarm Text",
    12 "TypeAsString": "Text"
    13 },
    14 {
    15 "__metadata": {
    16 "id": "https://pondhousedataog.sharepoint.com/_api/Web/Lists(guid'dd00d367-461f-402a-b954-6c1127917e3c')/Fields(guid'3ff75d29-d0f9-439f-9246-46dac677bd05')",
    17 "uri": "https://pondhousedataog.sharepoint.com/_api/Web/Lists(guid'dd00d367-461f-402a-b954-6c1127917e3c')/Fields(guid'3ff75d29-d0f9-439f-9246-46dac677bd05')",
    18 "type": "SP.FieldText"
    19 },
    20 "InternalName": "field_2",
    21 "Title": "Machine Part",
    22 "TypeAsString": "Text"
    23 },
    24 {
    25 "__metadata": {
    26 "id": "https://pondhousedataog.sharepoint.com/_api/Web/Lists(guid'dd00d367-461f-402a-b954-6c1127917e3c')/Fields(guid'9c1fc378-c5df-43d7-99a0-8088599862db')",
    27 "uri": "https://pondhousedataog.sharepoint.com/_api/Web/Lists(guid'dd00d367-461f-402a-b954-6c1127917e3c')/Fields(guid'9c1fc378-c5df-43d7-99a0-8088599862db')",
    28 "type": "SP.FieldText"
    29 },
    30 "InternalName": "field_3",
    31 "Title": "Solution",
    32 "TypeAsString": "Text"
    33 }
    34 ]
    35 }
    36}
  6. Als Nächstes lesen wir die internen Namen aus der Antwort aus. Das ist etwas lästig, aber nicht schlimm. Fügen Sie unter der HTTP-Anfrage die Aktion Parse JSON ("JSON analysieren") ein.

    Fügen Sie das JSON aus Schritt 5 als Beispiel ein, um daraus das Schema zu erzeugen. Meine Beispielantwort funktioniert unabhängig davon, welche Spalten Ihre Liste hat, weil alle Antworten dieselbe Struktur haben.

    Das Schema für Parse JSON aus einer Beispielantwort erzeugen

    Klicken Sie auf Done ("Fertig"). Die Karte zum Analysieren des JSON sollte jetzt so aussehen:

    Die fertig konfigurierte Karte Parse JSON

  7. Die Antwort ist jetzt ein strukturiertes JSON-Objekt. Wir wollen daraus nur die Daten, die wir brauchen: die internen Spaltennamen und ihre Anzeigenamen. Dafür fügen Sie darunter die Aktion Select ("Auswählen") ein.

    Klicken Sie auf das Blitz-Symbol und wählen Sie aus der Aktion Parse JSON den Eintrag Body results.

    Body results aus dem dynamischen Inhalt von Parse JSON auswählen

    Legen Sie dann im Bereich Map drei neue Felder an:

    • InternalName: ordnen Sie Body internalName aus dem dynamischen Inhalt zu
    • Title: ordnen Sie Body title aus dem dynamischen Inhalt zu (klicken Sie auf see more, um den Eintrag zu finden)
    • Type: ordnen Sie Body type aus dem dynamischen Inhalt zu

    Internen Namen, Titel und Typ in der Aktion Select zuordnen

    Ihre Karte Select sollte jetzt so aussehen:

    Die fertige Karte Select

    Zur Orientierung: So sieht die Ausgabe der Karte Select aus:

    1{
    2 "body": [
    3 {
    4 "InternalName": "field_1",
    5 "Title": "https://pondhousedataog.sharepoint.com/_api/Web/Lists(guid'dd00d367-461f-402a-b954-6c1127917e3c')/Fields(guid'286a5897-dcd7-41a3-a6bb-e9943e9f339c')",
    6 "Type": "SP.FieldText"
    7 },
    8 {
    9 "InternalName": "field_2",
    10 "Title": "https://pondhousedataog.sharepoint.com/_api/Web/Lists(guid'dd00d367-461f-402a-b954-6c1127917e3c')/Fields(guid'3ff75d29-d0f9-439f-9246-46dac677bd05')",
    11 "Type": "SP.FieldText"
    12 },
    13 {
    14 "InternalName": "field_3",
    15 "Title": "https://pondhousedataog.sharepoint.com/_api/Web/Lists(guid'dd00d367-461f-402a-b954-6c1127917e3c')/Fields(guid'9c1fc378-c5df-43d7-99a0-8088599862db')",
    16 "Type": "SP.FieldText"
    17 }
    18 ]
    19}

    Alles, was wir nicht brauchen, fällt weg, und pro Listenspalte bleiben drei Werte übrig.

    Genau diese Informationen bekommt ein Agent, wenn er diesen Flow aufruft.

  8. Füllen Sie zum Schluss die Karte Respond to the Agent ("Dem Agent antworten") aus. Klicken Sie auf Add output ("Ausgabe hinzufügen"), wählen Sie Text und tragen Sie ein:

    • Name: list-field-ids

    • Description: Internal SharePoint list field ids, use to find which column

    • Value: ordnen Sie Output aus der Karte Select zu

      Die Ausgabe list-field-ids in der Karte Respond to the Agent

Veröffentlichen Sie jetzt Ihren Agent-Flow. Wenn Sie möchten, klicken Sie auf "Test", um den Flow auszuführen und die Ausgaben der einzelnen Karten zu sehen. Klicken Sie in einem Testlauf auf der letzten Karte auf Show raw inputs, sollten Sie in etwa Folgendes sehen:

Testlauf: Die list-field-ids gehen an den Agenten zurück

Wechseln Sie in den Bereich Tools Ihres Agenten und geben Sie diesem Tool einen aussagekräftigen Namen und eine Beschreibung. Wir verwenden:

  • Name: Sharepoint list alarms - fetch ids
  • Description: Use this tool to fetch the internal column ids of the SharePoint list, which are required to query the list items. The output will be a list of column names, their respective internal ids and types. Follow up this tool with the 'Sharepoint list alarms - fetch data' tool.

Ein Tool, das gefilterte Elemente aus einer SharePoint-Liste abruft

Mit den internen Spaltennamen kann das zweite Tool jetzt die eigentlichen, vorgefilterten Listenelemente abrufen.

  1. Gehen Sie zurück zu Ihrem Agenten, fügen Sie ein weiteres Tool hinzu und wählen Sie wieder Agent Flow.

  2. Legen Sie im Designer des Agent-Flows eine Eingabe an:

    • odata-rest-api-query: die OData-Abfrage, mit der wir die Listenelemente filtern. Als Beschreibung verwenden Sie OData REST API query, starting with '_api'.

    Die Eingabe odata-rest-api-query des zweiten Agent-Flows

    Hinweis: Woher kommt die odata-rest-api-query? Der KI-Agent erzeugt sie selbst, auf Basis der Anweisungen, die wir später in die Beschreibung des Tools schreiben. Deshalb braucht dieses Tool auch die Feld-IDs aus dem ersten Tool nicht als Eingabe: Der Agent sieht alle Ergebnisse seiner Tools und kann sie direkt verwenden.

  3. Fügen Sie wie beim ersten Tool die Aktion Send HTTP Request to SharePoint ein. Melden Sie sich an, falls noch nicht geschehen.

    Verwenden Sie dieselbe Websiteadresse und Methode wie beim ersten Tool. Als URI des Endpunkts wählen Sie die Eingabe odata-rest-api-query aus dem dynamischen Inhalt.

    Karte für die HTTP-Anfrage mit der Eingabe odata-rest-api-query als URI

  4. Verbinden Sie zum Schluss die Ausgabe der HTTP-Aktion mit der Karte Respond to the Agent. Fügen Sie wie beim ersten Tool eine neue Ausgabe vom Typ Text hinzu, mit diesen Einstellungen:

    • Name: list-data
    • Description: The retrieved list items based on the provided OData query
    • Value: ordnen Sie Body aus der Karte HTTP zu

Veröffentlichen Sie auch diesen Agent-Flow.

Geben Sie auch diesem Tool im Bereich Tools Ihres Agenten einen aussagekräftigen Namen und eine Beschreibung:

  • Name: Sharepoint list alarms - fetch data

  • Description: Use this tool to fetch specific list items from the SharePoint list. Make sure to use the internal column names retrieved from the 'Sharepoint list alarms - fetch ids' tool when creating your OData query, so always first run the 'fetch ids' tool to get the column names and their respective internal names. This tool requires the odata-rest-api-query input, which should be an OData REST API query starting with _api.

    Feel free to run this tool multiple times with different OData filters, if you don't get the information you need with the first query.

    Do not filter too strictly (eg. don't use 'eq' for text columns), as you might filter out relevant information. Always prefer broader and more fuzzy filters.

Die Beschreibung weist den Agenten also an, das Tool ruhig mehrmals mit unterschiedlichen OData-Filtern aufzurufen und nicht zu streng zu filtern (etwa kein eq bei Textspalten), sondern breite, unscharfe Filter zu bevorzugen.

Klicken Sie im Bereich Inputs ("Eingaben") des Tools auf Customize ("Anpassen") und fügen Sie diese Beschreibung ein:

OData REST API query, starting with '\_api'.

You can create such a request as follows:

1. Start the URI with \_api/web/lists/getbytitle('machine_alarms_1000').
   Without leading '/'.
1. Append an ODATA filter query which is used to answer the user's
   question. This should pre-filter the sharepoint list according the
   users needs.
1. in a $select url parameter, include the sharepoint list columns as
   defined below. Make sure to include all columns which might be
   required to answer the users question and use the correct data types.
1. Return a single line of text being the sharepoint REST URI.

  Do not filter too strictly (eg. don't use 'eq' for text columns), as you
  might filter out relevant information. Always prefer boader and more
  fuzzy filters.

  The Alarm number is the ID column.

Beschreibung der Eingabe für das Tool fetch data in Copilot Studio

Prüfen Sie, ob Ihr Agent jetzt beide Tools hat:

Übersicht der Tools des Agenten mit beiden SharePoint-Listen-Tools

Den Agenten für die SharePoint-Liste testen

Um den Agenten zu testen, klicken Sie auf der Übersichtsseite des Agenten oben links auf "Test" ("Testen"). Dadurch öffnet sich der Testbereich, eine Chat-Oberfläche, in der Sie mit Ihrem Agenten sprechen und sehen, wie er antwortet.

Stellen Sie eine Frage, von der Sie wissen, dass Ihre SharePoint-Liste sie beantworten kann. Für Zusatzpunkte wählen Sie eine, die nur Einträge aus der unteren Hälfte Ihrer Liste beantworten können. So sehen Sie, ob die Filterung wirklich funktioniert, denn sonst könnte der Agent schummeln und einfach die ganze Liste abrufen.

Wenn der Agent beim Testen zum ersten Mal ein Tool verwenden will, fragt er nach der Berechtigung, sich mit SharePoint zu verbinden. Erlauben Sie den Zugriff mit "Allow".

Copilot Studio fragt nach der Berechtigung, sich mit SharePoint zu verbinden

Die Ergebnisse sind so, wie ich es mir erhofft hatte. Der Agent hat zuerst das Tool Sharepoint list alarms - fetch ids verwendet, um die internen Spaltennamen abzurufen. Danach hat er mit dem Tool Sharepoint list alarms - fetch data und einer selbst erzeugten OData-Abfrage die passenden Listenelemente abgerufen. Im Screenshot unten geht es um den Alarm ALM-0294: Der Agent hat die Liste mit substringof über die drei Textspalten und die ID gefiltert, das Ergebnis auf 10 Einträge begrenzt und mit Schritten zur Fehlerbehebung für diesen Alarm geantwortet.

Test des Agenten: Beide Tools liefen, und der Agent hat aus dem Listenelement geantwortet

Hinweis: Wie immer bei Copilot-Agenten lohnt es sich, an den Beschreibungen der Tools zu feilen. Es kann helfen, die einzelnen Spalten der SharePoint-Liste in der Beschreibung des Tools zu erklären.

Wenn Sie diesen Ansatz mit Agenten vergleichen möchten, die in Code gebaut werden, lesen Sie unseren Leitfaden zum Microsoft Agent Framework.

Die beiden Tools funktionieren gut für strukturierte Listenelemente. Liegt das Wissen dagegen in Dokumenten, passt ein Suchindex besser, wie in unserem RAG-Tutorial mit Azure AI Search. Sie planen einen Agenten auf Basis Ihrer eigenen SharePoint-Daten und wünschen sich eine zweite Meinung oder einen Prototyp? Werfen Sie einen Blick auf unsere KI-Beratung.

Sie möchten zuverlässige KI-Agenten-Systeme bauen?

Wir haben auf Basis aktueller Forschung einen ausführlichen Leitfaden (auf Englisch) erstellt, wie Sie robuste KI-Agenten-Systeme bauen, die auch im produktiven Betrieb funktionieren. Der Leitfaden behandelt:

  • die 14 systematischen Fehlerquellen in Multi-Agenten-Systemen
  • belegte Best Practices für das Design von Agenten
  • strukturierte Kommunikationsprotokolle und Prüfmechanismen

Weiterlesen

Andreas Nigg

Über den Autor

Andreas Nigg

Mitgründer, Pondhouse Data

Andreas entwickelt seit mehr als acht Jahren Datenanwendungen. Bei Pondhouse Data konzipiert und baut er KI-Systeme und integriert sie in komplexe, gewachsene Unternehmensumgebungen.