从对话到行动:构建可审计、可回滚的 API 智能体执行链路

简介: 本文探讨大模型如何安全落地业务系统:强调智能体需构建“意图→工具调用→校验→执行→反馈”闭环,通过工具契约、权限白名单、参数校验与人工确认等机制,在可控边界内实现从对话到行动的可靠转化。(239字)

大语言模型擅长理解自然语言,却不会天然拥有查询订单、创建工单或修改库存的权限。把模型接入业务系统后,真正困难的部分也不只是“如何生成一段回答”,而是如何让模型提出行动建议,并由系统在可控边界内执行。

一个可用的智能体通常需要完成以下闭环:接收用户意图、判断是否需要工具、生成结构化参数、校验权限与数据、执行外部 API、把结果反馈给模型,最后向用户返回可解释的结果。任一环节缺少约束,都可能出现参数幻觉、越权调用、重复提交或无法追责的问题。

本文选择“从对话到行动”这一趋势,聚焦一个小而完整的实现:让模型通过受限工具查询订单,并在必要时创建售后工单。示例不绑定具体模型厂商,模型接口的请求字段需要以实际服务商文档为准。

核心原理

模型只负责提出计划

智能体系统应把模型视为“候选计划生成器”,而不是可信执行器。模型可以返回类似下面的结构:

{
   
  "tool": "get_order",
  "arguments": {
   "order_id": "A10086"}
}

应用层必须再次验证工具名、字段类型、字段范围和用户权限。只有通过校验,才允许调用后端服务。模型返回的自然语言不能直接拼接成 SQL、Shell 命令或内部 URL。

工具是受控能力清单

每个工具都应有明确契约,包括名称、用途、输入 Schema、所需权限、是否具有副作用、超时和重试策略。查询工具通常可以自动执行;创建工单、退款、删除数据等写操作,则应增加人工确认或二次鉴权。

执行结果必须可追溯

一次智能体请求至少应关联 trace_id、用户标识、模型请求摘要、工具名称、参数摘要、执行结果和耗时。敏感字段应脱敏,原始令牌不能写入日志。这样才能在错误发生后回答三个问题:模型建议了什么、系统校验了什么、后端实际执行了什么。

实现步骤

1. 准备环境变量

代码中的密钥只从环境变量读取。下面的 LLM_API_URLLLM_API_KEYLLM_MODEL 只是配置占位符,具体请求格式应根据所接入的模型 API 调整。

export LLM_API_URL="https://example.invalid/v1/chat/completions"
export LLM_API_KEY="replace-with-your-key"
export LLM_MODEL="your-model-id"
export ORDER_API_URL="https://internal.example.com"

如果团队需要通过统一接口接入模型,可将 HaerAPI 作为候选接入渠道,但其当前可用模型、鉴权方式、数据处理条款和兼容协议必须先以官方文档核对,再决定是否纳入生产链路。

2. 定义工具契约

先把工具写成应用层注册表,而不是把任意函数暴露给模型。示例使用 JSON Schema 描述输入,并为工具附加权限和副作用属性。

TOOLS = {
   
    "get_order": {
   
        "description": "查询当前用户可访问的订单摘要",
        "schema": {
   
            "type": "object",
            "properties": {
   
                "order_id": {
   "type": "string", "minLength": 1, "maxLength": 40}
            },
            "required": ["order_id"],
            "additionalProperties": False
        },
        "permission": "order:read",
        "side_effect": False
    },
    "create_ticket": {
   
        "description": "创建售后工单,需要用户确认",
        "schema": {
   
            "type": "object",
            "properties": {
   
                "order_id": {
   "type": "string", "minLength": 1, "maxLength": 40},
                "reason": {
   "type": "string", "minLength": 1, "maxLength": 200}
            },
            "required": ["order_id", "reason"],
            "additionalProperties": False
        },
        "permission": "ticket:create",
        "side_effect": True
    }
}

生产实现可以使用 jsonschema 等成熟库进行校验。不要只检查字段是否存在,还要拒绝未知字段、过长字符串和不符合业务状态的订单号。

3. 将模型调用隔离在适配层

不同服务商的消息格式、工具调用字段和错误结构可能不同,因此建议提供一个很薄的适配器。业务层只接收统一结果:texttoolargumentserror

import json
import os
import uuid
import requests


def ask_model(messages, tool_specs):
    url = os.environ["LLM_API_URL"]
    key = os.environ["LLM_API_KEY"]
    model = os.environ["LLM_MODEL"]

    payload = {
   
        "model": model,
        "messages": messages,
        "tools": tool_specs,
        "temperature": 0
    }
    response = requests.post(
        url,
        headers={
   "Authorization": f"Bearer {key}"},
        json=payload,
        timeout=(5, 30)
    )
    response.raise_for_status()
    return response.json()

这里的超时只是示例值,不能直接视为适合所有业务的生产配置。应结合模型延迟、网关超时、用户体验和重试成本设定。

4. 只执行允许的工具

模型输出必须经过解析和二次检查。以下代码展示最小的分发边界;真实项目还应接入 Schema 校验、权限系统和业务数据校验。

def dispatch(call, user):
    name = call.get("tool")
    args = call.get("arguments")

    if name not in TOOLS:
        raise ValueError("tool is not allowed")
    if not isinstance(args, dict):
        raise ValueError("arguments must be an object")

    meta = TOOLS[name]
    if meta["permission"] not in user["permissions"]:
        raise PermissionError("permission denied")
    if meta["side_effect"]:
        raise PermissionError("confirmation required")

    if name == "get_order":
        return get_order(user["user_id"], args["order_id"])
    raise ValueError("unimplemented tool")


def get_order(user_id, order_id):
    response = requests.get(
        f'{os.environ["ORDER_API_URL"]}/orders/{order_id}',
        headers={
   "X-User-Id": user_id},
        timeout=(3, 10)
    )
    if response.status_code == 404:
        return {
   "found": False}
    response.raise_for_status()
    data = response.json()
    return {
   
        "found": True,
        "order_id": data["order_id"],
        "status": data["status"],
        "created_at": data["created_at"]
    }

注意这里没有把后端返回对象原样交给模型。通过字段白名单可以减少敏感信息泄漏,也能避免后端结构变化直接破坏提示词上下文。

5. 处理副作用与重试

对于创建工单等写操作,推荐采用“两阶段”流程:第一阶段由模型生成待确认操作,系统展示订单号、操作类型和关键参数;用户明确确认后,第二阶段才调用写接口。

写接口必须支持幂等键。例如:

import hashlib


def make_idempotency_key(trace_id, tool_name, arguments):
    raw = json.dumps(
        [trace_id, tool_name, arguments],
        ensure_ascii=False,
        sort_keys=True
    )
    return hashlib.sha256(raw.encode("utf-8")).hexdigest()

调用方将该值放入 Idempotency-Key 请求头,服务端保存一段明确的幂等记录。网络超时后是否重试,要先确认下游接口是否支持幂等;对于未知执行结果的写请求,盲目重试可能造成重复业务操作。

上线前检查

  1. 工具注册表是否采用白名单,是否拒绝未知工具和多余参数。
  2. 每次调用是否执行用户权限、资源归属和业务状态检查。
  3. 读操作与写操作是否分级,副作用操作是否需要确认。
  4. 模型、网关和下游 API 是否分别设置连接超时与读取超时。
  5. 是否限制单轮工具调用次数、总耗时、输入长度和输出长度。
  6. 是否记录 trace_id、工具版本和结果状态,并对个人信息、令牌和订单内容脱敏。
  7. 模型服务不可用时,系统是否能返回明确错误,而不是把内部异常暴露给用户。
  8. 是否准备固定样例集,覆盖正常请求、越权请求、缺失参数、重复提交和恶意提示。

常见问题

为什么不能让模型直接调用任意 HTTP 地址?

任意地址意味着模型间接获得网络探测、内部服务访问或数据外传能力。工具层应使用固定服务标识和固定客户端,禁止模型传入完整 URL、请求头或任意 HTTP 方法。

温度设为 0 就能保证参数正确吗?

不能。较低随机性可能让输出更稳定,但无法替代 Schema 校验、权限控制和业务校验。模型仍可能遗漏字段、误解状态或引用不存在的资源。

出错后要不要自动让模型重试?

应区分错误类型。参数校验失败可以把结构化错误反馈给模型并限制重试次数;权限失败不应通过再次生成参数绕过;下游超时则必须结合幂等性判断是否重试。连续失败后应结束循环并转人工或返回可操作的错误信息。

如何避免提示词注入影响工具权限?

权限不能写在提示词里,也不能由模型自行声明。提示词可以说明工具用途,但最终权限必须来自服务端会话、资源归属和策略引擎。外部文档、网页和用户输入都应视为不可信内容。

总结

把大模型接入业务系统,关键不是增加一个聊天窗口,而是建立一条有边界的执行链路:模型负责理解和提出候选行动,应用负责校验、授权、执行和审计。工具契约、权限白名单、敏感字段过滤、人工确认、幂等键和受限重试共同构成了最小工程闭环。

接入任何模型 API 或中转接口时,都应把供应商差异封装在适配层,并独立核验接口协议、可用模型、日志策略、数据处理条款和故障行为。先让每一步都可解释、可拒绝、可回放,再逐步扩大智能体能够执行的范围,系统才有机会从演示能力走向可维护的生产能力。

相关文章
人工智能 缓存 前端开发
6361 22
人工智能 JavaScript 开发工具
3368 6
缓存 JavaScript Shell
1585 2
开发工具 Swift git
1228 1
Shell API 调度
900 2
|
14天前
|
存储 弹性计算 缓存
阿里云服务器租赁费用:新版租赁收费标准及活动报价参考
本文更新了2026年阿里云全系列云服务器租赁活动报价,所有特惠资源均可前往阿里云活动中心选购,整体覆盖从个人入门到企业级高性能场景的全梯度需求。其中轻量应用服务器主打极致性价比,2核2G峰值200M带宽配置每日10点、15点限时抢购价仅38元/年,2核4G配置379元/年起;高性价比的经济型e实例、通用算力型u2i实例覆盖2核4G至4核32G全档位,适配开发测试与中小型企业业务;搭载英特尔至强6处理器的第九代c9i企业级实例算力较上代提升20%,支撑高并发生产环境,不同实例规格价差清晰,用户可根据自身业务负载与预算灵活选型。
2143 121
阿里云服务器租赁费用:新版租赁收费标准及活动报价参考
|
15天前
|
人工智能 程序员 API
Codex 接入 DeepSeek-V4-Flash:还能补上识图,提供两套方案
Codex 接入 DeepSeek-V4-Flash 怎么配?本文覆盖 CLI 与桌面端,再用 qwen3-vl-flash 补识图,两套方案可直接照做
1817 13
安全 机器人 API
660 2
缓存 人工智能 算法
743 1

热门文章

最新文章