三个工具,让 agent 在一次对话里完成研究、写码、调试与保存

简介: 本文展示了一个真正“具身智能”的多工具Agent:它能自动研究网页、编写/调试Python代码(如列表推导式)、运行验证并保存结果。核心不在工具本身,而在模型自主规划工作流——研究→写→测→修→存,全程无需硬编码逻辑。三工具即成系统,智能涌现于规划。

agent 抓了一份 Python 文档,写了三段 list comprehension 示例,然后跑起来。前两段没问题第三段抛出了语法错误。它没有停在那里,而是去读错误信息、找到问题、把代码改了,再跑一次。这次过了,到这一刻"agentic" 这个词才真正落地。

单个工具是噱头,工具集才是真正的系统。其实只要有三个工具就能把 agent 从聊天机器人变成能干活的东西:

fetch_url

读取任意网页,

write_file

把结果落到磁盘,

run_python

直接执行代码。一次对话里,研究、写、测、修可以全部走完。

真正有意思的不是工具本身而是规划,让agent 自己决定:"得先研究,再写代码,最后运行验证。" 这个顺序不是写死在代码里的;模型从目标推理出来,自动成形。

下面这段代码是一个完整的多工具 agent,能做网页研究、写并运行 Python,也能保存文件。

 import anthropic  
import subprocess, sys, tempfile, re  
import urllib.request  
from pathlib import Path  
client = anthropic.Anthropic()  
OUTPUT_DIR = Path("agent_output")  
OUTPUT_DIR.mkdir(exist_ok=True)  
# ── Tool implementations ──────────────────────────────────────────────────  
def fetch_url(url: str) -> str:  
    """Fetch a webpage and strip HTML - gives the agent access to the web."""  
    try:  
        req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})  
        with urllib.request.urlopen(req, timeout=10) as r:  
            html = r.read().decode("utf-8", errors="ignore")  
        text = re.sub(r"<[^>]+>", " ", html)  
        text = re.sub(r"\s+", " ", text).strip()  
        return text[:2500]  # cap to avoid filling the context window  
    except Exception as e:  
        return f"Error fetching {url}: {e}"  
def write_file(filename: str, content: str) -> str:  
    """Save content to the output directory."""  
    path = OUTPUT_DIR / filename  
    path.write_text(content)  
    return f"Saved {len(content)} chars to {path}"  
def run_python(code: str) -> str:  
    """Execute Python code in a subprocess. Returns stdout and stderr."""  
    with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:  
        f.write(code)  
        tmp = f.name  
    try:  
        result = subprocess.run(  
            [sys.executable, tmp],  
            capture_output=True, text=True, timeout=15  
        )  
        out = result.stdout or ""  
        err = result.stderr or ""  
        return (out + ("\nERROR:\n" + err if err else "")).strip() or "Ran with no output."  
    except subprocess.TimeoutExpired:  
        return "Error: timed out after 15 seconds."  
    finally:  
        Path(tmp).unlink(missing_ok=True)  
TOOLS = [  
    {  
        "name": "fetch_url",  
        "description": "Fetch the text content of any webpage. Use for research.",  
        "input_schema": {"type":"object","properties":{"url":{"type":"string"}},"required":["url"]}  
    },  
    {  
        "name": "write_file",  
        "description": "Save text to a file in the output directory.",  
        "input_schema": {"type":"object","properties":{"filename":{"type":"string"},"content":{"type":"string"}},"required":["filename","content"]}  
    },  
    {  
        "name": "run_python",  
        "description": "Execute Python code and return the output. Use to test code you write.",  
        "input_schema": {"type":"object","properties":{"code":{"type":"string"}},"required":["code"]}  
    }  
]  
def execute_tool(name, inputs):  
    if name == "fetch_url":  return fetch_url(inputs["url"])  
    if name == "write_file": return write_file(inputs["filename"], inputs["content"])  
    if name == "run_python": return run_python(inputs["code"])  
    return f"Unknown tool: {name}"  
# ── Agent loop ─────────────────────────────────────────────────────────────  
def run_agent(task: str):  
    print(f"\nTask: {task}\n" + "="*50)  
    messages = [{"role": "user", "content": task}]  
    system = """You are a research and coding agent. When given a task:  
1. Research first if needed (fetch_url)  
2. Write any code required  
3. Run the code to verify it works - fix it if it errors  
4. Save the final result to a file  
Be methodical. Show your reasoning before each tool call."""  
    for i in range(15):  
        response = client.messages.create(  
            model="claude-haiku-4-5-20251001",  
            max_tokens=1024,  
            system=system,  
            tools=TOOLS,  
            messages=messages  
        )  
        if response.stop_reason == "end_turn":  
            answer = next((b.text for b in response.content if hasattr(b,"text")), "Done.")  
            print(f"\nDone: {answer}")  
            return answer  
        tool_results = []  
        for block in response.content:  
            if block.type == "tool_use":  
                print(f"\n  [{block.name}]")  
                result = execute_tool(block.name, block.input)  
                # Print a preview so you can follow along  
                print(f"  → {result[:200]}{'...' if len(result)>200 else ''}")  
                tool_results.append({  
                    "type": "tool_result",  
                    "tool_use_id": block.id,  
                    "content": result  
                })  
        messages.append({"role":"assistant","content":response.content})  
        messages.append({"role":"user","content":tool_results})  
# Run it  
run_agent(  
    "Write three Python list comprehension examples - basic, filtered, and nested. "  
    "Run each one to verify it works. Save a cheat sheet to 'list_comprehensions.md'."  
 )
fetch_url

用正则把 HTML 标签去掉,方法粗糙,但拿到可读文本是够用的;timeout 用来防止 agent 在慢站上卡住。

run_python

走的是临时文件加 subprocess 隔离,比

exec()

安全一些,但放到生产环境仍有风险,timeout 同样用来防死循环。

system prompt 给 agent 划了一条工作路径:研究、写代码、测试、保存。它会自然按这个节奏走。

多工具带来的真正变化

agent 本身不会写代码,也不会上网。它只会用工具。智能落在规划上。

丢一个复杂任务进去,看它的执行序列:抓 URL → 综合信息 → 写代码 → 运行 → 读错误 → 改 bug → 再跑 → 保存结果。这条工作流不是你编排出来的,是模型自己推出来的。

这就是为什么工具设计比挑模型更关键。一个设计得当的工具,能让 agent 的能力上一个台阶。

最值得学习的一点:agent 会调试自己写的代码。看到报错,理解原因,动手修。这不是预设脚本,是循环加工具自然涌现出来的行为。

改进提高

加一个

read_file

工具,从输出目录读取已有文件。然后把这个任务交给 agent:"读取你之前生成的 list comprehensions cheat sheet,再加两个进阶示例,把文件更新一遍。"

看它怎么走:读 → 分析 → 扩展 → 保存。同一套规划逻辑,落到完全不同的工作流上。

https://avoid.overfit.cn/post/061983d61b58422e8436c0eece200573

by TechnoFin

目录
相关文章
|
1月前
|
人工智能 监控 算法
AI智能体的开发及上线
本文详解AI智能体从0到1的标准化开发与合规上线闭环:涵盖架构设计(大脑/规划/记忆/工具/感知)、低代码/代码级开发路径、RAG知识增强、算法备案、内容安全与数据脱敏等2026最新监管要求,助力高效、合规落地。
|
1月前
|
机器学习/深度学习 算法 安全
2026 年面向 LLM 的 RL方法总结:从 PPO 到 DPO 到 GRPO,再到多智能体 RL
本文梳理大模型对齐中强化学习的演进脉络:从PPO+RLHF起步,到DPO删去奖励模型、GRPO剔除Critic,再到MARL与智能体RL框架兴起。聚焦奖励信号变迁——由人类偏好转向可验证结果,并解析各算法适用场景、失效边界及开源技术栈(verl/TRL/Agent-R1等),揭示RL正从旁支走向LLM能力跃迁的核心引擎。
397 2
2026 年面向 LLM 的 RL方法总结:从 PPO 到 DPO 到 GRPO,再到多智能体 RL
|
弹性计算 Kubernetes Cloud Native
K8s 网关选型初判:Nginx 还是 Envoy?
本文将从性能和成本、可靠性、安全性 3 方面,对两大开源实现进行比对,希望对正在做 K8s 网关选型的企业有所借鉴。
K8s 网关选型初判:Nginx 还是 Envoy?
|
10天前
|
人工智能 缓存 弹性计算
阿里云服务器2核4G5M199元解析:独享型u1实例,性能、适用场景、购买和续费规则介绍
阿里云通用算力型u1实例(ecs.u1-c1m2.large)2核4G、5M带宽、80G ESSD Entry云盘,活动特惠价仅199元/年(官网价3498.36元),企业新老用户同享,续费同价至2027年3月31日,每人限购1台。该实例采用独享型架构,搭载Intel至强可扩展处理器,内网带宽1Gbit/s、收发包30万PPS、云盘IOPS 1万,性能稳定,适合企业官网、中小Web应用、轻量数据库及开发测试等场景。
|
2月前
|
存储 人工智能 JavaScript
Prompt、Context、Harness:AI Agent 工程的三层架构解析
2023年重“Prompt”(如何说),2025年重“Context”(看到什么),2026年跃升至“Harness”(系统级约束与验证)。三者非替代而是分层:Prompt优化表达,Context管理信息环境,Harness构建可信执行系统——模型是马,Harness才是缰绳、马鞍与路。
1006 10
Prompt、Context、Harness:AI Agent 工程的三层架构解析
|
1月前
|
人工智能 API 调度
主流编程CLI工具适配DeepSeek V4对比:兼容性、报错与可用方案完整梳理
DeepSeek V4系列模型发布后,凭借更强的代码能力、长上下文支撑与工具调用稳定性,迅速成为AI编程场景的热门选择。但与此同时,DeepSeek V4对上下文回传增加了强制校验规则:当模型返回的消息中包含tool_call时,下轮对话必须携带reasoning_content字段,否则会直接报错并中断任务。这一规则导致大量基于CLI运行的编程工具无法正常工作,包括多款主流AI编码助手。
1825 1
|
1月前
|
缓存 关系型数据库 数据库
【赵渝强老师】PostgreSQL的数据预热扩展pg_prewarm
本文详解PostgreSQL扩展pg_prewarm,支持手工与自动两种数据预热方式:手工调用pg_prewarm()函数将表数据预加载至缓冲区;自动模式通过后台进程周期记录并重启时恢复热点数据,显著提升查询性能。
193 1
【赵渝强老师】PostgreSQL的数据预热扩展pg_prewarm
|
1月前
|
JSON 前端开发 API
LangChain的工具调用 vs 原生Skill API:性能差在哪儿?
本文剖析LangChain工具调用的性能瓶颈:14层抽象、文本解析歧义、隐式重试导致延迟飙升与错误率上升;对比原生SDK,揭示“提示工程范式”与“模型内化工具调用”的代际差异,指出工程选型核心标准——**少看它能做什么,多看它默认替你做了哪些不可关的决策**。
|
1月前
|
设计模式 JSON 自然语言处理
我花一周拆解了企业级Skills库的全套设计模式
本文揭秘企业级Agent测试技能(Skill)体系落地实战:从200+混乱脚本“考古”出发,提炼出注册发现、能力抽象、副作用管理三层核心骨架,直击“Skill化后调度失灵、上下文爆炸、副作用失控”三大痛点。不讲空泛理论,只给可复用的设计模式、元描述模板与避坑指南。