☰
AI应用下半场:从模型能力到上下文工程与工具调用的系统化实践
2026/10/17 7:02:01 网站建设 项目流程

2024 年,做一个能对话的 AI 聊天 Demo,还值得发一篇技术博客;2025 年,再发同样的 Demo,评论区大概率会问:然后呢?

这不是开发者变挑剔了,而是 AI 应用开发的叙事真的变了。过去一年多的主线是模型能力竞赛,大家都在追参数、追榜单、追多模态。但当模型能力逐渐变成标准化 API,算力成本持续下降,开源模型快速追赶之后,应用层的竞争焦点就会迅速转移到一个更本质的问题上:谁能把模型稳定、安全、可控地嵌入真实业务流程,并产生可衡量的业务价值。

这篇文章想表达一个明确判断:AI 下半场,应用的新叙事,核心就是两个字——系统化。Model 能力已经不再是唯一变量,Context、Tools、Evaluation、Observability 这些传统软件工程要素,重新成为 AI 应用竞争的主战场。我会先讲清楚叙事为什么变了,再拆解 AI 应用从 Demo 到系统的几个关键阶段,最后用一个可复制的最小订单客服助手示例,演示模型路由、工具调用、结构化输出和评估闭环怎么落地,并给出生产环境常见问题和工程建议。全文把思路和代码放在一起,建议先收藏,后文可以照着跑。

1. 为什么“AI 应用的新叙事”从模型转向了应用

先看三个行业层面的信号。

第一个信号:产品话语体系正在变化。早期很多产品喜欢强调“接入了大模型”“支持多模态”。现在这类描述已经很难打动技术决策者,大家更关心的是:你的 AI 功能是否接入了真实数据?是否有人负责权限校验?模型答错之后流程怎么兜底?有没有评估集说明效果上限?

第二个信号:创业和内部项目的验收标准在变化。过去验收一个 AI Demo,看的是“能不能生成像样的文本”。现在的验收标准变成“这个功能跑在核心链路里,吞掉了多少工单?降低了多少耗时?准确率有没有业务指标支撑?”也就是说,AI 从展示品变成了生产力工具,从“会聊天”变成了“能干活”。

第三个信号:技术栈重心在转移。两年前聊 AI 应用,绕不开 Prompt 技巧;一年前聊 AI 应用,绕不开 RAG 召回率;现在聊 AI 应用,讨论最多的是工作流编排、工具调用协议、模型路由、评测数据集和可观测性。这不是说 Prompt 和 RAG 不重要,而是它们已经从“全部”变成“一部分”。

这背后其实是一个技术演变规律:当一个能力被平台化、标准化之后,它在应用层的稀缺性就会快速下降。模型推理能力正在走这条路。于是,应用层的竞争就回到了软件工程的基本盘——如何在一个复杂系统里,让不可完全预测的模型输出变得可控、可审计、可回滚。

如果把 AI 项目按照这个逻辑重新审视,你会发现大部分项目的风险根本不是“模型能力不够”,而是“应用边界没设计好”:数据权限不可控、工具调用不可追踪、输出格式不稳定、没有评测闭环、模型升级一次线上行为就漂移一次。这些问题,不是换一个大模型能解决的,需要用工程手段系统性解决。

所以,AI 下半场的应用新叙事,本质上是从“模型叙事”走向“工程叙事”。接下来的几个章节,我会把这个叙事拆成开发者的具体动作。

2. 从调用模型到构建系统:AI 应用开发的四个阶段

要理解“AI 应用的系统化”,可以先看 AI 应用演进的四个阶段。大部分团队都在这四个阶段里移动,但很多团队并没有意识到自己停在了哪个阶段。

2.1 阶段一:聊天玩具

特征:拿一个模型 API,写一段 System Prompt,做一个对话框。能回答通用问题,能生成文案,但无法访问业务数据,无法执行操作,无法验证回答正确性。

典型问题:用户问“我的订单到哪了”,它只能说“你可以去订单页面查看”。这在技术上是跑通的,在业务上是无效的。

2.2 阶段二:RAG 套壳应用

特征:在模型之外增加向量数据库,通过召回相关文档片段拼进 Prompt,让模型基于资料回答。这是目前最常见的一类 AI 应用形态。

典型问题:召回质量不稳定、引用来源不可靠、知识更新滞后。很多时候用户一眼就能看出答案是“拼接感”很强的,而不是真正理解了业务。

2.3 阶段三:Agent 工作流

特征:模型可以通过函数调用访问外部工具——查订单、调接口、写库、发消息。多轮对话中,模型自己决定调用哪些工具,并根据工具结果继续推理。

典型问题:工具调用不可控、循环不退出、权限边界模糊。Agent 能做了很多事,但也可能做错很多事。

2.4 阶段四:业务原生系统

特征:AI 不再是一个独立对话框,而是嵌入业务系统的模块。它有明确的输入输出约束、权限校验、审计日志、成本预算、评测集和灰度机制。用户无感知它在用 AI,只觉得“系统变聪明了”。

判断一个应用属于哪个阶段,看它失败时会发生什么就知道了:阶段一失败,用户关掉页面;阶段二失败,用户骂答案不准;阶段三失败,可能出现脏数据或越权操作;阶段四失败,有日志、有监控、有回滚、有补偿机制。

用表格总结一下:

阶段核心技术对业务的价值最大的坑
聊天玩具Prompt + 模型 API几乎为零无法对接业务
RAG 套壳向量检索 + 拼接信息查询类可用回答准确率难保证
Agent 工作流工具调用 + 多轮规划能执行一部分业务操作失控风险高,难调试
业务原生系统工程集成 + 评估 + 可观测性可嵌入核心链路工程复杂度上升

结论很清楚:真正能被业务接受的 AI 应用,一定是从阶段三向阶段四演进。而推动这个演进的三个核心工程问题,分别是上下文工程、工具调用与编排、评测与可观测性。接下来逐个拆解。

3. 上下文工程:真正拉开差距的软件问题

先说一个判断:Prompt 技巧正在贬值,上下文工程正在升值。

为什么?因为大模型本身的指令理解能力一直在提升。一年前需要用复杂 Prompt 约束的格式,现在用 JSON Mode 或结构化输出原生解决。但应用侧的上下文复杂度却在指数级上升:业务知识、用户画像、历史会话、实时数据、工具返回结果,这些信息怎么组织、怎么筛选、怎么压缩,决定了大模型输出的质量上限。

3.1 上下文不是一个“塞”字能解决的

新手最容易犯的错误是:把能拿到的信息全部塞进 Prompt,觉得上下文越长模型越聪明。真实情况是:

  • 长上下文有成本问题。Token 费用按输入长度计算,塞入无关内容直接浪费预算。
  • 长上下文有延迟问题。输入越长,首字延迟越高,用户体感变差。
  • 长上下文有注意力稀释问题。无关信息太多,模型反而更容易忽略关键业务约束。

所以,上下文工程的第一原则是:不是塞进去,而是选进来。你要让模型看到它决策所必需的最小信息集。

3.2 上下文工程的三个关键手段

第一,检索。RAG 系统的召回质量,不只是向量相似度的问题。分块策略、元数据过滤、查询改写、重排,每一步都能影响最终输入给模型的内容。经常被忽视的是分块:固定长度按字符切分虽然简单,但会把语义完整的段落切断。更稳妥的做法是按章节、段落、表格语义边界切分,让每个块尽量表达一个完整信息单元。

第二,压缩。当历史会话过长时,不是把全部消息原样塞回,而是先生成结构化摘要。比如:用户问了什么、系统答了什么、最终订单状态是什么、用户情绪是否激动。这些结构化信息保留下来,比完整历史更有用,也更能控制成本。

第三,预算。把上下文按优先级分层——固定系统约束、业务规则、用户数据、检索资料、历史摘要。给每一层设定最大 Token 预算,超过预算就裁剪或压缩。只有先学会控制“输入长度”,模型输出的稳定性和成本才能同时得到保证。

上下文工程做得好不好,最直接的观测指标就是:当模型输出出错时,你能不能快速定位是所有必要信息都给了但模型理解错,还是必要信息根本没被选进来。前者是模型问题,后者是应用问题——而后者的修复成本通常远低于前者。

4. 工具调用与 Agent 编排:从单次问答到业务闭环

如果说上下文工程是让 AI“说得准”,那么工具调用就是让 AI“做得到”。这是 Agent 从演示走向生产的关键转折。

4.1 Function Calling 不是新鲜事,但工程化是

模型通过函数调用访问外部系统,技术上已经有成熟方案。但真正的问题不是“能不能调用”,而是“该不该调用、调用了之后怎么校验结果”。在业务系统里,工具调用必须遵守几个硬约束:

  • 最小权限。工具签名只暴露必要参数。比如订单查询工具只接受 order_id,不接受“查询任意用户所有订单”的入口。用户身份从会话上下文获取,而不是让模型生成。
  • 幂等性。同一个工具调用因网络重试执行两次,不能产生两条重复工单。写操作必须做幂等控制。
  • 超时与熔断。外部服务不可用时,Agent 不能无限等待。要给工具调用加超时,超时后进入兜底回复流程。
  • 审计追踪。每一次工具调用都要记录:模型名、输入参数、执行结果、耗时、Token 消耗。没有审计日志的 Agent 不值得上线。

4.2 Agent 编排:把模型关进一个有边界的车间

很多团队对 Agent 的想象是“让模型自己规划、自己执行到底”。但在生产环境里,更稳妥的姿势是“有限自主”:给模型一个明确的任务范围、可调用的工具清单、必守的规则,以及最大循环次数。

举个例子,一个订单客服 Agent:

  • 用户身份由系统注入,不由模型猜测;
  • 只能调用订单查询工具,不能调用退款接口,除非进入二次确认流程;
  • 每轮对话最多执行 3 次工具调用,超过次数直接转人工;
  • 所有工具返回结果会经过一层服务端校验,不允许模型把“查无此单”编造成“订单异常”。

这样的 Agent 不是完全自主的“智能体”,而是一个被工程约束的“流程执行器”。恰恰是这种约束,才让它变得可用、可控。

4.3 ReAct 模式的简化理解

ReAct(Reasoning + Acting)是当前 Agent 工作流的一种常见模式:模型先推理下一步该做什么,然后调用工具观察结果,再继续推理。在生产代码里,它可以简化为两步循环:

  1. 模型根据当前对话状态,决定是否调用工具、调用哪个工具。
  2. 如果没有工具调用,直接生成最终回答;如果有工具调用,把工具结果追加回对话,再执行一次推理。

下面这个最小示例,就是把上面这套设计落到代码里。

5. 最小 AI 应用系统设计与完整代码实现

为了把前文抽象概念变成可运行的东西,我设计了一个最小订单客服助手。它的业务很简单:用户查询自己的订单状态,系统判断问题复杂度,选择适合的模型,必要时调用订单查询工具,最后给出回答,并记录 Token 消耗和延迟。

5.1 系统拆解

整个系统分四层:

  • 入口层:接收用户问题和用户 ID。
  • 路由层:根据业务关键词决定使用快模型还是强模型。
  • 工具层:提供订单查询函数,并在函数内部做用户身份校验。
  • LLM 层:调用模型生成回复,支持工具调用,记录日志。

5.2 第一步:配置文件

# config/app.yaml app: name: minimal-ai-assistant debug: false model: fast: fast-model-id # 替换为你所用平台的轻量模型 ID smart: smart-model-id # 替换为你所用平台的强推理模型 ID router_keywords: - 订单 - 物流 - 退款 - 换货 tool: order_query: enabled: true max_calls_per_conversation: 3 timeout_seconds: 5 logging: level: INFO output: ./logs/assistant.log

这个配置的核心是“路由关键词”和“工具调用次数上限”。前者控制成本,后者控制 Agent 失控风险。实际项目中,路由逻辑可以换成更复杂的意图分类模型,但规则本身就是一道可靠兜底。

5.3 第二步:核心代码

# src/assistant.py import json import logging import os import time # 以下为演示客户端。 # 如果你接的是其他模型平台,把 OpenAI 替换为对应 SDK 即可。 from openai import OpenAI logging.basicConfig( level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s", ) logger = logging.getLogger("minimal-assistant") client = OpenAI() FAST_MODEL = os.getenv("FAST_MODEL", "fast-model-id") SMART_MODEL = os.getenv("SMART_MODEL", "smart-model-id") ROUTER_KEYWORDS = ["订单", "物流", "退款", "换货"] MAX_TOOL_CALLS = int(os.getenv("MAX_TOOL_CALLS", "3")) def route_to_model(message: str) -> str: """极简路由:命中业务关键词走强模型,否则走快模型。""" if any(kw in message for kw in ROUTER_KEYWORDS): return SMART_MODEL return FAST_MODEL def query_user_context(user_id: str) -> dict: """演示用上下文获取,生产环境应从会话服务读取。""" return {"user_id": user_id, "display_name": "demo-user"} def query_order_status(user_id: str, order_id: str) -> dict: """ 工具函数:查询订单物流状态。 生产环境需要接入真实订单服务,并在下游再做一次鉴权。 """ # 演示用越权拦截,真实环境不能依赖模型层做权限判断。 if user_id != "demo-user": return {"error": "permission_denied"} # 演示数据,真实实现应查数据库或下游 API。 return { "order_id": order_id, "status": "shipped", "latest_station": "华东转运中心", } TOOLS = [ { "type": "function", "function": { "name": "query_order_status", "description": "查询当前登录用户在平台上的订单物流状态,必须传入用户自己的订单号。", "parameters": { "type": "object", "properties": { "order_id": {"type": "string", "description": "订单号"} }, "required": ["order_id"], }, }, } ] def run(question: str, user_id: str) -> dict: started = time.time() user_context = query_user_context(user_id) messages = [ { "role": "system", "content": ( "你是订单客服助手。" "你只能查询当前登录用户的订单,不得编造订单状态。" "涉及订单查询时,先调用工具,再基于工具结果回答。" ), }, { "role": "user", "content": f"用户信息:{json.dumps(user_context, ensure_ascii=False)}\n问题:{question}", }, ] model = route_to_model(question) logger.info("routed model=%s question=%s", model, question) # 第一轮调用:让模型决定是否需要调用工具 response = client.chat.completions.create( model=model, messages=messages, tools=TOOLS, tool_choice="auto", ) choice = response.choices[0] tool_calls = choice.message.tool_calls or [] tools_called = [] # 如果有工具调用,先追加助手消息,再依次追加工具返回结果 if tool_calls: messages.append(choice.message) for tc in tool_calls[:MAX_TOOL_CALLS]: if tc.function.name == "query_order_status": try: args = json.loads(tc.function.arguments) except json.JSONDecodeError: args = {} order_id = args.get("order_id", "") result = query_order_status(user_id, order_id) tools_called.append(tc.function.name) logger.info( "tool_called name=%s order_id=%s result=%s", tc.function.name, order_id, result, ) messages.append( { "role": "tool", "tool_call_id": tc.id, "content": json.dumps(result, ensure_ascii=False), } ) # 第二轮调用:结合工具结果生成最终回答 if tool_calls: final_response = client.chat.completions.create( model=model, messages=messages, ) final_text = final_response.choices[0].message.content else: final_text = choice.message.content elapsed_ms = (time.time() - started) * 1000 token_cost = response.usage.total_tokens if response.usage else 0 logger.info( "finished elapsed_ms=%.1f tokens=%d tools_called=%s", elapsed_ms, token_cost, tools_called, ) return { "reply": final_text, "model_used": model, "tokens": token_cost, "tools_called": tools_called, } if __name__ == "__main__": result = run("我的订单 20250001 现在到哪了?", "demo-user") print(json.dumps(result, ensure_ascii=False, indent=2))

这段代码要表达的不是某个特定 SDK 的用法,而是三个工程化思想:

  1. 路由即成本控制。简单寒暄走快模型,业务查询走强模型,用最少成本完成必要推理。
  2. 工具返回值不直接透传。查询工具内部先做用户身份校验,从服务端杜绝越权,不把安全交给模型自觉。
  3. 完整调用链路被日志记录。模型名、工具调用、Token 数、延迟,全部落日志,为后续评估和排查提供依据。

5.4 第三步:评估脚本

有评估集的 AI 应用才算进入系统化管理。下面是一个极简回归脚本,用来在修改 Prompt、切换模型、调整工具逻辑后快速验证核心行为没有跑偏。

# scripts/evaluate.py import json from src.assistant import run CASES = [ {"question": "你好", "expect_tool": False}, {"question": "我的订单 20250001 现在到哪了?", "expect_tool": True}, {"question": "你们平台的退款流程是什么?", "expect_tool": False}, ] def main(): passed = 0 for case in CASES: result = run(case["question"], user_id="demo-user") has_tool = len(result["tools_called"]) > 0 ok = has_tool == case["expect_tool"] print( f"{case['question']} -> {'passed' if ok else 'failed'} " f"model={result['model_used']} tools={result['tools_called']}" ) if ok: passed += 1 print(f"pass rate: {passed}/{len(CASES)}") if __name__ == "__main__": main()

这个评估脚本很简单,但已经是完整的回归测试雏形:给定输入、断言行为、统计通过率。实际项目中,评估集会扩展到上百条案例,覆盖正常查询、用户情绪、模糊表述、越权尝试、模型幻觉等场景,并且接入 CI,任何 Prompt 或模型版本变更都必须跑通评估集才能上线。

6. 运行效果与验证方式

先安装依赖:

pip install openai pyyaml

然后设置模型环境变量:

export FAST_MODEL="你的快模型ID" export SMART_MODEL="你的强模型ID"

运行评估脚本:

python scripts/evaluate.py

预期输出类似:

你好 -> passed model=fast-model-id tools=[] 我的订单 20250001 现在到哪了? -> passed model=smart-model-id tools=['query_order_status'] 你们平台的退款流程是什么? -> passed model=fast-model-id tools=[] pass rate: 3/3

验证是否成功的三个标准:

  • 简单问题没有触发工具调用,并且没有因为模型选错而走慢速链路。
  • 订单查询问题触发工具调用,且最终回复中包含工具返回的真实状态,而不是模型编造的字段。
  • 日志中能同时看到路由模型、工具调用参数、Token 数和耗时。

如果失败,先按下面顺序排查:

  1. 日志里有没有模型请求?没有,说明 API Key 或网络配置有问题。
  2. 日志里是否出现tool_called记录?没有,说明模型的工具调用没有触发,需要检查工具 JSON Schema 是否被模型正确理解,或换更强模型。
  3. 日志显示工具被调用,但最终回复不对?检查工具返回结果是否被拼进第二轮对话,以及 System Prompt 是否要求模型“基于工具结果回答”。

7. 常见问题与排查思路

问题现象可能原因排查方式解决方案
模型输出不符合 JSON 格式未启用结构化输出,或模型推理能力弱查看原始输出是否被截断;检查是否启用 JSON Mode优先使用结构化输出功能;在 System Prompt 中给出 JSON 示例
工具调用循环不退出缺最大调用次数限制,或工具返回结果让模型无法终止查看日志中工具调用次数增加MAX_TOOL_CALLS;工具返回成功/失败后给出明确终止信号
简单问题走了大模型,成本飙升路由逻辑太粗糙打印每次路由的模型名和 Token 数增加关键词规则;引入轻量意图分类模型做路由
用户问 A 订单,模型回答了 B 订单用户身份来自模型猜测,而非系统注入检查 messages 中用户信息字段来源用户身份一律由会话服务注入,不能在 Prompt 中让模型自造
模型升级后行为漂移没有回归评估集用评估集跑新版模型对比通过率建立核心 Case 集,模型升级必须跑回归并留版本快照
工具返回“查无此单”,模型仍假装有数据模型幻觉检查工具结果是否进第二轮,并查看回复是否引用工具字段在 System Prompt 中显式说明“查无数据时必须告知用户查不到”
同一请求重试两次,产生重复数据缺少幂等控制查看下游日志是否重复写入工具调用增加 request_id 做幂等,写操作加唯一约束

对比可见:大部分问题的根源,要么是设计阶段没把上下文和权限边界想清楚,要么是上线后没有评估闭环兜底。这两件事,恰恰是 AI 应用“系统化”和“玩具化”的分水岭。

8. AI 应用生产环境最佳实践

8.1 把 AI 模块当远程服务,而不是当本地函数

不要把模型调用代码直接散落在各处业务代码里。更推荐的做法是,把 AI 能力封装成一个独立服务,提供统一接口:输入用户上下文、业务参数,输出结构化结果。这样做的好处是:模型升级只影响服务内部,调用方无感;独立部署后可以单独扩容、限流和熔断;日志做到服务级收敛,排查问题不必翻遍全项目。

8.2 安全边界:永远不要信任模型输出

模型输出只是建议,不是指令。涉及删除、转账、退款、发布内容等敏感操作时,模型不能直接执行。正确流程是:模型生成操作意图 -> 服务端校验权限 -> 二次确认 -> 执行 -> 审计。所有越权尝试都应该被系统拦截,并记录到安全日志里。

8.3 成本治理:路由、缓存、降级三板斧

路由一定要做。不是所有请求都需要最强模型,很多高频场景用快模型就够。缓存也要做。同一个问题、同一份资料、同一类客户,答案可以在短时间内复用,减少重复推理。降级更重要:大模型服务不可用时,系统可以降级为固定话术模板、规则匹配或转人工,保证业务不中断。

8.4 评测不是一次性工作,而是持续机制

每个 AI 应用上线前必须回答三个问题:

  • 哪些场景必须成功?列出 50 到 200 条核心用例。
  • 失败的标准是什么?比如:误报物流状态、泄露他人订单、无法回答常见售后问题。
  • 每次模型或 Prompt 变更后,怎么验证没有回退?

只要能回答这些问题,AI 应用就算进入可管理状态。否则上线就是赌运气。

8.5 日志与可观测性

AI 应用的日志比传统应用多两个层次:模型层和对话层。模型层要记录:模型名、版本、输入 Token、输出 Token、延迟、是否触发工具。对话层要记录:会话 ID、用户 ID、完整消息序列、工具调用序列。只有这些都在,线上出了问题才能复现和归因。

8.6 灰度与回滚

模型版本切换不要一键全量。先在 5% 流量上跑新模型,对比评估通过率和用户反馈,确认稳定后逐步放大。一旦指标回退,马上切回旧版本。所有模型版本都保留快照,不做“悄悄升级”。

8.7 数据隐私与合规

用户输入和工具返回结果都可能包含敏感信息。日志中不要记录完整手机号、身份证号、地址详情;需要用脱敏标识符代替。输入大模型的文本也要在构造消息前完成脱敏,避免敏感数据进入第三方模型服务。数据保留设置应明确生命周期,超期清理。

9. 给开发者的下一步建议

如果你正在做 AI 应用,有四个方向值得优先投入:

第一,从业务问题找入口,而不是从模型能力找入口。先找到业务里“人处理太慢”或“人处理不一致”的环节,再思考模型能不能在其中扮演一个有限角色。反过来做,先拿到模型再找场景,大概率会做成又一个玩具。

第二,先做闭环,再优化效果。很多团队在 RAG 召回率和 Prompt 上反复调优,却连最基本的工具权限校验和结构化输出都没做。应该先把链路跑通:输入 -> 路由 -> 模型 -> 工具 -> 校验 -> 回复 -> 日志,然后再逐环节优化。

第三,尽早建立评估集和回归机制。哪怕一开始只有 30 条用例,也比没有强。每次改动模型版本、Prompt、工具逻辑都跑一遍评估集,这是控制 AI 应用质量最有效的低成本手段。

第四,深入理解 Agent 的工程约束。Agent 不只是一个“让模型自己规划”的噱头,它涉及工具协议、状态管理、错误恢复、幂等控制、安全性设计。建议从实现一个最小 Function Calling 服务开始,一步步加约束、加日志、加评估,真正理解模型在业务流程里的边界在哪里。

AI 应用的下半场,拼的已经不是谁手里的模型参数更大,而是谁能让模型在复杂业务系统里稳定地输出正确结果。这条路不像做 Demo 那么性感,却是一个 AI 应用真正产生业务价值的必经之路。把上下文、工具、评估、可观测性这些基本功做扎实,你就已经跑赢了绝大多数停留在“调模型”阶段的团队。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询