深入解析Function Calling、MCP和Ski (English)
深入解析Function Calling、MCP和Ski (English)
Generated: 2026-06-21 15:31:17
---
Imagine this scene—
A winter morning in the north. You’re huddled on a bus stop, scarf pulled up, wanting to check exactly how cold it is. You pull out your phone, unlock it, open the weather app, select the city, tap the date, and scroll back through the years… then finally hit search. By the time you’re done, your fingers are frozen!
Now imagine if you could just ask a weather tool through a large model? You only need to say: “What’s the weather like in Beijing today?”
Snap. Done.
That’s the experience of an AI Agent calling a tool—hiding all that clumsy, tedious work, leaving you to just say it out loud.
But speaking of that, I want to ask you something: Those people who go on about building Agents every day—do they really understand the relationship between Function Calling, MCP, and Skills?
Honestly, a lot of them are blowing smoke before they’ve even laid the foundation.
---
Function Calling: The Foundation. Don’t Look Down on It
When I built the first demo of the Lynxe framework, I had no idea what MCP was. It was just a primitive ReAct loop. What made it work?
One thing—Function Calling.
It solves the most fundamental problem: Large models only spit out text! How can they call a database? How can they query an API?
So Function Calling says: fine, I’ll give you a set of “lingo.” The model receives your question, reads the tool descriptions you provide, and generates a structured JSON—spelling out exactly which function to call and what the arguments are. The host program catches that JSON, executes the code, and feeds the result back to the model.
See? It’s almost embarrassingly simple.
I’ve seen plenty of articles that glorify Function Calling, but its actual working mode is that plain. And yet it’s that plainness that makes it the unshakeable foundation.
But once you start building real products, the problems show up—
You’re building an Agent that needs to talk to the GitHub API, operate a local database, and call a company’s ERP system. Every tool has a different interface, and you have to write separate adapter code for each. GitHub’s REST API uses one authentication scheme, MySQL uses another, third-party SaaS uses yet another. In a single project, the tool adapters alone can run into thousands of lines.
You think that’s it?
Even more painful is—after you throw all these tools at the model, the call success rate is like opening a blind box. For the same function, if the tool description is written by different people, the model’s understanding varies wildly.
---
MCP: The Ambition to Standardize
So MCP came along, essentially to solve a pain point in the community: can we stop everyone from reinventing the wheel for “tool integration”?
Under pressure from OpenAI’s competition, Anthropic did something really smart—they donated MCP to the Linux Foundation.
Think about it. Once they did that, big players like Microsoft and AWS had no reason to hesitate about picking a side. MCP went from a commercial company’s protocol to an industry standard. That move was genius.
I actually spent an entire weekend testing MCP. Let me tell you my real impression—
The MCP Server exposes tools, the Client connects, auto-discovers the tool list, and feeds them to the model in Function Calling format. That “auto-discovery” mechanism is genuinely satisfying. You no longer have to manually maintain dozens or hundreds of lines of tool schema. Whatever tools the MCP Server declares, the Client automatically picks them up.
But!
MCP is far from “universal.”
After I integrated 17 MCP Servers with the Lynxe framework, I ran into a particularly awkward problem: the data models returned by different servers conflicted. Two different MCP Servers both exposed a tool called “search”—one for searching Baidu Baike, the other for internal documents. The model often got confused. It either picked the wrong tool, or ran both at the same time, and the results didn’t match up.
Do you see the problem?
MCP only solved the problem of standardizing tool integration. It didn’t solve the “knowledge” problem of how to use those tools.
The model gets a pile of tools, but it doesn’t know when to use which one, let alone how to combine them to complete a complex task.
It’s like giving you top-of-the-line kitchen equipment, but not giving you a single recipe. You can stare at the pots all you want—they won’t cook for you.
---
Skills: Turning Your Experience into Knowledge Bags for Tools
This is exactly why Skills exist.
What module did I spend the most time on in Lynxe? Not the Function Calling JSON parser, not the MCP Server integration layer. It was the Skills management system.
Why?
Because what truly makes an Agent smart isn’t how many MCP tools it can call, but how well it knows to use them to complete a task.
The idea behind Skills is very simple: you write a structured document describing the steps, rules, and best practices for completing a certain type of task, and put it in a specific directory. When the Agent starts, it scans that directory. When a user task comes in, the Agent decides which Skill is relevant, and loads that Skill’s instructions as part of its context.
I looked closely at Nanobot’s open-source code. Its Skills structure looks a lot like Anthropic’s directory structure—
.claude/skills/
├── pdf-parsing/
│ ├── script.py
│ └── SKILL.md
├── python-code-style/
│ ├── REFERENCE.md
│ └── SKILL.md
Every Skill must have a SKILL.md file, written in Markdown, that clearly specifies: what this Skill is, when it should be triggered, the steps to execute, and which tools need to be called.
Let me give you an example I tested myself—I wrote a “code review” Skill in Lynxe:
name: code-review
description: Perform a line-by-line review of code changes, identify potential issues, and give improvement suggestions.
The instructions I wrote were very detailed: first pull the diff, then analyze it line by line across four dimensions—test coverage, performance, security, and code style—and finally output a structured review report.
You know what the difference is?
Without this Skill, the model can still do a code review, but its “review” is just a quick scan that says “looks good” or “could optimize a bit.” With the Skill, the review quality is on a completely different level.
---
MCP and Skills: Complementary or Competitive?
I’ll say it straight—they’re more competitive than complementary.
Why?
Because they’re both trying to solve the same problem: how to make the model use tools better.
It’s just that MCP takes a standardization and service-oriented approach, while Skills takes a knowledge and workflow-oriented approach.
MCP’s mindset is: “I’ve standardized the tool integration—now use them as you see fit.”
Skills’ mindset is: “I’ll not only give you the tools, but also teach you how to use them.”
If an MCP Server describes its tools in extreme detail and documents their usage, it’s encroaching on Skills’ turf. Conversely, if a Skill not only contains instructions but also wraps specific tool-calling scripts, it’s eating into MCP’s territory.
A lot of articles like to say “MCP and Skills are complementary.” I think that’s oversimplifying the problem.
Take my own project—I made Lynxe support both MCP and Skills. But in practice, what got used the most wasn’t complex combinations of MCP Servers, but a few carefully maintained Skills.
Why?
Because for most tasks, users don’t need “more tools.” They need “smarter ways to do things.”
---
Function Calling Is the Real Core
And here’s a conclusion that might offend some people—
Among these three, MCP and Skills are, to some extent, just dressing up the imperfections of Function Calling.
At the end of the day, the model only needs to know three things: what functions are available, what parameters each function requires, and the expected output of each function.
Function Calling already defines those three things clearly. MCP only standardizes the “discovery” of functions. Skills only “knowledge-ifies” how to use them.
But no matter how many layers of wrapping you add, what ultimately lands in front of the model is still that tool_calls JSON.
In Lynxe’s source code, I added a layer called “Skill Dispatcher.” All
Cael Lee
Full-stack developer with 8+ years of experience. Currently building AI-powered developer tools. I've tested 20+ AI API providers and coding assistants.