news 2026/8/12 14:45:54

大模型应用开发四大基石:Token、Prompt、Embedding与Function Calling详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
大模型应用开发四大基石:Token、Prompt、Embedding与Function Calling详解

1. 项目概述:大模型时代的四大基石

最近在社区里,看到不少朋友在讨论大模型应用开发时,对几个核心概念——Token、Prompt、Embedding和Function Calling——的理解还比较模糊,经常混为一谈。我自己在从零开始构建AI应用的过程中,也花了相当长的时间才把这些概念真正“吃透”。今天,我就从一个一线开发者的角度,结合我踩过的坑和积累的经验,把这四个概念掰开揉碎了讲清楚。这不仅仅是理论介绍,更是你能否高效、低成本地用好大模型,甚至设计出优秀AI产品的关键。无论你是刚入门的新手,还是已经有一定经验的开发者,理解这四个概念及其相互关系,都能帮你避开很多弯路,直接抓住问题的核心。

简单来说,你可以把这四个概念看作是与大模型交互的“四步曲”:Token是沟通的“货币”和“基本单位”,决定了你能说多少话、花多少钱;Prompt是你说的“话”本身,是引导模型产出的指令和上下文,说得好不好直接决定了结果的质量;Embedding是理解世界的“方式”,它将文本、图像等信息转化为模型能懂的数学向量,是构建长期记忆和知识库的基石;而Function Calling则是模型与外部世界“握手”的“接口”,让模型不仅能说会道,还能实际操作工具、查询数据、执行任务。接下来,我们就逐一深入。

2. Token:模型世界的“计价单位”与“信息原子”

2.1 Token究竟是什么?不只是“单词”

很多初学者会把Token简单地等同于英文单词或中文字符,这是一个常见的误解。实际上,Token是大模型用来理解和生成文本的最小语义单位。你可以把它想象成一种“信息原子”。

对于英文,一个Token通常对应一个常见的单词(如“apple”)、一个词根(如“un-”表示否定)或一个标点符号。但对于不常见的单词、长单词或专业术语,模型可能会将其拆分成多个子词(Subword)Token。例如,“unbelievable”可能会被拆分成“un”、“believe”、“able”三个Token。这种拆分的算法(如Byte-Pair Encoding, BPE)是模型在训练时学到的,目的是在词汇表大小和语义表示效率之间取得平衡。

对于中文,情况更特殊。主流的大模型(如GPT系列、Claude、国产的DeepSeek、通义千问等)通常采用基于字的切分或混合切分。一个汉字通常就是一个Token,但常见的词语或成语也可能被合并为一个Token。例如,“人工智能”四个字,在某些模型的Tokenizer里可能被切分为“人”、“工”、“智”、“能”四个Token,也可能被识别为“人工”、“智能”两个Token,这完全取决于模型训练时采用的语料和分词算法。

注意:不同模型、不同厂商的Tokenizer千差万别。用OpenAI的tiktoken库去数GPT的Token,和用Hugging Face的transformers库去数Llama的Token,结果很可能不同。这是成本计算和上下文长度管理时必须搞清楚的第一个坑。

2.2 为什么Token如此重要?成本与能力的标尺

Token的重要性体现在两个核心维度:成本上下文窗口

1. 成本维度:Token是计费的直接依据。几乎所有云服务商对大模型的收费都是基于Token的。无论是输入(Prompt Tokens)还是输出(Completion Tokens),都要计费。例如,GPT-4 Turbo的定价可能是每1000个输入Token收费$0.01,每1000个输出Token收费$0.03。如果你发送了一个500 Token的Prompt,模型生成了300 Token的回复,那么本次调用成本就是(500/1000)*0.01 + (300/1000)*0.03 = $0.014

这意味着,优化Prompt、减少不必要的废话、让模型输出更简洁,能直接降低你的使用成本。我见过不少项目,初期因为Prompt设计得冗长低效,导致月度API账单高得吓人。

2. 能力维度:上下文窗口(Context Window)由Token数定义。模型的“记忆力”是有限的,这个限度就是它能同时处理的Token总数,即上下文窗口。早期的GPT-3.5是4K(约3000字),现在的GPT-4 Turbo是128K,Claude 3 Opus甚至能达到200K。

这个窗口需要容纳你的系统指令(System Prompt)、用户问题(User Message)、历史对话记录以及模型即将生成的回答。如果你的对话总长度超过了这个限制,最旧的信息会被“遗忘”(从技术上讲,是被移出模型的注意力范围)。因此,在设计需要长上下文记忆的应用(如长文档分析、多轮复杂对话)时,你必须精打细算地管理Token消耗。

实操心得:如何高效管理Token?

  • 估算与监控:在发送请求前,先用对应模型的Tokenizer(如OpenAI的tiktoken, Hugging Face的transformers)估算Prompt的Token数。在应用日志中记录每次调用的Token消耗,便于分析和优化。
  • 压缩Prompt:移除System Prompt中不必要的描述;使用更精确的指令;对于长文本,可以先进行摘要(Summarization)再喂给模型。
  • 流式处理长内容:对于超长文档,不要一次性全部塞进上下文。可以采用“Map-Reduce”策略:先切分文档,让模型对每个片段进行分析(Map),再让模型对分析结果进行总结(Reduce)。
  • 警惕“百万Token”陷阱:虽然有些模型宣传支持超长上下文,但实测中,模型对位于上下文中间位置的信息的回忆能力(Needle in a Haystack)会显著下降。不要盲目依赖超长窗口,关键信息尽量放在Prompt的靠前或靠后位置。

3. Prompt:与模型对话的“艺术”与“工程”

3.1 超越指令:Prompt的构成与类型

Prompt远不止是你问的那句话。一个完整的、高效的Prompt通常是一个结构化的信息集合:

  1. 系统指令(System Prompt):设定模型的角色、行为规范和回答格式。这是对话的“宪法”,通常放在最前面且相对固定。例如:“你是一位资深软件架构师,回答需严谨、结构化,优先给出核心原理,再附上代码示例。”
  2. 上下文信息(Context):提供给模型完成任务所需的背景知识。这可以是用户上传的文档、数据库查询结果、之前的对话历史等。这是让模型“有据可依”的关键。
  3. 用户查询(User Query/Message):用户本次提出的具体问题或请求。
  4. 示例(Few-Shot Examples):在Prompt中提供一两个输入-输出的例子,让模型通过“示例学习”来掌握你想要的格式和风格。这对于复杂任务(如特定格式的JSON生成、诗歌创作)效果极佳。

根据交互方式,Prompt Engineering发展出了一些高级模式:

  • 思维链(Chain-of-Thought, CoT):在Prompt中要求模型“一步一步地思考”,鼓励它展示推理过程,通常能显著提升复杂逻辑和数学问题的准确性。
  • ReAct模式:结合推理(Reasoning)和行动(Acting),指导模型先思考要做什么,再决定调用哪个工具(Function),最后根据工具返回结果进行总结。这是实现智能Agent的基础。
  • 系统Prompt与Function Calling的协同:系统Prompt可以定义模型可以调用哪些函数(工具),而用户查询则触发模型决定是否及如何调用它们。两者需紧密配合。

3.2 从理论到实践:写出好Prompt的秘诀

写Prompt不是玄学,而是一项可以练习和优化的技能。以下是我总结的几个核心原则:

1. 明确性高于一切模糊的指令得到模糊的结果。对比一下:

  • 差:“写一篇关于人工智能的文章。”
  • 好:“以‘人工智能的伦理挑战’为题,撰写一篇800字左右的科普文章,目标读者是高中生。文章需包含三个主要部分:1) 算法偏见的具体案例;2) 数据隐私问题;3) 未来监管的展望。语言需生动易懂,每部分开头用一个小问题引入。”

2. 提供结构化上下文当需要模型处理特定信息时,将信息清晰地组织起来。不要扔给它一整段杂乱无章的文本。

请根据以下产品描述和用户评论,总结该产品的主要优点和待改进点: 【产品描述】 产品名称:智能水杯H2O Pro 核心功能:1. 饮水提醒(每2小时);2. 水温显示;3. 每日饮水量统计。 【用户评论】 - 用户A:“提醒功能很贴心,帮我养成了喝水习惯。” - 用户B:“水温显示不准,经常比实际温度低5度。” - 用户C:“App的统计图表很好看,但偶尔会同步失败。”

3. 使用分隔符和格式标记###”””<>【】等符号清晰地区分Prompt的不同部分,帮助模型理解结构。4. 指定输出格式如果你需要JSON、XML、Markdown或特定样式的文本,直接在Prompt中说明。例如:“请以JSON格式返回,包含namescorereason三个字段。”

踩坑实录:Prompt的常见陷阱

  • 指令冲突:System Prompt里说“回答要简短”,但User Query里又要求“详细分析”。模型会感到困惑,结果往往不如人意。
  • 上下文淹没:在超长的上下文里,你的关键指令如果被埋在中间,模型可能会“看不见”。重要的指令应置于System Prompt或最新User Message的突出位置。
  • 幻觉(Hallucination):当Prompt中信息不足或指令过于开放时,模型可能会编造看似合理但完全错误的信息。解决之道是提供充足的、准确的上下文,并让模型基于此进行回答。

4. Embedding:从文字到“向量空间”的魔法

4.1 理解Embedding:文本的“数学指纹”

如果说Token是离散的符号,那么Embedding就是将这些符号映射到一个连续的高维数学空间中的点(即向量)。这个空间被称为“嵌入空间”(Embedding Space)。

核心思想:语义相似的文本,其对应的向量在空间中的距离(通常用余弦相似度衡量)也相近。例如,“猫”和“ kitten”的向量会很接近,“编程”和“代码”的向量也会很接近,而“猫”和“汽车”的向量则相距甚远。

这个过程通常由专门的嵌入模型(Embedding Model)完成,如OpenAI的text-embedding-ada-002,国产的BGE(BAAI General Embedding)系列,Sentence-Transformers库提供的各种模型等。这些模型经过海量文本训练,学会了为任何一段文本(一个词、一句话、一个段落)生成一个固定长度的、富含语义信息的向量(比如1536维、768维)。

4.2 Embedding的核心应用:检索、聚类与记忆

Embedding不是用来直接生成文本的,而是用来理解、比较和检索文本的。它是构建大模型“长期记忆”和“专业知识”的核心技术。

1. 检索增强生成(Retrieval-Augmented Generation, RAG)这是当前最火热的AI应用架构之一。其核心流程是:

  • 索引:将你的私有知识库(文档、手册、问答对)全部通过Embedding模型转换成向量,存入向量数据库(如Pinecone、Chroma、Milvus、Qdrant)。
  • 检索:当用户提问时,将问题也转换成向量,然后在向量数据库中搜索与之最相似的几个知识片段(基于向量相似度)。
  • 增强:将这些检索到的相关片段作为上下文,与用户问题一起构成Prompt,发送给大语言模型生成答案。 这样,模型就能基于你的私有、最新的、准确的知识来回答问题,极大地减少了“幻觉”,并突破了模型本身知识截止日期的限制。

2. 文本聚类与分类通过计算大量文本的Embedding向量,可以利用聚类算法(如K-Means)自动发现文本主题。也可以基于已标注数据训练分类器,对新的文本进行自动分类。

3. 语义搜索超越关键词匹配的传统搜索。即使用户的查询词和文档中的用词不同,但只要语义相近,也能被检索出来。例如,搜索“如何修复汽车不启动”,能匹配到包含“车辆无法点火故障排除”的文档。

实操要点与模型选型

  • 维度与性能:Embedding向量的维度越高,通常能携带的语义信息越丰富,但计算和存储开销也越大。需要在精度和效率间权衡。text-embedding-ada-002是1536维,许多BGE模型是768维。
  • 模型选择
    • 通用领域:OpenAI的Embedding API简单易用,但需考虑网络和成本。text-embedding-3-small-3-large是新一代产品,性能更强。
    • 开源与本地部署BGE系列(如BGE-M3)、Sentence-Transformers模型(如all-MiniLM-L6-v2)是开源首选,可以免费商用、本地部署,数据隐私有保障。
    • 垂直领域:如果你的文档非常专业(如法律、医疗),使用在该领域语料上微调过的Embedding模型效果会好得多。
  • “No embedding model is loaded”错误:在使用LangChain、LlamaIndex等框架搭建RAG系统时,这个错误很常见。根本原因是框架没有正确配置或加载Embedding模型。你需要明确指定Embedding模型的名称或路径,例如在LangChain中:HuggingFaceEmbeddings(model_name="BAAI/bge-small-zh-v1.5")

5. Function Calling:让大模型成为“行动派”

5.1 什么是Function Calling?模型的“手”和“脚”

Function Calling(函数调用)是大语言模型根据用户请求,主动决定调用开发者预定义好的外部函数(工具)的能力。你可以把它理解为模型学会了“阅读工具说明书”并“按需使用工具”。

在没有Function Calling之前,模型只能“空谈”。有了它,模型就能:

  • 查询实时数据(如天气、股价、新闻)。
  • 操作外部系统(如发送邮件、创建日历事件、控制智能家居)。
  • 执行复杂计算(调用计算器、代码解释器)。
  • 检索数据库或知识库(这常与RAG结合,模型决定何时去向量库搜索)。

工作流程

  1. 定义工具:开发者告诉模型有哪些工具可用,每个工具的用途、所需参数(及其类型、描述)是什么。这通常通过一个JSON Schema列表来定义。
  2. 模型决策:用户提问后,模型会分析问题。如果判断需要调用工具,它不会直接执行,而是生成一个结构化的调用请求,包含要调用的函数名和具体的参数值。
  3. 本地执行:你的应用程序收到这个请求后,在本地安全地执行对应的函数,获取真实结果(如从数据库查到数据、调用了一次天气API)。
  4. 结果反馈:将执行结果以文本形式反馈给模型。
  5. 模型总结:模型结合工具返回的结果,生成最终的回答给用户。

5.2 实际开发中的关键细节

1. 如何定义好的Function?函数的描述至关重要,它是模型决定是否调用以及如何填参的依据。

  • 清晰的名称和描述:函数名和描述应直白地说明其功能。例如,get_current_weather描述为“获取指定城市的当前天气情况”。
  • 详细的参数说明:每个参数都要有类型和描述。例如,location参数描述为“城市名称,格式如‘北京’或‘New York’”。
  • 结构化响应:虽然模型不直接接收函数的代码返回值结构,但良好的设计有助于后续处理。

2. 与System Prompt的配合System Prompt里需要明确告知模型它可以使用这些函数,并说明在什么情况下使用。例如:“你是一个智能助手,可以帮用户查询天气、管理待办事项。当用户询问与天气相关的问题时,请调用天气查询函数。”

3. 错误处理与流程控制

  • 模型可能出错:模型可能调用错误的函数,或参数填得不合理。你的代码需要做校验,如果调用失败,可以将错误信息反馈给模型,让它重试或调整策略。
  • 多轮工具调用:复杂任务可能需要连续调用多个工具。你需要维护好对话状态,管理好每次模型返回的工具调用请求和你的执行反馈。

一个简单的代码示例(概念性): 假设我们定义了一个查询天气的函数。

# 1. 定义函数(工具) tools = [ { "type": "function", "function": { "name": "get_weather", "description": "获取指定城市的当前天气", "parameters": { "type": "object", "properties": { "location": {"type": "string", "description": "城市名,例如:上海"} }, "required": ["location"] } } } ] # 2. 将工具列表和用户问题一起发送给模型 response = client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": "上海今天天气怎么样?"}], tools=tools, tool_choice="auto", # 让模型自动决定是否调用工具 ) # 3. 检查模型是否想调用工具 message = response.choices[0].message if message.tool_calls: # 4. 提取模型想调用的函数名和参数 tool_call = message.tool_calls[0] function_name = tool_call.function.name arguments = json.loads(tool_call.function.arguments) # 5. 在本地安全地执行对应函数 if function_name == "get_weather": weather_result = get_weather(**arguments) # 你的本地函数 # 6. 将结果作为新的消息反馈给模型,让它生成最终回答 second_response = client.chat.completions.create( model="gpt-4", messages=[ {"role": "user", "content": "上海今天天气怎么样?"}, message, # 包含工具调用请求的模型消息 { "role": "tool", "content": str(weather_result), # 工具执行结果 "tool_call_id": tool_call.id } ] ) final_answer = second_response.choices[0].message.content print(final_answer) # 输出:“上海今天晴,气温25度,微风...”

6. 四大概念的协同:构建智能应用的蓝图

现在,让我们把这四个概念串联起来,看一个完整的智能客服Agent是如何运作的:

  1. 用户输入:“我上周买的智能水杯H2O Pro,水温显示不准怎么办?”(这句话被转换成一系列Token,消耗了输入Token配额)。
  2. 意图理解与检索(Embedding + Function Calling)
    • 系统将用户问题转换为Embedding向量。
    • 在向量数据库中检索相关的产品手册、故障排除指南和用户服务协议(这是通过一个“检索知识库”的Function实现的,模型决定调用它)。
    • 检索到的相关文档片段作为上下文被注入Prompt。
  3. 规划与执行(Prompt + Function Calling)
    • 系统Prompt定义了Agent的角色是“客服专员”,并告知其可以调用“查询订单”、“提供维修指南”、“发起售后申请”等函数。
    • 结合用户问题和检索到的上下文,模型分析后决定:先调用“查询订单”函数确认购买信息,然后调用“获取维修指南”函数。
    • 本地代码执行这些函数,返回订单状态和具体的校准水温传感器的步骤图文。
  4. 生成回复(Prompt + Token)
    • 模型将订单信息、维修步骤以及从知识库中检索到的“常见问题-温度校准”部分,整合进最终的回复中。
    • 它以友好、专业的口吻生成回答:“尊敬的客户,已确认您的订单。针对水温显示不准的问题,您可以尝试以下校准步骤:1...2...。如果问题依旧,您可以点击此链接发起售后申请。”这个回复被生成为一串新的Token,消耗输出Token配额。

在整个流程中,Token是贯穿始终的消耗单位,Prompt是组织和指挥所有行动的蓝图,Embedding为决策提供了长期记忆和知识支撑,而Function Calling则是执行具体任务的手和脚。理解并熟练运用这四者的关系,你就能从单纯地“调用API”升级为“设计AI工作流”,真正释放大模型的潜力。

7. 常见问题与避坑指南

在实际开发和调试中,你会遇到各种各样的问题。下面这个表格整理了我遇到的一些典型问题及其排查思路:

问题现象可能原因排查步骤与解决方案
API调用返回“invalid prompt”或内容被过滤1. Prompt中包含被模型安全策略禁止的敏感词。
2. 用户输入触发了内容安全过滤器。
1. 检查Prompt,移除或改写可能涉及暴力、仇恨、自残等违规内容。
2. 对用户输入进行预处理和过滤。
3. 尝试调整Prompt的表述方式,使其更中性。
Token消耗远超预期1. System Prompt过长或每次重复发送。
2. 对话历史未做修剪,无限累积。
3. Embedding检索返回的上下文过长。
1. 精简System Prompt,只保留核心指令。
2. 实现对话历史管理:仅保留最近N轮,或对历史进行摘要。
3. 控制检索返回的文档片段数量和长度(Top-K和字符限制)。
RAG效果差,模型回答“不知道”或胡编乱造1. Embedding模型与领域不匹配。
2. 检索到的文档不相关。
3. 相关文档未正确注入Prompt上下文。
1. 评估并尝试更换更适合你领域的Embedding模型(如换用BGE中文模型)。
2. 优化检索策略:尝试不同的相似度算法(余弦/点积/L2),调整检索阈值。
3. 检查Prompt模板,确保检索到的上下文被正确放置在{context}变量中。
Function Calling未被触发1. 函数描述不够清晰,模型不理解何时该调用。
2. System Prompt中未明确鼓励或授权模型使用工具。
3. 用户问题本身不需要调用工具。
1. 重写函数描述,使其目的和适用场景极度明确。
2. 在System Prompt中加入:“你可以使用我为你提供的工具来获取必要信息。”
3. 在User Prompt中也可以直接提示,如“请使用查询天气的工具来回答我的问题”。
模型生成的函数参数格式错误1. 参数Schema定义有歧义。
2. 模型对参数类型的理解有偏差。
1. 仔细检查参数JSON Schema,确保类型(string, number, boolean等)和格式描述准确无误。
2. 在函数描述中提供参数示例,如“location (string): 城市名,例如:‘北京市’”。
3. 在代码中增加参数校验和类型转换的容错逻辑。
“No embedding model is loaded”错误在使用LangChain等框架时,Embedding模型未正确初始化或配置路径错误。1. 确认已安装对应的Embedding模型包(如sentence-transformers)。
2. 检查初始化代码:embedding_model = HuggingFaceEmbeddings(model_name=“正确的模型名称或路径”)
3. 对于离线环境,确保模型文件已下载到本地,并指定本地路径。
长上下文下模型性能下降模型对位于上下文中间部分的信息关注度(注意力)减弱,这是当前Transformer架构的固有特性。1. 关键信息尽量放在Prompt的开头或结尾。
2. 对于超长文档,采用分层检索或Map-Reduce策略,而非一次性全部输入。
3. 考虑使用专门优化了长上下文能力的模型(如Claude 3)。

最后一点个人体会:学习这四个概念,最好的方法不是死记硬背,而是动手搭建一个最简单的RAG应用或一个能调用天气API的聊天机器人。在调试的过程中,你会对Token的消耗、Prompt的微妙影响、Embedding相似度的阈值、Function Calling的触发条件产生肌肉记忆般的理解。开始时可能会觉得繁琐,但一旦打通,你会发现构建AI应用的道路突然变得清晰而开阔。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/12 14:43:13

跨国能源民企干多干少一个样?华恒智信成功案例引入积分制

【客户行业】能源化工行业【问题类型】薪酬管理【客户背景】某综合性能源跨国集团是一家专注于能源加工行业的民营跨国企业&#xff0c;业务覆盖能源工程建设、高端装备制造、能源勘探开发、专业技术服务、炼化与销售及服务贸易等领域。目前&#xff0c;该跨国能源集团在全球多…

作者头像 李华
网站建设 2026/8/12 14:42:58

Python列表、字典和字符串题目

一、列表【题目】1、 (增删改指定位置操作)现有列表score [78, 92, 65, 88, 70]1. 在索引2的位置插入数字952. 删除列表中数值最小的元素3. 将最后一个元素修改为1004. 打印处理完成后的完整列表【代码】score [78, 92, 65, 88, 70] score.insert(2, 95) score.remove(min(sc…

作者头像 李华
网站建设 2026/8/12 14:39:51

Typora付费与破解风险解析:合法Markdown编辑器替代方案全攻略

1. 从Markdown编辑器的选择说起作为一名长期与文字和代码打交道的从业者&#xff0c;我对Markdown编辑器的选择一直很挑剔。它不仅是记录灵感的工具&#xff0c;更是构建知识体系、输出技术文档的生产力核心。在众多编辑器中&#xff0c;Typora以其“所见即所得”的沉浸式体验脱…

作者头像 李华
网站建设 2026/8/12 14:38:45

QQ群娱乐机器人推荐2026:先分清QQ开放平台机器人和第三方个人号机器人

2026年了&#xff0c;如果你去搜索引擎或者社交平台搜“QQ群娱乐机器人推荐”“免费QQ群机器人”或者“QQ机器人现在还能用吗”&#xff0c;大概率会被网上的两拨说法搞懵。 一波文章在卖力推荐各种签到、点歌、AI聊天和小游戏机器人&#xff1b;另一波文章则在严肃警告你&…

作者头像 李华
网站建设 2026/8/12 14:38:32

Unity项目中使用C#新特性:通过unity-csharp-patch实现程序集级版本控制

1. 项目概述&#xff1a;为什么Unity开发者需要C#版本自定义&#xff1f; 如果你是一个Unity开发者&#xff0c;尤其是那些对代码质量、开发效率和现代语言特性有追求的开发者&#xff0c;那么你很可能已经对Unity内置的C#版本限制感到头疼。Unity为了确保跨平台兼容性和运行时…

作者头像 李华