AI 工程化实战:不学算法也能用好的 LLM 指南
<div class="output_wrapper" id="output_wrapper_id"><blockquote><p>本文全面介绍了大模型相关知识,包括大模型(LLM)、提示词工程(PE)、检索增强生成(RAG)、工具调用(Function Calling)、模型上下文协议(MCP) 等,适合零基础小白入门。</p>
</blockquote>
<p>近些年,AI 的发展速度越来越快,越来越多的业务开始寻求“AI 赋能”。面对这个黑盒,很多研发人员的反应是疑惑:<em>“我需要学习神经网络算法吗?我要懂 Transformer 架构吗?”</em></p>
<p><strong>其实,对于非算法人员,我们不需要成为研发“发动机”的算法科学家,而是要成为能够驾驭“赛车”的 AI 工程师。</strong>我们无需深究底层的数学原理,但必须洞察它的能力边界,知道如何将这个“黑盒能力”高效、稳定地融入到我们的业务系统中。</p>
<h1 id="hllm"><span>一. LLM(大模型)</span></h1>
<h2 id="h"><span><strong>传统编程:显式的逻辑规则</strong></span></h2>
<p>作为研发人员,我们的日常工作本质上就是在定义各种函数 <span class="katex"><span class="katex-mathml"></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height: 1em; vertical-align: -0.25em"></span><span class="mord mathit" style="margin-right: 0.10764em">f</span><span class="mopen">(</span><span class="mord mathit">x</span><span class="mclose">)</span></span></span></span>。在传统的软件工程中,这些函数的内部逻辑是<strong>确定性</strong>的。比如判断一个人是否成年,可以写出以下函数:</p>
<pre><code class="python language-python hljs" style="font-family: Consolas, Inconsolata, Courier, monospace; display: block !important; white-space: pre !important; word-wrap: normal !important; word-break: normal !important; overflow: auto !important"><span class="hljs-function" style="word-wrap: inherit !important; word-break: inherit !important"><span class="hljs-keyword" style="word-wrap: inherit !important; word-break: inherit !important">def</span> <span class="hljs-title" style="word-wrap: inherit !important; word-break: inherit !important">is_adult</span><span class="hljs-params" style="word-wrap: inherit !important; word-break: inherit !important">(age)</span> {<br> <span class="hljs-title" style="word-wrap: inherit !important; word-break: inherit !important">return</span> <span class="hljs-title" style="word-wrap: inherit !important; word-break: inherit !important">age</span> >= 18<br>}<br></span></code></pre>
<p>在这种模式下,我们明确知道输入什么参数,经过怎样的判断,一定会得到确定的输出。</p>
<p>但当我们面对“识别图片中是猫还是狗”或“总结一篇文档”这类任务时,规则变得极其复杂且模糊,此时我们无法写一个确定性的<span class="katex"><span class="katex-mathml"></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height: 1em; vertical-align: -0.25em"></span><span class="mord mathit" style="margin-right: 0.10764em">f</span><span class="mopen">(</span><span class="mord mathit">x</span><span class="mclose">)</span></span></span></span>函数来完成对应的任务。</p>
<h2 id="hfx"><span><strong>机器学习:拟合复杂的 f(x)</strong></span></h2>
<p>既然无法手写复杂规则,机器学习便放弃了 “直接定义逻辑” 的思路,转而通过算法让机器在大规模数据中自动寻找规律,从而<strong>拟合</strong>出那个极其复杂的函数 <span class="katex"><span class="katex-mathml"></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height: 1em; vertical-align: -0.25em"></span><span class="mord mathit" style="margin-right: 0.10764em">f</span><span class="mopen">(</span><span class="mord mathit">x</span><span class="mclose">)</span></span></span></span>。</p>
<p>具体而言,机器学习会首先构建一个巨大的数学模型(神经网络),通过训练来修正模型内部的权重 (<span class="katex"><span class="katex-mathml"></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height: 0.43056em; vertical-align: 0"></span><span class="mord mathit" style="margin-right: 0.02691em">w</span></span></span></span>) 和 偏差 (<span class="katex"><span class="katex-mathml"></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height: 0.69444em; vertical-align: 0"></span><span class="mord mathit">b</span></span></span></span>)。训练的过程,本质上是一个迭代“试错”的过程:</p>
<ol>
<li><strong>预测</strong>:模型基于当前参数对输入数据做出预测(初始阶段基本是随机“瞎猜”)。</li>
<li><strong>反馈</strong>:当发现预测值与真实标签不符时(例如将猫误认为狗),算法会计算两者之间的误差。</li>
<li><strong>微调</strong>:利用数学方法(反向传播)回溯并微调内部的权重参数,目标是减小误差,让下一次预测更准。</li>
</ol>
<p>经过数百万次的重复训练,模型最终能基本精准地将输入映射到输出。此时,我们便得到了一个拟合好的函数 <span class="katex"><span class="katex-mathml"></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height: 1em; vertical-align: -0.25em"></span><span class="mord mathit" style="margin-right: 0.10764em">f</span><span class="mopen">(</span><span class="mord mathit">x</span><span class="mclose">)</span></span></span></span>。即便面对从未见过的数据,它也能根据从海量样本中提取出的特征规律,给出相应的判断。</p>
<p><strong>需要注意的是:</strong> 机器学习得到的函数是一个<strong>概率模型</strong>。它不像传统代码那样保证 100% 的绝对准确,而是在统计学上不断逼近正确答案。因此它天然存在出错的可能——即便是一张清晰的猫,模型仍有极小的概率产生偏差,将其识别成狗。</p>
<h2 id="hllm-1"><span><strong>大模型(LLM):量变引起的“涌现”</strong></span></h2>
<p>在传统机器学习时代,参数量通常在几百万到几亿级别,且大多是<strong>专用型</strong>的:识图模型无法处理翻译任务,翻译模型无法编写代码等。</p>
<p>而当参数量和训练数据突破临界点(如 GPT-3的千亿级参数)时,发生了神奇的<strong>“涌现现象”</strong>,模型的能力发生了质的飞跃(这类大参数量模型被称为大模型):</p>
<ul>
<li><strong>通用性</strong>:在学习预测万亿级语料的过程中,它自然而然地掌握了摘要、翻译、代码编写等多种能力,成为了一个可以处理几乎所有自然语言任务的“通用大脑”。</li>
<li><strong>上下文学习</strong>:不需要修改模型参数,只需在提示词(Prompt)里给出几个示例(Few-Shot),模型就能凭借强大的学习能力,快速适配新任务并执行。</li>
</ul>
<p>以 GPT (Generative Pre-trained Transformer) 为例,尽管其功能看似复杂,但底层核心机制十分纯粹,类似于“成语接龙”:</p>
<ul>
<li><strong>输入</strong>:用户的提示词 + 模型已经生成的上文(比如 “床前明月”)。</li>
<li><strong>预测</strong>:模型在词表中计算下一个最可能出现的词的概率分布(就像接龙时想 “床前明月” 后面该接 “光”)。</li>
<li><strong>输出</strong>:模型通常选取概率最高的词(例如输出 “光”),将该词拼接到原有输入中,形成新的上下文(“床前明月光”),再进入下一轮预测,直至触发结束标志。</li>
</ul>
<h1 id="hpe"><span>二. PE(提示词工程)</span></h1>
<h2 id="hpe-1"><span>什么是 PE?</span></h2>
<p>我们已经知道 LLM 本质上是一个<strong>“概率预测机”</strong>,它读取文本,计算概率,预测下一个词,循环往复。在这个过程中,我们给 LLM 的所有输入统称为 <strong>Prompt(提示词)</strong>。</p>
<p>但这里有个工程难题:<strong>如果输入是发散的,输出必然也是发散的。</strong> </p>
<p>举个例子,我们想让 LLM 判断用户反馈是正面还是负面:</p>
<p><strong>写法 A</strong>:<code>这条评论是正面的还是负面的?用户说界面太丑了,卸载了。</code></p>
<p>LLM 可能这样回答:</p>
<ul>
<li><span>"是负面的。"</span></li>
<li><span>"负面情绪"</span></li>
<li><span>"这条评论表达了用户的负面情绪,因为他说界面太丑,还卸载了应用。"</span></li>
</ul>
<p>三种回答都对,但格式完全不同。这在聊天时没问题,但如果你的程序需要解析这个结果(比如存入数据库、触发告警),这种不统一的格式简直是开发者的噩梦。</p>
<p><strong>写法B</strong>:<code>你是一个情感分析专家。请判断以下用户反馈的情感倾向,只返回"正面"或"负面",不要输出任何解释:
用户反馈:"界面太丑了,卸载了!"</code></p>
<p>这一次 LLM 的输出就很稳定:<code>负面</code>。</p>
<p><strong>为什么?因为写法 A 模棱两可,LLM 不知道你想要什么格式;写法 B 明确了角色、任务和输出要求。</strong></p>
<p>这就是<strong><em>提示词工程(Prompt Engineering)</em></strong>的核心:<strong>通过精心设计 Prompt,让 LLM 的输出更稳定、更准确、更符合业务需求。</strong></p>
<p>在聊天场景下,我们和 LLM 对话是"发散"的,它可能会说很多无关紧要的话,输出格式也可能随机变化。但一旦要把 LLM 接入业务系统,问题就来了:程序需要解析 LLM 的返回结果,一个格式不对的 JSON 就能让整个系统崩溃。</p>
<p>因此,PE 的核心目标是从“自由对话”转向“工程化协议”,<strong>就像调用 API 需要构造请求参数、定义返回格式一样,Prompt 就是这个"人机接口的协议"</strong> 。</p>
<h2 id="hpe-2"><span>如何写好 PE?</span></h2>
<p>写 Prompt 就像给实习生布置任务:你说得越清楚,他干得越靠谱。我们继续用"判断用户反馈情感"这个例子,看看如何逐步优化。</p>
<p><strong>(1) 先把话清楚:明确角色和任务</strong></p>
<p>第一步是“定义人设”,告诉 LLM:你是谁,要做什么。在 API 开发中,这通常通过 <strong>System Prompt(系统提示词)</strong> 来实现。</p>
<ul>
<li><strong>角色定义</strong>:"你是一个情感分析专家"——这样 LLM 会自动调整"专业程度",知道要从用户反馈中提取情感信号。</li>
<li><strong>任务指令</strong>:"请判断用户反馈的情感倾向"——不要让 LLM 去猜你想干什么,直接说清楚。</li>
</ul>
<pre><code class="markdown language-markdown hljs" style="font-family: Consolas, Inconsolata, Courier, monospace; display: block !important; white-space: pre !important; word-wrap: normal !important; word-break: normal !important; overflow: auto !important"><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important"># 角色</span><br>你是一个情感分析专家,擅长从用户反馈中识别情绪。<br><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important"># 任务</span><br>请判断用户反馈的情感倾向,只返回"正面"或"负面":<br></code></pre>
<p><strong>(2)给出模板:让 LLM 照着做</strong></p>
<p>直接下指令,LLM 有时仍会“放飞自我”。比如你要求“只返回正面或负面”,它可能会输出“这条反馈是负面的”或者“Negative”。这些都是"负面"的意思,但格式不一致。<strong>这时候,给他几个示例最有效</strong>,这叫 <strong><em>少样本学习(Few-Shot Learning)</em></strong>。</p>
<pre><code class="markdown language-markdown hljs" style="font-family: Consolas, Inconsolata, Courier, monospace; display: block !important; white-space: pre !important; word-wrap: normal !important; word-break: normal !important; overflow: auto !important"><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important"># 角色</span><br>你是一个情感分析专家,擅长从用户反馈中识别情绪。<br><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important"># 任务</span><br>请判断用户反馈的情感倾向,只返回"正面"或"负面":<br><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important"># 示例</span><br><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important">## 示例1输入:</span><br>这个APP太棒了!<br><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important">## 示例1输出:</span><br>正面<br><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important">## 示例2输入:</span><br>用了一天就崩了,垃圾软件。<br><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important">## 示例2输出:</span><br>负面<br></code></pre>
<p>就像给实习生一个"参考答案模板",他看了几个例子,自然就明白该怎么干了。而且这不需要重新训练模型,完全靠 LLM 强大的"上下文学习能力",给它几个例子,它就能学会新任务的规律。</p>
<p><strong>(3)让它慢下来:逐步推理</strong></p>
<p>在处理复杂情感时(比如阴阳怪气、转折句),LLM 容易直接“跳步”给错答案。比如用户评论:“界面漂亮但反应慢、想卸载”。LLM 可能看到“漂亮”就直觉式地判断为“正面”。</p>
<p>如果加一句话: <strong>"请逐步思考(Let's think step by step)"</strong> ,准确率会神奇地提升。这就是 <strong>CoT(Chain of Thought,思维链)</strong>。</p>
<p><strong>LLM 的内部逻辑流会变为:</strong></p>
<ol>
<li><strong>关键词提取</strong>:“界面漂亮”(正)、“反应慢”(负)、“想卸载”(极负)。</li>
<li><strong>意图分析</strong>:虽然有视觉上的夸赞,但最终行为是卸载,表达了强烈的挫败感。</li>
<li><strong>最终结论</strong>:负面。</li>
</ol>
<p><strong>核心逻辑:</strong> 强迫 LLM 先把推理过程写出来,这个过程会成为后续生成的“上下文”,相当于模型在<strong>“自我检查”</strong>,确保结论是推导出来的,而不是“猜”出来的。</p>
<pre><code class="markdown language-markdown hljs" style="font-family: Consolas, Inconsolata, Courier, monospace; display: block !important; white-space: pre !important; word-wrap: normal !important; word-break: normal !important; overflow: auto !important"><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important"># 角色</span><br>你是一个情感分析专家,擅长从用户反馈中识别情绪。<br><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important"># 任务</span><br>请判断用户反馈的情感倾向。请逐步思考后再输出结果。只返回"正面"或"负面":<br><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important"># 示例</span><br><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important">## 示例1输入:</span><br>这个APP太棒了!<br><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important">## 示例1输出:</span><br>正面<br><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important">## 示例2输入:</span><br>用了一天就崩了,垃圾软件。<br><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important">## 示例2输出:</span><br>负面<br></code></pre>
<p><strong>(4)格式约束:让程序能读懂</strong></p>
<p>前面解决的是“答得对”,但在代码场景下,还有一个关键问题:<strong>让 LLM “答得能被程序解析”。</strong></p>
<p>业务系统中,我们通常希望 LLM 返回 JSON 这种结构化数据。但 LLM 是个“话痨”,你让它返回 JSON,它可能随口回一句:“<strong>好的,这是你要的结果:{…}</strong>”。这多出来的几个字,就会导致 <code>json.loads()</code> 直接报错。</p>
<p>为了解决这个问题,<strong>工程上通常采用“事前约束 + 事后纠错”的组合拳</strong>:</p>
<p><strong>1. 结构化 Prompt(事前约束)</strong></p>
<ul>
<li><span>直接给模型一个标准的 JSON 模板,并约束它不要输出多余的解释。</span></li>
</ul>
<pre><code class="markdown language-markdown hljs" style="font-family: Consolas, Inconsolata, Courier, monospace; display: block !important; white-space: pre !important; word-wrap: normal !important; word-break: normal !important; overflow: auto !important"><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important"># 角色</span><br>你是一个情感分析专家,擅长从用户反馈中识别情绪。<br><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important"># 任务</span><br>请判断用户反馈的情感倾向并分析原因。请逐步思考后再输出结果。<br><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important"># 输入格式</span><br>{<br> "feedback": "<span class="xml" style="word-wrap: inherit !important; word-break: inherit !important"><span class="hljs-tag" style="word-wrap: inherit !important; word-break: inherit !important"><<span class="hljs-name" style="word-wrap: inherit !important; word-break: inherit !important">用户反馈内容</span>></span></span>"<br>}<br><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important"># 输出格式</span><br>{<br> "sentiment": "正面/负面",<br> "reason": "<span class="xml" style="word-wrap: inherit !important; word-break: inherit !important"><span class="hljs-tag" style="word-wrap: inherit !important; word-break: inherit !important"><<span class="hljs-name" style="word-wrap: inherit !important; word-break: inherit !important">原因分析</span>></span></span>"<br>}<br><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important"># 约束</span><br><span class="hljs-bullet" style="word-wrap: inherit !important; word-break: inherit !important">1. </span>必须仅返回 JSON 数据,禁止任何解释性文字<br><span class="hljs-bullet" style="word-wrap: inherit !important; word-break: inherit !important">2. </span>sentiment 字段只能是 "正面" 或 "负面"<br><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important"># 示例</span><br><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important">## 示例1输入</span><br>{"feedback": "这个APP太棒了!"}<br><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important">## 示例1输出</span><br>{"sentiment": "正面", "reason": "用户对产品表示满意"}<br><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important">## 示例2输入</span><br>{"feedback": "用了一天就崩了,垃圾软件。"}<br><span class="hljs-section" style="word-wrap: inherit !important; word-break: inherit !important">## 示例2输出</span><br>{"sentiment": "负面", "reason": "用户遇到稳定性问题"}<br></code></pre>
<p><strong>2. 工程化鲁棒性(事后纠错)</strong> 在实际业务中,单靠 Prompt 依然会有概率遇到非法格式。研发通常会引入以下兜底方案:</p>
<ul>
<li><strong>原生 JSON 模式</strong>:调用 API 时开启模型自带的 <code>response_format: { "type": "json_object" }</code> 模式,强制模型输出。(如果平台支持的话)。</li>
<li><strong>自动修复(Repair)</strong>:使用类似 <code>json_repair</code> 的库。这些库利用算法修复模型输出中缺失的引号、括号或多余的解释语。</li>
<li><strong>重试机制(Retry)</strong>:如果解析失败,自动进行 2-3 次重试,或者在重试时把错误信息返还给模型(“你刚才返回的格式错了,请修正”)。</li>
</ul>
<h1 id="hrag"><span>三. RAG(检索增强生成)</span></h1>
<p>PE(提示词工程)解决了让大模型“更听话”的问题,但即便再会写 Prompt,大模型本质上仍是一个<strong>静态的知识库</strong>(它的记忆停留在训练结束的那一天)。它有两大无法克服的缺陷:<strong>幻觉</strong>和<strong>知识滞后</strong>。</p>
<ul>
<li><strong>幻觉(一本正经的胡说八道</strong>):无论我们对大模型说些什么,它都会通过“概率预测”生成一段回答,这段回答看起来很专业,但可能完全是错误的,就像学生在考试时遇到不会的题,凭借“直觉”编一个听起来像样的答案。</li>
<li><strong>知识滞后(不知道最新的事)</strong>:LLM 无法实时获取信息。无法用它来查询公司最新的内部文档或今天的实时销售数据。</li>
</ul>
<p>为了解决这些问题,就诞生了<strong>RAG (Retrieval-Augmented Generation,检索增强生成)</strong> ,它将大模型的“生成能力”与传统数据检索的“准确性”结合起来,<strong>给大模型外挂一个“实时更新的知识库”</strong>。</p>
<p>如果把大模型直接回答问题比作“<strong>闭卷考试</strong>”,那么 RAG 就是让它变成一个“<strong>开卷考试</strong>”的学生。</p>
<ul>
<li><strong>闭卷模式</strong>:由于模型没学过公司的私有文档,它只能凭直觉“编”。</li>
<li><strong>开卷模式(RAG)</strong>:</li>
</ul>
<ol>
<li><strong>翻书(检索)</strong>:当用户提问时,系统先去内部文档库里搜索相关的段落。</li>
<li><strong>摘抄(增强)</strong>:把找到的准确信息“抄”在 Prompt 里,作为背景参考资料。</li>
<li><strong>作答(生成)</strong>:最后让大模型根据这些“参考资料”来组织语言回答。</li>
</ol>
<p>这样,AI 就不再是凭空想象,而是“有据可查”。要把这套“开卷考试”系统跑通,需要经历以下核心步骤:</p>
<p><strong>第一步:准备阶段 —— 语义向量化</strong></p>
<p>计算机读不懂文字,它只懂数字。我们需要把文字转换成一种数学表达,这就是 <strong>Embedding</strong>(词嵌入)。</p>
<ul>
<li><strong>Embedding 模型</strong>:这是一种特殊的模型,它能把文本映射成一串高维数组(向量)。</li>
<li><strong>核心逻辑</strong>:<strong>语义相近的文本,在数学空间里的“距离”也更近。</strong> 比如,“猫”和“小猫”的向量距离,会比“猫”和“挖掘机”近得多。这使得“语义搜索”成为可能。</li>
</ul>
<p><strong>第二步:检索阶段 —— 向量数据库</strong></p>
<p>有了向量,我们需要一个专门的“仓库”来存储和查询它们。</p>
<ul>
<li><strong>入库</strong>:我们将公司文档切割成一个个小段(Chunking),算出向量,存入<strong>向量数据库</strong>。</li>
<li><strong>查询</strong>:当用户问“怎么申请年假?”时,系统先算出这个问题的向量。</li>
<li><strong>搜索</strong>:向量数据库会瞬间找出仓库里和该问题“空间距离最近”的文档段落(这就是 Top-K 检索)。</li>
</ul>
<p><strong>第三步:生成阶段 —— Prompt 增强</strong></p>
<p>这是最关键的一步,当系统从向量数据库中检索出相关的文档段落后,需要把这些资料和大模型连接起来。怎么做?很简单:<strong>把检索到的资料作为"上下文",嵌入到 Prompt 里。</strong>这样,大模型在回答问题时,就能看到“参考资料”,而不是“凭空编造”。</p>
<h1 id="hfunctioncalling"><span>四. Function Calling(工具调用)</span></h1>
<p>如果说 PE(提示词工程)让大模型学会了“说话”,RAG(检索增强生成)让大模型拥有了<strong>“</strong>知识<strong>”</strong>,那么此时的大模型更像是一个“军师”,只能在对话框里指点江山,却无法替你出门办事。</p>
<p>比如当问它:“今天北京天气怎么样?”,它会说:“我无法获取实时信息。”;当让它发封邮件,它会抱歉地说:“我没有操作权限。”</p>
<p>为了解决这个问题,就诞生了<strong>Function Calling(函数调用)</strong>,相当于给大模型装了一双“<strong>手脚</strong>”,让它从只会聊天的机器人,进化为能够干活的智能助手。</p>
<p>Function Calling 的核心机制,是让大模型具备<strong>意图识别</strong>和<strong>参数生成</strong>的能力:</p>
<ol>
<li><strong>意图识别</strong>:用户的问题需要调用什么工具?</li>
<li><strong>参数生成</strong>:调用这个工具需要什么参数?</li>
</ol>
<p>很多人会误解以为大模型亲自去查了天气、发了邮件。但实际上大模型本身不会“执行”任何函数,它只是告诉服务端:“我觉得应该调用这个函数,参数是这样的”。真正的执行,依然是由你的服务端程序去完成的。</p>
<p>一个完整的 Function Calling 流程,包括四个步骤:</p>
<ol>
<li><strong>工具注册</strong>:在让大模型使用工具之前,开发者需要先告诉它有哪些工具可以用。开发者会向大模型<strong>注册</strong>它能使用的函数,并提供一个<strong>严格的 JSON Schema</strong>。这个 Schema 定义了:</li>
</ol>
<ul>
<li><p>函数叫什么名字</p></li>
<li><p>函数是干什么的</p></li>
<li><p>需要什么参数</p></li>
<li><p>参数的类型是什么</p>
<p>这就像给大模型一本"工具说明书":"如果你看到查天气、发邮件的意图,你可以调用我注册的这些函数。"</p></li>
</ul>
<ol>
<li><p><strong>模型的意图识别</strong>:当用户提问时,大模型会做两件事:</p></li>
<li><p><strong>判断是否需要调用工具</strong>:用户是只想聊聊天,还是真的需要执行某个操作?</p></li>
<li><p><strong>如果需要,生成调用信息</strong>:调用哪个函数?参数是什么?</p>
<p>关键是:大模型<strong>不再生成自然语言回答</strong>,而是生成一个<strong>符合 Schema 的 JSON 结构</strong>。举个例子:</p>
<p>用户问: <strong>"今天北京天气怎么样?"</strong></p>
<p>大模型分析后,不会说"我查一下天气",而是生成一个 JSON:</p>
<pre><code class="json language-json hljs" style="font-family: Consolas, Inconsolata, Courier, monospace; display: block !important; white-space: pre !important; word-wrap: normal !important; word-break: normal !important; overflow: auto !important">{<br> <span class="hljs-attr" style="word-wrap: inherit !important; word-break: inherit !important">"function"</span>: <span class="hljs-string" style="word-wrap: inherit !important; word-break: inherit !important">"get_weather"</span>,<br> <span class="hljs-attr" style="word-wrap: inherit !important; word-break: inherit !important">"parameters"</span>: {<br> <span class="hljs-attr" style="word-wrap: inherit !important; word-break: inherit !important">"city"</span>: <span class="hljs-string" style="word-wrap: inherit !important; word-break: inherit !important">"北京"</span><br> }<br>}<br></code></pre>
<p>这就是 Function Call 的核心,大模型扮演的是"调度员",它负责理解意图、提取参数,但不真正执行操作。</p></li>
<li><p><strong>执行函数与结果回传</strong>:服务端接收到这个 JSON,就知道:"哦,用户想查北京天气。此时会执行真正的业务函数,比如调用天气 API,拿到实时数据:"北京今天 15°C,晴。"然后,这个执行结果被打包成文本,作为<strong>新的 Prompt 上下文</strong>,<strong>重新喂回给大模型</strong>。</p></li>
<li><p><strong>最终回复</strong>:</p>
<p>现在,大模型有了实时数据——"北京今天 15°C,晴",它可以根据这些信息,生成最终的自然语言回答:"北京今天天气不错,温度是 15°C,晴朗。"</p></li>
</ol>
<h1 id="hmcp"><span>五. MCP(模型上下文协议)</span></h1>
<p><strong>Function Calling</strong> 赋予了大模型执行任务的能力,但在实际工程中,开发者面临着一个巨大的痛苦:<strong>协议碎片化</strong>。</p>
<p>想象一下,你为 OpenAI 的模型写了一套查天气的工具,但换到 Google 的模型上,这套工具完全不能用,你需要重新写一遍。这就好像每家手机厂商都有自己的充电接口,你的充电器只能给自家的手机充电,换个牌子就没法用了。</p>
<p>为了实现大规模协作和生态互联,需要<strong>统一的标准</strong>和<strong>高效的工具</strong>。这个时候就诞生了<strong>MCP(Model Context Protocol,模型上下文协议)</strong> ,可以将其理解为它是 AI 时代的 <strong>Type-C 接口</strong>或 <strong>TCP/IP 协议</strong>。</p>
<p>MCP 的核心目标是实现 <strong>“一次开发,到处可用”</strong>。它将 LLM(大脑)与 Context/Tools(知识与工具)彻底解耦。</p>
<ul>
<li><strong>之前(模型绑定)</strong>:工具和数据源往往与特定的模型厂商深度绑定。你想让模型读取你的本地文件或数据库,必须为每个模型量身定制适配层。</li>
<li><strong>现在(通用标准)</strong>:无论是哪个模型(大脑),只要它支持 MCP 标准,就能像插拔 Type-C 设备一样,无缝调用任何遵守 MCP 协议的数据源或工具。</li>
</ul>
<p>对于开发者和企业来说,MCP 协议的出现具有里程碑式的意义:</p>
<ol>
<li><strong>统一的标准协议</strong>: MCP 就像是 AI 领域的 <strong>TCP/IP 协议</strong>。它定义了一套通用的语言,让模型能够以统一的方式发现工具(Tools)、读取资源(Resources)和查看提示词模板(Prompts)。</li>
<li><strong>极低的适配成本</strong>:</li>
</ol>
<ul>
<li><strong>以前</strong>:如果你有 10 个数据源(数据库、GitHub、Slack 等)和 3 个主流模型,你可能需要维护 30 套适配逻辑。</li>
<li><strong>现在</strong>:你只需要让这 10 个数据源支持 MCP 协议,任何支持 MCP 的模型(如 Claude Desktop 或各类 AI IDE)都能立即接管并使用它们。</li>
</ul>
<ol>
<li><strong>生态互联的基石</strong>: MCP 为 AI生态的爆发奠定了基础。开发者可以像拼乐高积木一样,将来自不同供应商的 MCP 服务器(数据源)组合在一起,构建出极其复杂的自动化工作流。</li>
</ol>
<h1 id="h-1"><span>总结</span></h1>
<p>AI 不是黑魔法,它是一个有概率、需要被控制(PE)、需要知识(RAG)、需要执行能力(Function Calling)和标准互联(MCP)的复杂系统。</p>
<ul>
<li><strong>PE(提示词工程)</strong> :解决了"如何让 AI 听话"。</li>
<li><strong>RAG(检索增强生成)</strong> :解决了"如何让 AI 有知识"。</li>
<li><strong>Function Calling(工具调用)</strong> :解决了"如何让 AI 能干活"。</li>
<li><strong>MCP(模型上下文协议)</strong> :解决了"如何让 AI 生态互联"。</li>
</ul>
<h1 id="h-2"><span>写到最后</span></h1>
<p>目前我在公司主要是做一些 AI 的业务,所以更加理解作为研发人员,需要深入了解哪些,而哪些知识只需要简单了解即可。本文主要是作为一个概述,通俗的讲一下 AI 相关的名词概念,后续会更加深入的讲一下必要的知识点,比如提示词工程(PE)、检索增强(RAG)、工作流(Workflow)、智能体(Agent)、Langchain、Coze、n8n等等。</p>
<p><strong>欢迎关注,一起成为能够驾驭“赛车”的 AI 工程师。</strong></p></div><br><br>
来源:https://www.cnblogs.com/yifeng-coding/p/19638882
頁:
[1]