템플릿으로 에이전트 만들기

Semantic Kernel 템플릿으로 에이전트 만들기

Semantic Kernel의 프롬프트 템플릿

에이전트의 역할은 대부분 받는 지시문(instructions) 에 의해 결정돼요. 지시문이 행동과 동작을 좌우하죠. Kernel 프롬프트를 호출할 때처럼, 에이전트의 지시문에도 값과 함수를 담은 템플릿 파라미터를 넣을 수 있고, 실행 중에 동적으로 치환됩니다. 덕분에 실시간 입력에 맞춰 출력을 조정하는 유연하고 컨텍스트를 아는 응답이 가능해져요.

또한 프롬프트 템플릿 구성(Prompt Template Configuration) 으로 에이전트를 직접 정의할 수 있어요. 이 접근은 에이전트 행동을 구조화하고 재사용 가능하게 정의할 수 있는 방법을 제공해서, 다양한 사용 사례에서 지시문을 표준화·커스터마이즈하고 일관성을 유지하면서도 동적 적응력을 지킬 수 있게 해줍니다.

지시문을 템플릿으로 쓰기

템플릿 파라미터로 에이전트를 만들면, 시나리오나 요구 사항에 따라 지시문을 쉽게 커스터마이즈할 수 있어요. 템플릿에 특정 값이나 함수를 치환해 에이전트 행동을 맞추는 거죠. 여러 작업이나 컨텍스트에 적응할 수 있어서, 핵심 로직을 건드리지 않고 다양한 사용 사례에 맞는 범용 에이전트를 설계할 수 있어요.

채팅 완성 에이전트

agent = ChatCompletionAgent(
    service=AzureChatCompletion(), # or other supported AI services
    name="StoryTeller",
    instructions="Tell a story about {{$topic}} that is {{$length}} sentences long.",
    arguments=KernelArguments(topic="Dog", length="2"),
)

C#에서는 KernelPromptTemplateFactory()PromptTemplateConfig 를 조합해 만들고, KernelArguments 에 기본값을 채워 넣어요.

var instructions = "Tell a story about {{$topic}} that is {{$length}} sentences long.";

ChatCompletionAgent agent =
    new(templateFactory: new KernelPromptTemplateFactory(),
        templateConfig: new(instructions) { TemplateFormat = PromptTemplateConfig.SemanticKernelTemplateFormat })
    {
        Kernel = kernel,
        Name = "StoryTeller",
        Arguments = new KernelArguments()
        {
            { "topic", "Dog" },
            { "length", "3" },
        }
    };

OpenAI 어시스턴트 에이전트

템플릿 지시문은 OpenAIAssistantAgent 와 함께 쓸 때 특히 강력해요. 하나의 어시스턴트 정의를 여러 번 재사용하면서, 매번 작업이나 컨텍스트에 맞는 다른 파라미터 값을 넣을 수 있거든요. 같은 어시스턴트 프레임워크로 넓은 시나리오를 처리하면서도 핵심 행동의 일관성을 유지할 수 있어요.

client, model = AzureAssistantAgent.setup_resources()

# Retrieve the assistant definition from the server based on the assistant ID
definition = await client.beta.assistants.retrieve(
    assistant_id="your-assistant-id",
)

agent = AzureAssistantAgent(
    client=client,
    definition=definition,
    arguments=KernelArguments(topic="Dog", length="3"),
)

프롬프트 템플릿에서 에이전트 정의하기

Kernel 프롬프트 함수를 만들 때 쓰는 것과 똑같은 프롬프트 템플릿 구성으로 에이전트를 정의할 수 있어요. 이러면 프롬프트와 에이전트를 하나의 방식으로 관리해서 일관성과 재사용을 높일 수 있습니다. 에이전트 정의를 코드베이스에서 분리하면 여러 에이전트를 관리하기 쉬워지고, 기반 로직을 바꾸지 않고도 업데이트·유지 보수하기 좋아져요. 개발자는 코드를 고치는 대신 구성을 갱신하는 것만으로 에이전트 행동을 바꾸거나 새 에이전트를 추가할 수 있어요.

YAML 템플릿

name: GenerateStory
template: |
  Tell a story about {{$topic}} that is {{$length}} sentences long.
template_format: semantic-kernel
description: A function that generates a story about a topic.
input_variables:
  - name: topic
    description: The topic of the story.
    is_required: true
  - name: length
    description: The number of sentences in the story.
    is_required: true

에이전트 초기화

import yaml

from semantic_kernel.prompt_template import PromptTemplateConfig

# Read the YAML file
with open("./GenerateStory.yaml", "r", encoding="utf-8") as file:
    generate_story_yaml = file.read()

# Parse the YAML content
data = yaml.safe_load(generate_story_yaml)

prompt_template_config = PromptTemplateConfig(**data)

agent = ChatCompletionAgent(
    service=AzureChatCompletion(), # or other supported AI services
    prompt_template_config=prompt_template_config,
    arguments=KernelArguments(topic="Dog", length="3"),
)

C#에서는 KernelFunctionYaml.ToPromptTemplateConfig(generateStoryYaml) 로 YAML을 PromptTemplateConfig 로 바꾼 뒤 new ChatCompletionAgent(templateConfig) 형태로 에이전트를 만들어요.

직접 호출 시 템플릿 값 오버라이드

에이전트를 직접 호출할 때는 파라미터를 필요에 따라 덮어쓸 수 있어요. 특정 작업에서 에이전트의 행동을 더 세밀하게 제어하고, 요구에 맞게 지시문이나 설정을 그때그때 바꿀 수 있어요.

agent = ChatCompletionAgent(
    service=AzureChatCompletion(),
    name="StoryTeller",
    instructions="Tell a story about {{$topic}} that is {{$length}} sentences long.",
    arguments=KernelArguments(topic="Dog", length="2"),
)

thread = None
override_arguments = KernelArguments(topic="Cat", length="3")

# Two ways to get a response from the agent
response = await agent.get_response(messages="user input", arguments=override_arguments)
thread = response.thread

# or use invoke to return an AsyncIterable of ChatMessageContent
async for response in agent.invoke(messages="user input", arguments=override_arguments):
    thread = response.thread

다음 단계

end-to-end 예제는 How-To: ChatCompletionAgent 를, 이어서 Agent orchestration 를 확인해 보세요.