How can I make the agent recognize Agent Skills before tools?

takeolexus 220 Reputation points
2026-07-06T06:16:17.9733333+00:00

I am implementing Agent Skills for the first time based on the Agent_Step01_FileBasedSkills sample in the Microsoft Agent Framework repository.

I modified it to register a tool that performs web searches using HostedWebSearchTool(), and I tried instructing the agent to do a web search through the skill. However, the agent performs the web search directly (web_search) and ignores the skill.

Since I expect the instructions to grow in the future, I want to keep the instructions on the skill side.

How can I make the skill take priority?

using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;

string endpoint = Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("FOUNDRY_PROJECT_ENDPOINT is not set.");
string deploymentName = Environment.GetEnvironmentVariable("FOUNDRY_MODEL") ?? "gpt-5.4-mini";

var skillsProvider = new AgentSkillsProvider(Path.Combine(AppContext.BaseDirectory, "skills"));

AIAgent agent = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
    .AsAIAgent(new ChatClientAgentOptions
    {
        Name = "InternetResearchAgent",
        ChatOptions = new()
        {
            ModelId = deploymentName,
            Instructions = """
                You are a helpful assistant.
                
                Prioritize available Skills over Tools.
                Check Skills first, follow their steps,
                and use Tools only as a last resort.
                """,
            Tools = [new HostedWebSearchTool()]
        },
        AIContextProviders = [skillsProvider],
    });

AgentResponse response = await agent.RunAsync(
    "Please tell me what the Japanese Prime Minister is up to today.");
Console.WriteLine($"Agent: {response.Text}");

response = await agent.RunAsync(
    "Did you use `internet-research` skill?");
Console.WriteLine($"Agent: {response.Text}");
---
name: internet-research
description: Perform an internet search to obtain the latest necessary information.
allowed-tools:
  - web_search
---

# Internet Research
Search for time-sensitive information such as the latest news, specification changes, release information, incident/outage information, and comparison information, and summarize the key points.

# Tools to Use
- web_search
 - Performs internet searches.

# Rules for Responses
- In responses using this skill, always include the following at the beginning:
 **Includes internet search results**

Foundry Tools
Foundry Tools

Formerly known as Azure AI Services or Azure Cognitive Services is a unified collection of prebuilt AI capabilities within the Microsoft Foundry platform

0 comments No comments

Answer accepted by question author
Manish Deshpande 8,215 Reputation points Microsoft External Staff Moderator
2026-07-11T21:43:14.4766667+00:00

Hello @takeolexus

Good question this trips people up because "Skills vs Tools" sounds like a priority setting, but it works a little differently. Here's what's happening and how to get the behavior you want.

Why the skill is being skipped

Skills and tools are complementary, not competing — there's no runtime switch that says "always use skills before tools." Instead, only each skill's name and description (~100 tokens) are placed in the prompt. The model decides, per turn, whether a skill is relevant by matching your message against that description; if it fires, the skill body is loaded and guides the run. If it doesn't fire, the model just uses whatever tools are directly available.

So your "Prioritize available Skills over Tools" line in Instructions is only a soft hint — it can't reliably override the model choosing to call web_search directly, especially when that tool is registered and trivially answers the query. That's the core reason it's going straight to the tool.

The real lever: make the description match your prompts

Your description — "Perform an internet search to obtain the latest necessary information" — is too narrow. A prompt like "what is the Japanese PM up to today" doesn't obviously map to it, so the orchestrator never activates the skill. Skill selection is description-driven, so spell out the trigger scenarios and keywords:

---
name: internet-research
description: >
  Use for any request that needs up-to-date or time-sensitive information from
  the web — current events, "today/now/latest" questions, news, release or spec
  changes, incident/outage status, prices, or comparisons. Prefer this skill
  whenever a fresh web lookup is required.
---

The richer and more scenario-specific the description (up to 1024 chars), the more reliably the model reaches for the skill. That's the intended control.

Important correction on allowed-tools

Don't remove your top-level Tools=[new HostedWebSearchTool()] registration. In the SKILL.md frontmatter, allowed-tools is a pre-approval list of tools a skill may use — it's currently experimental and doesn't register or provide the tool itself, and support varies by agent implementation. If you drop the top-level registration expecting the skill to supply web_search, your agent could end up with no web-search capability at all. So keep the tool registered; use the description to route through the skill. If you do add allowed-tools, note it's a space-delimited value, e.g.:

allowed-tools: web_search

(Also: name must match the skill's parent directory name — lowercase letters, numbers, and hyphens only.)

If you need it guaranteed, not just likely

Set expectations honestly: orchestration is LLM-driven, so even a great description makes activation high-probability, not deterministic. If a given path must always run, don't rely on prompt priority — drive it from your application/workflow code (call the skill/step explicitly, or model it as a workflow). Same principle as forcing tool order generally: prompts guide the model, code guarantees the sequence.

Short version: the fix isn't a priority flag — it's a stronger, keyword-rich description so the model actually activates the skill, while keeping web_search registered. And if you need this path to run every time, enforce it in code. Since Skills are in preview, keep an eye on the release notes as the controls evolve. Happy to look at your revised SKILL.md and agent setup if it still isn't activating.

https://learn.microsoft.com/en-us/agent-framework/journey/adding-skills#how-skills-differ-from-tools
https://learn.microsoft.com/en-us/agent-framework/agents/skills?pivots=programming-language-csharp#skill-structure

https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/tools/skills?pivots=rest-api

Thanks,
Manish.

Was this answer helpful?

1 person found this answer helpful.

1 additional answer

Sort by: Oldest
  1. Megha Ramakrishnan 500 Reputation points
    2026-07-06T09:31:11.83+00:00

    Hi @takeolexus ,

    Can you try to remove the ⁠HostedWebSearchTool⁠ from the ⁠ChatOptions.Tools⁠ collection. Instead, add it to the ⁠AgentSkillsProvider⁠ constructor so the provider knows the tool exists, but doesn't force it onto the agent globally.

    using Azure.AI.Projects;
    using Azure.Identity;
    using Microsoft.Agents.AI;
    using Microsoft.Extensions.AI;
    string endpoint = Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("FOUNDRY_PROJECT_ENDPOINT is not set.");
    string deploymentName = Environment.GetEnvironmentVariable("FOUNDRY_MODEL") ?? "gpt-4o-mini"; // Standardizing to current real models
    // Pass the available tools into the skills provider
    var searchTool = new HostedWebSearchTool();
    var skillsProvider = new AgentSkillsProvider(Path.Combine(AppContext.BaseDirectory, "skills"),  tools: [searchTool] 
    );
    AIAgent agent = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential()).AsAIAgent(new ChatClientAgentOptions  {      Name = "InternetResearchAgent",      ChatOptions = new()      {          ModelId = deploymentName,          Instructions = """             You are a helpful assistant.                                Prioritize available Skills over Tools.                 Check Skills first, follow their steps,                 and use Tools only as a last resort.                 """ ,          Tools = []      },      AIContextProviders = [skillsProvider],  });
    AgentResponse response = await agent.RunAsync("Please tell me what the Japanese Prime Minister is up to today.");
    Console.WriteLine($"Agent: {response.Text}");
    response = await agent.RunAsync("Did you use internet-research skill?");
    Console.WriteLine($"Agent: {response.Text}");
    

    Please 'Upvote'(Thumbs-up) and 'Accept' as answer if the reply was helpful. This will be benefitting other community members who face the same issue.

    Thank you!

    Was this answer helpful?


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.