For anything beyond a quick experiment, keep agent definitions out of Program.cs. A separate Agents folder keeps identity, instructions, model settings, and tool attachments easier to review.
usingRuniq.Agents;usingRuniq.Agents.Tools;usingRuniq.WorkflowTravelPlanner.Tools;namespaceRuniq.WorkflowTravelPlanner.Agents;publicsealedclassWeatherAgent : Agent{privateWeatherAgent(string? apiKey) : base(id: "weather-agent",name: "Weather Agent",instructions: ""You are the WeatherAnalyst in a deterministic travel planning workflow.Yourresponsibility: - Analyze weather and travel comfort only. - Always use WeatherTool when the request involves a city or trip plan. - AfterusingWeatherTool, write a short natural-language contribution.Boundaries: - Do not create an itinerary. - Do not write the final travel plan. - Do not print raw JSON."",model: "openai/gpt-5",apiKey: apiKey) { }publicstaticAgentCreate(string? apiKey) {returnnewWeatherAgent(apiKey) .AddTool<WeatherTool>(); }}
The constructor is private because application code should use WeatherAgent.Create(...). That factory returns the agent with its required tool attached.
The planner has a different responsibility and a different tool:
C#
usingRuniq.Agents;usingRuniq.Agents.Tools;usingRuniq.WorkflowTravelPlanner.Tools;namespaceRuniq.WorkflowTravelPlanner.Agents;publicsealedclassPlannerAgent : Agent{privatePlannerAgent(string? apiKey) : base(id: "planner-agent",name: "Planner Agent",instructions: ""You are the final TravelPlanner in a deterministic travel planning workflow.Yourresponsibility: - Create the final user-facing itinerary. - Use the previous workflow step output as context. - Always use MealSuggestionTool before finalizing. - Produce a practical, clear, low-fatigue travel plan.Boundaries: - Do not print raw JSON. - Do not expose internal tool output directly."",model: "openai/gpt-5",apiKey: apiKey) { }publicstaticAgentCreate(string? apiKey) {returnnewPlannerAgent(apiKey) .AddTool<MealSuggestionTool>(); }}
This is usually easier to maintain than one large "travel agent" with every responsibility and every tool attached.
Local providers such as ollama are represented in the current runtime defaults without an API key requirement:
C#
newAgent(id: "local-agent",name: "Local Agent",instructions: "Answer using the local model.",model: "ollama/llama3.2");
OpenAI, Groq, Mistral, DeepSeek, OpenRouter, Together, Fireworks, NVIDIA, and Azure OpenAI are registered as API-key providers in the current implementation.