7  Χρήση του API συνομιλίας του Nous

Χρησιμοποιήστε το API συνομιλίας του Nous για να στείλετε μια ερώτηση από δικό σας πρόγραμμα ή εφαρμογή σε έναν Χώρο εργασίας Nous. Το αίτημα ξεκινά συνομιλία με το μοντέλο που έχει ρυθμιστεί για τον Χώρο εργασίας. Μπορεί να χρησιμοποιήσει τη γνώση και τους agents στους οποίους έχει πρόσβαση ο κάτοχος του διακριτικού.

7.1 Αποκτήστε διακριτικό και διεύθυνση Χώρου εργασίας

Δημιουργήστε ένα προσωπικό διακριτικό API ή ζητήστε από διαχειριστή Χώρου εργασίας ένα διακριτικό λογαριασμού υπηρεσίας, αν μια ενσωμάτωση χρειάζεται δική της ταυτότητα. Αντιγράψτε το διακριτικό όταν εμφανιστεί και χρησιμοποιήστε τη διεύθυνση Nous αυτού του Χώρου εργασίας. Το προσωπικό διακριτικό ενεργεί ως ο κάτοχός του, ενώ το διακριτικό υπηρεσίας ενεργεί ως ο αντίστοιχος λογαριασμός. Κανένα δεν παρέχει πρόσβαση σε έγγραφα ή agents πέρα από τα δικαιώματα της ταυτότητάς του.

Ορίστε τις παρακάτω τιμές στο τερματικό σας, αντικαθιστώντας το διακριτικό. Το https://nous.sophea.ai είναι το NOUS_URL για την παραγωγική εγκατάσταση· σε άλλη εγκατάσταση χρησιμοποιήστε τη διεύθυνση Nous του αντίστοιχου Χώρου εργασίας. Μην αποθηκεύετε το διακριτικό στον πηγαίο κώδικα ή σε κοινόχρηστα αρχεία καταγραφής.

NOUS_URL='https://nous.sophea.ai'
NOUS_TOKEN='<paste-your-token>'

curl -sS -X GET "$NOUS_URL/api/me" \
  -H "Authorization: Bearer $NOUS_TOKEN"

Το GET /api/me ελέγχει το διακριτικό και την ταυτότητα στον Χώρο εργασίας. Στο Power Automate, χρησιμοποιήστε ενέργεια HTTP με μέθοδο GET, αυτό το URI, την κεφαλίδα Bearer token και χωρίς σώμα. Αν δεν επιστρέψει την αναμενόμενη ταυτότητα, ελέγξτε το διακριτικό και τη διεύθυνση του Χώρου εργασίας πριν στείλετε αίτημα συνομιλίας.

7.2 Στείλτε το πρώτο μήνυμα

Αυτό το αίτημα ξεκινά συνομιλία με τον προεπιλεγμένο agent. Το message είναι η ερώτηση ή η οδηγία που θέλετε να απαντήσει ο βοηθός.

Για ροές cloud του Power Automate, χρησιμοποιήστε τις οδηγίες υποβολής και διαδοχικών ελέγχων, όχι μια ενέργεια HTTP που περιμένει συγχρονισμένα ολόκληρη την απάντηση. Το παρακάτω παράδειγμα παραμένει χρήσιμο για πελάτες που περιμένουν την πλήρη απάντηση.

Αν ένας τέτοιος πελάτης μπορεί να σταματήσει να περιμένει πριν ολοκληρωθεί η απάντηση, χρησιμοποιήστε το ασύγχρονο API ή το υπάρχον μοτίβο ανάκτησης με γνωστό ID συνομιλίας.

curl -sS -X POST "$NOUS_URL/api/chat/send-chat-message" \
  -H "Authorization: Bearer $NOUS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Συνοψίστε την πολιτική εισαγωγής μας",
    "knowledge_search_enabled": true,
    "stream": false
  }'

Το knowledge_search_enabled: true επιτρέπει στον agent να αναζητήσει, όταν χρειάζεται, σε ευρετηριασμένες πηγές στις οποίες έχει πρόσβαση ο κάτοχος του διακριτικού. Δεν επιβάλλει αναζήτηση. Χρειάζεται επίσης ενεργό εργαλείο αναζήτησης και κατάλληλο εύρος γνώσης. Το stream: false επιστρέφει μία απόκριση JSON, πιο εύχρηστη για μια πρώτη ενσωμάτωση.

7.3 Επιλέξτε παραμέτρους αιτήματος

Πεδίο Τι κάνει Αν παραλειφθεί
message Το μήνυμα προς τον βοηθό. Υποχρεωτικό. Το αίτημα είναι άκυρο.
knowledge_search_enabled Το true επιτρέπει στον agent να αναζητήσει σε επιτρεπόμενη γνώση όταν είναι χρήσιμο· το false απενεργοποιεί την αυτόματη αναζήτηση. Δεν ζητείται αναζήτηση γνώσης.
stream Το false επιστρέφει μία απόκριση JSON· το true επιστρέφει αντικείμενα JSON, ένα ανά γραμμή. true: η απόκριση είναι ροή γραμμών JSON, όχι ένα αντικείμενο JSON.
chat_session_info Ξεκινά νέα συνομιλία. Προσθέστε {"persona_id":123} για να επιλέξετε διαθέσιμο agent. Ξεκινά νέα συνομιλία με τον προεπιλεγμένο agent, εφόσον παραλείπεται και το chat_session_id.
chat_session_id Συνεχίζει υπάρχουσα συνομιλία με το ID που επέστρεψε προηγούμενη απόκριση. Ξεκινά νέα συνομιλία, εφόσον παραλείπεται και το chat_session_info.
include_citations Το false αφαιρεί τις παραπομπές από το κείμενο της απάντησης. true: περιλαμβάνονται παραπομπές όταν είναι διαθέσιμες.

Στείλτε είτε chat_session_info είτε chat_session_id, ποτέ και τα δύο στο ίδιο αίτημα. Για συνήθη χρήση, ξεκινήστε με το πρώτο παράδειγμα και προσθέστε παράμετρο μόνο όταν τη χρειάζεστε.

Με stream: true, ο τύπος περιεχομένου HTTP είναι text/event-stream, αλλά το σώμα περιέχει JSON σε ξεχωριστές γραμμές αντί για συμβάντα data:. Διαβάστε κάθε γραμμή ως ένα αντικείμενο JSON.

7.4 Διαβάστε την απόκριση

Με stream: false, η απόκριση JSON περιλαμβάνει την απάντηση. Η πρώτη απόκριση μιας νέας συνομιλίας περιλαμβάνει επίσης το chat_session_id. Αποθηκεύστε αυτό το ID και συνεχίστε να το χρησιμοποιείτε στα επόμενα μηνύματα· οι επόμενες αποκρίσεις μπορεί να περιέχουν "chat_session_id": null. Ακολουθεί απόσπασμα· τα αντικείμενα εγγράφων περιέχουν περισσότερα πεδία στην πραγματική απόκριση.

{
  "answer": "Η πολιτική απαιτεί επικοινωνία την πρώτη εβδομάδα. [1]",
  "chat_session_id": "cba35529-7e57-4c57-8f84-0c9733277f5c",
  "message_id": 42,
  "top_documents": [
    {
      "document_id": "onboarding-policy",
      "semantic_identifier": "Πολιτική εισαγωγής"
    }
  ],
  "citation_info": [
    {
      "type": "citation_info",
      "citation_number": 1,
      "document_id": "onboarding-policy"
    }
  ],
  "error_msg": null,
  "error_code": null,
  "error_is_retryable": null,
  "stop_reason": null
}

Το top_documents περιέχει πηγές που ανακτήθηκαν και το citation_info συνδέει αριθμημένες παραπομπές με έγγραφα. Μια απάντηση μπορεί να μην έχει παραπομπές αν ο agent δεν ανέκτησε πηγή.

Το HTTP 200 από μόνο του δεν σημαίνει ότι η απάντηση ολοκληρώθηκε. Πριν χρησιμοποιήσετε το answer, ελέγξτε τα error_msg, error_code και stop_reason. Η κανονική ολοκλήρωση JSON έχει τιμές null στα σφάλματα και στο stop_reason, αφού αποθηκευτεί η οριστική απάντηση. Μια έγκυρη αποθηκευμένη απάντηση μπορεί να είναι κενή. Το "stop_reason": "user_cancelled" σημαίνει διακοπή παραγωγής, όχι κανονική ολοκλήρωση. Αποτυχημένη ή αβέβαιη ολοκλήρωση επιστρέφει δομημένο σφάλμα και κενό answer.

Για stream: true, θεωρήστε τα τμήματα της απάντησης προσωρινά και συνεχίστε την ανάγνωση μέχρι να τελειώσει η ροή χωρίς σφάλμα μεταφοράς ή απόκρισης. Η κανονική ολοκλήρωση απαιτεί και τα τρία:

  1. Τελικό αποθηκευμένο μήνυμα που αντιστοιχεί στο δεσμευμένο assistant message_id και στη συνομιλία. Αναγνωρίστε τα υπάρχοντα πεδία του, όπως message_type: "assistant", message και files· δεν έχει πεδίο διάκρισης type.
  2. Πακέτο stop για το συγκεκριμένο μοντέλο, με null ή χωρίς stop_reason.
  3. Τέλος της ροής χωρίς σφάλμα και χωρίς νέο τμήμα απάντησης μετά το Stop.

Ο διακομιστής στέλνει το τελικό μήνυμα πριν από το Stop. Δεχτείτε οποιαδήποτε σειρά κατά την ανάγνωση, αλλά μη σταματάτε στο Stop: μεταγενέστερο σφάλμα ακυρώνει την υποψήφια ολοκλήρωση. Μόνο τελικό μήνυμα, μόνο Stop, διακοπή, άγνωστος λόγος και μερική ροή δεν αποτελούν κανονική επιτυχία.

Το CHAT_COMPLETION_FAILED σημαίνει ότι δεν επιβεβαιώθηκε η ολοκλήρωση της απάντησης. Το CHAT_RESPONSE_UNAVAILABLE σημαίνει ότι η απάντηση αποθηκεύτηκε, αλλά δεν επιστράφηκαν τα τελικά στοιχεία της. Και τα δύο έχουν ένδειξη επανάληψης false. Ανοίξτε ξανά τη συνομιλία ή ανακτήστε τη με GET /api/chat/get-chat-session/<chat_session_id> πριν στείλετε άλλο μήνυμα· μην επαναλαμβάνετε αυτόματα ένα αβέβαιο αίτημα. Αυτός ο έλεγχος δεν προσθέτει ανθεκτική ανάκτηση μετά από απώλεια διεργασίας ούτε εγγυάται μία και μόνο εκτέλεση εξωτερικών ενεργειών.

Οι χρόνοι απάντησης στη συνομιλία ιστού διακρίνουν την προετοιμασία από την επιτυχημένη ολοκλήρωση της επεξεργασίας στον διακομιστή. Κανένας από τους δύο δεν είναι η διάρκεια του αιτήματος HTTP. Το ChatFullResponse δεν προσθέτει πεδίο συνολικής διάρκειας αιτήματος.

7.5 Υποβάλετε έναν γύρο και ελέγξτε το αποτέλεσμά του

Χρησιμοποιήστε αυτόν τον προαιρετικό τρόπο επικοινωνίας για συνήθεις συνομιλίες με ένα μοντέλο, όταν ο πελάτης σας δεν πρέπει να περιμένει ολόκληρη την απάντηση σε ένα αίτημα HTTP. Τα υπάρχοντα συγχρονισμένα endpoints και τα endpoints ροής παραμένουν αμετάβλητα.

Το POST /api/chat/send-chat-message-async δέχεται τις υπάρχουσες παραμέτρους συνομιλίας, αλλά απορρίπτει το deep_research: true. Το πεδίο llm_overrides, που έχει καταργηθεί, αγνοείται αν σταλεί και η απάντηση δίνεται από ένα μόνο μοντέλο. Το μεμονωμένο llm_override, η επιτρεπόμενη αναζήτηση γνώσης, τα εργαλεία/MCP, τα αρχεία, οι παραπομπές, τα έργα και το προσωρινό περιεχόμενο διατηρούν την υπάρχουσα συμπεριφορά τους. Το παλιό πεδίο stream δεν επηρεάζει αυτή την απόκριση: η παραγωγή διαβάζεται εσωτερικά ως ροή, ενώ η απόκριση HTTP είναι πάντα JSON.

Και τα δύο νέα endpoints απαιτούν ταυτοποιημένο χρήστη στον τρέχοντα Χώρο εργασίας. Αν δοθεί chat_session_id, πρέπει να αντιστοιχεί σε μη διαγραμμένη συνομιλία που ανήκει στην ίδια ταυτότητα. Η δημόσια κοινοποίηση, η συμμετοχή σε έργο ή η πρόσβαση διαχειριστή σε συνομιλία άλλου κατόχου δεν καλύπτουν αυτή την απαίτηση. Μπορείτε επίσης να ξεκινήσετε νέα συνομιλία με το υπάρχον chat_session_info ή παραλείποντας και τα δύο πεδία συνομιλίας. Για ενσωματώσεις, δημιουργήστε πρώτα ξεχωριστή συνομιλία και αποθηκεύστε το ID της, ώστε να μπορείτε να ελέγξετε μια αβέβαιη υποβολή. Στέλνετε τους γύρους διαδοχικά· το API δεν προσθέτει εγγυήσεις σειράς για ταυτόχρονους πελάτες.

Στείλτε αντικείμενο JSON με το διακριτικό Bearer και Content-Type: application/json, για παράδειγμα:

{
  "chat_session_id": "cba35529-7e57-4c57-8f84-0c9733277f5c",
  "message": "Συνοψίστε την πολιτική εισαγωγής μας",
  "knowledge_search_enabled": true
}

Το HTTP 202 σημαίνει ότι τα ID και το σήμα ενεργής επεξεργασίας έχουν αποθηκευτεί οριστικά, όχι ότι ολοκληρώθηκε η παραγωγή. Ολόκληρο το σώμα της απόκρισης περιέχει αυτά τα πεδία:

{
  "chat_session_id": "cba35529-7e57-4c57-8f84-0c9733277f5c",
  "user_message_id": 41,
  "reserved_assistant_message_id": 42
}
Πεδίο Τύπος και σημασία
chat_session_id UUID της συνομιλίας που έγινε αποδεκτή.
user_message_id Ακέραιος ή null, ανάλογα με την υπάρχουσα συμπεριφορά του γύρου.
reserved_assistant_message_id Ακέραιος που προσδιορίζει το δεσμευμένο μήνυμα assistant. Αποθηκεύστε τον μαζί με το ID συνομιλίας.

Δεν υπάρχει απάντηση, ID εργασίας ή κεφαλίδα Location. Η απόκριση έχει Cache-Control: no-store· δεν παρέχει αυτόματους ελέγχους κατάστασης μέσω εγγενούς μηχανισμού HTTP.

Εκτελούνται το πολύ τέσσερις ασύγχρονοι καταναλωτές ανά διεργασία API, χωρίς ουρά αναμονής. Δεν πρόκειται για συνολικό όριο όλων των διακομιστών ούτε για όριο όλων των νημάτων παρόχων/εργαλείων. Αν δεν υπάρχει διαθέσιμη θέση, η υποβολή επιστρέφει HTTP 429 με Retry-After: 10 πριν δημιουργήσει αλλαγές στη συνομιλία. Η προετοιμασία έχει όριο αναμονής αποδοχής 30 δευτερολέπτων. Αν εξαντληθεί, η υποβολή επιστρέφει ασφαλές HTTP 503, όχι 202· μια καθυστερημένη αποδοχή δεν μπορεί να ξεκινήσει παραγωγή μοντέλου ή αποστολή σε εξωτερικό agent. Η προετοιμασία μπορεί ήδη να έχει προκαλέσει ενέργειες ή να έχει αποθηκεύσει δέσμευση μηνύματος. Άλλα σφάλματα επικύρωσης, πρόσβασης, ορίων χρήσης διακριτικού ή προετοιμασίας δεν αποτελούν αποδεκτούς γύρους. Μην επαναλαμβάνετε αυτόματα POST μετά από σφάλμα, λήξη χρονικού ορίου ή αβέβαιη απόκριση.

Μετά το 202, ανακτήστε το συγκεκριμένο μήνυμα assistant που έγινε αποδεκτό:

GET /api/chat/get-chat-message-result/<chat_session_id>/<reserved_assistant_message_id>

Οι ανακτήσεις με έγκυρη πρόσβαση επιστρέφουν HTTP 200, Cache-Control: no-store και όλα τα παρακάτω πεδία:

Πεδίο Τύπος και σημασία
chat_session_id UUID της συνομιλίας.
reserved_assistant_message_id Ακέραιος που προσδιορίζει αυτό το μήνυμα assistant.
status RUNNING, COMPLETED, FAILED ή CANCELLED.
result Το οριστικό αποθηκευμένο ChatMessageDetail μόνο για COMPLETED· διαφορετικά null. Περιλαμβάνει message, πηγές/παραπομπές, files και αποθηκευμένους χρόνους όταν υπάρχουν, όχι το παλιό πεδίο answer.
error Ασφαλές για τον καλούντα κείμενο σφάλματος για FAILED/CANCELLED· διαφορετικά null.
error_code Συμβολοσειρά κωδικού σφάλματος για FAILED/CANCELLED· διαφορετικά null.
error_is_retryable Λογική ένδειξη δυνατότητας επανάληψης ή null. Δεν αποτελεί άδεια επανάληψης αβέβαιου POST. Η ακύρωση, η διακοπή και η αβέβαιη ολοκλήρωση έχουν ένδειξη false.

Το RUNNING έχει null αποτέλεσμα και πεδία σφάλματος, ακόμη και όσο ένας επιλεγμένος agent παρασκηνίου παραμένει ενεργός. Χρησιμοποιήστε το result.message μόνο όταν το status είναι COMPLETED· μια κενή συμβολοσειρά είναι έγκυρη ολοκληρωμένη απάντηση. Τα FAILED και CANCELLED δεν έχουν αποτέλεσμα. Αν λείπουν στοιχεία ολοκλήρωσης ή υπάρχουν αντικρουόμενα στοιχεία, αναφέρεται αποτυχία και όχι επιτυχία βάσει του ορατού κειμένου.

Άκυρα αποτελέσματα, αποτελέσματα άλλου Χώρου εργασίας ή κατόχου, διαγραμμένες συνομιλίες ή αποτελέσματα με περιορισμένη πρόσβαση στις πηγές επιστρέφουν μη αποκαλυπτικό 404. Διαπιστευτήρια που λείπουν ή έχουν ανακληθεί διατηρούν τη συνήθη συμπεριφορά αποτυχίας ταυτοποίησης. Οι έλεγχοι κατάστασης δεν ξεκινούν παραγωγή, δεν επαναλαμβάνουν εργαλεία και δεν επιστρέφουν προσωρινό κείμενο ως ολοκληρωμένη απάντηση. Μόνο αυτό το endpoint αποτελέσματος εξαιρείται από την απόδοση λειτουργίας στη χρέωση συνομιλίας· η υποβολή παραμένει λειτουργία chat. Σε εγκαταστάσεις με επιβολή χρέωσης, χρησιμοποιήστε X-Sophea-Operation-ID στη δημιουργία, την υποβολή και την ανάκτηση πλήρους συνομιλίας. Προσδιορίζει τη λειτουργία και δεν είναι κλειδί idempotency.

Ο καταναλωτής συνεχίζει ανεξάρτητα από τη σύνδεση υποβολής όσο η διεργασία API παραμένει ενεργή. Η επανεκκίνηση δεν συνεχίζει τη συνήθη παραγωγή. Η υπάρχουσα ανάκτηση παλιών δεσμεύσεων μπορεί να αναφέρει FAILED με GENERATION_INTERRUPTED· αυτό δεν εγγυάται αμετάβλητη κατάσταση αν μια ενεργή διεργασία αποθήκευσης χάσει μόνο το σήμα επεξεργασίας της. Δεν προστίθεται endpoint ακύρωσης, ανθεκτική ουρά ή εγγύηση μίας και μόνο εκτέλεσης εξωτερικών ενεργειών. Η λήξη χρονικού ορίου ροής ή η αποσύνδεση πελάτη δεν αποδεικνύει ακύρωση. Κρατήστε τα ID και χρησιμοποιήστε την ανάκτηση με γνωστό ID συνομιλίας για έλεγχο αβέβαιης έκβασης, ποτέ για αυτόματη επανάληψη αποστολής.

7.6 Χρησιμοποιήστε ροή cloud του Power Automate

Αυτές είναι τεκμηριωμένες οδηγίες HTTP, ελεγμένες ως προς τη σύμβαση του API και τις παρακάτω πηγές της Microsoft, όχι εκτελεσμένη ή πιστοποιημένη ροή Power Automate. Χρησιμοποιούν ενέργειες cloud· δεν απαιτούν Windows ή Power Automate Desktop. Επιβεβαιώστε ότι η αδειοδότηση και οι πολιτικές του οργανισμού σας επιτρέπουν τη συνήθη ενέργεια HTTP και την πρόσβαση στη διεύθυνση του Χώρου εργασίας. Χρησιμοποιήστε Authorization: Bearer <token>, όχι τον connector HTTP with Microsoft Entra ID.

Ελέγξτε πρώτα το GET /api/me με αυτό το διακριτικό και τη διεύθυνση του Χώρου εργασίας, όπως περιγράφεται παραπάνω. Σταματήστε αν η ταυτότητα που επιστρέφεται δεν είναι ο επιθυμητός λογαριασμός. Χρησιμοποιήστε τον χώρο αποθήκευσης μυστικών του οργανισμού σας. Ενεργοποιήστε Secure Inputs και Secure Outputs, δηλαδή προστασία εισόδων και εξόδων, στις ενέργειες που χειρίζονται το διακριτικό ή το περιεχόμενο συνομιλίας, καθώς και σε Compose/μεταβλητές και ενέργειες ανάκτησης όπου εφαρμόζεται. Μην αποθηκεύετε διακριτικά στο αποθετήριο και μην εμφανίζετε κεφαλίδες σε στιγμιότυπα ή εξαγωγές ιστορικού εκτέλεσης.

1. Προετοιμάστε τη ροή και δημιουργήστε ξεχωριστή συνομιλία.

Αρχικοποιήστε μεταβλητές τύπου String: Nous_URL (τη βασική διεύθυνση του Χώρου εργασίας χωρίς τελική κάθετο), Chat_session_id (κενή) και Chat_status (RUNNING). Προσθέστε ενέργεια Compose (σύνθεση τιμής) με όνομα Operation_ID και έκφραση guid(), πριν από το Create_chat_session. Δημιουργήστε την τιμή μία φορά ανά εκτέλεση.

Προσθέστε ενέργεια HTTP με όνομα Create_chat_session:

Ρύθμιση Τιμή
Method POST
Έκφραση URI concat(variables('Nous_URL'), '/api/chat/create-chat-session')
Headers Authorization: Bearer <token>, Content-Type: application/json· σε εγκαταστάσεις με επιβολή χρέωσης, X-Sophea-Operation-ID με έκφραση outputs('Operation_ID').
Body Το παρακάτω αντικείμενο JSON. Αν χρειάζεται, αντικαταστήστε το 0 με ID agent στον οποίο έχετε πρόσβαση.
Settings Retry Policy: None (καμία επανάληψη)· Asynchronous Pattern: Off (χωρίς αυτόματους ασύγχρονους ελέγχους), όπου εμφανίζεται.
{
  "persona_id": 0
}

Μετά από επιτυχημένη απόκριση δημιουργίας, ορίστε το Chat_session_id ως body('Create_chat_session')?['chat_session_id']. Απαιτήστε μη κενό ID πριν από την υποβολή. Κρατήστε αυτό το ID έξω από τις ομάδες ενεργειών υποβολής/ελέγχων, για ανάκτηση. Δημιουργήστε μία συνομιλία ανά εκτέλεση ροής και μη στείλετε άλλους γύρους μέχρι να διευκρινιστεί η έκβαση αυτού του γύρου.

2. Υποβάλετε μία φορά.

Προσθέστε ενέργεια HTTP με όνομα Submit_chat, μέθοδο POST και έκφραση URI concat(variables('Nous_URL'), '/api/chat/send-chat-message-async'). Χρησιμοποιήστε τις ίδιες κεφαλίδες με τη δημιουργία, μαζί με το ίδιο outputs('Operation_ID') σε εγκαταστάσεις με επιβολή χρέωσης. Ορίστε Retry Policy: None και Asynchronous Pattern: Off όπου εμφανίζεται η ρύθμιση. Η απόκριση 202 δεν έχει Location ούτε σύμβαση εγγενούς αυτόματου ελέγχου κατάστασης.

Χρησιμοποιήστε αυτό το αντικείμενο στο πεδίο σώματος, όχι συμβολοσειρά JSON μέσα σε εισαγωγικά. Εισαγάγετε την έκφραση συνομιλίας όπως φαίνεται και αντικαταστήστε το μήνυμα ή χρησιμοποιήστε δυναμικό περιεχόμενο:

{
  "chat_session_id": "@{variables('Chat_session_id')}",
  "message": "Συνοψίστε την πολιτική εισαγωγής μας",
  "knowledge_search_enabled": true
}

Συνεχίστε μόνο μετά από HTTP 202 με chat_session_id και reserved_assistant_message_id. Ελέγξτε ότι η συνομιλία που επιστρέφεται συμφωνεί με το Chat_session_id και αποθηκεύστε το ID assistant από το body('Submit_chat')?['reserved_assistant_message_id']. Αποθηκεύστε το user_message_id όταν δεν είναι null. Αν λείπει ID ή η υποβολή είναι αβέβαιη, ακολουθήστε ανάκτηση, όχι νέα αποστολή.

3. Ελέγξτε την κατάσταση μέσα σε ομάδα ενεργειών με όρια.

Προσθέστε Do until (επανάληψη μέχρι να ισχύσει η συνθήκη) με αυτή την έκφραση:

not(equals(variables('Chat_status'), 'RUNNING'))

Ορίστε τα όριά του σε Count: 180 (μέγιστες επαναλήψεις) και Timeout: PT30M (χρονικό όριο). Μέσα στον βρόχο, προσθέστε την ενέργεια HTTP Get_chat_result, με μέθοδο GET, κεφαλίδα Bearer, χωρίς σώμα και Retry Policy: None. Ο έλεγχος κατάστασης δεν χρειάζεται X-Sophea-Operation-ID. Χρησιμοποιήστε ακριβώς αυτή την έκφραση URI:

concat(variables('Nous_URL'), '/api/chat/get-chat-message-result/', body('Submit_chat')?['chat_session_id'], '/', string(body('Submit_chat')?['reserved_assistant_message_id']))

Μετά από κάθε επιτυχημένο GET, ορίστε το Chat_status από το body('Get_chat_result')?['status']. Προσθέστε Condition (συνθήκη) για equals(variables('Chat_status'), 'RUNNING') και στον κλάδο Yes προσθέστε Delay (καθυστέρηση) 10 δευτερολέπτων. Μην προσθέτετε καθυστέρηση μετά από τελική κατάσταση. Άγνωστη κατάσταση ή απουσία κατάστασης είναι σφάλμα, όχι ολοκλήρωση.

Μετά τον βρόχο, επιλέξτε κλάδο βάσει του Chat_status:

  • COMPLETED: χρησιμοποιήστε το body('Get_chat_result')?['result']?['message'], ακόμη και αν είναι έγκυρη κενή απάντηση. Απαιτήστε το αναμενόμενο αντικείμενο αποτελέσματος και συμφωνία των ID.
  • FAILED ή CANCELLED: τερματίστε με τα ασφαλή για τον καλούντα error και error_code· μη χρησιμοποιήσετε αποτέλεσμα και μη στείλετε ξανά.
  • Κάθε άλλη κατάσταση, μαζί με RUNNING μετά την εξάντληση των επαναλήψεων, παραμένει αδιευκρίνιστη. Κρατήστε τα ID και τερματίστε για έλεγχο. Η επιτυχία της ενέργειας βρόχου από μόνη της δεν επιβεβαιώνει ολοκλήρωση.

4. Χειριστείτε αποτυχίες και λήξεις χρονικών ορίων χωρίς νέα αποστολή.

Τοποθετήστε την υποβολή σε Scope (ομάδα ενεργειών) με όνομα Submit_scope και τους ελέγχους μαζί με την τελική επικύρωση σε Poll_scope. Εκτελέστε το Poll_scope μόνο αφού επιτύχει το Submit_scope και επικυρωθούν τα αποδεκτά ID. Προσθέστε ομάδες χειρισμού αποτυχίας με Configure run after (ρύθμιση εκτέλεσης μετά από προηγούμενη ενέργεια) για has failed, has timed out και is skipped, όπου χρειάζεται, και για τις δύο ομάδες. Χειριστείτε επίσης αποτυχημένη δημιουργία χωρίς υποβολή. Μην τοποθετείτε δεύτερο Submit_chat σε κλάδο επανάληψης, ανάκτησης ή βρόχου.

Οι χειριστές κρατούν το Chat_session_id και τυχόν αποδεκτά ID μηνυμάτων, καταγράφουν ασφαλή έκβαση και τερματίζουν. Ένα GET ανάκτησης με χρονικό όριο μπορεί να ελέγξει το concat(variables('Nous_URL'), '/api/chat/get-chat-session/', variables('Chat_session_id')) με την ίδια ταυτότητα Bearer και, σε εγκαταστάσεις με επιβολή χρέωσης, το ίδιο X-Sophea-Operation-ID: outputs('Operation_ID'). Ορίστε και για την ανάκτηση Retry Policy: None. Ακολουθήστε τους ελέγχους ολοκλήρωσης με γνωστό ID συνομιλίας· αυτό το GET επιστρέφει ιστορικό, όχι το μικρό αντικείμενο αποτελέσματος. Αν αποτύχει και η ανάκτηση, κρατήστε τα ID για ανθρώπινο έλεγχο αντί για απεριόριστες επαναλήψεις.

Αποτυχία HTTP, απουσία αποδεκτών ID, αποτυχία βρόχου, λήξη χρονικού ορίου ή εξάντληση ελέγχων δεν προκαλεί ποτέ δεύτερο γύρο. Η απουσία ιστορικού μετά από αβέβαιη αποστολή δεν αποδεικνύει μη αποδοχή. Ελέγξτε χειροκίνητα τη συνομιλία και τυχόν εξωτερικές ενέργειες πριν αποφασίσετε νέο γύρο. Η διακοπή ροής ή η λήξη του χρονικού ορίου της δεν αποδεικνύει ακύρωση εργασίας στον διακομιστή, και η συνήθης εργασία δεν συνεχίζεται μετά από επανεκκίνηση API.

Πηγές Microsoft: όρια αιτημάτων, βρόχων και επαναλήψεων, ρυθμίσεις ασύγχρονου μοτίβου HTTP και παράδειγμα Do until στο Power Automate. Οι ρυθμίσεις του σχεδιαστή μπορεί να διαφέρουν· η πηγή για το ασύγχρονο μοτίβο περιγράφει στοιχεία ελέγχου του Azure Logic Apps. Δεν δηλώνεται εδώ εκτέλεση ροής Microsoft ή λήψη στιγμιοτύπων της.

7.7 Ανάκτηση όταν ο πελάτης σταματήσει να περιμένει

Για ένα συνήθες αίτημα με ένα μοντέλο, δημιουργήστε ξεχωριστή συνομιλία πριν στείλετε την ερώτηση. Έτσι γνωρίζετε το ID της, ακόμη και αν κοπεί η επόμενη απόκριση. Μη στέλνετε άλλα μηνύματα σε αυτή τη συνομιλία μέχρι να διευκρινιστεί η έκβαση αυτού του γύρου.

Σε εγκαταστάσεις με επιβολή χρέωσης, δημιουργήστε ένα X-Sophea-Operation-ID πριν από τη δημιουργία και στείλτε την ίδια τιμή στη δημιουργία, την αποστολή και την ανάκτηση πλήρους συνομιλίας. Η κεφαλίδα προσδιορίζει τη λειτουργία, δεν αποτρέπει διπλή εκτέλεση. Οι χρήστες Power Automate πρέπει να ακολουθούν την ασύγχρονη ακολουθία ροής cloud· αυτή η ενότητα διατηρεί την ανάκτηση για το υπάρχον endpoint ροής και τις αβέβαιες υποβολές.

  1. Στείλτε POST /api/chat/create-chat-session με {"persona_id":0} για τον προεπιλεγμένο agent ή με το ID ενός agent στον οποίο έχετε πρόσβαση. Συνεχίστε μόνο μετά από επιτυχημένη απόκριση και αποθηκεύστε το chat_session_id.
  2. Στείλτε ένα μόνο POST /api/chat/send-chat-message με αυτό το ID, το message σας και "stream":true. Απενεργοποιήστε τις αυτόματες επαναλήψεις POST στον πελάτη HTTP. Αν η ροή δώσει τα μεταδεδομένα δέσμευσης, αποθηκεύστε τα user_message_id και reserved_assistant_message_id.
  3. Αν λήξει το χρονικό όριο της ροής, χαθεί η σύνδεση ή η ολοκλήρωση είναι αβέβαιη, ανακτήστε GET /api/chat/get-chat-session/<chat_session_id> με την ίδια ταυτότητα. Μη στείλετε ξανά την ερώτηση για να ανακτήσετε την απάντηση.

Οι παρακάτω εντολές curl δείχνουν τη γενική ακολουθία του API. Εκτελέστε πρώτα τη δημιουργία και αντικαταστήστε την ενδεικτική τιμή με το ID που επιστράφηκε πριν εκτελέσετε την αποστολή και την ανάκτηση. Το όριο των 120 δευτερολέπτων στην αποστολή είναι χρονικό όριο του πελάτη, όχι ακύρωση στον διακομιστή ή αναμενόμενη διάρκεια απάντησης.

CHAT_OPERATION_ID="$(uuidgen)"

curl -sS --fail-with-body --retry 0 --max-time 30 \
  -X POST "$NOUS_URL/api/chat/create-chat-session" \
  -H "Authorization: Bearer $NOUS_TOKEN" \
  -H "X-Sophea-Operation-ID: $CHAT_OPERATION_ID" \
  -H "Content-Type: application/json" \
  -d '{"persona_id":0}'

CHAT_SESSION_ID='<returned-chat_session_id>'

curl -sS --fail-with-body --retry 0 --max-time 120 \
  -X POST "$NOUS_URL/api/chat/send-chat-message" \
  -H "Authorization: Bearer $NOUS_TOKEN" \
  -H "X-Sophea-Operation-ID: $CHAT_OPERATION_ID" \
  -H "Content-Type: application/json" \
  -d "{\"chat_session_id\":\"$CHAT_SESSION_ID\",\"message\":\"Summarize our onboarding policy\",\"knowledge_search_enabled\":true,\"stream\":true}"

curl -sS --fail-with-body --retry 0 --max-time 30 \
  "$NOUS_URL/api/chat/get-chat-session/$CHAT_SESSION_ID" \
  -H "Authorization: Bearer $NOUS_TOKEN" \
  -H "X-Sophea-Operation-ID: $CHAT_OPERATION_ID"

Η ανάκτηση επιστρέφει messages και πακέτα επανάληψης packets, όχι το πεδίο answer της πλήρους απόκρισης. Σε αυτή την ξεχωριστή συνομιλία ενός γύρου, εντοπίστε το μήνυμα χρήστη και το θυγατρικό του μήνυμα assistant (το parent_message ισούται με το message_id του χρήστη). Αν αποθηκεύσατε το δεσμευμένο ID του assistant, πρέπει να συμφωνεί. Διαβάστε τα αποθηκευμένα message, πηγές, παραπομπές και files του αντίστοιχου assistant, όχι το προσωρινό κείμενο της ροής.

Ελέγξτε τα σφάλματα και την πρόσβαση πριν αποδεχτείτε μια απάντηση:

Κατάσταση που ανακτήθηκε Τι να κάνετε
HTTP 401/403 ή is_restricted: true Σταματήστε. Επιλύστε το θέμα διαπιστευτηρίων ή πρόσβασης πριν από άλλη ανάκτηση· μην επαναλάβετε την αποστολή.
Το error ή το error_code του assistant δεν είναι null Θεωρήστε τον γύρο αποτυχημένο, ακόμη και αν το message περιέχει κείμενο. Κρατήστε τα ID και αναφέρετε το σφάλμα· η ένδειξη επανάληψης δεν καθιστά ασφαλή την επανάληψη POST.
Assistant is_generating: true Ο γύρος βρίσκεται ακόμη σε εξέλιξη. Τυχόν ορατό κείμενο είναι προσωρινό· ανακτήστε ξανά εντός των ορίων αναμονής σας.
Assistant is_generating: false, χωρίς περιορισμό πρόσβασης, με null σφάλματα και αντίστοιχο πακέτο επανάληψης obj.type: "stop" με null ή χωρίς stop_reason Μετά από πλήρη, επιτυχημένη ανάκτηση GET, αποδεχτείτε το αποθηκευμένο message. Μια έγκυρη ολοκληρωμένη απάντηση μπορεί να είναι κενή. Για αυτή τη συνομιλία με ένα μήνυμα assistant, η επανάληψή του είναι η μοναδική καταχώριση στο packets.
Ακύρωση ή άγνωστο stop_reason, απουσία του αντίστοιχου assistant ή του κανονικού Stop στην επανάληψη Δεν είναι κανονική ολοκλήρωση. Αν δεν αναφέρεται ακύρωση ή σφάλμα, ανακτήστε ξανά εντός των ορίων αναμονής σας, ακόμη και αν το is_generating είναι false. Κρατήστε τα ID· μη συμπεράνετε επιτυχία μόνο από το HTTP 200, το μη κενό κείμενο ή το is_generating: false.
Κανένα ορατό μήνυμα χρήστη ή assistant μετά από αβέβαιη αποστολή Είναι μόνο στιγμιότυπο. Δεν αποδεικνύει ότι το POST δεν έγινε ποτέ αποδεκτό ή ότι είναι ασφαλές να σταλεί ξανά.

Επαναλαμβάνετε μόνο GET, με καθυστέρηση μεταξύ αιτημάτων, χρονικό όριο ανά αίτημα και πεπερασμένο συνολικό όριο αναμονής ή μέγιστο αριθμό προσπαθειών. Δώστε μερικά λεπτά για να ταξινομηθεί ένας γύρος που διακόπηκε· οι μεγάλες απαντήσεις μπορεί να χρειάζονται μεγαλύτερο όριο. Αν το όριο εξαντληθεί, σταματήστε τις ανακτήσεις, κρατήστε τα ID συνομιλίας και μηνυμάτων και αφήστε την έκβαση αδιευκρίνιστη για ανθρώπινο έλεγχο. Ούτε το χρονικό όριο του πελάτη ούτε το κλείσιμο της ροής επιβεβαιώνουν ακύρωση.

Ένας γύρος του οποίου η παραγωγή έχει ξεκινήσει μπορεί να ολοκληρωθεί μετά την αποσύνδεση του πελάτη, όσο ο διακομιστής συνεχίζει να λειτουργεί. Η απώλεια της διεργασίας διακομιστή δεν συνεχίζει αυτόματα το μοντέλο ή τα εργαλεία· η ανάκτηση μπορεί να αναφέρει GENERATION_INTERRUPTED. Αυτό το σφάλμα δεν εγγυάται ότι η αποθηκευμένη κατάσταση δεν μπορεί ποτέ να αλλάξει, επομένως μην επαναλαμβάνετε αυτόματα την αποστολή. Το endpoint αποστολής δεν έχει κλειδί idempotency και δεν εγγυάται μία και μόνο εκτέλεση ενεργειών εργαλείων. Ένας άνθρωπος πρέπει να ελέγξει την αποθηκευμένη συνομιλία και τυχόν εξωτερικές ενέργειες πριν αποφασίσει να στείλει νέο γύρο. Αυτό το μοτίβο δεν είναι ανθεκτική ανάκτηση μετά από απώλεια διεργασίας ούτε πιστοποιημένη ροή Power Automate.

7.8 Εκτέλεση του δείγματος Python

Από ένα αντίγραφο του αποθετηρίου της πλατφόρμας, εκτελέστε:

(
  cd nous
  NOUS_ACCESS_TOKEN="$NOUS_TOKEN" uv run --locked python \
    backend/scripts/api_inference_sample.py \
    --onyx-url "$NOUS_URL" \
    --test-question "Summarize our onboarding policy"
)

Το δείγμα διαβάζει τα ένθετα πακέτα obj.type: "message_delta" και εμφανίζει κάθε τμήμα obj.content μόλις φτάσει. Αναλύει JSON ανά γραμμή, παρότι ο τύπος περιεχομένου είναι text/event-stream. Το κείμενο που εμφανίζεται παραμένει προσωρινό μέχρι η εντολή να τερματιστεί επιτυχώς.

Ο κωδικός εξόδου 0 απαιτεί αποθηκευμένο μήνυμα assistant που αντιστοιχεί στη συνομιλία που δημιουργήθηκε και στο δεσμευμένο ID του assistant, ένα κανονικό Stop με null ή χωρίς λόγο διακοπής, και τέλος ροής χωρίς σφάλμα. Το τελικό μήνυμα και το Stop μπορεί να φτάσουν με οποιαδήποτε σειρά. Το αποθηκευμένο message δεν εμφανίζεται δεύτερη φορά. Μια ολοκληρωμένη κενή απάντηση είναι έγκυρη.

Ένα ανακτήσιμο σφάλμα βήματος εργαλείου μέσα σε πακέτο δεν αποτυγχάνει από μόνο του ολόκληρο τον γύρο. Σφάλμα απόκρισης στο ανώτερο επίπεδο, διακοπή ή άγνωστος λόγος, διπλό σήμα ολοκλήρωσης, μη έγκυρα δεδομένα, μεταγενέστερο σφάλμα ή κομμένη απόκριση προκαλούν μη μηδενικό κωδικό εξόδου· το κείμενο που έχει ήδη εμφανιστεί μπορεί να είναι ελλιπές. Τμήμα απάντησης μετά το Stop απορρίπτεται αντί να εμφανιστεί.

Και τα δύο αιτήματα έχουν χρονικά όρια, απορρίπτουν ανακατευθύνσεις και δεν επαναλαμβάνονται αυτόματα. Χρησιμοποιήστε την τελική διεύθυνση του χώρου εργασίας και το NOUS_ACCESS_TOKEN· το παλιό DANSWER_API_KEY δεν διαβάζεται. Η διακοπή της εντολής κλείνει τη σύνδεση, αλλά δεν επιβεβαιώνει ακύρωση της εργασίας στον διακομιστή. Χρησιμοποιήστε την ανάκτηση με γνωστό ID συνομιλίας για να ελέγξετε έναν αβέβαιο γύρο, όχι για να επαναλάβετε αυτόματα την αποστολή του.

7.9 Συνεχίστε τη συνομιλία

Χρησιμοποιήστε το chat_session_id της πρώτης απόκρισης σε κάθε επόμενο μήνυμα της ίδιας συνομιλίας. Αντικαταστήστε το ενδεικτικό ID με αυτό που επέστρεψε το πρώτο σας αίτημα. Μην αντικαταστήσετε το αποθηκευμένο ID με την τιμή null μιας επόμενης απόκρισης.

curl -sS -X POST "$NOUS_URL/api/chat/send-chat-message" \
  -H "Authorization: Bearer $NOUS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Τι πρέπει να κάνει μετά ο προϊστάμενος;",
    "chat_session_id": "cba35529-7e57-4c57-8f84-0c9733277f5c",
    "knowledge_search_enabled": true,
    "stream": false
  }'

7.10 Ξεκινήστε με άλλον agent

Δείτε τους agents που είναι διαθέσιμοι για το διακριτικό σας και χρησιμοποιήστε ένα ID agent στο πρώτο μήνυμα νέας συνομιλίας:

curl -sS "$NOUS_URL/api/agents?page_size=100" \
  -H "Authorization: Bearer $NOUS_TOKEN"

curl -sS -X POST "$NOUS_URL/api/chat/send-chat-message" \
  -H "Authorization: Bearer $NOUS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Συνοψίστε την πολιτική εισαγωγής μας",
    "chat_session_info": {"persona_id": 123},
    "knowledge_search_enabled": true,
    "stream": false
  }'

Αντικαταστήστε το 123 με το ID διαθέσιμου agent. Για επόμενα μηνύματα προς τον ίδιο agent, χρησιμοποιήστε το chat_session_id που επιστράφηκε αντί για chat_session_info.

7.11 Αν κάτι δεν λειτουργεί

  • Αποτυχία ταυτοποίησης ή πρόσβασης: ελέγξτε τη διεύθυνση του Χώρου εργασίας, τη λήξη του διακριτικού και την πρόσβαση του κατόχου του στον Χώρο εργασίας και τον agent. Μη στέλνετε το διακριτικό στην υποστήριξη μέσα σε εικόνα ή μήνυμα.
  • Το API επιστρέφει HTTP 422 (σφάλμα επικύρωσης): βεβαιωθείτε ότι το αίτημα έχει σώμα με αντικείμενο JSON, έγκυρη σύνταξη JSON και το υποχρεωτικό πεδίο message. Ορίστε Content-Type: application/json. Στο Power Automate, μετατρέψτε το JSON που είναι αποθηκευμένο ως κείμενο σε αντικείμενο πριν το δώσετε στην ενέργεια HTTP.
  • Η απόκριση του παλιού endpoint αποστολής περιέχει γραμμές JSON αντί για ένα αντικείμενο JSON: ορίστε "stream":false στο /api/chat/send-chat-message. Το ασύγχρονο endpoint υποβολής επιστρέφει πάντα JSON.
  • Η απάντηση δεν έχει παραπομπές γνώσης: στείλτε "knowledge_search_enabled":true, βεβαιωθείτε ότι ο κάτοχος του διακριτικού έχει πρόσβαση στην πηγή και ελέγξτε ότι ο agent διαθέτει ενεργό εργαλείο αναζήτησης. Ο agent μπορεί και πάλι να κρίνει ότι δεν χρειάζεται αναζήτηση. Δείτε την Αναζήτηση γνώσης για το εύρος αναζήτησης.
  • Το αίτημα HTTP ολοκληρώνεται, αλλά η απάντηση δεν είναι αξιοποιήσιμη: ελέγξτε το δομημένο σφάλμα και το stop_reason και, αν χρησιμοποιείτε streaming, επαληθεύστε ολόκληρη τη ροή. Αν η ολοκλήρωση είναι αβέβαιη, χρησιμοποιήστε την ανάκτηση με γνωστό ID συνομιλίας· μην επαναλαμβάνετε αυτόματα την αποστολή.