Korzystanie z narzędzia do używania komputera dla agentów (wersja zapoznawcza)

Ważne

Elementy oznaczone (wersja zapoznawcza) w tym artykule są obecnie dostępne w publicznej wersji zapoznawczej. Ta wersja zapoznawcza jest udostępniana bez umowy dotyczącej poziomu usług i nie zalecamy korzystania z niej w przypadku obciążeń produkcyjnych. Niektóre funkcje mogą nie być obsługiwane lub mogą mieć ograniczone możliwości. Aby uzyskać więcej informacji, zobacz Wygólne warunki użytkowania Microsoft Azure Previews.

Ostrzeżenie

Narzędzie do korzystania z komputera wiąże się ze znacznym ryzykiem związanym z bezpieczeństwem i prywatnością, w tym atakami polegającymi na wstrzyknięciu monitów. Aby uzyskać więcej informacji na temat zamierzonych zastosowań, możliwości, ograniczeń, czynników ryzyka i kwestii przy wyborze przypadku użycia, zobacz notę transparentności Azure OpenAI.

Tworzenie agentów, którzy interpretują zrzuty ekranu i automatyzują interakcje interfejsu użytkownika, takie jak klikanie, wpisywanie i przewijanie. Narzędzie do korzystania z komputera używa modelu Foundry computer-use-preview do proponowania działań opartych na zawartości wizualnej, umożliwiając agentom interakcję z aplikacjami desktopowymi i przeglądarkowymi poprzez ich interfejsy użytkownika.

W tym przewodniku pokazano, jak zintegrować narzędzie do obsługi komputera z pętlą aplikacji (zrzut ekranu → akcja → zrzut ekranu) przy użyciu najnowszych pakietów SDK.

Wymagania wstępne

Wsparcie użytkowania

W poniższej tabeli przedstawiono zestaw SDK i obsługę konfiguracji.

Obsługa Microsoft Foundry zestaw SDK Python Zestaw SDK języka C# Zestaw SDK dla języka JavaScript zestaw SDK Java interfejs API REST Konfiguracja agenta podstawowego Konfiguracja agenta standardowego
✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️

Fragmenty kodu w tym artykule koncentrują się na integracji z interfejsem API agentów i odpowiedzi. Są one zależne od kodu pomocniczego i przykładowych zrzutów ekranu, więc nie są autonomiczne. Użyj tych utrzymywanych przykładów i narzędzi pomocniczych:

Pomocnicy Python i Java symulują maszynę stanu, zwracając wstępnie przechwycone zrzuty ekranu dla żądanych akcji. Nie zastępują one kodu aplikacji, który weryfikuje i wykonuje działania w środowisku izolowanym, rejestruje wynikowy stan i wymaga wyraźnej zgody użytkownika przed potwierdzeniem oczekujących kontroli bezpieczeństwa.

Wskazówka

Sklonuj przykładowe repozytorium, aby pliki pomocnicze i wstępnie przechwycone zasoby zrzutu ekranu pozostały w ich oczekiwanych lokalizacjach względnych.

Żądanie dostępu

Aby uzyskać dostęp do computer-use-preview modelu, musisz się zarejestrować. Microsoft udziela dostępu na podstawie kryteriów kwalifikowalności. Jeśli masz dostęp do innych modeli ograniczonego dostępu, nadal musisz zażądać dostępu dla tego modelu.

Aby zażądać dostępu, zobacz formularz aplikacji.

Po przyznaniu dostępu Microsoft należy utworzyć wdrożenie dla modelu.

Przykłady kodu

Ostrzeżenie

Użyj narzędzia do używania komputera na maszynach wirtualnych bez dostępu do poufnych danych ani krytycznych zasobów. Aby uzyskać więcej informacji o zamierzonych zastosowaniach, możliwościach, ograniczeniach, ryzyku i zagadnieniach dotyczących wybierania przypadku użycia, zapoznaj się z informacjami o przejrzystości usługi Azure OpenAI.

Potrzebny jest najnowszy pakiet zestawu SDK. Zestaw SDK .NET jest obecnie w wersji zapoznawczej.

Zrzut ekranu przedstawiający inicjowanie na potrzeby wykonywania narzędzi na komputerze

W poniższych fragmentach pokazano, jak utworzyć wersję agenta za pomocą narzędzia do użycia komputera, wysłać początkowe żądanie ze zrzutem ekranu i wykonać wiele iteracji w celu wykonania zadania. Fragmenty dotyczące Prompt Agents opierają się na utrzymywanym przykładzie w języku Python oraz skrypcie pomocniczym, do których podlinkowano wcześniej. Wybierz Prompt Agents, aby użyć zestawu SDK Azure AI Projects do utworzenia agenta promptów po stronie serwera, lub Hosted Agents, aby użyć struktury Agent Framework FoundryChatClient do zbudowania efemerycznego agenta działającego w procesie.

Pobudzaj agentów

from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import PromptAgentDefinition, ComputerUsePreviewTool

# Import shared helper functions
from computer_use_util import (
    SearchState,
    load_screenshot_assets,
    handle_computer_action_and_take_screenshot,
    print_final_output,
)

"""Main function to demonstrate Computer Use Agent functionality."""
# Initialize state machine
current_state = SearchState.INITIAL

# Load screenshot assets
try:
    screenshots = load_screenshot_assets()
    print("Successfully loaded screenshot assets")
except FileNotFoundError:
    print("Failed to load required screenshot assets. Use the maintained SDK sample on GitHub to get the helper file and images.")
    exit(1)

Tworzenie wersji agenta za pomocą narzędzia

# Format: "https://resource_name.ai.azure.com/api/projects/project_name"
PROJECT_ENDPOINT = "your_project_endpoint"

project = AIProjectClient(
    endpoint=PROJECT_ENDPOINT,
    credential=DefaultAzureCredential(),
)

computer_use_tool = ComputerUsePreviewTool(display_width=1026, display_height=769, environment="windows")

agent = project.agents.create_version(
    agent_name="ComputerUseAgent",
    definition=PromptAgentDefinition(
        model="computer-use-preview",
        instructions="""
        You are a computer automation assistant. 

        Be direct and efficient. When you reach the search results page, read and describe the actual search result titles and descriptions you can see.
        """,
        tools=[computer_use_tool],
    ),
    description="Computer automation agent with screen interaction capabilities.",
)
print(f"Agent created (id: {agent.id}, name: {agent.name})")

Jedna iteracja narzędzia do przetwarzania zrzutu ekranu i wykonania następnego kroku

openai = project.get_openai_client()

# Initial request with screenshot - start with Bing search page
response = openai.responses.create(
    input=[
        {
            "role": "user",
            "content": [
                {
                    "type": "input_text",
                    "text": "I need you to help me search for 'OpenAI news'. Please type 'OpenAI news' and submit the search. Once you see search results, the task is complete.",
                },
                {
                    "type": "input_image",
                    "image_url": screenshots["browser_search"]["url"],
                    "detail": "high",
                },  # Start with Bing search page
            ],
        }
    ],
    extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}},
    truncation="auto",
)

print(f"Initial response received (ID: {response.id})")

Wykonywanie wielu iteracji

Upewnij się, że przeglądasz każdą iterację i akcję. Poniższy przykładowy kod przedstawia podstawowe żądanie interfejsu API. Po wysłaniu początkowego żądania interfejsu API wykonaj pętlę, w której kod aplikacji wykonuje określoną akcję. Wyślij zrzut ekranu po każdym kroku, aby model mógł ocenić zaktualizowany stan środowiska. Przykład zawiera maksymalną liczbę iteracji, aby zapobiec nieskończonym pętlom, ale możesz dostosować ją zgodnie z potrzebami.


max_iterations = 10  # Allow enough iterations for completion
iteration = 0

while True:
    if iteration >= max_iterations:
        print(f"\nReached maximum iterations ({max_iterations}). Stopping.")
        break

    iteration += 1
    print(f"\n--- Iteration {iteration} ---")

    # Check for computer calls in the response
    computer_calls = [item for item in response.output if item.type == "computer_call"]

    if not computer_calls:
        print_final_output(response)
        break

    # Process the first computer call
    computer_call = computer_calls[0]
    action = computer_call.action
    call_id = computer_call.call_id

    # Never execute an action with pending safety checks without user approval.
    safety_checks = computer_call.pending_safety_checks or []
    if safety_checks:
      for check in safety_checks:
        print(f"Safety check: {check.code}: {check.message}")
      if input("Approve this action? Type yes to continue: ").lower() != "yes":
        print("Action rejected by the user.")
        break

    # Handle the action and get the screenshot info
    screenshot_info, current_state = handle_computer_action_and_take_screenshot(action, current_state, screenshots)

    # Regular response with just the screenshot
    response = openai.responses.create(
        previous_response_id=response.id,
        input=[
            {
                "call_id": call_id,
                "type": "computer_call_output",
                "acknowledged_safety_checks": safety_checks,
                "output": {
                    "type": "computer_screenshot",
                    "image_url": screenshot_info["url"],
                },
            }
        ],
        extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}},
        truncation="auto",
    )

    print(f"Iteration {iteration}: response received (ID: {response.id})")

Czyszczenie

project.agents.delete_version(agent_name=agent.name, agent_version=agent.version)
print("Agent deleted")

Oczekiwane dane wyjściowe

Poniższy przykład przedstawia oczekiwane dane wyjściowe podczas uruchamiania poprzedniego przykładu kodu:

Successfully loaded screenshot assets
Agent created (id: ..., name: ComputerUseAgent, version: 1)
Starting computer automation session (initial screenshot: cua_browser_search.png)...
Initial response received (ID: ...)
--- Iteration 1 ---
Processing computer call (ID: ...)
  Typing text "OpenAI news" - Simulating keyboard input
  -> Action processed: type
Sending action result back to agent (using cua_search_typed.png)...
Follow-up response received (ID: ...)
--- Iteration 2 ---
Processing computer call (ID: ...)
    Click at (512, 384) - Simulating click on UI element
    -> Assuming click on Search button when search field was populated, displaying results.
    -> Action processed: click
Sending action result back to agent (using cua_search_results.png)...
Follow-up response received (ID: ...)
OpenAI news - Latest Updates
Agent deleted

Hostowani agenci

Ten przykład używa elementu FoundryChatClient z platformy Microsoft Agent Framework i wywołuje get_computer_use_tool(), aby dołączyć narzędzie w wersji zapoznawczej do obsługi komputera. Zainstaluj pakiet za pomocą pip install agent-framework-foundry aiohttp, ustaw FOUNDRY_PROJECT_ENDPOINT (wskazując FOUNDRY_MODEL na wdrożenie computer-use-preview) i zaloguj się za pomocą az login. Pętla przechwytywania zrzutów ekranu zależy od aplikacji; zobacz wspomniany poniżej źródłowy plik pomocniczy z przykładu.

import asyncio

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient
from azure.identity import AzureCliCredential


async def main() -> None:
    agent = Agent(
        client=FoundryChatClient(credential=AzureCliCredential()),
        instructions=(
            "You are a computer automation assistant. Be direct and efficient. "
            "When you reach the search results page, describe the actual result titles you can see."
        ),
        tools=[
            FoundryChatClient.get_computer_use_tool(
                environment="windows",
                display_width=1026,
                display_height=769,
            )
        ],
    )

    # Replace this with your screenshot capture + action handler loop.
    # See the upstream samples folder for a reference implementation.
    result = await agent.run(
        "Help me search for 'OpenAI news'. Type the query and submit the search."
    )
    print(f"Agent: {result.text}")


if __name__ == "__main__":
    asyncio.run(main())

Oczekiwane dane wyjściowe

Agent wystawia akcje użycia komputera (kliknięcia, naciśnięcia klawiszy, zrzuty ekranu) do momentu zakończenia zadania, a następnie opisuje stronę, do których dotarł:

Agent: I searched for "OpenAI news" in the address bar. The top results include articles from OpenAI's blog, TechCrunch, and The Verge ...

Aby uzyskać pełną implementację pętli zrzutów ekranu, zobacz przykłady dostawców rozwiązania Foundry.


Przykład użycia agenta z narzędziem do korzystania z komputera

W poniższym przykładzie kodu w języku C# pokazano, jak utworzyć agenta za pomocą narzędzia do użycia komputera, wysłać początkowe żądanie ze zrzutem ekranu i wykonać wiele iteracji w celu wykonania zadania. Wybierz Prompt Agents, aby za pomocą zestawu SDK Azure AI Projects utworzyć po stronie serwera agenta opartego na monicie, lub Hosted Agents, aby za pomocą Microsoft Agent Framework utworzyć tymczasowego agenta działającego w procesie.

Pobudzaj agentów

Aby umożliwić agentowi korzystanie z narzędzia do obsługi komputera, użyj ResponseTool.CreateComputerTool() podczas konfigurowania narzędzi agenta. W tym przykładzie użyto synchronicznego kodu. Aby uzyskać informacje na temat użycia asynchronicznego, zobacz przykładowy kod w repozytorium Azure SDK for .NET na GitHubie.

using System;
using System.Runtime.CompilerServices;
using Azure.AI.Projects;
using Azure.AI.Extensions.OpenAI;
using Azure.Identity;

class ComputerUseDemo
{
    // Format: "https://resource_name.ai.azure.com/api/projects/project_name"
    private const string ProjectEndpoint = "your_project_endpoint";

    // Read image files using `ReadImageFile` method.
    private static BinaryData ReadImageFile(string name, [CallerFilePath] string pth = "")
    {
        var dirName = Path.GetDirectoryName(pth) ?? "";
        return new BinaryData(File.ReadAllBytes(Path.Combine(dirName, name)));
    }

    // Create a helper method to parse the ComputerTool outputs and to respond
    // to Agents queries with new screenshots. Note that throughout
    // this sample the media type for image is set. Agents support `image/jpeg`,
    // `image/png`, `image/gif` and `image/webp` media types.
    private static string ProcessComputerUseCall(ComputerCallResponseItem item, string oldScreenshot)
    {
        string currentScreenshot = "browser_search";
        switch (item.Action.Kind)
        {
            case ComputerCallActionKind.Type:
                Console.WriteLine($"  Typing text \"{item.Action.TypeText}\" - Simulating keyboard input");
                currentScreenshot = "search_typed";
                break;
            case ComputerCallActionKind.KeyPress:
                HashSet<string> codes = new(item.Action.KeyPressKeyCodes);
                if (codes.Contains("Return") || codes.Contains("ENTER"))
                {
                    // If we have typed the value to the search field, go to search results.
                    if (string.Equals(oldScreenshot, "search_typed"))
                    {
                        Console.WriteLine("  -> Detected ENTER key press, when search field was populated, displaying results.");
                        currentScreenshot = "search_results";
                    }
                    else
                    {
                        Console.WriteLine("  -> Detected ENTER key press, on results or unpopulated search, do nothing.");
                        currentScreenshot = oldScreenshot;
                    }
                }
                else
                {
                    Console.WriteLine($"  Key press: {item.Action.KeyPressKeyCodes.Aggregate("", (agg, next) => agg + "+" + next)} - Simulating key combination");
                }
                break;
            case ComputerCallActionKind.Click:
                Console.WriteLine($"  Click at ({item.Action.ClickCoordinates.Value.X}, {item.Action.ClickCoordinates.Value.Y}) - Simulating click on UI element");
                if (string.Equals(oldScreenshot, "search_typed"))
                {
                    Console.WriteLine("  -> Assuming click on Search button when search field was populated, displaying results.");
                    currentScreenshot = "search_results";
                }
                else
                {
                    Console.WriteLine("  -> Assuming click on Search on results or when search was not populated, do nothing.");
                    currentScreenshot = oldScreenshot;
                }
                break;
            case ComputerCallActionKind.Drag:
                string pathStr = item.Action.DragPath.ToArray().Select(p => $"{p.X}, {p.Y}").Aggregate("", (agg, next) => $"{agg} -> {next}");
                Console.WriteLine($"  Drag path: {pathStr} - Simulating drag operation");
                break;
            case ComputerCallActionKind.Scroll:
                Console.WriteLine($"  Scroll at ({item.Action.ScrollCoordinates.Value.X}, {item.Action.ScrollCoordinates.Value.Y}) - Simulating scroll action");
                break;
            case ComputerCallActionKind.Screenshot:
                Console.WriteLine("  Taking screenshot - Capturing current screen state");
                break;
            default:
                break;
        }
        Console.WriteLine($"  -> Action processed: {item.Action.Kind}");

        return currentScreenshot;
    }

    public static void Main()
    {
        // Create project client
        AIProjectClient projectClient = new(endpoint: new Uri(ProjectEndpoint), tokenProvider: new DefaultAzureCredential());

        // Read in three example screenshots and place them into a dictionary.
        Dictionary<string, BinaryData> screenshots = new() {
            { "browser_search", ReadImageFile("Assets/cua_browser_search.png")},
            { "search_typed", ReadImageFile("Assets/cua_search_typed.png")},
            { "search_results", ReadImageFile("Assets/cua_search_results.png")},
        };

        // Create a PromptAgentDefinition with ComputerTool.
        DeclarativeAgentDefinition agentDefinition = new(model: "computer-use-preview")
        {
            Instructions = "You are a computer automation assistant.\n\n" +
                            "Be direct and efficient. When you reach the search results page, read and describe the actual search result titles and descriptions you can see.",
            Tools = {
                ResponseTool.CreateComputerTool(
                    environment: new ComputerToolEnvironment("windows"),
                    displayWidth: 1026,
                    displayHeight: 769
                ),
            }
        };
        AgentVersion agentVersion = projectClient.AgentAdministrationClient.CreateAgentVersion(
            agentName: "myAgent",
            options: new(agentDefinition)
        );
        // Create an `ResponseResult` using `ResponseItem`, containing two `ResponseContentPart`:
        // one with the image and another with the text. In the loop, request Agent
        // while it is continuing to browse web. Finally, print the tool output message.
        ProjectResponsesClient responseClient = projectClient.ProjectOpenAIClient.GetProjectResponsesClientForAgent(agentVersion.Name);
        CreateResponseOptions responseOptions = new()
        {
            TruncationMode = ResponseTruncationMode.Auto,
            InputItems =
            {
                ResponseItem.CreateUserMessageItem(
                [
                    ResponseContentPart.CreateInputTextPart("I need you to help me search for 'OpenAI news'. Please type 'OpenAI news' and submit the search. Once you see search results, the task is complete."),
                    ResponseContentPart.CreateInputImagePart(imageBytes: screenshots["browser_search"], imageBytesMediaType: "image/png", imageDetailLevel: ResponseImageDetailLevel.High)
                ]),
            },
        };
        bool computerUseCalled = false;
        string currentScreenshot = "browser_search";
        int limitIteration = 10;
        ResponseResult response;
        do
        {
            response = responseClient.CreateResponse(responseOptions);
            computerUseCalled = false;
            responseOptions.InputItems.Clear();
            responseOptions.PreviousResponseId = response.Id;
            foreach (ResponseItem responseItem in response.OutputItems)
            {
                responseOptions.InputItems.Add(responseItem);
                if (responseItem is ComputerCallResponseItem computerCall)
                {
                  if (computerCall.PendingSafetyChecks.Count > 0)
                  {
                    throw new InvalidOperationException(
                      "Pause execution and obtain end-user approval before acknowledging safety checks."
                    );
                  }
                    currentScreenshot = ProcessComputerUseCall(computerCall, currentScreenshot);
                    responseOptions.InputItems.Add(ResponseItem.CreateComputerCallOutputItem(callId: computerCall.CallId, output: ComputerCallOutput.CreateScreenshotOutput(screenshotImageBytes: screenshots[currentScreenshot], screenshotImageBytesMediaType: "image/png")));
                    computerUseCalled = true;
                }
            }
            limitIteration--;
        } while (computerUseCalled && limitIteration > 0);
        Console.WriteLine(response.GetOutputText());

        // Clean up resources by deleting Agent.
        projectClient.AgentAdministrationClient.DeleteAgentVersion(agentName: agentVersion.Name, agentVersion: agentVersion.Version);
    }
}

Oczekiwane dane wyjściowe

Poniższy przykład przedstawia oczekiwane dane wyjściowe podczas uruchamiania poprzedniego przykładu kodu:

Agent created (id: ..., name: myAgent, version: 1)
Starting computer automation session (initial screenshot: cua_browser_search.png)...
Initial response received (ID: ...)
--- Iteration 1 ---
Processing computer call (ID: ...)
  Typing text "OpenAI news" - Simulating keyboard input
  -> Action processed: Type
Sending action result back to agent (using cua_search_typed.png)...
Follow-up response received (ID: ...)
--- Iteration 2 ---
Processing computer call (ID: ...)
  Click at (512, 384) - Simulating click on UI element
  -> Assuming click on Search button when search field was populated, displaying results.
  -> Action processed: Click
Sending action result back to agent (using cua_search_results.png)...
Follow-up response received (ID: ...)
OpenAI news - Latest Updates
Agent deleted

Hostowani agenci

W tym przykładzie użyto platformy Microsoft Agent Framework i wywołano AsAIAgent(...) dla AIProjectClient wraz z FoundryAITool.CreateComputerTool(...) z Microsoft.Agents.AI.Foundry, aby udostępnić agentowi narzędzie do obsługi komputera. Zainstaluj pakiety Microsoft.Agents.AI.Foundry i Azure.AI.Projects, ustaw AZURE_AI_PROJECT_ENDPOINT i AZURE_AI_COMPUTER_USE_DEPLOYMENT_NAME zmiennych środowiskowych i zaloguj się przy użyciu az login. Ten przykład pomija funkcje pomocnicze do wykonywania zrzutów ekranu — zobacz pełny przykład z pętlą akcji i narzędziami do obsługi zasobów.

using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Foundry;
using Microsoft.Extensions.AI;
using OpenAI.Responses;

string endpoint = Environment.GetEnvironmentVariable("AZURE_AI_PROJECT_ENDPOINT")
    ?? throw new InvalidOperationException("AZURE_AI_PROJECT_ENDPOINT is not set.");
string deploymentName = Environment.GetEnvironmentVariable("AZURE_AI_COMPUTER_USE_DEPLOYMENT_NAME") ?? "computer-use-preview";

AIProjectClient projectClient = new(new Uri(endpoint), new DefaultAzureCredential());
using IHostedFileClient fileClient = projectClient.GetProjectOpenAIClient().AsIHostedFileClient();

AIAgent agent = projectClient.AsAIAgent(
    model: deploymentName,
    name: "ComputerAgent",
    instructions: "You are a computer automation assistant.",
    tools: [FoundryAITool.CreateComputerTool(ComputerToolEnvironment.Browser, 1026, 769)]);

// Upload pre-captured screenshots that simulate browser state transitions.
// (See the full sample for ComputerUseUtil implementation.)
Dictionary<string, string> screenshots = await ComputerUseUtil.UploadScreenshotAssetsAsync(fileClient);

ChatClientAgentRunOptions runOptions = new()
{
    ChatOptions = new ChatOptions
    {
        RawRepresentationFactory = (_) => new CreateResponseOptions { TruncationMode = ResponseTruncationMode.Auto },
    }
};

ChatMessage message = new(ChatRole.User,
[
    new TextContent("Search for 'OpenAI news'. Type it and submit. Once you see results, the task is complete."),
    new AIContent { RawRepresentation = ResponseContentPart.CreateInputImagePart(imageFileId: screenshots["browser_search"], imageDetailLevel: ResponseImageDetailLevel.High) }
]);

AgentSession session = await agent.CreateSessionAsync();
AgentResponse response = await agent.RunAsync(message, session: session, options: runOptions);

// Loop: parse computer call actions from response, simulate them, return new screenshots.
for (int i = 0; i < 10; i++)
{
    ComputerCallResponseItem? computerCall = response.Messages
        .SelectMany(m => m.Contents)
        .Select(c => c.RawRepresentation as ComputerCallResponseItem)
        .FirstOrDefault(item => item is not null);

    if (computerCall is null) break;

    (_, string fileId) = await ComputerUseUtil.GetScreenshotAsync(computerCall.Action, default, screenshots);

    AIContent callOutput = new()
    {
        RawRepresentation = new ComputerCallOutputResponseItem(
            computerCall.CallId,
            output: ComputerCallOutput.CreateScreenshotOutput(screenshotImageFileId: fileId))
    };

    response = await agent.RunAsync([new ChatMessage(ChatRole.User, [callOutput])], session: session, options: runOptions);
}

await ComputerUseUtil.EnsureDeleteScreenshotAssetsAsync(fileClient, screenshots);
Console.WriteLine($"Response: {response.Text}");

Oczekiwane dane wyjściowe

Po zakończeniu pętli akcji końcowa odpowiedź agenta opisuje stronę, do której dotarł:

Response: I searched for "OpenAI news" in the address bar. The top results include articles from OpenAI's blog, TechCrunch, and The Verge ...

Aby uzyskać pełną implementację pomocnika zrzutu ekranu i kompleksową pętlę akcji, zobacz Agent_Step15_ComputerUse.


Przykład użycia agenta z narzędziem do korzystania z komputera

Poniższy fragment języka TypeScript pokazuje, jak utworzyć wersję agenta za pomocą narzędzia do użycia komputera, wysłać początkowe żądanie ze zrzutem ekranu i wykonać wiele iteracji. Importuje lokalny computerUseUtil.js moduł pomocniczy i wymaga zasobów zrzutów ekranu, które nie są dołączone do tego artykułu. Traktuj ten fragment jako zarys integracji i zapewnij wykonywanie działań po stronie aplikacji, wykonywanie zrzutów ekranu oraz wyraźną zgodę dotyczącą bezpieczeństwa przed potwierdzeniem nierozstrzygniętych kontroli bezpieczeństwa.

import { DefaultAzureCredential } from "@azure/identity";
import { AIProjectClient } from "@azure/ai-projects";
import { createInterface } from "node:readline/promises";
import { stdin, stdout } from "node:process";
import {
  SearchState,
  loadScreenshotAssets,
  handleComputerActionAndTakeScreenshot,
  printFinalOutput,
  type ComputerAction,
} from "./computerUseUtil.js";

// Format: "https://resource_name.ai.azure.com/api/projects/project_name"
const PROJECT_ENDPOINT = "your_project_endpoint";

export async function main(): Promise<void> {
  // Initialize state machine
  let currentState = SearchState.INITIAL;

  // Load screenshot assets
  const screenshots = loadScreenshotAssets();
  console.log("Successfully loaded screenshot assets");

  // Create AI Project client
  const project = new AIProjectClient(PROJECT_ENDPOINT, new DefaultAzureCredential());
  const openai = project.getOpenAIClient();

  console.log("Creating Computer Use Agent...");
  const agent = await project.agents.createVersion("ComputerUseAgent", {
    kind: "prompt" as const,
    model: "computer-use-preview",
    instructions: `
You are a computer automation assistant.

Be direct and efficient. When you reach the search results page, read and describe the actual search result titles and descriptions you can see.
    `.trim(),
    tools: [
      {
        type: "computer_use_preview",
        display_width: 1026,
        display_height: 769,
        environment: "windows" as const,
      },
    ],
  });
  console.log(`Agent created (id: ${agent.id}, name: ${agent.name}, version: ${agent.version})`);

  // Initial request with screenshot - start with Bing search page
  console.log(
    "Starting computer automation session (initial screenshot: cua_browser_search.png)...",
  );
  let response = await openai.responses.create(
    {
      input: [
        {
          role: "user" as const,
          content: [
            {
              type: "input_text",
              text: "I need you to help me search for 'OpenAI news'. Please type 'OpenAI news' and submit the search. Once you see search results, the task is complete.",
            },
            {
              type: "input_image",
              image_url: screenshots.browser_search.url,
              detail: "high",
            },
          ],
        },
      ],
      truncation: "auto",
    },
    {
      body: { agent_reference: { name: agent.name, type: "agent_reference" } },
    },
  );

  console.log(`Initial response received (ID: ${response.id})`);

  // Main interaction loop with deterministic completion
  const maxIterations = 10; // Allow enough iterations for completion
  let iteration = 0;

  while (iteration < maxIterations) {
    iteration++;
    console.log(`\n--- Iteration ${iteration} ---`);

    // Check for computer calls in the response
    const computerCalls = response.output.filter((item) => item.type === "computer_call");

    if (computerCalls.length === 0) {
      printFinalOutput({
        output: response.output,
        status: response.status ?? "",
      });
      break;
    }

    // Process the first computer call
    const computerCall = computerCalls[0];
    const action: ComputerAction = computerCall.action;
    const callId: string = computerCall.call_id;

    // Never execute an action with pending safety checks without user approval.
    const safetyChecks = computerCall.pending_safety_checks ?? [];
    if (safetyChecks.length > 0) {
      for (const check of safetyChecks) {
        console.warn(`Safety check: ${check.code}: ${check.message}`);
      }
      const prompt = createInterface({ input: stdin, output: stdout });
      const answer = await prompt.question("Approve this action? Type yes to continue: ");
      prompt.close();
      if (answer.toLowerCase() !== "yes") {
        throw new Error("Action rejected by the user.");
      }
    }

    console.log(`Processing computer call (ID: ${callId})`);

    // Handle the action and get the screenshot info
    const [screenshotInfo, updatedState] = handleComputerActionAndTakeScreenshot(
      action,
      currentState,
      screenshots,
    );
    currentState = updatedState;

    console.log(`Sending action result back to agent (using ${screenshotInfo.filename})...`);
    // Regular response with just the screenshot
    response = await openai.responses.create(
      {
        previous_response_id: response.id,
        input: [
          {
            call_id: callId,
            type: "computer_call_output",
            acknowledged_safety_checks: safetyChecks,
            output: {
              type: "computer_screenshot",
              image_url: screenshotInfo.url,
            },
          },
        ],
        truncation: "auto",
      },
      {
        body: { agent_reference: { name: agent.name, type: "agent_reference" } },
      },
    );

    console.log(`Follow-up response received (ID: ${response.id})`);
  }

  if (iteration >= maxIterations) {
    console.log(`\nReached maximum iterations (${maxIterations}). Stopping.`);
  }

  // Clean up resources
  console.log("\nCleaning up...");
  await project.agents.deleteVersion(agent.name, agent.version);
  console.log("Agent deleted");

  console.log("\nComputer Use Agent sample completed!");
}

main().catch((err) => {
  console.error("The sample encountered an error:", err);
});

Oczekiwane dane wyjściowe

Poniższy przykład przedstawia oczekiwane dane wyjściowe podczas uruchamiania poprzedniego przykładu kodu:

Successfully loaded screenshot assets
Creating Computer Use Agent...
Agent created (id: ..., name: ComputerUseAgent, version: 1)
Starting computer automation session (initial screenshot: cua_browser_search.png)...
Initial response received (ID: ...)
--- Iteration 1 ---
Processing computer call (ID: ...)
  Typing text "OpenAI news" - Simulating keyboard input
  -> Action processed: type
Sending action result back to agent (using cua_search_typed.png)...
Follow-up response received (ID: ...)
--- Iteration 2 ---
Processing computer call (ID: ...)
    Click at (512, 384) - Simulating click on UI element
    -> Assuming click on Search button when search field was populated, displaying results.
    -> Action processed: click
Sending action result back to agent (using cua_search_results.png)...
Follow-up response received (ID: ...)
OpenAI news - Latest Updates
Cleaning up...
Agent deleted
Computer Use Agent sample completed!

Używanie komputera w agencie Java

Dodaj zależność do elementu pom.xml:

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-ai-agents</artifactId>
    <version>2.4.0</version>
</dependency>

Tworzenie agenta użycia komputera

import com.azure.ai.agents.AgentsClient;
import com.azure.ai.agents.AgentsClientBuilder;
import com.azure.ai.agents.ResponsesClient;
import com.azure.ai.agents.models.*;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;

import java.util.Collections;

public class ComputerUseExample {
    // Format: "https://resource_name.ai.azure.com/api/projects/project_name"
    private static final String PROJECT_ENDPOINT = "your_project_endpoint";

    public static void main(String[] args) {

        AgentsClientBuilder builder = new AgentsClientBuilder()
            .credential(new DefaultAzureCredentialBuilder().build())
            .endpoint(PROJECT_ENDPOINT);

        AgentsClient agentsClient = builder.buildAgentsClient();
        ResponsesClient responsesClient = builder.buildResponsesClient();

        // Create computer use tool
        ComputerUsePreviewTool tool = new ComputerUsePreviewTool(
            ComputerEnvironment.WINDOWS,
            1024,
            768
        );

        // Create agent with computer use tool
        PromptAgentDefinition agentDefinition = new PromptAgentDefinition("computer-use-preview")
            .setInstructions("You are a computer automation assistant.")
            .setTools(Collections.singletonList(tool));

        AgentVersionDetails agent = agentsClient.createAgentVersion("computer-use-agent", agentDefinition);
        System.out.printf("Agent created: %s (version %s)%n", agent.getName(), agent.getVersion());

        // Create a response with initial screenshot
        AgentReference agentReference = new AgentReference(agent.getName())
            .setVersion(agent.getVersion());

        Response response = responsesClient.createAzureResponse(
            new AzureCreateResponseOptions().setAgentReference(agentReference),
            ResponseCreateParams.builder()
                .input("Open the browser and navigate to microsoft.com"));

        System.out.println("Response: " + response.output());

        // The response will contain computer_call items with actions
        // to execute. Process each action, take screenshots, and
        // send results back using responsesClient.createAzureResponse()
        // with the previousResponseId and computer call output.

        // Clean up
        agentsClient.deleteAgentVersion(agent.getName(), agent.getVersion());
    }
}

W przypadku pełnej pętli symulowanej użyj obsługiwanego przykładu ComputerUseSync.java z pomocnikiem ComputerUseUtil.java. Pomocnik przyporządkowuje żądane akcje do wcześniej przechwyconych zrzutów ekranu. Zastąp tę symulację mechanizmem wykonywania działań aplikacji, mechanizmem przechwytywania zrzutów ekranu oraz procesem zatwierdzania pod kątem bezpieczeństwa.

Używanie komputera z interfejsem API REST

Uzyskiwanie tokenu dostępu:

export AGENT_TOKEN=$(az account get-access-token --scope "https://ai.azure.com/.default" --query accessToken -o tsv)

Tworzenie agenta z użyciem komputera

curl -X POST "$FOUNDRY_PROJECT_ENDPOINT/agents?api-version=v1" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AGENT_TOKEN" \
  -d '{
    "name": "computer-use-agent",
    "definition": {
      "kind": "prompt",
      "model": "computer-use-preview",
      "instructions": "You are a computer automation assistant.",
      "tools": [
        {
          "type": "computer_use_preview",
          "environment": "windows",
          "display_width": 1024,
          "display_height": 768
        }
      ]
    }
  }'

Generowanie odpowiedzi

curl -X POST "$FOUNDRY_PROJECT_ENDPOINT/openai/v1/responses" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AGENT_TOKEN" \
  -d '{
    "agent_reference": {"type": "agent_reference", "name": "computer-use-agent"},
    "input": "Open the browser and navigate to microsoft.com"
  }'

Odpowiedź zawiera computer_call elementy wyjściowe z akcjami do wykonania. Przed wykonaniem działania sprawdź pending_safety_checks. Jeśli tablica nie jest pusta, wstrzymaj i wyświetl akcję i kontrole bezpieczeństwa dla użytkownika końcowego. Kontynuuj tylko po jawnym zatwierdzeniu akcji przez użytkownika.

Przesyłanie wyników akcji za pomocą zrzutu ekranu

Gdy użytkownik zatwierdzi wszelkie oczekujące kontrole bezpieczeństwa, a aplikacja wykona działanie na komputerze, przechwyć zrzut ekranu i odeślij go. Uwzględnij każdą zatwierdzoną kontrolę w acknowledged_safety_checks. Jeśli nie zostały zwrócone żadne kontrole, użyj pustej tablicy.

curl -X POST "$FOUNDRY_PROJECT_ENDPOINT/openai/v1/responses" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AGENT_TOKEN" \
  -d '{
    "agent_reference": {"type": "agent_reference", "name": "computer-use-agent"},
    "previous_response_id": "<RESPONSE_ID>",
    "input": [
      {
        "type": "computer_call_output",
        "call_id": "<CALL_ID>",
        "acknowledged_safety_checks": [],
        "output": {
          "type": "computer_screenshot",
          "image_url": "data:image/png;base64,<BASE64_SCREENSHOT>"
        }
      }
    ]
  }'

Zastąp wartości <RESPONSE_ID>, <CALL_ID> i <BASE64_SCREENSHOT> wartościami z poprzedniej odpowiedzi. Powtórz ten cykl, dopóki model nie zwróci odpowiedzi tekstowej zamiast computer_call.

Czyszczenie

curl -X DELETE "$FOUNDRY_PROJECT_ENDPOINT/agents/computer-use-agent?api-version=v1" \
  -H "Authorization: Bearer $AGENT_TOKEN"

Co można zrobić za pomocą narzędzia do korzystania z komputera

Po zintegrowaniu pętli żądanie-odpowiedź (zrzut ekranu —> akcja —> zrzut ekranu), narzędzie do obsługi komputera może pomóc agentowi:

  • Zaproponuj akcje interfejsu użytkownika, takie jak klikanie, wpisywanie, przewijanie i żądanie nowego zrzutu ekranu.
  • Dostosuj się do zmian interfejsu użytkownika, ponownie oceniając najnowszy zrzut ekranu po każdej akcji.
  • Praca zarówno w przeglądarce, jak i w interfejsie użytkownika pulpitu, w zależności od sposobu, w jaki hostujesz swoje środowisko sandbox.

Narzędzie nie kontroluje bezpośrednio urządzenia. Aplikacja wykonuje każdą żądaną akcję i zwraca zaktualizowany zrzut ekranu.

Różnice między automatyzacją przeglądarki a użyciem komputera

W poniższej tabeli wymieniono niektóre różnice między narzędziem do używania komputera i narzędziem do automatyzacji przeglądarki .

Funkcja Automatyzacja przeglądarki Narzędzie do korzystania z komputera
Obsługa modelu Wszystkie modele GPT computer-use-preview tylko model
Czy mogę zwizualizować, co się dzieje? Tak Tak
Jak rozumie ekran Analizuje strony HTML lub XML w dokumentach DOM Nieprzetworzone dane pikseli ze zrzutów ekranu
Jak działa Lista akcji udostępnianych przez model Wirtualna klawiatura i mysz
Czy jest to wieloetapowe? Tak Tak
Interfejsy Przeglądarka Komputer i przeglądarka
Czy muszę przynieść własny zasób? Własny zasób Playwright z kluczami przechowywanymi jako połączenie. Nie są wymagane żadne dodatkowe zasoby, ale uruchom to narzędzie w środowisku izolowanym.

Kiedy należy używać każdego narzędzia

Wybierz użycie komputera, jeśli musisz:

  • Interakcja z aplikacjami stacjonarnymi poza przeglądarką
  • Wizualizowanie danych widocznych przez agenta za pomocą zrzutów ekranu
  • Praca w środowiskach, w których analizowanie DOM nie jest dostępne

Wybierz automatyzację przeglądarki, jeśli musisz:

  • Wykonywanie interakcji tylko z internetem bez ograniczonych wymagań dotyczących dostępu
  • Użyj dowolnego modelu GPT (nie tylko computer-use-preview)
  • Unikaj zarządzania pętlami przechwytywania zrzutów ekranu i wykonywania akcji

Regionalne wsparcie

Aby użyć narzędzia do obsługi komputera, potrzebne jest wdrożenie modelu użycia komputera. Model użycia komputera jest dostępny w następujących regionach:

Region Stan
eastus2 Dostępne
swedencentral Dostępne
southindia Dostępne

Informacje o integracji użycia komputera

Podczas pracy z narzędziem do korzystania z komputera zintegruj go z aplikacją, wykonując następujące kroki:

  1. Wyślij wniosek do modelu zawierający wywołanie narzędzia do obsługi komputera, rozmiar ekranu i środowisko. Możesz również dołączyć zrzut ekranu przedstawiający początkowy stan środowiska w pierwszym żądaniu interfejsu API.

  2. Odbierz odpowiedź z modelu. Jeśli odpowiedź zawiera elementy akcji, te elementy zawierają sugerowane akcje, aby poczynić postępy w kierunku określonego celu. Na przykład akcja może być screenshot taka, że model może ocenić bieżący stan za pomocą zaktualizowanego zrzutu ekranu lub click współrzędnych X/Y wskazujących, gdzie należy przenieść mysz.

  3. Wykonaj akcję przy użyciu kodu aplikacji na komputerze lub w środowisku przeglądarki.

  4. Po wykonaniu akcji przechwyć zaktualizowany stan środowiska jako zrzut ekranu.

  5. Wyślij nowe żądanie z nowym stanem jako tool_call_output, a następnie powtarzaj tę pętlę, dopóki model nie przestanie żądać akcji lub zdecydujesz się zatrzymać.

    Uwaga

    Przed użyciem narzędzia skonfiguruj środowisko, które umożliwia przechwytywanie zrzutów ekranu i wykonywanie zalecanych akcji przez agenta. Ze względów bezpieczeństwa należy użyć odizolowanego środowiska, takiego jak Playwright.

Zarządzanie historią konwersacji

Użyj parametru , previous_response_id aby połączyć bieżące żądanie z poprzednią odpowiedzią. Użyj tego parametru, gdy nie chcesz wysyłać pełnej historii konwersacji z każdym wywołaniem.

Jeśli nie używasz tego parametru, pamiętaj, aby uwzględnić w tablicy danych wejściowych wszystkie elementy zwrócone w odpowiedzi na poprzednie żądanie. To wymaganie obejmuje elementy rozumowania, jeśli są obecne.

Zagadnienia dotyczące kontroli bezpieczeństwa i zabezpieczeń

Ostrzeżenie

Korzystanie z komputera wiąże się ze znacznym ryzykiem bezpieczeństwa i prywatności oraz odpowiedzialnością użytkowników. Zarówno błędy w ocenie przez sztuczną inteligencję, jak i obecność złośliwych lub mylących instrukcji na stronach internetowych, pulpitach lub innych środowiskach operacyjnych, które napotyka sztuczna inteligencja, mogą spowodować wykonanie przez nią poleceń, które Ty lub inne osoby nie miały na myśli. Te zagrożenia mogą zagrozić bezpieczeństwu przeglądarek, komputerów i kont użytkowników, do których sztuczna inteligencja ma dostęp, w tym systemów osobistych, finansowych lub przedsiębiorstwa.

Użyj narzędzia do używania komputera na maszynach wirtualnych bez dostępu do poufnych danych ani krytycznych zasobów. Aby uzyskać więcej informacji o zamierzonych zastosowaniach, możliwościach, ograniczeniach, ryzyku i zagadnieniach dotyczących wybierania przypadku użycia, zapoznaj się z informacjami o przejrzystości usługi Azure OpenAI.

Interfejs API ma kontrole bezpieczeństwa, które pomagają chronić przed wstrzyknięciem polecenia i błędami modelu. Te testy obejmują:

Wykrywanie złośliwych instrukcji: system ocenia obraz zrzutu ekranu i sprawdza, czy zawiera niepożądane treści, które mogą zmienić zachowanie modelu.

Nieistotne wykrywanie domeny: system ocenia current_url parametr (jeśli podano) i sprawdza, czy bieżąca domena jest odpowiednia, biorąc pod uwagę historię konwersacji.

Wykrywanie domen poufnych: system sprawdza current_url parametr (jeśli podano) i zgłasza ostrzeżenie, gdy wykryje, że użytkownik znajduje się w domenie poufnej.

Jeśli zostanie wyzwolony co najmniej jeden z powyższych testów, model zgłasza ostrzeżenie o bezpieczeństwie podczas zwracania następnego computer_call przy użyciu parametru pending_safety_checks.

"output": [ 
    { 
        "type": "reasoning", 
        "id": "rs_67cb...", 
        "summary": [ 
            { 
                "type": "summary_text", 
                "text": "Exploring 'File' menu option." 
            } 
        ] 
    }, 
    { 
        "type": "computer_call", 
        "id": "cu_67cb...", 
        "call_id": "call_nEJ...", 
        "action": { 
            "type": "click", 
            "button": "left", 
            "x": 135, 
            "y": 193 
        }, 
        "pending_safety_checks": [ 
            { 
                "id": "cu_sc_67cb...", 
                "code": "malicious_instructions", 
                "message": "We've detected instructions that may cause your application to perform malicious or unauthorized actions. Please acknowledge this warning if you'd like to proceed." 
            } 
        ], 
        "status": "completed" 
    } 
]

Należy ponownie przejść kontrole bezpieczeństwa, tak jak acknowledged_safety_checks w następnym żądaniu, aby kontynuować.

"input":[ 
        { 
            "type": "computer_call_output", 
            "call_id": "<call_id>", 
            "acknowledged_safety_checks": [ 
                { 
                    "id": "<safety_check_id>", 
                    "code": "malicious_instructions", 
                    "message": "We've detected instructions that may cause your application to perform malicious or unauthorized actions. Please acknowledge this warning if you'd like to proceed." 
                } 
            ], 
            "output": { 
                "type": "computer_screenshot", 
                "image_url": "<image_url>" 
            } 
        } 
    ]

Obsługa kontroli bezpieczeństwa

We wszystkich przypadkach, w których pending_safety_checks są zwracane, przekaż akcje użytkownikowi końcowemu w celu potwierdzenia prawidłowego zachowania i dokładności modelu.

malicious_instructions i irrelevant_domain: Użytkownicy końcowi powinni przejrzeć akcje modelu i potwierdzić, że model działa zgodnie z oczekiwaniami.

sensitive_domain: Upewnij się, że użytkownik końcowy aktywnie monitoruje akcje modelu w tych witrynach. Dokładna implementacja tego "trybu obserwacji" może się różnić w zależności od aplikacji, ale potencjalnym przykładem może być zbieranie danych wrażenia użytkownika w witrynie w celu upewnienia się, że istnieje aktywne zaangażowanie użytkowników końcowych w aplikację.

Rozwiązywanie problemów

Kwestia Przyczyna Rozdzielczość
Nie widzisz computer_call w odpowiedzi. Agent nie jest skonfigurowany za pomocą narzędzia do zarządzania komputerem, wdrożenie nie korzysta z modelu użytkowania komputera lub monit nie wymaga interakcji z interfejsem użytkownika. Upewnij się, że agent ma narzędzie computer_use_preview, wdrożenie jest modelem computer-use-preview, a monit wymaga akcji interfejsu użytkownika (wpisanie, kliknięcie lub zrzut ekranu).
Przykładowy kod nie działa z powodu brakujących plików pomocy lub zrzutów ekranu. Fragmenty odwołują się do narzędzi pomocnika i przykładowych obrazów, które nie są częścią tego repozytorium dokumentacji. Sklonuj jeden z obsługiwanych przykładów w sekcji "Uruchamianie obsługiwanych przykładów zestawu SDK", aby jego pomocnik i zasoby pozostały w ich oczekiwanych lokalizacjach względnych. W przypadku języka TypeScript podaj własne zasoby pomocnicze i zrzuty ekranu.
Pętla zatrzymuje się na limicie iteracji. Zadanie wymaga większej liczby iteracji lub aplikacja nie stosuje się do działań żądanych przez model. Zwiększ limit iteracji i sprawdź, czy kod wykonuje żądaną akcję oraz wysyła nowy zrzut ekranu po każdej iteracji.
Otrzymasz komunikat pending_safety_checks. Usługa wykryła potencjalne zagrożenie bezpieczeństwa (wstrzyknięcie poleceń lub wrażliwa domena, na przykład). Wstrzymaj automatyzację, wymagaj, by użytkownik końcowy przejrzał żądanie, i kontynuuj tylko po wysłaniu acknowledged_safety_checks z następnym computer_call_output.
Model powtarza "wykonaj zrzut ekranu" bez podejmowania postępów. Zrzut ekranu nie jest aktualizowany, ma niską jakość lub nie wyświetla odpowiedniego stanu interfejsu użytkownika. Wyślij nowy zrzut ekranu po każdej akcji i w razie potrzeby użyj obrazu o wyższym poziomie szczegółowości. Upewnij się, że zrzut ekranu zawiera odpowiedni interfejs użytkownika.
Odmowa dostępu podczas żądania computer-use-preview modelu. Nie zarejestrowano cię w celu uzyskania dostępu lub nie udzielono dostępu. Prześlij formularz aplikacji i poczekaj na zatwierdzenie. Sprawdź wiadomość e-mail w celu potwierdzenia.
Zrzut ekranu przedstawiający błędy kodowania. Nieobsługiwany format obrazu lub problem z kodowaniem base64. Użyj formatu PNG lub JPEG. Upewnij się, że kodowanie base64 jest prawidłowe i nie ulega uszkodzeniu. Sprawdź, czy wymiary obrazu są zgodne display_width i display_height.
Akcje są wykonywane na nieprawidłowych współrzędnych. Niezgodność rozdzielczości ekranu między zrzutem ekranu a rzeczywistym wyświetlaniem. Upewnij się, że display_width i display_height w ComputerUsePreviewTool odpowiadają rzeczywistej rozdzielczości ekranu.
Model halucynuje elementy interfejsu użytkownika. Jakość zrzutu ekranu jest zbyt niska lub interfejs użytkownika zmienił się między etapami. Użyj zrzutów ekranu o wyższej rozdzielczości. Wysyłaj nowe zrzuty ekranu bezpośrednio po każdej akcji. Zmniejsz opóźnienie między akcją a zrzutem ekranu.