La poursuite intelligente de document est une fonctionnalité pilotée par l'IA qui génère un contenu de suivi cohérent et contextuellement pertinent, en s'appuyant sur votre texte existant, son sujet et son style.
Prérequis
Avant de commencer, assurez-vous d'avoir :
Un projet IMM associé à votre bucket OSS. Intelligent Media Management (IMM) constitue la couche d'orchestration des modèles d'IA qui traite les demandes de poursuite. Cette configuration est unique. Si vous ne l'avez pas encore effectuée, suivez la procédure décrite dans Prise en main ou appelez l'API AttachOSSBucket avant d'utiliser cette API.
Les autorisations requises. Pour plus de détails, consultez la rubrique Permissions
Notes d'utilisation
La poursuite intelligente de document prend uniquement en charge le traitement synchrone.
Les requêtes doivent utiliser la méthode POST.
L'accès anonyme est refusé.
Le paramètre content accepte jusqu'à 19 500 octets de texte encodé en Base64 URL-safe. Les requêtes dépassant cette limite renvoient une erreur.
Fonctionnement
Soumettez une requête POST vers un objet de votre bucket avec le paramètre x-oss-process=doc/continue. Le nom du fichier sert uniquement de marqueur : OSS lit le paramètre content et non le contenu du fichier pour exécuter la poursuite.
La réponse contient le texte généré dans le champ Output.Text. Vérifiez la valeur de Output.FinishReason pour déterminer si la tâche est terminée :
| Valeur | Signification | Action |
|---|---|---|
null |
La tâche est toujours en cours d'exécution. En mode SSE, d'autres événements suivent. | Continuez à lire les événements. |
stop |
La tâche s'est terminée avec succès. | Lisez la valeur finale de Output.Text et arrêtez le traitement. |
Paramètres
Opération : doc/continue
Paramètres de requête
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
content |
string | Oui | Le texte source, encodé en Base64 URL-safe. Taille maximale : 19 500 octets. |
format |
string | Non | Format de la réponse. json (par défaut) renvoie un seul paquet contenant la réponse complète. event-stream active le mode Server-Sent Events (SSE) et renvoie plusieurs paquets incrémentiels. |
history |
string | Non | Sorties de poursuite précédentes pour les sessions multi-tours, encodées en Base64 URL-safe. Consultez la section Poursuite multi-tours. |
Paramètres de réponse
| Paramètre | Type | Description |
|---|---|---|
RequestId |
string | L'identifiant unique de la requête. |
Output.Text |
string | Le texte de poursuite généré. |
Output.FinishReason |
string | État de la tâche : null (en cours) ou stop (terminé). |
Utiliser l'API RESTful
Mode JSON
Le mode JSON renvoie un seul paquet de réponse contenant l'intégralité du texte généré.
Exemple de requête
POST /example.doc?x-oss-process HTTP/1.1
Host: doc-demo.oss-cn-hangzhou.aliyuncs.com
Date: Fri, 28 Oct 2022 06:40:10 GMT
Authorization: OSS4-HMAC-SHA256 Credential=LTAI********************/20250417/cn-hangzhou/oss/aliyun_v4_request,Signature=a7c3554c729d71929e0b84489addee6b2e8d5cb48595adfc51868c299c0c218e
x-oss-process=doc/continue,content_RXJuZXN0IEhlbWluZ3dheSdzICJUaGUgT2xkIE1hbiBhbmQgdGhlIFNlYSIgaXMgYSB0YWxlIG9mIGFuIG9sZCBmaXNoZXJtYW4sIFNhbnRpYWdvLCBhbmQgaGlzIGVwaWMgc3RydWdnbGUgdG8gY2F0Y2ggYSBnaWFudCBtYXJsaW4uIFRoaXMgc3RvcnkgaXMgYSBwcm9mb3VuZCBleHBsb3JhdGlvbiBvZiBodW1hbiBlbmR1cmFuY2UsIHBlcnNldmVyYW5jZSwgYW5kIHRoZSBiYXR0bGUgYWdhaW5zdCB0aGUgZm9yY2VzIG9mIG5hdHVyZS4gU2FudGlhZ28ncyB1bndhdmVyaW5nIGRldGVybWluYXRpb24gYW5kIGRpZ25pdHkgaW4gdGhlIGZhY2Ugb2YgYWR2ZXJzaXR5IHNlcnZlIGFzIGEgdGVzdGFtZW50IHRvIHRoZSBzdHJlbmd0aCBvZiB0aGUgaHVtYW4gc3Bpcml0Lg==
Exemple de réponse
{
"RequestId": "6761445E8A0E5D383974169B",
"Output": {
"Text": "Ernest Hemingway's \"The Old Man and the Sea\" ...\n\nSet in the Gulf Stream off the coast of Cuba...",
"FinishReason": "stop"
}
}
Mode SSE
Le mode SSE diffuse la réponse sous forme d'événements incrémentiels. Chaque événement contient le texte cumulé généré jusqu'à présent, et non seulement le nouveau fragment. Lisez la valeur de FinishReason pour détecter la fin du flux.
Exemple de requête
POST /example.doc?x-oss-process HTTP/1.1
Host: doc-demo.oss-cn-hangzhou.aliyuncs.com
Date: Fri, 28 Oct 2022 06:40:10 GMT
Authorization: OSS4-HMAC-SHA256 Credential=LTAI********************/20250417/cn-hangzhou/oss/aliyun_v4_request,Signature=a7c3554c729d71929e0b84489addee6b2e8d5cb48595adfc51868c299c0c218e
x-oss-process=doc/continue,format_event-stream,content_RXJuZXN0IEhlbWluZ3dheSdzICJUaGUgT2xkIE1hbiBhbmQgdGhlIFNlYSIgaXMgYSB0YWxlIG9mIGFuIG9sZCBmaXNoZXJtYW4sIFNhbnRpYWdvLCBhbmQgaGlzIGVwaWMgc3RydWdnbGUgdG8gY2F0Y2ggYSBnaWFudCBtYXJsaW4uIFRoaXMgc3RvcnkgaXMgYSBwcm9mb3VuZCBleHBsb3JhdGlvbiBvZiBodW1hbiBlbmR1cmFuY2UsIHBlcnNldmVyYW5jZSwgYW5kIHRoZSBiYXR0bGUgYWdhaW5zdCB0aGUgZm9yY2VzIG9mIG5hdHVyZS4gU2FudGlhZ28ncyB1bndhdmVyaW5nIGRldGVybWluYXRpb24gYW5kIGRpZ25pdHkgaW4gdGhlIGZhY2Ugb2YgYWR2ZXJzaXR5IHNlcnZlIGFzIGEgdGVzdGFtZW50IHRvIHRoZSBzdHJlbmd0aCBvZiB0aGUgaHVtYW4gc3Bpcml0Lg==
Exemple de réponse (abrégé — le flux complet contient de nombreux événements ; seuls le premier et le dernier sont affichés)
HTTP/1.1 200 OK
Content-Type: text/event-stream;charset=UTF-8
Transfer-Encoding: chunked
id: 0
event: Result
data: {"RequestId":"67614545E3FA66313474AAC8","Output":{"Text":"Er","FinishReason":"null"}}
id: 1
event: Result
data: {"RequestId":"67614545E3FA66313474AAC8","Output":{"Text":"Ernest","FinishReason":"null"}}
...
id: 131
event: Result
data: {"RequestId":"67614545E3FA66313474AAC8","Output":{"Text":"Ernest Hemingway's \"The Old Man and the Sea\" ... making his triumphs and tribulations deeply personal. Through Santiago's eyes, we see ...","FinishReason":"stop"}}
Le champTextde chaque événement contient la sortie accumulée complète, et non seulement le nouveau fragment. Pour afficher uniquement le nouveau texte, comparez les événements consécutifs et extrayez la différence. Arrêtez la lecture lorsqueFinishReasona la valeurstop.
Consommation du flux SSE
Le pseudocode suivant illustre le traitement des événements et la détection de la fin du flux :
previousText = ""
for each SSE event received:
parse event.data as JSON
currentText = data.Output.Text
newFragment = currentText[len(previousText):] // extract only the new portion
display(newFragment)
previousText = currentText
if data.Output.FinishReason == "stop":
break // stream is complete
Poursuite multi-tours
Transmettez les sorties de poursuite précédentes via le paramètre history pour vous appuyer sur les résultats antérieurs. Encodez le tableau en Base64 URL-safe avant de le soumettre.
Format du tableau history
[
{"content": "text generated in the first turn"},
{"content": "text generated in the second turn"}
]
Exemple : poursuite en deux tours
Tour 1 — Soumettez la requête initiale avec le paramètre content uniquement :
x-oss-process=doc/continue,content_<base64url_initial_content>
Réponse du tour 1 :
{
"RequestId": "...",
"Output": {
"Text": "Santiago gazed out at the horizon, the weight of eighty-four fishless days pressing on his shoulders...",
"FinishReason": "stop"
}
}
Tour 2 — Intégrez la sortie du tour 1 dans le tableau history, encodez ce tableau en Base64, puis soumettez la requête avec les paramètres content (nouveau texte source) et history (tableau encodé) :
Tableau history avant encodage :
[
{"content": "Santiago gazed out at the horizon, the weight of eighty-four fishless days pressing on his shoulders..."}
]
Requête du tour 2 :
x-oss-process=doc/continue,content_<base64url_new_content>,history_<base64url_encoded_history_array>
Pour chaque tour suivant, ajoutez la dernière valeur de Output.Text au tableau history avant de l'encoder.
Utiliser les SDK
Les exemples de SDK suivants utilisent tous le même schéma : encodez votre texte source en Base64 URL-safe, puis transmettez-le comme valeur du paramètre content dans l'instruction x-oss-process.
Java
Le SDK OSS pour Java version 3.17.4 ou ultérieure est requis.
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.common.utils.IOUtils;
import com.aliyun.oss.model.GenericResult;
import com.aliyun.oss.model.ProcessObjectRequest;
import java.io.IOException;
import java.util.Formatter;
public class Demo {
public static void main(String[] args) throws ClientException, com.aliyuncs.exceptions.ClientException {
// Specify the endpoint of the region where the bucket is located.
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// Specify the Alibaba Cloud region ID. Example: cn-hangzhou.
String region = "cn-hangzhou";
// Obtain access credentials from environment variables.
// Set OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET before running this code.
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// Specify the bucket name. Example: examplebucket.
String bucketName = "examplebucket";
// The object name is a placeholder — its content is not read.
String key = "example.docx";
// Specify the source text.
String content = "Ernest Hemingway's \"The Old Man and the Sea\" is a tale of an old fisherman...";
// URL-safe Base64-encode the source text.
String encodeContent = BinaryUtil.toBase64String(content.getBytes())
.replaceAll("\\+", "-")
.replaceAll("/", "_")
.replaceAll("=", "");
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.build();
try {
StringBuilder sbStyle = new StringBuilder();
Formatter styleFormatter = new Formatter(sbStyle);
// Build the processing instruction.
styleFormatter.format("doc/continue,content_%s", encodeContent);
ProcessObjectRequest request = new ProcessObjectRequest(bucketName, key, sbStyle.toString());
GenericResult processResult = ossClient.processObject(request);
String json = IOUtils.readStreamAsString(processResult.getResponse().getContent(), "UTF-8");
processResult.getResponse().getContent().close();
System.out.println(json);
} catch (OSSException oe) {
System.out.println("Error Message: " + oe.getErrorMessage());
System.out.println("Error Code: " + oe.getErrorCode());
System.out.println("Request ID: " + oe.getRequestId());
} catch (ClientException ce) {
System.out.println("Error Message: " + ce.getMessage());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
PHP
Le SDK OSS pour PHP version 2.7.0 ou ultérieure est requis.
<?php
// Obtain access credentials from environment variables.
// Set OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET before running this code.
$ak = getenv('OSS_ACCESS_KEY_ID');
$sk = getenv('OSS_ACCESS_KEY_SECRET');
// Specify the bucket name. Example: examplebucket.
$bucket = 'examplebucket';
// The object name is a placeholder — its content is not read.
$objectKey = 'example.docx';
// Specify the source text.
$txt = "Ernest Hemingway's \"The Old Man and the Sea\" is a tale of an old fisherman...";
// URL-safe Base64-encode the source text.
$base64url = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($txt));
// Build the processing instruction.
$body = sprintf("x-oss-process=doc/continue,content_%s", $base64url);
$httpVerb = 'POST';
$contentMd5 = base64_encode(md5($body, true));
$contentType = '';
$date = gmdate('D, d M Y H:i:s T');
$stringToSign = $httpVerb . "\n" . $contentMd5 . "\n" . $contentType . "\n" . $date . "\n" . "/{$bucket}/{$objectKey}?x-oss-process";
$signature = base64_encode(hash_hmac('sha1', $stringToSign, $sk, true));
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://{$bucket}.oss-cn-hangzhou.aliyuncs.com/{$objectKey}?x-oss-process");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Date: ' . $date,
'Authorization: OSS ' . $ak . ':' . $signature,
'Content-Type: ' . $contentType,
'Content-Md5: ' . $contentMd5,
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
$response = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($response === false) {
echo "Error: " . curl_error($ch);
} elseif ($httpcode == 200) {
var_dump($response);
} else {
echo "Error: HTTP code " . $httpcode;
}
Go
Le SDK OSS pour Go version 3.0.2 ou ultérieure est requis.
package main
import (
"encoding/base64"
"encoding/json"
"fmt"
"io"
"os"
"strings"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
type TextData struct {
RequestId string `json:"RequestId"`
Output struct {
Text string `json:"Text"`
FinishReason string `json:"FinishReason"`
} `json:"Output"`
}
func main() {
// Obtain access credentials from environment variables.
// Set OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET, and OSS_SESSION_TOKEN before running this code.
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// Create an OSSClient instance.
client, err := oss.New(
"https://oss-cn-hangzhou.aliyuncs.com", "", "",
oss.SetCredentialsProvider(&provider),
oss.AuthVersion(oss.AuthV4),
oss.Region("cn-hangzhou"),
)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// Specify the bucket name. Example: examplebucket.
bucketName := "examplebucket"
bucket, err := client.Bucket(bucketName)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
params := make(map[string]interface{})
params["x-oss-process"] = nil
// Specify the source text.
txt := "Ernest Hemingway's \"The Old Man and the Sea\" is a tale of an old fisherman..."
// Build the processing instruction with URL-safe Base64-encoded content.
data := fmt.Sprintf("x-oss-process=doc/continue,content_%v", base64.URLEncoding.EncodeToString([]byte(txt)))
// The object name (example.docx) is a placeholder — its content is not read.
response, err := bucket.Do("POST", "example.docx", params, nil, strings.NewReader(data), nil)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
defer response.Body.Close()
jsonData, err := io.ReadAll(response.Body)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
var text TextData
if err = json.Unmarshal(jsonData, &text); err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
fmt.Printf("RequestId: %v\n", text.RequestId)
fmt.Printf("Text: %v\n", text.Output.Text)
fmt.Printf("FinishReason: %v\n", text.Output.FinishReason)
}