OfficeAgent.NET을 사용하여 .NET IChatClient에 Word 편집 도구 추가하기
요약
OfficeAgent.NET을 사용하여 .NET IChatClient에 Word 문서 편집 도구를 직접 통합하는 방법을 설명합니다. 별도의 에이전트 프레임워크 없이 함수 호출(Function Calling) 기능을 활용해 모델이 문서를 편집하고 관리할 수 있는 구현 가이드를 제공합니다.
핵심 포인트
- IChatClient와 Microsoft.Extensions.AI를 통한 직접적인 도구 투영
- ChatClientAgent를 사용하지 않는 경량화된 통합 방식 제시
- Azure OpenAI의 함수 호출 기능을 활용한 Word 문서 편집 구현
- UseFunctionInvocation을 통한 도구 호출 및 결과 반환 자동화
.NET 채팅 애플리케이션이 Word 문서를 편집할 수 있도록 하려면 전체 에이전트 프레임워크 (Agent Framework)가 반드시 필요한 것은 아닙니다. 모델이 함수 호출 (Function Calling)을 지원한다면, OfficeAgent.NET을 IChatClient 상의 Microsoft.Extensions.AI 도구로 직접 투영할 수 있습니다.
아래의 작은 호스트는 하나의 문서를 등록하고, 모델에 네 가지 제한된 도구를 제공하며, apply_plan에서 반환된 ID를 통해 저장된 .docx 파일을 가져옵니다. OfficeAgent의 더 광범위한 AgentEdit 샘플과 달리, 이 방식은 ChatClientAgent를 사용하지 않습니다. 이 방식의 구체적인 목적은 직접적인 IChatClient 통합과 호스트 측에서의 출력 ID 캡처를 보여주는 것입니다.
시작하기 전에 필요한 사항
- .NET 8 이상
./contracts/contract.docx경로에Invoices are payable within 60 days of receipt.라는 정확한 문장이 포함된 가상의 Word 문서- 함수 호출 (Function Calling)을 지원하는 모델이 배포된 Azure OpenAI
AZURE_OPENAI_ENDPOINT및AZURE_OPENAI_DEPLOYMENT환경 변수az login을 통한 Azure CLI 로그인DefaultAzureCredential에 의해 선택된 ID가 Azure OpenAI 리소스에 대해Cognitive Services OpenAI User역할을 가지고 있어야 함
패키지를 추가합니다:
mkdir OfficeAgentChat
cd OfficeAgentChat
dotnet new console --framework net8.0
...
여전히 OfficeAgentChat 디렉토리 내에서, 사전 요구 사항에 명시된 정확한 가상 문장을 포함하는 ./contracts/contract.docx를 생성합니다. 아래의 모든 상대 경로는 이 프로젝트 디렉토리를 기준으로 해결됩니다.
패키지 이름에도 불구하고, OfficeAgent.AgentFramework는 일반적인 AIFunction 객체를 노출합니다. 다음 예제는 ChatClientAgent를 사용하지 않습니다.
OfficeAgent 구성 및 문서 등록
using System.Text.Json;
using Azure.AI.OpenAI;
using Azure.Identity;
...
호스트는 경로를 등록합니다. 초기 주소 지정 시, 모델은 경로 또는 자격 증명 대신 연결 이름과 불투명한(opaque) 문서 ID를 받습니다. 그런 다음 검사(inspection) 및 찾기(find) 도구가 편집 계획을 세우는 데 필요한 문서 텍스트와 구조를 반환합니다.
IChatClient에 함수 호출(function invocation) 추가하기
string endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
?? throw new InvalidOperationException("Set AZURE_OPENAI_ENDPOINT.");
string deployment = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT")
...
UseFunctionInvocation()은 필수적입니다. 이 메서드는 모델이 요청한 AIFunction을 실행하고, 구조화된 결과(structured result)를 모델에 반환하며, 모델이 최종 답변을 생성할 때까지 이 과정을 반복합니다. 이 작은 훅(hook)은 도구 호출 순서를 기록하고, 모델이 이를 산문(prose)으로 복사하는 것에 의존하는 대신 애플리케이션 코드 내에 저장된 문서 ID를 유지합니다. NormalizeToolResult는 함수 어댑터(function adapter)가 노출할 수 있는 두 가지 JSON 형태, 즉 JSON 객체 또는 JSON 문자열을 처리하므로, 모델은 구조화된 결과를 볼 수 있고 호스트는 outputDocumentId를 안정적으로 읽을 수 있습니다.
이 수집기(collector)는 의도적으로 단일 콘솔 실행에 국한됩니다. 동시 대화를 처리하는 싱글톤 클라이언트(singleton client)에 이와 같은 공유 클로저(shared closure)를 연결하지 마세요. 요청 범위(request-scoped)의 상태를 생성하거나, 캡처된 도구 결과(tool results)를 대화 또는 요청 ID와 상관시키십시오.
추적 가능한 편집 수행하기
string instructions = $"""
You are editing connectionId=contracts,
documentId={source.ItemId}.
...
안전 시퀀스는 탐색(discovery), 미리보기(preview), 그리고 적용(apply) 순으로 진행됩니다. 탐색은 inspect_document로 시작되며, 모델은 특정 앵커(anchor)가 필요할 때 find_in_document를 호출할 수도 있습니다. OfficeAgent의 계획 검증(plan validation)이 문서를 보호하지만, 어떤 탐색 도구를 요청할지는 여전히 모델이 결정합니다. 모델의 지침(instruction)을 좁게 유지하고, 운영 환경에서는 도구 호출(tool calls)을 로그로 남기십시오.
결과 가져오기
using var saved = await office.OpenReadAsync(
DocumentReference.ForFileSystem("contracts", outputDocumentId));
await using var output = File.Create("reviewed-contract.docx");
...
.docx 바이트는 모델을 거치지 않습니다. 호스트는 구성된 제공자(provider)로부터 이를 가져오며, 일반적인 다운로드 또는 첨부 채널을 통해 이를 반환할 수 있습니다.
이 합성 콘솔 실습(synthetic console exercise)의 경우, 실행이 실패했을 때 전체 apply_plan 결과를 출력하는 것이 유용합니다. 프로덕션(production) 환경에서는 문서 내용을 노출하지 않으면서 오류 코드와 상관관계 데이터(correlation data)를 로그로 남기십시오.
이것이 유용한 경계(boundary)입니다: IChatClient는 대화를 처리하고, OfficeAgent.NET은 검증된 Word 작업을 처리하며, 여러분의 애플리케이션은 저장 및 전달에 대한 제어권을 유지합니다. Microsoft는 AI tool calling for .NET에서 일반적인 함수 호출 루프(function calling loop)를 설명합니다. Microsoft의 Azure OpenAI authentication guidance는 DefaultAzureCredential 및 RBAC 요구 사항을 설명합니다. 위의 전체 블록은 순서대로 하나의 Program.cs를 구성합니다. 더 광범위한 OfficeAgent 워크플로(workflow)는 agent-integration guide에 있습니다. 이 호스트와 정확히 일치하는 실행 가능한 전체 버전은 IChatClient Word-editing sample에서 확인할 수 있습니다.
직접 시도해 보려면, 위에서 설명한 콘솔 프로젝트와 합성 문서(synthetic document)를 생성하고, 순서대로 된 코드 블록을 Program.cs에 붙여넣은 다음 dotnet run을 실행하십시오. 이 첫 번째 실행은 단일 요청(single-request)으로 유지하고, 트레이스(trace)가 apply_plan으로 끝나는지 확인하십시오.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기