第 7 课 / 共 7 课18 分钟2 个闯关

Agent 与工具调用:让模型能干活

@tool、五步循环的真实样子、三条不能越过的安全红线。

让模型能干活,而不只是说话

模型算不对数、查不了今天的天气、发不了邮件——它只能生成文字。

但如果我们告诉它"你可以让我帮你调这几个函数",它就能决定什么时候调、传什么参数,然后我们替它执行,把结果再喂回去。这就是 Agent。

定义工具

from langchain_core.tools import tool

@tool
def add(a: int, b: int) -> int:
    """计算两个整数的和。"""
    return a + b

@tool
def get_weather(city: str) -> str:
    """查询指定城市的当前天气。city 用中文城市名,如 北京。"""
    return f"{city}:晴,22 度"

@tool 装饰器会把函数名、参数类型、文档字符串一起打包发给模型。

所以:

  • 文档字符串不是注释,是给模型看的说明书。 写清楚"什么时候该用它"、参数是什么格式。写得含糊,模型就会在错误的时机调用它。
  • 类型注解必须写。 模型靠它知道该传什么类型。

绑定并调用

llm_with_tools = llm.bind_tools([add, get_weather])

resp = llm_with_tools.invoke("北京天气怎么样?")
print(resp.tool_calls)
# [{'name': 'get_weather', 'args': {'city': '北京'}, 'id': 'call_abc'}]

注意:模型并没有执行函数,它只是说"我想调用 get_weather,参数是北京"。执行是你的事。

完整的一轮长这样:

from langchain_core.messages import HumanMessage, ToolMessage

messages = [HumanMessage("北京天气怎么样?")]
ai_msg = llm_with_tools.invoke(messages)
messages.append(ai_msg)

tools_by_name = {"add": add, "get_weather": get_weather}
for call in ai_msg.tool_calls:
    result = tools_by_name[call["name"]].invoke(call["args"])
    messages.append(ToolMessage(content=str(result), tool_call_id=call["id"]))

final = llm_with_tools.invoke(messages)
print(final.content)     # 北京现在是晴天,22 度。

五步:问 → 模型说要调工具 → 你执行 → 把结果塞回消息列表 → 模型基于结果作答。

Agent 框架(LangGraph 等)做的就是把这五步包成一个循环,让模型可以连续调用多个工具直到得出答案。但底层就是上面这段代码,没有魔法。

三条必须守住的安全红线

Agent 是大模型应用里风险最高的部分,因为它真的会执行动作。

1. 绝不把无限制的执行能力给模型。

@tool
def run_sql(sql: str) -> str:
    """执行任意 SQL。"""      # ← 绝对不要这样

模型可能被提示词注入诱导,生成 DROP TABLE。正确做法是收窄工具:提供 query_order_by_id(order_id: str),而不是"执行任意 SQL"。工具的权限要按最小必要原则设计,就像给实习生开数据库账号一样。

2. 有副作用的操作必须人工确认。 发邮件、付款、删数据、发布内容——让模型生成方案,人点确认。不可逆的动作永远不要全自动。

3. 加上限。 循环次数上限、超时、单次调用工具数上限。没有上限的 Agent 循环可以在你睡觉时烧掉整月预算。

什么时候不该用 Agent

流程固定就别用 Agent。

"翻译→润色→存档"这种确定流程,直接写三步链。它更快、更便宜、结果可预测、出错好排查。Agent 的价值在于"事先不知道需要哪几步"的场景。

工程上的常见教训是:一半的 Agent 项目其实应该是一条固定的链。先用链把问题解决掉,确实解决不了再上 Agent。

你已经学完了这条路线

回头看,你现在掌握的是一条完整的能力链:调用模型(第 2 课)→ 管理提示词(第 3 课)→ 拿到结构化输出(第 4 课)→ 维持对话(第 5 课)→ 接入私有知识(第 6 课)→ 执行动作(第 7 课)。

这六块拼起来,就是一个企业级 AI 应用的骨架。

接下来值得投入的方向:LangGraph(把 Agent 的循环显式建模成状态图,可控性远高于黑盒 Agent)、评估(建一套测试集,量化每次改动的效果——没有评估的提示词调优就是在赌博)、可观测性(LangSmith 之类,把每次调用的输入输出都记下来,否则线上问题无从查起)。

10 秒自测

为什么工具函数的文档字符串这么重要?

因为它是发给模型的说明书,模型靠它判断什么时候该调用这个工具、参数该传什么。写得含糊,模型就会乱调或漏调。

广告位(未配置 AdSense,上线后在此展示)

动手闯关

读懂了不算会,写出来才算

0/2 已通过

闯关和判题完全免费,交错了不扣任何东西。卡住随时点「问 AI」,它能看到你正在写的代码。

关卡 01选择+10 点 · +15 XP

模型调用工具时到底发生了什么

`llm_with_tools.invoke("北京天气怎么样?")` 之后,模型做了什么?

  • 可能是多选,选错不扣点数,随便试。
登录后闯关拿点数
关卡 02选择+18 点 · +25 XP

Agent 的安全红线

设计 Agent 工具时,下面哪些做法是对的?(可多选)

  • 可能是多选,选错不扣点数,随便试。
登录后闯关拿点数

学完了?标记一下

标记完成会记进度、涨 40 XP,还会点亮连续学习天数。