agent 详解 LLM→agent→MCP→结果
这篇文章详细解释了OpenHands系统中LLM、Agent和MCP三者之间的关系与协作机制。主要内容包括: 角色分工: LLM(如DeepSeek v3)负责思考和生成文本 Agent作为编排层管理工具调用流程 MCP Server提供具体工具服务 MCP Client负责通信连接 工作流程: Agent将可用工具清单注入LLM提示词 LLM决定是否调用工具 Agent执行实际工具调用并回传结果
文章目录
- 谁是谁、谁干啥
- SSE vs STDIO(你截图里两个类型)
- 典型一次调用的实际流程(逐步)
- Agent 的定义与作用(再总结)
- 你的当前接法是否“对”?
- 实操小建议
- 先给结论(一句话)
- 详细分解 —— LLM vs Agent(你理解中容易混淆的点)
- Agent 的实现方式(三类常见模式)
- 在 OpenHands 中 agent 是什么、跑在哪里、为何不需要单独 API Key?
- 交互流程(一步步,方便脑补)
- 怎么判断 OpenHands 的 agent 在“做什么”?(实践建议)
- 为什么把 agent 与 LLM 分离是有益的(设计理由)
- 如果你想“把 agent 当成也要训练的模型”——可行吗?
- 给你的可执行建议(一步步来)
- 小结(便于记忆)
你的理解差不多对了,但还差一个关键角色: agent(代理/编排层)。给你一张“分层心智模型”,把 OpenHands + LLM + MCP 的关系一次说清:
谁是谁、谁干啥
-
LLM(DeepSeek v3):只是一台“会思考写字”的引擎。它根据提示词和可用工具说明,生成下一步动作——要么直接回复文本,要么提出一个工具调用(function_call / tool_call)。
-
Agent(OpenHands 的编排层):大脑的“执行官”。它负责:
- 把可用工具清单(从 MCP 服务器发现到的工具,含参数 JSON Schema)告诉 LLM;
- 读取 LLM 的输出;
- 如果 LLM 要调用工具,就由 agent 去真正执行(通过 MCP 客户端与工具通信);
- 把工具结果塞回上下文,再让 LLM 继续思考,循环直到给出最终答复;
- 做控制:防死循环、超时、错误重试、多个工具的顺序编排等。
-
MCP Client(在 OpenHands 里):通信胶水。它知道你配置了哪些 MCP 服务器(SSE 或 STDIO),会做握手、拉取工具列表、调用工具、拿到 JSON 结果。
-
MCP Server(你的 MarsWeather、阿里达摩 AMap 等):工具提供者。暴露一个或多个“工具”(带参数、返回 JSON),支持标准握手与调用协议(SSE/STDIO 传输方式不同,但协议一致)。
一句话:你跟 LLM 对话 → agent 把工具清单给 LLM → LLM“决定”要不要用哪个工具 → agent 代为调用 MCP 工具 → 结果回给 LLM → LLM 产出最终答复。
LLM 不直接“初始化”MCP;始终是 agent在背后握手/调用/回填结果。
SSE vs STDIO(你截图里两个类型)
- SSE:HTTP 流式连接的远程 MCP 服务器(比如你连的 AMap)。
- STDIO:本机进程型 MCP(比如你的
python /app/mcp/mars_weather_mcp.py
)。
二者在 OpenHands 看起来都只是“可用工具的来源”。谁调用?agent 调;何时调用?LLM 输出工具调用意图后由 agent 决定执行。
典型一次调用的实际流程(逐步)
-
你在 OpenHands UI 添加/启用 MCP 服务器(SSE/STDIO)。
-
Agent 启动 MCP 客户端与每个服务器握手,拿到
serverInfo/capabilities/tools
。 -
Agent 把“工具目录”(含名称、参数 JSON Schema、描述)以“函数/工具规范”的形式塞到 LLM 的系统提示词里。
-
你发消息。
-
LLM 输出:
- 若是普通文本:agent 就直接把它回给你;
- 若是工具调用(带工具名+JSON 参数):agent 执行该调用(经 MCP Client→MCP Server→具体工具),拿回结构化 JSON结果。
-
Agent 将“工具结果”作为“观察”添加到上下文,再让 LLM 继续思考;反复数轮,直到 LLM 产出“最终答复”。
Agent 的定义与作用(再总结)
-
定义:在“模型”与“环境/工具/用户”之间,负责状态管理与决策执行的一层。
-
作用:
- 工具发现与注入(把工具规范提供给 LLM);
- 决策循环(思考→行动→观察→再思考);
- 执行与安全(真正发起工具/系统调用、做权限/超时/重试/回退);
- 任务拆解、记忆与上下文管理;
- 多工具编排与优先级/预算控制。
没有 agent,只有 LLM + 工具规范,通常很难稳定完成一整套闭环(错误处理、上下文累积、重试与终止条件都没人管)。
你的当前接法是否“对”?
- 你选了 DeepSeek v3 作为唯一 LLM ✅
- 再挂了一个或多个 MCP 服务器(SSE 的 AMap、STDIO 的 MarsWeather)✅
- 在对话时,确实是 agent 决定是否执行工具;这个决策来自 LLM 的输出意图,但最终调用与结果回灌由 agent 完成 ✅
实操小建议
-
给工具写简短而清晰的描述与严格 JSON Schema参数(越清晰,LLM 越会正确调用)。
-
返回值保持稳定 JSON 结构(成功/错误都结构化),agent 才好回灌给 LLM。
-
名称要“可提示”(短、语义清晰,如
query_mars_temperature
)。 -
在 OpenHands 打开你已经设置的
LOG_ALL_EVENTS=true
,能看到每次:- MCP 握手(工具注册成功日志);
- LLM 的工具调用意图;
- 调用参数与返回 JSON;
- Agent 的多轮循环与停止原因。
如果你愿意,我可以把你的 mars_weather_mcp.py
再加上一点点更“工具友好”的描述与错误码,并给一个PowerShell 一键本地回放脚本,这样你能在不打开 OpenHands 的情况下,也用标准 JSON-RPC 管道测试“LLM→agent→MCP→结果”这条链路的关键一段。
很好的问题——你抓住了核心的困惑:“agent 是不是就是另一只大模型?”。下面我把概念、实现与运行时位置、以及为什么 OpenHands 不要你再额外配置 agent 的 API Key 都讲清楚,并给出可操作的检查/优化建议。
先给结论(一句话)
Agent 不是单纯的“又一个大模型”,而是一个在 LLM 与外部世界(工具、用户、存储)之间做决策与编排的运行时层。
它可以只是一些 orchestration 代码 + prompt 模式(不需要独立模型),也可以包含一个专门训练的模型或子模型做决策(这时才“看起来像另一个模型”)。
详细分解 —— LLM vs Agent(你理解中容易混淆的点)
-
LLM(大模型):负责语言理解与生成,是“思考/表达”的核心能力。它基于输入(prompt + 上下文),输出下一步要做的文本或工具调用意图(例如 function_call)。
-
Agent(代理/控制器):负责把 LLM 的输出翻译为实际动作并管理动作的执行过程,它的职能包括:
- 将可用工具(MCP 列表、函数签名/JSON Schema)注入到 LLM 的上下文/系统提示;
- 解析 LLM 输出(是否要调用工具?工具名称和参数是什么?);
- 真正发起对工具的调用(通过 MCP client 做 handshake / call);
- 处理工具返回值、错误、重试、超时、并把结果回灌给 LLM 继续决策;
- 维护对话状态、记忆、权限/安全检查、并决定何时结束循环。
-
不同点总结:
- LLM = 智力 / 语言生成(“我想做什么”);
- Agent = 执行 / 管理(“如何把想法变成动作并保证安全与正确”)。
Agent 的实现方式(三类常见模式)
-
Prompt-driven agent(最常见、最轻量)
- Agent 本质上是一个控制循环(程序代码),把工具清单 + few-shot 示例放进 system prompt,调用你配置的 LLM(通过 API key),让 LLM 输出“要调用哪个工具/参数”。
- Agent 负责解析并实际调用工具、回填结果、再向 LLM 继续交互。
- 优点:实现简单、不需要额外训练;缺点:对 prompt/示例敏感,复杂决策能力受限。
-
Model-based agent(有专门训练的 agent 模型)
- Agent 包含一个单独的小模型或策略网络(可用监督/RLHF 训练),用于做“是否调用/如何拆解任务”的决策;LLM 仍用于自然语言生成。
- 这种情况下 agent 看起来像“另一个大模型”,但其职责更偏向决策策略而非生成自然语言。
-
Hybrid(混合)
- 使用规则/分类器(判断意图)+ LLM 的强语言能力 + agent 控制循环。用于强化可靠性与响应速度。
在 OpenHands 中 agent 是什么、跑在哪里、为何不需要单独 API Key?
-
OpenHands 内含一个 agent runtime(Orchestrator):这通常是 OpenHands 服务端的一段程序代码(运行在本地容器或本地进程中),负责上面那套“发现工具 → 注入到 prompt → 读 LLM 输出 → 调用 MCP → 回灌”流程。
-
这段 agent 代码并不是一个独立需要你提供 API Key 的 LLM。它只是用来管理对话、工具调用与 LLM 请求。
-
为什么不需要单独 agent API Key? 因为 agent 并不一定是“要调用模型”的独立模型:它会使用你在 OpenHands 中配置的那把 LLM API Key(比如 DeepSeek v3)去请求 LLM。也就是说:
- 你提供 LLM 的 API Key(DeepSeek v3)→ OpenHands 使用它去调用 LLM;
- Agent runtime 在 OpenHands 中负责把请求组织好并送给 LLM;它不需要自己单独的模型授权或 API Key。
-
运行位置:Agent 运行在 OpenHands 服务进程里(如果你本地运行 OpenHands,则运行在容器/本机的 OpenHands server 里);若你开启云版,agent 就运行在 OpenHands Cloud 的服务端。
交互流程(一步步,方便脑补)
- OpenHands 的 agent 启动并通过 MCP client 与你的 MCP servers 握手,读取每个服务的工具清单(name、description、parameters JSON Schema 等)。
- agent 把这些“工具描述”注入给 LLM(装进 system prompt 或函数调用描述)。
- 用户发一句话给 UI → OpenHands 把对话发送给 LLM(通过你配置的 API key)。
- LLM 决定:直接答话,或以“工具调用”的形式返回(比如 function_call),表明想用
query_mars_temperature
。 - agent 解析该意图,调用对应 MCP(SSE/STDIO)接口,得到 JSON 返回。
- agent 把返回结果放回对话上下文,再次调用 LLM 或直接返回最终答复给用户。
- agent 管控错误、重试、超时、并记录日志。
怎么判断 OpenHands 的 agent 在“做什么”?(实践建议)
- 打开完整日志:你已经用
LOG_ALL_EVENTS=true
,这会显示 agent 与 LLM 交互、工具调用、工具返回等事件。看日志里的关键字:tools/list
、tools/call
、function_call
、tool_result
。 - 观察 LLM 输出:当 LLM 选择调用工具时,会输出类似
function_call
的结构,agent 会捕获这个并去执行。日志能直接告诉你“哪个工具什么时候被调用,参数是什么,返回了什么”。 - 试验:发一个明确会触发工具调用的 prompt(例如 “帮我查 2025 年火星平均温度”),看是否能看到
query_mars_temperature
的调用与返回。
为什么把 agent 与 LLM 分离是有益的(设计理由)
- 安全/权限控制:agent 可以限制工具的调用频率、做白名单/黑名单、审计调用日志。
- 错误处理:LLM 可能会生成不完全合法的参数,agent 可以 validate(校验)与修正,或者拒绝并反馈给 LLM。
- 能力组合:agent 可以把多个工具组合成复杂流程(task planning),而不需要训练出更大更复杂的单一模型。
- 成本控制:agent 可以决定何时调用昂贵的模型,何时用本地规则/缓存直接回答,节约成本。
如果你想“把 agent 当成也要训练的模型”——可行吗?
-
可行,但代价不小。典型思路有两种:
- 用监督数据训练一个决策模型(什么时候调用哪个工具、如何拆解任务)。
- 用 RL(例如 RLHF)训练一个策略网络,让 agent 在模拟环境中学会最优调度。
-
建议:先用 prompt-driven agent(已有 OpenHands 运行时)把流程跑通并积累日志/示例;有了大量示例后再考虑是否需要训练专门的 agent 策略模型。
给你的可执行建议(一步步来)
-
观察日志(最重要):继续用
LOG_ALL_EVENTS=true
,找以下事件链:tools/list
→LLM function_call
→tools/call
→tool_result
。这能直接验证“LLM 发出调用意图 → agent 执行 → 结果回填”的闭环。 -
完善工具描述:在 MCP server 的
tool
注释里写清楚description
+ 参数 JSON Schema。越精确,LLM 越少误用。示例格式:{ "name": "query_mars_temperature", "description": "查询指定年份(2020-2030)火星全球平均温度,返回 JSON 包含 year, temperature, unit, note。", "parameters": { "type": "object", "properties": { "year": {"type":"integer","minimum":2020,"maximum":2030} }, "required": ["year"] } }
-
用测试提示验证:在 OpenHands 中发送会触发工具调用的 prompt,检查是否出现
tools/call
。 -
如需更智能的 agent 行为:可以在 OpenHands 的 agent 配置(如果有)加入 few-shot 示例,或者在平台上启用 function-calling 风格(让模型以结构化形式输出工具调用)。
-
如果未来要训练 agent:先积累“例子(LLM 想调用哪个工具 → agent 执行 → 实际结果)”的日志,作为监督数据。
小结(便于记忆)
- Agent = orchestration layer(代码 + 可能的模型/策略),负责“把 LLM 的意图变成动作并保证执行的安全与可靠”。
- OpenHands 的 agent 通常是内置在平台里的 runtime,不需要额外 API Key,因为它使用你配置的 LLM API Key 来向模型发送请求。
- 你现在的配置思路是正确的:LLM(DeepSeek)做思考,大的决策意图由 LLM 输出,agent(OpenHands runtime)来执行 MCP 工具调用并回灌结果。
如果你愿意,我可以立刻帮你做两件事(任选其一或都做):
- 给出一个你当前
query_mars_temperature
的标准 tool schema(JSON),并说明如何把它暴露在 MCP 中以提高 LLM 调用准确率; - 帮你写一个简单的本地测试脚本(PowerShell 或 Python),模拟 agent 的行为:把 tool 描述注入到 prompt、发送给你的 DeepSeek(如果你愿意给示例输出格式),并展示 function_call → 执行 → 回灌 的示例日志。
想要哪个我就直接给你(我不会再问问题,直接给两份都可)。
你这个问题问得非常到点子上 👍。其实你现在已经抓住了 agent 的“本质二元性”:
- 一方面它必然有硬编码结构(调度逻辑、协议解析、工具调用、错误处理、状态管理),因为这些是必须可靠运行的,不可能完全丢给 LLM 去“自由发挥”。
- 另一方面,它可以借助语言模型来做更复杂的判断(例如:用户意图识别、选择用哪个工具、如何组合工具),这时它看起来就像“一个具备智能的东西”。
所以说 agent 并不是完全的 LLM,也不是完全的硬编码,它通常是两者的结合。
你现在的倾向(“硬编码 + 语言模型结合”)其实正是目前学术界和工业界对 agent 的共识。
从学术/专业角度怎么理解 Agent?
在学术和工程里,“agent”这个词有几个比较典型的定义:
-
AI Agent(人工智能代理)
- 定义:能感知环境、做出决策、并采取行动的自主系统。
- 出处:Russell & Norvig 的经典教材《Artificial Intelligence: A Modern Approach》。
- 特征:感知 (perception) → 推理/规划 (reasoning/planning) → 行动 (action)。
-
LLM Agent(大模型代理,较新的概念)
-
定义:基于语言模型的推理能力,通过一个 control loop(控制循环) + 外部工具调用机制 来完成任务。
-
特征:
- 硬编码部分:控制循环(prompt 注入、结果解析、工具调用、错误重试…)。
- 智能部分:LLM 负责意图识别、工具选择、参数填充、结果解释。
-
代表论文:
- ReAct (2022): “Reasoning and Acting with LLMs”,首次提出 LLM 可以同时输出思维链和动作调用。
- LangChain Whitepaper: 定义了 Agent = LLM + 工具接口 + 控制逻辑。
- Voyager (2023, Minecraft Agent): 展示了如何结合 LLM 和工具不断探索环境。
-
-
Multi-Agent Systems(多智能体系统)
- 定义:一组 agent 协同工作,各自有目标和能力,通过通信与协作解决复杂任务。
- 相关研究:OpenAI “AutoGPT”“BabyAGI”,以及近期很多关于多智能体协作的论文。
你的问题对应的答案
-
是不是纯硬编码? ❌ 不是。
硬编码部分只负责 框架 & 协议执行(比如 MCP 初始化、固定格式的工具调用)。 -
是不是纯语言模型? ❌ 不是。
语言模型虽然强大,但它不稳定、不可靠,必须有一层硬编码逻辑兜底。 -
那它是什么? ✅ Agent = 硬编码框架 + LLM 的智能结合。
- 硬编码保证 “能跑、能调度、能对接 MCP”。
- LLM 提供 “智能决策能力(用哪个工具、怎么解释用户需求)”。
推荐的学习/研究资源 📚
我帮你整理几个层次:
入门级(直观理解)
-
LangChain Docs: Agents
👉 https://python.langchain.com/docs/modules/agents/
解释了为什么需要 agent,agent 是如何通过“工具 + LLM + 控制循环”来工作的。 -
ReAct 论文 (Reason+Act, 2022)
👉 https://arxiv.org/abs/2210.03629
很经典,提出让 LLM 同时生成“思维链 (Thought)”和“动作 (Action)”,几乎是所有现代 agent 框架的思想源头。
中级(更工程化)
-
OpenAI Function Calling Blog (2023)
👉 https://openai.com/research/function-calling-and-other-api-updates
展示了 LLM 如何以结构化方式调用函数,跟 agent 的工具调用逻辑非常类似。 -
LangChain Whitepaper (2023)
👉 https://arxiv.org/abs/2306.10312
里面有完整的“Agent = LLM + 工具 + 控制器”的框架定义。
高级(研究视角)
-
Voyager (2023, Minecraft)
👉 https://voyager.minedojo.org/
展示了一个真正“自主探索环境”的 LLM agent。 -
AutoGPT / BabyAGI
这些是开源项目,强调 “自主规划 + 工具调用”,很多学术论文引用它们作为 baseline。 -
Russell & Norvig《Artificial Intelligence: A Modern Approach》
AI 教科书,里面有“agent 的定义和分类”(反应式 agent、基于目标的 agent、基于效用的 agent、学习型 agent)。
最后给你一个直观的比喻 🎯
- 大模型 (LLM):像一个很聪明但随性的人,可以给建议、可以想办法,但有时胡说八道。
- 硬编码部分 (Agent Framework):像一份固定的“公司制度/流程手册”,规定了文档格式、工单提交流程、签字顺序,不能改。
- Agent(组合体):聪明人按照公司制度办事 → 他能自己选择怎么完成工作,但制度保证了他不会乱来。
要是你愿意,我可以帮你画一个Agent 架构图,把 硬编码部分 和 LLM 智能部分标出来,这样你一眼就能看到两者是怎么结合在一起的。
要不要我帮你画这个图?
更多推荐
所有评论(0)