问题与目标
上一阶段已经能通过 API 得到模型回复,但“请求成功”不等于“应用可用”。真实应用还要接收输入、读取外部数据、维护状态、校验结果、处理超时,并留下能够复盘的运行记录。
本篇把单次模型调用扩展成一条最小应用链路。完成标准不是回答看起来聪明,而是同一请求能够被追踪,失败能够被分类,模型输出越界时程序能够拒绝。本篇只设计边界,不引入 LangChain、RAG 或 Agent。
用户输入 → 输入校验 → 上下文组装 → 模型调用 → 结果校验 → 业务输出
↓ ↓ ↓
拒绝请求 超时/重试 降级/人工复核

主链负责产生结果,三条向下的失败路径负责拒绝、降级和复盘;模型只是链路中的一个不确定组件。
核心概念
模型负责什么,程序负责什么
模型适合处理语义理解、归纳和生成;程序必须负责身份、权限、金额、状态机、参数范围和副作用。Prompt 中写“不要越权”只是提示,不是权限控制。
一条可维护链路至少包含:
- 输入协议:字段、类型、长度和必填项;
- 上下文:系统规则、用户输入、外部事实和版本;
- 状态:会话、任务进度和幂等标识;
- 执行策略:超时、重试、并发和取消;
- 输出契约:字段、枚举、引用和拒答条件;
- 运行记录:请求 ID、步骤、耗时、版本和错误类型。
三类失败边界
- 调用失败:网络、限流、认证、超时和服务端错误。
- 协议失败:字段缺失、JSON 无效、类型或枚举不符。
- 语义失败:格式正确但事实错误、证据不足或违反业务规则。
只有第一类中的瞬时错误适合自动重试。协议失败应保留原始响应并有限修复,语义失败需要规则、检索证据或人工复核。
可运行实现
下面用纯 Python 模拟模型,将链路控制与模型实现分开。输入是一条运行事件,输出是带状态、摘要和追踪信息的字典。
from dataclasses import asdict, dataclass
from time import perf_counter
from uuid import uuid4
@dataclass
class Result:
request_id: str
status: str
summary: str | None
error: str | None
elapsed_ms: int
def fake_model(text: str) -> str:
# 只模拟模型边界,便于离线验证链路。
return text.strip().replace(";", ",")[:60]
def handle_event(payload: dict) -> dict:
started = perf_counter()
request_id = str(uuid4())
try:
text = payload.get("text")
if not isinstance(text, str) or not text.strip():
raise ValueError("text_required")
if len(text) > 500:
raise ValueError("text_too_long")
summary = fake_model(text)
if not summary or len(summary) > 60:
raise ValueError("invalid_model_output")
result = Result(request_id, "ok", summary, None, 0)
except ValueError as error:
result = Result(request_id, "rejected", None, str(error), 0)
result.elapsed_ms = round((perf_counter() - started) * 1000)
return asdict(result)
print(handle_event({"text": "节点 AX-3 温度偏高;复核后确认为传感器漂移。"}))
print(handle_event({"text": ""}))
输出类似:
{'status': 'ok', 'summary': '节点 AX-3 温度偏高,复核后确认为传感器漂移。', ...}
{'status': 'rejected', 'summary': None, 'error': 'text_required', ...}
把 fake_model() 换成真实模型客户端时,上层协议、校验和记录逻辑不需要改变。生产日志还应记录模型、Prompt 和数据版本,但不应写入密钥与完整敏感正文。
常见问题与排查
把全部规则塞进 Prompt
检查哪些约束能由 Python、数据库约束或权限系统确定执行。凡是涉及安全、资金和副作用,都不能只依赖模型自觉。
失败后无限重试
先按错误类型分类,再设置单次超时、最大次数和总体截止时间。写操作还要使用幂等键,避免请求重放造成重复副作用。
只保存最终答案
没有请求 ID、步骤耗时、模型版本和错误分类,就难以判断问题发生在输入、检索、模型还是解析阶段。日志应可关联,但遵守数据最小化。
用“能生成”代替验收
先定义可检查的完成条件,例如字段齐全、编号保留、无证据时拒答、P95 延迟和失败率,再评价语言质量。
小结
大模型应用的核心不是把更多文本发给模型,而是用程序建立确定边界:输入可验证、状态可隔离、失败可分类、结果可校验、过程可追踪。下一篇再用 LangChain 的抽象组织模型、消息、提示词和解析器。
许可协议:CC BY-NC 4.0
更新于 1 小时前
觉得文章有帮助?点个赞吧!
0 条评论


