다음을 통해 공유


에이전트 실행

기본 에이전트 추상화는 에이전트를 실행하기 위한 다양한 옵션을 노출합니다. 호출자는 0개, 1개 또는 많은 입력 메시지를 제공할 수 있습니다. 호출자는 스트리밍과 비 스트리밍 중에서 선택할 수도 있습니다. 다양한 사용 시나리오를 살펴보겠습니다.

스트리밍 및 비 스트리밍

Microsoft Agent Framework는 에이전트를 실행하기 위한 스트리밍 및 비 스트리밍 방법을 모두 지원합니다.

비 스트리밍의 경우 메서드를 RunAsync 사용합니다.

Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?"));

스트리밍의 경우 메서드를 RunStreamingAsync 사용합니다.

await foreach (var update in agent.RunStreamingAsync("What is the weather like in Amsterdam?"))
{
    Console.Write(update);
}

비 스트리밍의 경우 메서드를 run 사용합니다.

result = await agent.run("What is the weather like in Amsterdam?")
print(result.text)

스트리밍의 경우 .와 함께 stream=True메서드를 run 사용합니다. 비동기적으로 반복할 수 있는 개체를 반환 ResponseStream 합니다.

async for update in agent.run("What is the weather like in Amsterdam?", stream=True):
    if update.text:
        print(update.text, end="", flush=True)

ResponseStream

반환된 run(..., stream=True) 개체는 ResponseStream 다음 두 가지 사용 패턴을 지원합니다.

패턴 1: 비동기 반복 - 실시간 표시를 위해 도착하는 업데이트를 처리합니다.

response_stream = agent.run("Tell me a story", stream=True)
async for update in response_stream:
    if update.text:
        print(update.text, end="", flush=True)

패턴 2: 직접 종료 - 반복을 건너뛰고 전체 응답을 가져옵니다.

response_stream = agent.run("Tell me a story", stream=True)
final = await response_stream.get_final_response()
print(final.text)

패턴 3: 결합 - 실시간 표시를 반복한 다음 집계된 결과를 가져옵니다.

response_stream = agent.run("Tell me a story", stream=True)

# First, iterate to display streaming output
async for update in response_stream:
    if update.text:
        print(update.text, end="", flush=True)

# Then get the complete response (uses already-collected updates, does not re-iterate)
final = await response_stream.get_final_response()
print(f"\n\nFull response: {final.text}")
print(f"Messages: {len(final.messages)}")

에이전트 실행 옵션

기본 에이전트 추상화는 각 에이전트 실행에 대한 옵션 개체를 전달할 수 있지만 추상화 수준에서 실행을 사용자 지정하는 기능은 매우 제한적입니다. 에이전트는 크게 달라질 수 있으므로 일반적인 사용자 지정 옵션은 없습니다.

호출자가 작업 중인 에이전트의 형식을 알고 있는 경우 실행을 사용자 지정할 수 있도록 형식별 옵션을 전달할 수 있습니다.

예를 들어 여기서 에이전트는 a ChatClientAgent 이며 상속되는 개체를 ChatClientAgentRunOptions 전달할 수 있습니다 AgentRunOptions. 이렇게 하면 호출자가 빌드된 항목에 전달되기 전에 에이전트 수준 옵션과 병합되는 사용자 지정 ChatOptionsIChatClient 제공할 수 ChatClientAgent 있습니다.

var chatOptions = new ChatOptions() { Tools = [AIFunctionFactory.Create(GetWeather)] };
Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?", options: new ChatClientAgentRunOptions(chatOptions)));

Python 에이전트는 매개 변수를 통해 각 실행을 사용자 지정할 수 options 있습니다. 옵션은 TypedDict로 전달되며 생성 시간(통해 default_options)과 실행당(통해 options) 둘 다에서 설정할 수 있습니다. 각 공급자에는 공급자별 설정에 대한 전체 IDE 자동 완성 및 형식 검사를 제공하는 고유한 TypedDict 클래스가 있습니다.

일반 옵션은 다음과 같습니다.

  • max_tokens: 생성할 최대 토큰 수
  • temperature: 응답 생성의 임의성을 제어합니다.
  • model_id: 이 특정 실행에 대한 모델 재정의
  • top_p: Nucleus 샘플링 매개 변수
  • response_format: 응답 형식 지정(예: 구조적 출력)

비고

tools 매개 변수는 instructions 직접 키워드 인수로 유지되며 사전을 options 통해 전달되지 않습니다.

from agent_framework.openai import OpenAIChatClient, OpenAIChatOptions

# Set default options at construction time
agent = OpenAIChatClient().as_agent(
    instructions="You are a helpful assistant",
    default_options={
        "temperature": 0.7,
        "max_tokens": 500
    }
)

# Run with custom options (overrides defaults)
# OpenAIChatOptions provides IDE autocomplete for all OpenAI-specific settings
options: OpenAIChatOptions = {
    "temperature": 0.3,
    "max_tokens": 150,
    "model_id": "gpt-4o",
    "presence_penalty": 0.5,
    "frequency_penalty": 0.3
}

result = await agent.run(
    "What is the weather like in Amsterdam?",
    options=options
)

# Streaming with custom options
async for update in agent.run(
    "Tell me a detailed weather forecast",
    stream=True,
    options={"temperature": 0.7, "top_p": 0.9},
    tools=[additional_weather_tool]  # tools is still a keyword argument
):
    if update.text:
        print(update.text, end="", flush=True)

각 공급자에는 해당 공급자가 지원하는 전체 옵션 집합을 노출하는 고유한 TypedDict 클래스(예: OpenAIChatOptions, AnthropicChatOptions, OllamaChatOptions)가 있습니다.

실행 default_options 당 옵션이 둘 다 options 제공되면 실행당 옵션이 우선하며 기본값과 병합됩니다.

응답 형식

에이전트의 스트리밍 및 비 스트리밍 응답에는 에이전트에서 생성된 모든 콘텐츠가 모두 포함됩니다. 콘텐츠에는 에이전트의 결과(즉, 사용자 질문에 대한 답변)가 아닌 데이터가 포함될 수 있습니다. 반환된 다른 데이터의 예로는 함수 도구 호출, 함수 도구 호출 결과, 추론 텍스트, 상태 업데이트 등이 있습니다.

반환된 모든 콘텐츠가 결과인 것은 아니므로 결과를 다른 콘텐츠와 격리하려고 할 때 특정 콘텐츠 형식을 찾는 것이 중요합니다.

응답에서 텍스트 결과를 추출하려면 모든 항목의 모든 TextContentChatMessages 항목을 집계해야 합니다. 이를 Text 간소화하기 위해 모든 TextContent을 집계하는 모든 응답 형식에서 속성을 사용할 수 있습니다.

비 스트리밍 사례의 경우 모든 항목이 하나의 AgentResponse 개체로 반환됩니다. AgentResponse 에서는 속성을 통해 Messages 생성된 메시지에 액세스할 수 있습니다.

var response = await agent.RunAsync("What is the weather like in Amsterdam?");
Console.WriteLine(response.Text);
Console.WriteLine(response.Messages.Count);

스트리밍 사례 AgentResponseUpdate 의 경우 개체가 생성될 때 스트리밍됩니다. 각 업데이트에는 에이전트의 결과 일부와 기타 다양한 콘텐츠 항목이 포함될 수 있습니다. 비 스트리밍 사례와 마찬가지로, 속성을 사용하여 Text 업데이트에 포함된 결과의 일부를 가져와서 속성을 통해 Contents 세부 정보를 드릴할 수 있습니다.

await foreach (var update in agent.RunStreamingAsync("What is the weather like in Amsterdam?"))
{
    Console.WriteLine(update.Text);
    Console.WriteLine(update.Contents.Count);
}

비 스트리밍 사례의 경우 모든 항목이 하나의 AgentResponse 개체로 반환됩니다. AgentResponse 에서는 속성을 통해 messages 생성된 메시지에 액세스할 수 있습니다.

응답에서 텍스트 결과를 추출하려면 모든 항목의 모든 TextContentMessage 항목을 집계해야 합니다. 이를 Text 간소화하기 위해 모든 TextContent을 집계하는 모든 응답 형식에서 속성을 사용할 수 있습니다.

response = await agent.run("What is the weather like in Amsterdam?")
print(response.text)
print(len(response.messages))

# Access individual messages
for message in response.messages:
    print(f"Role: {message.role}, Text: {message.text}")

스트리밍 사례 AgentResponseUpdate 의 경우 개체는 반환run(..., stream=True)된 개체를 통해 ResponseStream 생성될 때 스트리밍됩니다. 각 업데이트에는 에이전트의 결과 일부와 기타 다양한 콘텐츠 항목이 포함될 수 있습니다. 비 스트리밍 사례와 마찬가지로, 속성을 사용하여 text 업데이트에 포함된 결과의 일부를 가져와서 속성을 통해 contents 세부 정보를 드릴할 수 있습니다.

response_stream = agent.run("What is the weather like in Amsterdam?", stream=True)
async for update in response_stream:
    print(f"Update text: {update.text}")
    print(f"Content count: {len(update.contents)}")

    # Access individual content items
    for content in update.contents:
        if hasattr(content, 'text'):
            print(f"Content: {content.text}")

# Get the aggregated final response after streaming
final = await response_stream.get_final_response()
print(f"Complete text: {final.text}")

메시지 유형

에이전트의 입력 및 출력은 메시지로 표시됩니다. 메시지는 콘텐츠 항목으로 세분화됩니다.

Microsoft 에이전트 프레임워크는 추상화에서 제공하는 메시지 및 콘텐츠 형식을 Microsoft.Extensions.AI 사용합니다. 메시지는 클래스로 ChatMessage 표시되고 모든 콘텐츠 클래스는 기본 AIContent 클래스에서 상속됩니다.

다양한 유형의 콘텐츠를 나타내는 데 사용되는 다양한 AIContent 하위 클래스가 있습니다. 일부는 기본 Microsoft.Extensions.AI 추상화의 일부로 제공되지만 공급자는 필요한 경우 자체 형식을 추가할 수도 있습니다.

다음은 다음과 같은 인기 있는 형식입니다.Microsoft.Extensions.AI

유형 Description
TextContent 사용자 또는 개발자의 입력과 에이전트의 출력을 모두 입력할 수 있는 텍스트 콘텐츠입니다. 일반적으로 에이전트의 텍스트 결과를 포함합니다.
DataContent 입력 및 출력이 모두 될 수 있는 이진 콘텐츠입니다. 이미지, 오디오 또는 비디오 데이터를 에이전트(지원되는 위치)와 오가는 데 사용할 수 있습니다.
UriContent 일반적으로 이미지, 오디오 또는 비디오와 같은 호스트된 콘텐츠를 가리키는 URL입니다.
FunctionCallContent 함수 도구를 호출하기 위한 유추 서비스의 요청입니다.
FunctionResultContent 함수 도구 호출의 결과입니다.

Python 에이전트 프레임워크는 패키지의 메시지 및 콘텐츠 형식을 agent_framework 사용합니다. 메시지는 클래스로 Message 표시되고 모든 콘텐츠 클래스는 기본 Content 클래스에서 상속됩니다.

다양한 유형의 콘텐츠를 나타내는 데 사용되는 다양한 Content 하위 클래스가 있습니다.

유형 Description
Content 팩터리 메서드(Content.from_text(), Content.from_data(), Content.from_uri())를 사용한 통합 콘텐츠 형식입니다. type 속성을 사용하여 콘텐츠 형식("text", "data", "uri")을 확인합니다.
FunctionCallContent 함수 도구를 호출하기 위한 AI 서비스의 요청입니다.
FunctionResultContent 함수 도구 호출의 결과입니다.
ErrorContent 처리가 실패할 때의 오류 정보입니다.
UsageContent AI 서비스의 토큰 사용량 및 청구 정보입니다.

다양한 콘텐츠 형식으로 작업하는 방법은 다음과 같습니다.

from agent_framework import Message, Content

# Create a text message
text_message = Message(role="user", contents=["Hello!"])

# Create a message with multiple content types
image_data = b"..."  # your image bytes
mixed_message = Message(
    role="user",
    contents=[
        Content.from_text("Analyze this image:"),
        Content.from_data(data=image_data, media_type="image/png"),
    ]
)

# Access content from responses
response = await agent.run("Describe the image")
for message in response.messages:
    for content in message.contents:
        if content.type == "text":
            print(f"Text: {content.text}")
        elif content.type == "data":
            print(f"Data URI: {content.uri}")
        elif content.type == "uri":
            print(f"External URI: {content.uri}")

다음 단계: