Matlamat: Membina ejen AI pertama anda dengan arahan berterusan dan persona yang ditakrifkan, dikuasakan oleh model tempatan melalui Foundry Local.
Ejen AI membalut model bahasa dengan arahan sistem yang mentakrifkan tingkah laku, personaliti, dan sekatanannya. Berbeza dengan panggilan penyelesaian sembang tunggal, ejen menyediakan:
- Persona - identiti yang konsisten ("Anda adalah penilai kod yang membantu")
- Memori - sejarah perbualan merentasi giliran
- Pengkhususan - tingkah laku fokus yang dipandu oleh arahan yang direka dengan baik
Rangka Kerja Ejen Microsoft (AGF) menyediakan abstraksi ejen standard yang berfungsi merentasi backend model yang berbeza. Dalam bengkel ini kami memadankannya dengan Foundry Local supaya semuanya berjalan di komputer anda - tanpa memerlukan awan.
| Konsep | Penerangan |
|---|---|
FoundryLocalClient |
Python: mengendalikan permulaan servis, muat turun/muatan model, dan mencipta ejen |
client.as_agent() |
Python: mencipta ejen dari klien Foundry Local |
AsAIAgent() |
C#: kaedah sambungan pada ChatClient - mencipta AIAgent |
instructions |
Arahan sistem yang membentuk tingkah laku ejen |
name |
Label yang boleh dibaca manusia, berguna dalam senario berbilang ejen |
agent.run(prompt) / RunAsync() |
Menghantar mesej pengguna dan menerima respons ejen |
Nota: Rangka Kerja Ejen mempunyai SDK Python dan .NET. Untuk JavaScript, kami melaksanakan kelas
ChatAgentringan yang mencerminkan corak yang sama menggunakan SDK OpenAI secara langsung.
Sebelum menulis kod, kaji komponen utama ejen:
- Klien model - menyambung ke API sepadan OpenAI Foundry Local
- Arahan sistem - prompt "personaliti"
- Gelung jalan - hantar input pengguna, terima output
Fikirkan: Bagaimana arahan sistem berbeza dari mesej pengguna biasa? Apa yang berlaku jika anda mengubahnya?
🐍 Python
Prasyarat:
cd python
python -m venv venv
# Windows (PowerShell):
venv\Scripts\Activate.ps1
# macOS:
source venv/bin/activate
pip install -r requirements.txtJalankan:
python foundry-local-with-agf.pyPenjelasan kod (python/foundry-local-with-agf.py):
import asyncio
from agent_framework_foundry_local import FoundryLocalClient
async def main():
alias = "phi-4-mini"
# FoundryLocalClient mengendalikan permulaan perkhidmatan, muat turun model, dan pemuatan
client = FoundryLocalClient(model_id=alias)
print(f"Client Model ID: {client.model_id}")
# Cipta ejen dengan arahan sistem
agent = client.as_agent(
name="Joker",
instructions="You are good at telling jokes.",
)
# Bukan penstriman: dapatkan respons lengkap sekaligus
result = await agent.run("Tell me a joke about a pirate.")
print(f"Agent: {result}")
# Penstriman: dapatkan keputusan semasa ia dijana
async for chunk in agent.run("Tell me another joke.", stream=True):
if chunk.text:
print(chunk.text, end="", flush=True)
asyncio.run(main())Perkara penting:
FoundryLocalClient(model_id=alias)mengendalikan permulaan servis, muat turun, dan muatan model dalam satu langkahclient.as_agent()mencipta ejen dengan arahan sistem dan namaagent.run()menyokong mod tidak penstriman dan penstriman- Pasang melalui
pip install agent-framework-foundry-local --pre
📦 JavaScript
Prasyarat:
cd javascript
npm installJalankan:
node foundry-local-with-agent.mjsPenjelasan kod (javascript/foundry-local-with-agent.mjs):
import { OpenAI } from "openai";
import { FoundryLocalManager } from "foundry-local-sdk";
class ChatAgent {
constructor({ client, modelId, instructions, name }) {
this.client = client;
this.modelId = modelId;
this.instructions = instructions;
this.name = name;
this.history = [];
}
async run(userMessage) {
const messages = [
{ role: "system", content: this.instructions },
...this.history,
{ role: "user", content: userMessage },
];
const response = await this.client.chat.completions.create({
model: this.modelId,
messages,
});
const assistantMessage = response.choices[0].message.content;
// Simpan sejarah perbualan untuk interaksi berbilang pusingan
this.history.push({ role: "user", content: userMessage });
this.history.push({ role: "assistant", content: assistantMessage });
return { text: assistantMessage };
}
}
async function main() {
FoundryLocalManager.create({ appName: "FoundryLocalWorkshop" });
const manager = FoundryLocalManager.instance;
await manager.startWebService();
const catalog = manager.catalog;
const model = await catalog.getModel("phi-3.5-mini");
if (!model.isCached) {
console.log("Downloading model: phi-3.5-mini...");
await model.download();
}
await model.load();
const client = new OpenAI({
baseURL: manager.urls[0] + "/v1",
apiKey: "foundry-local",
});
const agent = new ChatAgent({
client,
modelId: model.id,
instructions: "You are good at telling jokes.",
name: "Joker",
});
const result = await agent.run("Tell me a joke about a pirate.");
console.log(result.text);
}
main();Perkara penting:
- JavaScript membina kelas
ChatAgentsendiri yang mencerminkan corak AGF Python this.historymenyimpan giliran perbualan untuk sokongan multi-giliranstartWebService()secara eksplisit → semakan cache →model.download()→model.load()memberi visibiliti penuh
💜 C#
Prasyarat:
cd csharp
dotnet restoreJalankan:
dotnet run agentPenjelasan kod (csharp/SingleAgent.cs):
using Microsoft.AI.Foundry.Local;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Agents.AI;
using OpenAI;
using System.ClientModel;
// 1. Start Foundry Local and load a model
var alias = "phi-3.5-mini";
await FoundryLocalManager.CreateAsync(
new Configuration
{
AppName = "FoundryLocalSamples",
Web = new Configuration.WebService { Urls = "http://127.0.0.1:0" }
}, NullLogger.Instance, default);
var manager = FoundryLocalManager.Instance;
await manager.StartWebServiceAsync(default);
var catalog = await manager.GetCatalogAsync(default);
var model = await catalog.GetModelAsync(alias, default);
var isCached = await model.IsCachedAsync(default);
if (!isCached)
{
Console.WriteLine($"Downloading model: {alias}...");
await model.DownloadAsync(null, default);
}
await model.LoadAsync(default);
var key = new ApiKeyCredential("foundry-local");
var client = new OpenAIClient(key, new OpenAIClientOptions
{
Endpoint = new Uri(manager.Urls[0] + "/v1")
});
// 2. Create an AIAgent using the Agent Framework extension method
AIAgent joker = client
.GetChatClient(model.Id)
.AsAIAgent(
instructions: "You are good at telling jokes. Keep your jokes short and family-friendly.",
name: "Joker"
);
// 3. Run the agent (non-streaming)
var response = await joker.RunAsync("Tell me a joke about a pirate.");
Console.WriteLine($"Joker: {response}");
// 4. Run with streaming
await foreach (var update in joker.RunStreamingAsync("Tell me another joke."))
{
Console.Write(update);
}Perkara penting:
AsAIAgent()adalah kaedah sambungan dariMicrosoft.Agents.AI.OpenAI- tiada kelasChatAgenttersuai diperlukanRunAsync()mengembalikan respons penuh;RunStreamingAsync()menstrim token demi token- Pasang melalui
dotnet add package Microsoft.Agents.AI.OpenAI --version 1.0.0-rc3
Ubah instructions ejen untuk mencipta persona yang berbeza. Cuba setiap satu dan perhatikan bagaimana output berubah:
| Persona | Arahan |
|---|---|
| Penilai Kod | "Anda adalah penilai kod pakar. Berikan maklumbalas membina dengan fokus pada kebolehbacaan, prestasi, dan ketepatan." |
| Panduan Pelancongan | "Anda adalah panduan pelancongan yang mesra. Berikan cadangan peribadi untuk destinasi, aktiviti, dan masakan tempatan." |
| Tutor Socratik | "Anda adalah tutor Socratik. Jangan beri jawapan terus - sebaliknya, bimbing pelajar dengan soalan yang mendalam." |
| Penulis Teknikal | "Anda adalah penulis teknikal. Terangkan konsep dengan jelas dan ringkas. Gunakan contoh. Elakkan jargon." |
Cuba:
- Pilih persona dari jadual di atas
- Gantikan rentetan
instructionsdalam kod - Laraskan prompt pengguna yang sepadan (contoh: minta penilai kod menilai satu fungsi)
- Jalankan semula contoh dan bandingkan output
Petua: Kualiti ejen sangat bergantung pada arahan. Arahan khusus dan berstruktur baik menghasilkan keputusan lebih baik daripada yang samar.
Kembangkan contoh untuk menyokong gelung sembang multi-giliran supaya anda boleh melakukan perbualan bolak-balik dengan ejen.
🐍 Python - gelung multi-giliran
import asyncio
from agent_framework_foundry_local import FoundryLocalClient
async def main():
client = FoundryLocalClient(model_id="phi-4-mini")
agent = client.as_agent(
name="Assistant",
instructions="You are a helpful assistant.",
)
print("Chat with the agent (type 'quit' to exit):\n")
while True:
user_input = input("You: ")
if user_input.strip().lower() in ("quit", "exit"):
break
result = await agent.run(user_input)
print(f"Agent: {result}\n")
asyncio.run(main())📦 JavaScript - gelung multi-giliran
import { OpenAI } from "openai";
import { FoundryLocalManager } from "foundry-local-sdk";
import * as readline from "node:readline/promises";
// (guna semula kelas ChatAgent dari Latihan 2)
async function main() {
FoundryLocalManager.create({ appName: "FoundryLocalWorkshop" });
const manager = FoundryLocalManager.instance;
await manager.startWebService();
const catalog = manager.catalog;
const model = await catalog.getModel("phi-3.5-mini");
if (!model.isCached) {
console.log("Downloading model: phi-3.5-mini...");
await model.download();
}
await model.load();
const client = new OpenAI({
baseURL: manager.urls[0] + "/v1",
apiKey: "foundry-local",
});
const agent = new ChatAgent({
client,
modelId: model.id,
instructions: "You are a helpful assistant.",
name: "Assistant",
});
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
console.log("Chat with the agent (type 'quit' to exit):\n");
while (true) {
const userInput = await rl.question("You: ");
if (["quit", "exit"].includes(userInput.trim().toLowerCase())) break;
const result = await agent.run(userInput);
console.log(`Agent: ${result.text}\n`);
}
rl.close();
}
main();💜 C# - gelung multi-giliran
using Microsoft.AI.Foundry.Local;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Agents.AI;
using OpenAI;
using System.ClientModel;
var alias = "phi-3.5-mini";
var config = new Configuration
{
AppName = "FoundryLocalSamples",
Web = new Configuration.WebService { Urls = "http://127.0.0.1:0" }
};
await FoundryLocalManager.CreateAsync(config, NullLogger.Instance, default);
var manager = FoundryLocalManager.Instance;
await manager.StartWebServiceAsync(default);
var catalog = await manager.GetCatalogAsync(default);
var model = await catalog.GetModelAsync(alias, default);
var isCached = await model.IsCachedAsync(default);
if (!isCached)
{
Console.WriteLine($"Downloading model: {alias}...");
await model.DownloadAsync(null, default);
}
await model.LoadAsync(default);
var key = new ApiKeyCredential("foundry-local");
var client = new OpenAIClient(key, new OpenAIClientOptions
{
Endpoint = new Uri(manager.Urls[0] + "/v1")
});
AIAgent agent = client
.GetChatClient(model.Id)
.AsAIAgent(
instructions: "You are a helpful assistant.",
name: "Assistant"
);
Console.WriteLine("Chat with the agent (type 'quit' to exit):\n");
while (true)
{
Console.Write("You: ");
var userInput = Console.ReadLine();
if (string.IsNullOrWhiteSpace(userInput) ||
userInput.Equals("quit", StringComparison.OrdinalIgnoreCase) ||
userInput.Equals("exit", StringComparison.OrdinalIgnoreCase))
break;
var result = await agent.RunAsync(userInput);
Console.WriteLine($"Agent: {result}\n");
}Perhatikan bagaimana ejen mengingati giliran sebelumnya - tanya soalan susulan dan lihat konteks terangkut.
Arahan ejen supaya sentiasa memberi respon dalam format tertentu (contoh: JSON) dan parse hasilnya:
🐍 Python - output JSON
import asyncio
import json
from agent_framework_foundry_local import FoundryLocalClient
async def main():
client = FoundryLocalClient(model_id="phi-4-mini")
agent = client.as_agent(
name="SentimentAnalyzer",
instructions=(
"You are a sentiment analysis agent. "
"For every user message, respond ONLY with valid JSON in this format: "
'{"sentiment": "positive|negative|neutral", "confidence": 0.0-1.0, "summary": "brief reason"}'
),
)
result = await agent.run("I absolutely loved the new restaurant downtown!")
print("Raw:", result)
try:
parsed = json.loads(str(result))
print(f"Sentiment: {parsed['sentiment']} (confidence: {parsed['confidence']})")
except json.JSONDecodeError:
print("Agent did not return valid JSON - try refining the instructions.")
asyncio.run(main())💜 C# - output JSON
using System.Text.Json;
AIAgent analyzer = chatClient.AsAIAgent(
name: "SentimentAnalyzer",
instructions:
"You are a sentiment analysis agent. " +
"For every user message, respond ONLY with valid JSON in this format: " +
"{\"sentiment\": \"positive|negative|neutral\", \"confidence\": 0.0-1.0, \"summary\": \"brief reason\"}"
);
var response = await analyzer.RunAsync("I absolutely loved the new restaurant downtown!");
Console.WriteLine($"Raw: {response}");
try
{
var parsed = JsonSerializer.Deserialize<JsonElement>(response.ToString());
Console.WriteLine($"Sentiment: {parsed.GetProperty("sentiment")} " +
$"(confidence: {parsed.GetProperty("confidence")})");
}
catch (JsonException)
{
Console.WriteLine("Agent did not return valid JSON - try refining the instructions.");
}Nota: Model tempatan kecil mungkin tidak selalu menghasilkan JSON yang sah sempurna. Anda boleh tingkatkan kebolehpercayaan dengan memasukkan contoh dalam arahan dan sangat jelas tentang format yang dijangka.
| Konsep | Apa Yang Anda Pelajari |
|---|---|
| Ejen vs panggilan LLM mentah | Ejen membalut model dengan arahan dan memori |
| Arahan sistem | Tawalan paling penting untuk mengawal tingkah laku ejen |
| Perbualan multi-giliran | Ejen boleh membawa konteks merentasi pelbagai interaksi pengguna |
| Output berstruktur | Arahan boleh menguatkuasakan format output (JSON, markdown, dll.) |
| Pelaksanaan tempatan | Semua berjalan di peranti melalui Foundry Local - tiada awan diperlukan |
Dalam Bahagian 6: Aliran Kerja Berbilang Ejen, anda akan menggabungkan beberapa ejen ke dalam saluran berkoordinasi di mana setiap ejen mempunyai peranan khusus.
Penafian:
Dokumen ini telah diterjemahkan menggunakan perkhidmatan terjemahan AI Co-op Translator. Walaupun kami berusaha untuk ketepatan, sila ambil perhatian bahawa terjemahan automatik mungkin mengandungi kesilapan atau ketidaktepatan. Dokumen asal dalam bahasa asalnya harus dianggap sebagai sumber yang sahih. Untuk maklumat yang kritikal, terjemahan profesional oleh manusia adalah disyorkan. Kami tidak bertanggungjawab atas sebarang salah faham atau tafsiran yang timbul daripada penggunaan terjemahan ini.
