当前位置: 首页 > news >正文

S02|工具使用:让 Agent 真正会干活,加工具不改循环的核心设计

在上一章 S01 里,我们搭好了 Agent 的最小循环,让模型能调用工具、把结果喂回自己继续推理。但当时只有一个bash工具,既不安全也不好扩展。

这一章 S02,我们要解决工具扩展、安全限制、统一分发三大问题,实现一句核心原则:加一个工具,只加一个 handler,循环完全不用改。


本章核心信息

  • 核心闭环:把模型意图 → 路由成真实动作
  • 工具数量:4 个(bash /read_file/write_file /edit_file)
  • 核心思想:主循环不变,靠分发层扩展能力

先把本章所有名词讲明白

1. Handler(工具处理器)

每个工具真正执行的代码函数。比如读文件、写文件、执行命令,各自有独立的处理逻辑。

2. Dispatch Map / 工具路由表

一张 “对照表”:工具名字 → 对应的处理函数

比如,模型说要用read_file,程序就查表找到run_read执行。

3. Harness 层(工具调度层)

统一管理所有工具的中间层,负责:

接收模型调用 → 找到对应工具 → 执行 → 返回结果。

4. Path Sandbox 路径沙箱

安全限制:Agent 只能读写指定文件夹内的文件,不能越权访问系统文件,防止删库、偷文件。

5. Tool Schema(工具描述)

给模型看的 “工具说明书”,告诉它:这个工具叫什么、需要传什么参数、用来干什么。

6. normalize_messages(消息规范化)

把内部消息整理成模型 API 能接受的格式,保证:

  • 工具调用和结果一一对应
  • 消息角色不连续重复
  • 不携带内部字段导致报错

7. turn(轮次)

一轮 = 模型思考 + 可能的工具调用 + 结果返回一轮结束进入下一轮,直到任务完成。

8. state(状态)

Agent 运行时的全部记忆:消息历史、轮次数、继续 / 停止原因。


为什么不能只用一个 bash 工具?

S01 我们只用了bash(命令行),看起来万能,其实隐患巨大:

  1. cat 读文件可能被截断特殊字符、长文件会导致输出不完整,模型拿到错误信息。

  2. sed 编辑极易崩溃遇到$ & / \等符号,命令直接报错。

  3. 完全没有安全边界模型可以执行任何命令:删文件、改系统配置、泄露信息。

所以必须拆成专用工具read_filewrite_fileedit_file,并加上安全沙箱。


本章架构:一句话看懂

用户输入 → LLM 思考 → 工具分发(查表执行)→ 结果返回 → 写回消息 → 下一轮

工具分发是关键:LLM 不需要知道代码怎么实现,它只说 “工具名 + 参数”,系统查表找到对应函数执行,循环完全不用改


核心实现:工具路由表 + 安全路径

1. 路径安全校验(沙箱)

保证 Agent 只能在工作目录内操作:

def safe_path(p: str) -> Path: path = (WORKDIR / p).resolve() if not path.is_relative_to(WORKDIR): raise ValueError(f"路径超出工作区:{p}") return path

2. 读文件工具(带长度限制)

def run_read(path: str, limit: int = None) -> str: text = safe_path(path).read_text() lines = text.splitlines() if limit and limit < len(lines): lines = lines[:limit] return "\n".join(lines)[:50000]

3. 工具路由表(核心设计)

TOOL_HANDLERS = { "bash": lambda **kw: run_bash(kw["command"]), "read_file": lambda **kw: run_read(kw["path"], kw.get("limit")), "write_file": lambda **kw: run_write(kw["path"], kw["content"]), "edit_file": lambda **kw: run_edit(kw["path"], kw["old_text"], kw["new_text"]), }

4. 循环中统一分发

和 S01 循环几乎一样,只是把硬编码改成查表:

for block in response.content: if block.type == "tool_use": handler = TOOL_HANDLERS.get(block.name) output = handler(**block.input) if handler else f"未知工具:{block.name}" results.append({ "type": "tool_result", "tool_use_id": block.id, "content": output })

关键洞察:加工具不用改循环

以后你想加新工具,比如:

  • search_web
  • run_python
  • get_weather

只需要两步:

  1. 写一个 handler 函数
  2. TOOL_HANDLERS里加一行映射

agent_loop 代码一行不动这就是工业级 Agent 的标准设计。


为什么要消息规范化?

随着工具变多,消息会越来越乱:

  • 工具调用缺结果
  • 连续两条 user 消息
  • 带内部字段 API 不识别

所以必须在发给模型前规范化

def normalize_messages(messages: list) -> list: # 1. 清理内部字段 # 2. 补齐缺失的 tool_result # 3. 合并连续同角色消息 ...

调用模型时这样用:

response = client.messages.create( model=MODEL, system=SYSTEM, messages=normalize_messages(messages), # 先规范化 tools=TOOLS, max_tokens=8000 )

S01 → S02 到底升级了什么?

模块S01S02
工具数量1 个(bash)4 个
工具调用硬编码路由表分发
安全路径沙箱
消息直接发送规范化后发送
扩展性极强
主循环不变不变

初学者可以直接试的 Prompt

Read the file requirements.txt Create a file called greet.py with a greet(name) function Edit greet.py to add a docstring to the function Read greet.py to check the result

你会看到:Agent 会自主选择工具,自动读写编辑,完全不用你干预。


本章教学边界(不搞复杂,只抓核心)

本章不讲权限、不讲缓存、不讲流式、不讲异常恢复。只牢牢抓住三件事:

  1. Tool Schema给模型看
  2. Handler Map给代码分发
  3. Tool Result回流到循环

只要懂这三点,你就掌握了所有 Agent 工具系统的底层结构


一句话总结本章

Agent 的能力增长,不靠把循环写复杂,而靠一层清晰的工具分发层。加工具只加 handler,循环永远不动。

http://www.jsqmd.com/news/674238/

相关文章:

  • 蓝桥杯嵌入式备赛避坑指南:从STM32G431升降控制器看PWM与GPIO的配置冲突
  • STM32硬件SPI驱动ST7796S屏,如何优化刷屏速度并实现流畅GUI?
  • 梯度增强物理信息神经网络 (gPINN)求解矩形薄板力学正反问题(Python代码实现)
  • 如何防御SQL注入恶意代码_对上传文件执行严格过滤
  • 3种高阶数据操控方案解锁赛博朋克2077存档编辑潜能
  • 计算机系统基础知识(十七):软件篇之系统工程详解(下篇)——软件可靠性建模、设计技术及MBSE实践
  • LFM2.5-1.2B-Thinking-GGUF代码审查效果案例:自动发现Java代码中的潜在缺陷
  • 工业肌肉:09 安全运动控制(STO、SS1)
  • 国际半导体展哪家好?2026年全球优质半导体展甄选 - 品牌2026
  • 踩坑实录:Go 语言高并发+短效代理IP,数万个“幽灵连接”是怎么榨干服务器的?
  • 微信小程序开发入门与核心语法
  • 【会议征稿通知 | 中南大学主办 | IEEE出版 | EI 、Scopus稳定检索】第七届计算机视觉、图像与深度学习国际学术会议(CVIDL 2026)
  • React Hook 状态同步优化策略
  • 计算机视觉入门:什么是计算机视觉及核心应用场景
  • Unity基础:场景切换:SceneManager的核心用法
  • Unity Shader 深度写入与关闭ZWrite Off · 半透明排序 · 粒子穿插
  • adobe acrobat pro 2024 经常无故退出,是什么原因,是破解不成功,还是那个序列号到期了,如何解决?
  • KH Coder:无需编程的终极文本挖掘与内容分析完整指南
  • YOLO11涨点优化:注意力机制 | Omni-dimensional Dynamic Convolution (ODConv) 兼具卷积与注意力特性,全维度涨点
  • 检测 Python 游戏中三位随机数的数字重复情况并计算胜率倍数
  • 实在Agent入选 IDC《中国AI Agent应用市场概览》「企业级智能体应用」
  • 解决elementUI icon乱码问题,实现简单,不需修改原先代码
  • 【会议征稿通知 | 西华大学主办 | IEEE出版 | EI 、Scopus稳定检索】第五届新能源系统与电力工程国际学术会议(NESP 2026)
  • Claude Code 配置NVIDIAAPI完整教程 - 免费使用国产大模型
  • 死磕 CTF 必藏!20 个练习平台,让你从菜鸟一路冲到大神
  • 保姆级教程:手把手教你用UDS诊断仪刷写汽车ECU Bootloader(附ISO 15765-3/14229-1实战避坑)
  • Qwen3-ASR-1.7B GPU利用率提升方案:FP16+梯度检查点+批处理吞吐优化
  • Harmonyos状态管理5:@Observed @ObjectLink
  • Spring Boot 4.0 Agent-Ready 架构入门到精通:12个真实故障复盘案例,含Arthas热修复失败、JFR采样丢失、agent-classloader冲突等致命问题
  • 国际半导体全产业链展会哪家好?2026年国际半导体全产业链展会推荐 - 品牌2026