
在实际智能体项目中你可能会遇到一个很反常的现象同一个模型在 A 平台上会自动调用工具、按流程执行多步任务甚至能自行修正错误换到 B 平台后却只会普通问答连一次函数调用都做不对。很多人会把原因归结为“模型能力不足”但真正改变行为的是模型背后的部署框架。模型负责生成下一个 Token框架负责决定这个 Token 如何被解析、校验、使用、循环和终止。所以理解智能体行为不能只盯着模型参数和权重要看它被部署在什么样的框架里。这篇文章围绕“智能体行为更多由部署框架而非模型决定”展开。先拆开模型、智能体、部署框架三者的边界再通过 vLLM 部署和 Dify 工作流两个具体案例说明部署框架如何从请求参数、上下文管理、工具调用、失败路径等多个维度改写智能体的外部表现。最后给出一套可复现的最小构建示例和一份可以直接用于排错的清单。1. 先拆开“模型”“智能体”“部署框架”三层概念很多讨论把模型和智能体混在一起导致问题定位困难。实际上它们至少是三层东西每一层解决的问题完全不同。1.1 模型只提供单步推理能力不决定行为边界通俗地说大语言模型是一个“预测下一个词”的引擎。它根据当前输入的文本和自身权重输出一段后续文本。所谓“智能”本质上是模型在大规模文本上学到的统计能力。模型并不知道自己处于智能体中也不知道外部环境里有哪些工具更不知道任务最终要交付什么格式。更技术化的描述是模型学习的是一个条件概率分布P(下一个Token | 当前上下文, 模型权重)。它每生成一个 Token只依据当前上下文和内部参数做一次选择。放到智能体场景里模型只是“大脑里的推理单元”。它负责把“用户问题 中间结果 工具返回内容”变成“下一步动作描述”。比如用户问“今天北京天气如何”模型可能输出“需要调用天气查询接口”但它不会真的去请求天气服务。最小示例是直接调用一个兼容 OpenAI 协议的模型服务curl http://localhost:8000/v1/chat/completions \ -H Content-Type: application/json \ -d { model: qwen-agent, messages: [ {role: user, content: 今天北京天气如何} ] }返回结果可能是一段普通的回答也可能是包含tool_calls字段的结构化内容。但无论哪种模型都没有真正执行任何外部动作。它只是给出了一个“文本描述”。真正让这个描述变成实际行为的是框架。这里有一个容易误解的地方模型输出了工具调用格式不意味着模型在“执行工具”。执行工具、解析返回结果、把结果回填给模型这一整条链路都由部署框架完成。1.2 智能体的可观察行为来自框架编排智能体可以理解为一个能感知、决策、行动、观察并循环运行的软件系统。它的完整行为链路至少包括感知接收用户输入或外部事件。决策调用模型生成下一步动作。行动调用工具、查询数据库、发起 HTTP 请求。观察读取工具返回结果。循环把工具结果回填给模型再次决策。终止满足结束条件后输出最终答案。这些环节都不是模型内部能定义的。模型只负责“决策”这一步。至于什么时候调用工具、选择哪个工具、如何解析工具返回、超时后是否重试、上下文保留多少、是否允许无限循环都取决于框架。举例说明。模型可能输出这样一段结构化内容{ action: get_weather, args: { city: 北京 } }但框架必须回答这些问题是否信任这个字段get_weather是否在已注册的工具列表中args.city是否为合法参数调用真实天气 API 超时后怎么办工具返回空数据时是重试还是直接告诉用户失败最终回答的格式是否要经过二次模型校验这些决策综合起来才是用户能感知到的“智能体行为”。所以智能体的行为边界本质上是框架设计出来的行为边界。1.3 部署框架至少包含三层不能只理解为一层日常说的“部署框架”其实是一个复合概念。按职责可以拆成三层层级代表组件核心职责对智能体行为的影响模型服务层vLLM、Ollama、SGLang、TensorRT-LLM把模型权重变成可调用的在线服务决定并发、吞吐、上下文长度、API 协议、function calling 兼容性Agent 编排层Dify、Coze、LangGraph、自研工作流定义流程、工具、记忆、循环、终止条件决定智能体的任务完成度、工具使用方式和失败路径应用接入层前端、机器人、客服系统、API 网关把智能体能力嵌入业务场景决定用户输入边界、权限、数据隔离和交互体验模型服务层决定了“模型以什么协议对外提供服务”Agent 编排层决定了“模型输出如何变成任务行为”应用接入层决定了“行为如何被业务用户使用”。任何一层的差异都会让同一个模型表现出完全不同的智能体行为。所以当你说“这个模型不适合做智能体”之前先确认框架层是否已经把模型的能力释放出来。很多时候不是模型不行而是框架根本没有触发模型的能力。2. 从一次部署对比看框架如何改写智能体行为2.1 同一个模型的三种部署形态假设你拥有同一个 Qwen 系列模型权重比如 Qwen3.6-35B-A3B。你可以用三种方式部署它最终用户感知到的“智能体”完全不同。第一种是裸对话服务。直接用 vLLM 启动一个 OpenAI 兼容接口只暴露/v1/chat/completions。这时候智能体行为就是单轮或多轮问答模型不会主动使用工具也不会执行任务流程。第二种是带工具调度服务的形态。模型服务层不变但外部有一个 Agent 调度进程。调度进程发送消息时附带工具定义模型返回tool_calls后调度进程去调用真实工具再把结果以roletool的消息回填给模型。此时智能体行为变成了“会调用工具完成任务”。第三种是接入 Dify、Coze 或自研工作流平台。模型只是工作流里的一个节点输入来自上游节点输出进入条件分支失败时还能触发兜底节点。此时智能体行为变成了“按流程图执行”。部署形态框架职责用户看到的行为裸对话服务只完成文本生成普通聊天回答依赖模型记忆带工具调度解析工具调用并执行能查天气、查数据库、调用外部 API工作流编排控制流程、分支、回退能按固定流程完成任务失败时有兜底同一个模型三种行为。模型权重没有变变化的是部署框架。2.2 vLLM 部署模型时启动参数如何影响服务行为vLLM 是目前常用的模型服务部署框架。很多人以为启动 vLLM 只是把模型跑起来实际上启动参数直接影响模型对外呈现的行为能力。一个典型的部署命令如下vllm serve Qwen3.6-35B-A3B \ --served-model-name qwen-agent \ --max-model-len 32768 \ --gpu-memory-utilization 0.85 \ --tensor-parallel-size 4 \ --dp 2每个参数都不只是性能配置还影响智能体行为--served-model-name客户端请求时model字段需要填的值。如果填错服务直接返回模型不存在。很多接入问题都出在这里。--max-model-len允许的最大上下文长度包括输入和输出。如果设置过小长文档或长历史会被截断智能体就会“失忆”。--gpu-memory-utilization显存利用率上限。设置过高可能导致并发请求时 OOM设置过低可能限制并发吞吐。--tensor-parallel-size张量并行度用于多卡部署。它会改变 KV Cache 的分布影响可用上下文长度和吞吐。--dp部分新版本 vLLM 支持的并行相关参数具体语义与版本有关。有些版本里它表示数据并行有些场景下影响专家并行或负载均衡。参数含义汇总如下启动参数作用设置过小的影响设置过大的风险--max-model-len控制最大上下文长度长任务被截断智能体丢失早期信息显存占用过高容易 OOM--gpu-memory-utilization控制显存利用率并发能力下降高并发时服务不稳定--tensor-parallel-size多卡张量并行长上下文可能放不下超出显卡数量时报错--dp数据/专家并行相关配置具体看版本行为不同版本语义不统一需先查帮助特别注意不同 vLLM 版本的参数差异很大。落地前先执行vllm serve --help确认当前版本的参数名称和含义不要直接照搬网上的过期命令。2.3 为什么“模型能写诗”不等于“智能体能写报告”很多人在验收智能体时会混淆“模型能力”和“智能体能力”。模型能写诗只说明它具备文本生成能力。智能体能写报告要求它能检索资料、生成大纲、分段撰写、校验数据、引用来源、按格式输出。后者是一个流程性行为不是一次文本生成。部署框架在这里起的作用是“流程控制”。框架决定模型生成的每一段文本放在什么位置决定是否需要对生成结果做二次校验决定哪一步失败后可以从哪里重试。还有一个容易被忽略的细节模型自身的注意力窗口可能是滑动的。比如某些模型使用滑动窗口注意力有效建模距离限制在窗口范围内。即使模型的max_position_embeddings很大实际有效上下文也可能受窗口限制。框架如果把过多历史消息持续塞进上下文早期关键信息可能被“滑出”窗口。用户看到的表象是“智能体忘了前面交代的任务”实际原因是框架的上下文管理策略不当而不是模型变笨了。3. Dify、Coze 这类智能体平台到底在做什么如果说明确一点Dify、Coze 这类智能体平台核心工作是把“模型推理能力”编排成“可执行的任务行为”。3.1 一个典型工作流由哪些节点组成以 Dify 的工作流为例一个最小可用的智能体流程通常包含这些节点输入节点定义用户输入参数比如上传文件内容、查询关键词。模型节点调用大模型把上游内容转换成指令输出。工具节点调用外部服务比如搜索、数据库查询、HTTP API。条件分支节点根据模型输出或工具结果决定走哪条分支。结束节点把流程结果返回给用户。这些节点组合在一起就构成了智能体行为。模型节点只是其中一个环节而不是全部。一个概念性的配置片段如下{ nodes: [ {id: start, type: input, label: 接收用户文件}, {id: llm, type: llm, label: 提取文档关键信息}, {id: tool, type: tool, label: 查询内部数据库}, {id: branch, type: if-else, condition: tool_result is empty}, {id: end, type: output, label: 输出最终结论} ] }这段 JSON 只是示例真实平台里每个节点都有更详细的参数。它表达的核心思想是智能体的行为被建模成一张图模型只是图中的一个节点。3.2 工具调用协议是框架行为的分水岭模型原生只生成文本但业界已经发展出多种“让模型表达调用意图”的结构化方式。OpenAI function calling / tool calling 格式模型在输出中携带tool_calls字段包含函数名和 JSON 参数。MCPModel Context Protocol一种标准化工具接入协议让模型服务可以统一访问外部工具和数据源。自定义 HTTP 工具平台通过 OpenAPI 描述工具让模型按格式调用。框架在这里的作用是把模型输出的结构化字段转换成真实程序调用。比如模型返回{ tool_calls: [ { function: { name: search_products, arguments: {\keyword\:\笔记本\} } } ] }框架要做的事情包括校验arguments是否是合法 JSON。查看search_products是否已注册。执行真实搜索函数。把结果转成文本并以roletool的消息追加到上下文。再次请求模型让模型基于工具结果生成最终回答。如果框架没有实现这一层模型输出再标准的tool_calls也不会触发任何真实动作。所谓“智能体会用工具”其实是框架实现了工具调用闭环。3.3 记忆和会话管理对行为的影响上下文窗口总是有限制所以框架必须决定“哪些历史要保留、哪些要压缩、哪些可以丢弃”。常见策略有滑动窗口截断只保留最近 N 轮对话。关键信息抽取把历史消息压缩成摘要。向量检索把历史内容存入向量库按需检索相关片段。外部记忆把用户偏好、任务状态存到独立数据库。不同策略会带来完全不同行为。使用滑动窗口截断的智能体在多轮长对话中表现更像“短期记忆”使用外部数据库记忆的智能体跨会话还能记得用户偏好。所以当你说“这个智能体记忆不好”时先不要怪模型。模型只是上下文里的文本阅读器保留哪些文本、怎样保留是框架策略。3.4 框架决定失败路径模型可能会生成非法 JSON、可能调用不存在的工具、可能无限循环、可能超时。这些异常在模型层无法处理只能由框架兜底。框架需要定义工具调用超时时间默认多少秒。重试次数重试间隔。模型输出解析失败时的降级策略比如是否强制 JSON 格式。循环次数上限超过后如何处理。日志记录什么内容便于事后排查。是否允许人工介入审批。这些失败路径共同构成了智能体的“鲁棒性”。模型再强如果框架没有失败处理能力智能体在实际任务中依然会频繁中断。4. 实战在 Dify 中构建一个行为更完整的智能体这一节用 Dify 平台跑通一个最小闭环接收用户上传文件内容提取关键字段调用一个查询工具最终输出结构化结果。重点不是实现多复杂的功能而是看清楚框架在行为塑造中的作用。4.1 环境准备Dify 社区版一键启动学习环境可以使用 Docker Compose 启动 Dify 社区版。git clone https://github.com/langgenius/dify.git cd dify/docker cp .env.example .env docker compose up -d启动完成后访问http://localhost进入控制台初始化管理员账号。需要注意这个部署方式只适合本地学习和功能验证。生产环境还需要考虑独立数据库、Redis、对象存储、HTTPS 证书、密钥管理、日志采集和备份策略。不要直接把默认配置搬到生产环境。4.2 接入模型服务把 vLLM 作为模型供应商Dify 本身不包含模型它需要连接一个模型服务。在 Dify 控制台的“设置 - 模型供应商”中选择 OpenAI-API-compatible 类型填入 vLLM 服务的地址和模型名。配置项填写内容说明API Base URLhttp://vllm-host:8000/v1必须是/v1结尾API Key任意值或 vLLM 配置的 key本地环境可填EMPTYModel Nameqwen-agent与 vLLM--served-model-name保持一致Model TypeLLM表示这是对话/生成模型接入后先做一次手动测试确认 Dify 能成功调用模型再继续创建应用。这个检查点能避免后面出现问题时分不清是平台问题还是模型服务问题。4.3 最小工作流识别文件内容并输出结构化结果在 Dify 中创建一个“工作流”类型应用。设计如下流程输入节点接收用户上传的文件Dify 会先把文件内容抽取成文本。模型节点让模型按指定字段提取信息并输出 JSON。工具节点根据提取结果调用一个内部查询工具。条件分支如果查询结果为空走兜底提示。结束节点把结果返回给用户。模型节点的 Prompt 可以这样写你是文档处理助手。请从用户上传的文本中提取以下字段 - name文档名称 - date文档日期 - amount涉及金额 - summary不超过50字的内容摘要 要求 1. 只输出 JSON不要输出额外说明。 2. 字段缺失时输出 null。 3. JSON 格式为 { name: , date: , amount: null, summary: }预期输出{ name: 项目季度总结.docx, date: 2025-06-30, amount: 128000, summary: 本季度项目整体推进正常预算使用率约85%。 }工具节点可以是一个预设的 HTTP 工具例如根据name查询内部合同编号。工具返回后再让模型基于工具结果生成最终结论。这里的关键是模型只负责“提取”和“讲解”是否查询、查询什么、查不到怎么办都由框架流程控制。4.4 验证“框架决定行为”这一结论你可以做一组对比实验实验 A直接对话模式把同一份文档内容发给模型让它输出 JSON。实验 B工作流模式模型节点提取字段后工具节点自动查询内部系统条件分支在查询结果为空时给出不同提示。两个实验用同一份文档、同一个底层模型。结果会完全不同维度直接对话工作流模式是否调用工具不会会是否自动处理空结果不会会走兜底分支输出格式稳定性不稳定由流程控制失败恢复无有重试和兜底模型没有变行为变了。这就是“部署框架决定智能体行为”的可复现证明。5. 部署框架带来的常见坑与排查路径5.1 昇腾 910B-A2 服务器上 vLLM 无法启动 embedding 和 reranker 模型现象在昇腾 910B-A2 服务器上通过 vLLM 启动 embedding 向量模型或 reranker 重排模型失败或启动后无法返回预期结果。可能原因vLLM 对模型架构的支持范围与具体硬件平台相关。embedding 和 reranker 类模型在推理框架里的支持程度可能低于生成模型。昇腾平台的算子实现也可能与训练框架不完全一致。排查方式确认当前 vLLM 版本是否支持目标模型类型。查看错误日志中是否出现“unsupported model architecture”或“kernel not found”等关键词。检查模型配置文件config.json中的architectures字段是否在框架支持列表内。尝试在普通 GPU 环境复现排除硬件算子差异。处理建议对 embedding 和 reranker 模型优先选择框架官方声明支持的模型架构。不要强行复用同一个 vLLM 实例同时服务生成模型和向量模型建议拆分服务。如果特定硬件平台不支持尽早采用替代部署方式比如独立向量检索服务。5.2 模型能直接输出工具调用接入智能体平台后却不执行工具现象通过 curl 直接请求模型服务时返回内容包含tool_calls但接入 Dify、Coze 或自研框架后智能体始终不调用工具只会普通回答。常见原因智能体平台未开启工具调用能力。工具定义过长超出模型上下文限制被截断。平台发送给模型的tools参数格式与模型要求不兼容。模型名称没有指向支持 function calling 的模型服务。检查方式在平台日志里查看实际发送给模型的请求体确认tools字段是否完整。手工构造一份相同请求发给模型服务确认模型返回。对比平台模型版本和 curl 测试时的模型版本是否一致。处理建议确保平台版本与模型服务接口兼容。简化工具描述把关键参数和用途写清楚。使用同一个模型服务地址和模型名进行平台接入。5.3 上下文截断导致智能体“变傻”现象短对话表现正常多轮长对话后智能体忘记早期指令或开始重复无效输出。常见原因--max-model-len设置过小上下文被截断。模型使用滑动窗口注意力老消息被滑出窗口。框架没有压缩历史导致有效信息被淹没。输出 token 限制过小模型回答被强行截断。检查方式查看框架日志中每次请求的prompt_tokens和max_tokens。确认上下文是否接近窗口上限。在模型服务日志中查看是否有截断提示。处理建议根据实际任务调整--max-model-len。在框架中启用历史摘要或向量记忆。给关键指令设置固定注入避免被截断。5.4 部署排错清单问题现象常见原因检查方式处理建议请求model不存在served-model-name不一致查看模型服务日志统一模型名称长任务丢失早期信息上下文被截断查看prompt_tokens调大max-model-len或启用记忆压缩模型不调用工具平台未发送工具定义抓取平台请求体开启工具调用并检查格式工具结果不生效未将工具结果回填模型查看框架消息历史确认roletool回填链路高并发下服务不稳定显存利用率过高查看 GPU 显存监控降低gpu-memory-utilization模型在特定硬件无法启动框架不支持该模型架构查看日志和架构字段更换支持框架或拆分服务这张表可以打印出来部署智能体时逐项对照。6. 工程实践让“框架决定行为”成为可维护的设计6.1 把模型当作可替换组件而不是系统核心业务逻辑不要绑定到某一个模型的输出习惯上。模型升级、换供应商、换开源权重都应该是可配置的变化不影响整体智能体行为。具体做法所有模型请求走统一抽象层。Prompt 从配置或模板中读取不硬编码。工具注册表独立维护模型输出通过名称匹配工具。模型输出结果在前置逻辑中统一解析。这样做的收益是模型从“不可控变量”变成“可替换的推理引擎”。6.2 行为层与模型层分离把智能体系统分成两层模型层只负责文本推理。行为层负责流程编排、工具调用、记忆策略、输出校验、失败恢复。行为层应该沉淀在代码、配置和平台流程里而不是依赖模型临场发挥。例如要求模型输出 JSON就不要只靠 Prompt 提示还要在框架层做 JSON 解析和失败重试。对应关系如下能力点模型层负责行为层负责生成回答是否决定调用哪个工具建议校验并执行工具执行否是上下文管理读取选择输入哪些内容失败恢复否是输出格式保证尽量强制校验6.3 区分学习、测试、生产环境学习环境可以用 Docker 快速启动不需要复杂配置。测试环境要有独立的模型服务、模拟工具和日志追踪。生产环境必须考虑配置外置、权限控制、超时重试、监控告警和回滚方案。环境模型服务工具数据关注点学习本地 vLLM 单卡模拟工具测试数据跑通流程测试独立部署Mock 服务脱敏数据验证行为稳定生产多副本真实服务真实数据稳定性、安全、可观测性不要在学习环境验证完成后直接上生产。至少补一遍超时、并发、权限和日志检查。6.4 可复用的部署前检查清单模型服务名称、API 地址、端口是否已确认。模型上下文长度与实际任务是否匹配。工具列表是否已在平台注册且描述清晰。工具调用失败时是否配置了重试和兜底分支。模型输出是否为结构化格式框架是否能校验。历史消息是否会超过上下文窗口是否有压缩策略。高并发下显存和端口是否足够。日志是否覆盖模型请求、工具调用、错误分支。生产环境是否有配置外置和回滚机制。是否需要人工审批节点以及审批超时如何处理。每次上线新智能体按这份清单走一遍能减少大量生产事故。回到最初的问题为什么同一个模型在不同平台上表现差异巨大因为模型只是推理引擎真正塑造行为的是部署框架。模型能力决定智能体的上限部署框架决定智能体的实际表现下限。优化智能体时优先检查框架链路是否完整再考虑是否换更大的模型。新手最有价值的练习是用 Dify 搭一个带工具的工作流再替换底层模型观察行为差异。这个过程会比单纯比较模型参数更能让你理解智能体系统的真实结构。