Bài blog
Xây Dựng Agentic Workflow trên Azure AI Foundry với MCP Server trong .NET
Agentic workflow không chỉ là prompt kèm một vòng lặp. Agent production cần goal rõ ràng, tool contract, memory boundary, evaluation, observability, và chính sách tích hợp an toàn.
- Danh mục
- ai
- Xuất bản
Project
GitHub placeholder: agentic-azure-mcp-dotnet
Project dự kiến mô phỏng một agent workflow theo hướng enterprise:
- .NET API nhận request để bắt đầu workflow.
- Azure AI Foundry host agent và model deployment.
- Agent có thể gọi tool để search, lookup ticket/claim, retrieve document, và chuẩn bị action.
- .NET MCP server expose cùng bộ tool qua một protocol chuẩn.
- Workflow lưu trace, tool call, evaluation result, và failure state.
Agentic Workflow Là Gì
Agentic workflow là luồng phần mềm nơi model có thể chọn bước tiếp theo trong một tập tool và policy được kiểm soát.
Ba ý quan trọng:
- Model có thể quyết định: model không chỉ tạo text, mà có thể chọn action.
- Tool bị giới hạn: model không có quyền vô hạn, chỉ được gọi tool đã định nghĩa.
- Policy kiểm soát workflow: hệ thống có permission, guardrail, retry, evaluation, và observability.
Chatbot đơn giản trả lời một message. Agentic workflow có thể kiểm tra hồ sơ, retrieve tài liệu, so sánh policy, tạo summary, hỏi thông tin thiếu, và chuẩn bị action để con người duyệt.
Kịch Bản Thực Tế
Ví dụ một support operations agent cho nền tảng bảo hiểm.
User hỏi:
Review claim CLM-10482, check whether missing documents block approval,
and prepare a message for the customer.
Agent không nên đoán. Nó cần:
- Lookup claim.
- Retrieve policy rule.
- Kiểm tra required documents.
- So sánh submitted files với rule set.
- Draft customer message.
- Đưa recommendation vào trạng thái pending human approval.
Model thực hiện reasoning, nhưng application vẫn sở hữu data access, permission, tool execution, và side effect cuối cùng.
Azure AI Foundry Đóng Vai Trò Gì
Azure AI Foundry cung cấp platform để build, deploy, và vận hành AI application/agent. Với team .NET, các phần quan trọng là:
- Model deployment cho GPT và các model được hỗ trợ.
- Agent runtime concept: conversation, run, tool, response.
- SDK access qua package như
Azure.AI.Projects. - Authentication với Azure Identity và managed identity.
- Evaluation và monitoring cho AI system đã deploy.
Giá trị production không chỉ là model trả lời được. Giá trị là agent, tool, deployment, identity, monitoring, và evaluation có thể nằm trong cùng governance model của Azure.
Kiến Trúc Tổng Quan
User or Application
-> .NET API
-> Azure AI Foundry Agent
-> Model Deployment
-> Tool Call Decision
-> Tool Adapter
-> MCP Server or Internal Service
-> Business Data
-> Tool Result
-> Agent Response
-> Evaluation and Trace Store
Side effect nên nằm sau application layer. Agent có thể yêu cầu tool call, nhưng code của bạn quyết định tool đó có được phép chạy không và chạy như thế nào.
Thiết Lập .NET Client
Ứng dụng .NET thường dùng Azure Identity để authenticate.
using Azure.AI.Projects;
using Azure.Identity;
var endpoint = new Uri(builder.Configuration["AzureAI:ProjectEndpoint"]!);
var credential = new DefaultAzureCredential();
var projectClient = new AIProjectClient(endpoint, credential);
Local development có thể dùng Azure CLI sign-in. Production nên dùng managed identity. Tránh đặt API key trực tiếp trong application settings nếu có lựa chọn tốt hơn.
Agent Instructions Là Product Requirement
Instruction cho agent nên giống operating policy, không phải prompt mơ hồ.
You are a support operations assistant for an insurance platform.
Goals:
- Help staff review claim readiness.
- Use tools to retrieve claim, policy, and document information.
- Never invent claim facts.
Rules:
- You may draft messages but may not send them.
- You may recommend status changes but may not apply them.
- You must cite the tool result that supports each recommendation.
Instruction định nghĩa agent được làm gì, không được làm gì, và output cần có cấu trúc ra sao để application evaluate được.
Tool Calling
Tool calling cho phép model yêu cầu gọi function với argument có cấu trúc. Application thực thi function và trả kết quả về cho agent.
Tool schema là contract:
{
"name": "get_claim",
"description": "Retrieve claim details by claim id.",
"parameters": {
"type": "object",
"properties": {
"claimId": {
"type": "string",
"description": "The claim identifier, for example CLM-10482."
}
},
"required": ["claimId"]
}
}
Tool implementation trong .NET vẫn nên là code bình thường, testable, và có authorization:
public sealed class ClaimTools
{
private readonly IClaimsRepository _claims;
private readonly IAuthorizationService _authorization;
public async Task<ClaimToolResult> GetClaimAsync(
string claimId,
ClaimsPrincipal user,
CancellationToken cancellationToken)
{
if (!await _authorization.CanReadClaimAsync(user, claimId, cancellationToken))
{
throw new ToolAuthorizationException("User cannot read this claim.");
}
var claim = await _claims.GetByIdAsync(claimId, cancellationToken);
return claim is null ? ClaimToolResult.NotFound(claimId) : ClaimToolResult.FromClaim(claim);
}
}
Model quyết định get_claim hữu ích, nhưng .NET code vẫn validate input, enforce permission, log call, và trả response đã giới hạn.
Vì Sao MCP Quan Trọng
Model Context Protocol là cách chuẩn để application expose tool, resource, và prompt cho AI client.
Nếu không có MCP, mỗi agent platform có thể cần adapter riêng:
Agent platform A -> custom tool wrapper A
Agent platform B -> custom tool wrapper B
Internal assistant -> custom tool wrapper C
Developer IDE agent -> custom tool wrapper D
Với MCP, một service expose tool qua protocol chung:
Claim Tools MCP Server
-> get_claim
-> search_policy
-> list_required_documents
-> create_draft_customer_message
Nhiều client có thể dùng chung contract này. Tool behavior cũng dễ test và vận hành hơn.
MCP Server Trong .NET
Official C# SDK hỗ trợ dependency injection và attribute-based tool registration.
var builder = Host.CreateApplicationBuilder(args);
builder.Services
.AddMcpServer()
.WithStdioServerTransport()
.WithToolsFromAssembly();
builder.Services.AddSingleton<IClaimsRepository, ClaimsRepository>();
await builder.Build().RunAsync();
Expose tool:
using ModelContextProtocol.Server;
using System.ComponentModel;
[McpServerToolType]
public sealed class ClaimMcpTools
{
private readonly IClaimsRepository _claims;
[McpServerTool]
[Description("Retrieve claim details by claim id.")]
public async Task<ClaimDto> GetClaim(string claimId, CancellationToken cancellationToken)
{
var claim = await _claims.GetByIdAsync(claimId, cancellationToken);
if (claim is null)
{
throw new InvalidOperationException($"Claim {claimId} was not found.");
}
return ClaimDto.FromClaim(claim);
}
}
Stdio MCP server phù hợp local và developer tooling. HTTP MCP server phù hợp tool dùng chung trong enterprise vì dễ deploy, secure, observe, và rate limit hơn.
Kết Nối Foundry Agent Với MCP
Foundry agent tool calling và MCP nằm ở hai layer khác nhau:
- Foundry agent tool calling là cách hosted agent yêu cầu action.
- MCP là cách tool server expose capability chuẩn.
.NET application có thể bridge hai layer này:
Foundry Agent requests function call: get_claim({ claimId: "CLM-10482" })
-> .NET Tool Adapter receives the call
-> Adapter calls MCP client
-> MCP server executes ClaimMcpTools.GetClaim
-> Adapter returns result to Foundry Agent
Boundary này giúp Foundry-specific code nằm trong adapter, còn tool thật vẫn portable.
Tool Result Nên Nhỏ và Có Cấu Trúc
Tool không nên trả về toàn bộ database object. Model cần dữ liệu đủ để reason, không cần mọi field nội bộ.
{
"claimId": "CLM-10482",
"status": "PendingDocuments",
"policyType": "Health",
"missingDocuments": ["hospital_discharge_summary", "invoice"],
"submittedDocuments": ["claim_form", "identity_card"],
"approvalBlocked": true
}
Response nhỏ giúp giảm token, giảm rủi ro lộ dữ liệu, và làm evaluation dễ hơn.
Giới Hạn Planning Loop
Agent không nên được phép loop vô hạn. Workflow runner nên giới hạn số vòng tool call.
public sealed class AgentWorkflowRunner
{
private const int MaxToolRounds = 6;
public async Task<AgentWorkflowResult> RunAsync(
AgentRequest request,
CancellationToken cancellationToken)
{
for (var round = 0; round < MaxToolRounds; round++)
{
var step = await _agent.RunNextStepAsync(request, cancellationToken);
if (step.IsComplete)
{
return AgentWorkflowResult.Completed(step.FinalResponse);
}
if (step.RequiresToolCall)
{
var result = await _tools.ExecuteAsync(step.ToolCall, cancellationToken);
await _agent.SubmitToolResultAsync(step, result, cancellationToken);
continue;
}
}
return AgentWorkflowResult.Failed("Agent exceeded the maximum tool round limit.");
}
}
Nguyên tắc: giới hạn loop, inspect từng tool call, execute qua application boundary, và stop khi complete hoặc vi phạm policy.
Human Approval Cho Side Effect
Không nên cho agent quyền write trực tiếp ngay từ đầu.
Chia tool thành ba nhóm:
- Read tools:
get_claim,search_policy. - Draft tools:
draft_customer_message. - Commit tools:
send_customer_message,approve_claim.
Bắt đầu với read và draft tools. Commit tool nên đi qua human approval cho đến khi workflow có evaluation đủ mạnh.
Guardrails
Guardrail nên nằm ở nhiều lớp.
Application guardrails:
- Validate mọi tool argument.
- Authorize từng tool call phía server.
- Reject tool không được phép trong workflow hiện tại.
- Limit result size.
- Mask sensitive field trước khi trả cho model.
Agent guardrails:
- Instruction rõ ràng về việc được làm và không được làm.
- Yêu cầu citation từ tool output.
- Yêu cầu structured response khi cần automation.
Operational guardrails:
- Giới hạn số tool round.
- Rate limit tool đắt tiền.
- Log tool input/output với redaction.
- Dead-letter handling cho workflow fail.
Evaluation
Agentic workflow cần eval suite trước production.
{
"input": "Review claim CLM-10482 and draft the customer message.",
"expectedToolCalls": ["get_claim", "list_required_documents", "draft_customer_message"],
"mustNotCall": ["approve_claim", "send_customer_message"],
"expectedOutcome": "approval_blocked_missing_documents"
}
Evaluate ở nhiều tầng:
- Agent chọn đúng tool không?
- Thứ tự tool call có hợp lý không?
- Final answer có grounded vào tool result không?
- Agent có tránh forbidden tool không?
- Output có đúng schema không?
LLM-as-judge hữu ích, nhưng nên kết hợp deterministic checks cho required tool call, forbidden tool call, schema validity, và final state.
Observability và Security
Trace workflow như một cây:
AgentWorkflow
-> AgentRun
-> ToolCall get_claim
-> MCP request ClaimMcpTools.GetClaim
-> Database query Claims
-> FinalResponse
-> Evaluation
Mỗi span nên có workflow ID, agent ID, model deployment, tool name, duration, result status, và evaluation result. Không log raw sensitive data mặc định.
Security rule quan trọng: agent không phải security boundary. Model output là untrusted.
- Authenticate user trước khi start workflow.
- Pass user context vào tool execution.
- Authorize từng tool call server-side.
- Dùng managed identity cho Azure resources.
- Lưu secret trong Key Vault.
- Allowlist tool theo workflow.
- Human approval cho action rủi ro cao.
Kết Luận
Use Azure AI Foundry khi bạn cần managed model deployment, agent runtime, Azure identity, và governance cho AI workflow.
Use MCP khi bạn muốn tool reusable giữa nhiều AI client thay vì viết adapter riêng cho từng platform.
Use .NET khi enterprise API, identity, dữ liệu, và vận hành đã nằm trong Microsoft ecosystem.
Kiến trúc tốt không phải là "cho model quyền làm mọi thứ". Kiến trúc tốt là workflow được kiểm soát: model reason, application enforce policy, MCP chuẩn hóa tool access, và Azure AI Foundry cung cấp platform để deploy, evaluate, observe, và vận hành.