Agent = LLM + Harness:用Python代码跑一遍就懂了

📅 2026/6/26 2:28:32
Agent = LLM + Harness:用Python代码跑一遍就懂了
2026年很多Agent产品爆火了从OpenClaw到Hermes再到Codex、Workbuddy等这些Agent突然闯入了我们的工作和生活中。人们都在谈Agent那Agent到底是什么NVIDIA GTC 台北2026中黄仁勋给出了以下解释AgentLLMHarness。谈一下我的理解LLM相当于人类的大脑Harness相当于人的四肢与感官LLM提供思考能力感官与四肢可以与现实进行互动。从定义来看Agent能够感知环境、进行决策并执行行动以达成特定目标。有这么一个公式Agent LLM (大脑) Planning (规划) Tool use (执行) Memory (记忆)。相较于传统的软件Agent更像是一个有自主性的员工他可以理解用户的任务目标制定计划、使用工具、根据情况调整、持续执行直到完成任务。这里提一个实际的Agent任务例子比如我让Agent帮我打车到公司Agent会先分析这是一个使用APP的任务拆解任务为1. 找到打车软件 2. 输入目的地 3. 下单然后模拟用户操作去完成下单每次操作截图使用视觉模型分析当前页面及下一步要点击的位置直到页面显示正在呼叫司机。在这个例子中LLM负责思考Planning负责拆解任务Tool Use负责完成具体操作Memory负责记住用户的信息比如公司位置、打车平台偏好等。ReAct模式Reasoning Act提到Agent不得不说ReAct模式即ReasoningAct可以理解为边思考边行动。ReAct模式是常见的Agent推理执行模式通常分为以下步骤Thought思考LLM理解任务并拆解任务判断下一步操作Action行动Harness使用工具完成相应的任务Observation观察程序将工具执行返回给LLMLLM基于结果判断下一步Repeat循环重复1-3直到LLM认为任务已完成并给出最终答案对应前边我们提到的AgentLLMHarnessAgent能力上限不仅仅取决于LLM还取决于Harness的设计以及LLMHarness这个套餐适配程度。之前看到一个观点LLM厂商通常会对自家Harness做针对性优化在这个背景下原厂LLM原厂Harness理论上会更稳定。我写了一个Agent ReAct模式的代码工具是计算器用户提问内容是“帮我算一下 6 * 5 六 等于多少再计算这个结果乘以 2最后告诉我答案”源代码放到文末了先看打印输出打印输出 第 1 次调用 [1] system 你是一个简洁的 Agent。需要计算时使用 calculator 工具。 [2] user 帮我算一下 6 * 5 六 等于多少再计算这个结果乘以 2最后告诉我答案 tools definitions { type: function, function: { name: calculator, description: 用于执行简单数学计算, parameters: { type: object, properties: { expression: { type: string, description: 要计算的数学表达式例如2 3 * 4 } }, required: [ expression ] } } } LLM 返回内容先算第一个表达式6 * 5 6 LLM 返回 tool call tool_call_id: call_00_guHDSVstflmqe6hru9rZ9277 name: calculator arguments: {expression: 6 * 5 6} LLM tool call 执行内容 tool_call_id: call_00_guHDSVstflmqe6hru9rZ9277 name: calculator arguments: {expression: 6 * 5 6} tool 执行结果36 第 2 次调用 [1] system 你是一个简洁的 Agent。需要计算时使用 calculator 工具。 [2] user 帮我算一下 6 * 5 六 等于多少再计算这个结果乘以 2最后告诉我答案 [3] assistant 先算第一个表达式6 * 5 6 [4] tool 36 tool_call_id: call_00_guHDSVstflmqe6hru9rZ9277 tools definitions 省略 tools definitions LLM 返回内容再计算 36 × 2 LLM 返回 tool call tool_call_id: call_00_dvhsq8Jk5Lm6504Afrg19236 name: calculator arguments: {expression: 36 * 2} LLM tool call 执行内容 tool_call_id: call_00_dvhsq8Jk5Lm6504Afrg19236 name: calculator arguments: {expression: 36 * 2} tool 执行结果72 第 3 次调用 [1] system 你是一个简洁的 Agent。需要计算时使用 calculator 工具。 [2] user 帮我算一下 6 * 5 六 等于多少再计算这个结果乘以 2最后告诉我答案 [3] assistant 先算第一个表达式6 * 5 6 [4] tool 36 tool_call_id: call_00_guHDSVstflmqe6hru9rZ9277 [5] assistant 再计算 36 × 2 [6] tool 72 tool_call_id: call_00_dvhsq8Jk5Lm6504Afrg19236 tools definitions 省略 tools definitions LLM 返回内容计算结果如下 1. **6 × 5 6** 30 6 **36** 2. **36 × 2** **72** 最终答案是 **72** ✅ 最终结果: 计算结果如下 3. **6 × 5 6** 30 6 **36** 4. **36 × 2** **72** 最终答案是 **72** ✅代码执行过程分析在这个代码执行过程中我们来分析一下Thought阶段 LLM接收到用户的指令帮我算一下 6 * 5 六 等于多少再计算这个结果乘以 2最后告诉我答案以及tool定义后LLM判断需要执行计算返回了第一个tool callAction阶段 程序调用eval来执行tool call生成结果Observation阶段程序将结果追加到messages中用于LLM后续思考Thought阶段LLM读取上一轮Observation发现任务未完成返回第二个tool callAction阶段程序调用eval来执行tool call生成结果Observation阶段程序将结果追加到messages中用于LLM后续思考Final Answer阶段LLM读取上一轮Observation判断任务已完成直接生成最终答案最后本文我们了解了Agent是什么以及它的工作原理纸上得来终觉浅真正上手后还能体会到Agent与LLM的不同。最后我来推荐几个用的还不错的AgentCodex推荐指数5星拥有Computer Use、浏览器操作功能的桌面Agent既可完成工作也可以编写代码免费用户有额度订阅用户经常会重置用量好评WorkBuddy推荐指数4星半腾讯家的桌面Agent有免费额度可用可以用于工作和生活中容易上手推荐所有人使用是当前国内最热的Agent之一Github Copilot程序开发推荐指数4星半有免费额度作为IDE插件代码补全很好用也可以对代码提问Claude Code程序开发推荐指数4星定位是开发者工具编程领域强大缺点是需要购买LLM、对普通办公用户不太友好。但是如果你是开发者并已经订阅了Coding Plan那它的推荐指数可以给到5星Claude Code已经成为CLI编程Agent的标杆产品。附源码importosimportjsonfromopenaiimportOpenAI clientOpenAI(api_keyos.getenv(DEEPSEEK_API_KEY),base_urlhttps://api.deepseek.com)defcalculator(expression:str)-str:try:resulteval(expression,{__builtins__:{}})returnstr(result)exceptExceptionase:returnf计算失败{e}tools[{type:function,function:{name:calculator,description:用于执行简单数学计算,parameters:{type:object,properties:{expression:{type:string,description:要计算的数学表达式例如2 3 * 4}},required:[expression]}}}]tool_map{calculator:calculator}defprint_messages(messages):打印当前完整对话上下文print(\n 当前 messages )fori,minenumerate(messages,1):print(f\n[{i}] role:{m.get(role)ifisinstance(m,dict)elsem.role})ifisinstance(m,dict):print(fcontent:{m.get(content)})ifm.get(tool_call_id):print(ftool_call_id:{m.get(tool_call_id)})else:print(fcontent:{m.content})ifm.tool_calls:print(tool_calls:)fortcinm.tool_calls:print(f id:{tc.id})print(f name:{tc.function.name})print(f arguments:{tc.function.arguments})print(\n)defdedupe_repeated_content(content:str)-str:normalizedcontent.strip()ifnotnormalized:returncontentiflen(normalized)%20:first_halfnormalized[:len(normalized)//2].strip()second_halfnormalized[len(normalized)//2:].strip()iffirst_halfandfirst_halfsecond_half:returnfirst_half linesnormalized.splitlines()iflen(lines)%20:halflen(lines)//2first_half_lines[line.rstrip()forlineinlines[:half]]second_half_lines[line.rstrip()forlineinlines[half:]]iffirst_half_linessecond_half_lines:return\n.join(first_half_lines).strip()paragraphs[p.strip()forpinnormalized.split(\n\n)ifp.strip()]iflen(paragraphs)%20:halflen(paragraphs)//2ifparagraphs[:half]paragraphs[half:]:return\n\n.join(paragraphs[:half])returncontentdefbuild_full_prompt(messages,toolsNone):构建完整 prompt 文本包含 messages 和 tools 定义prompt_chunks[]fori,minenumerate(messages,1):ifisinstance(m,dict):rolem.get(role)contentm.get(content,)else:rolem.role contentm.content prompt_chunks.append(f[{i}]{role}\n{content})ifisinstance(m,dict)andm.get(tool_call_id):prompt_chunks.append(ftool_call_id:{m[tool_call_id]})iftools:prompt_chunks.append(\n tools definitions )fortoolintools:prompt_chunks.append(json.dumps(tool,ensure_asciiFalse,indent2))return\n.join(prompt_chunks)defrun_agent(user_input:str):messages[{role:system,content:你是一个简洁的 Agent。需要计算时使用 calculator 工具。},{role:user,content:user_input}]round_num1whileTrue:print(f\n 第{round_num}次调用 )print(build_full_prompt(messages,toolstools))responseclient.chat.completions.create(modeldeepseek-v4-flash,messagesmessages,toolstools,tool_choiceauto)# 提取调用返回的 token 统计信息方便后续调试和成本分析usagegetattr(response,usage,None)ifusageisNoneandisinstance(response,dict):usageresponse.get(usage,{})prompt_tokensusage.get(prompt_tokens)ifisinstance(usage,dict)elsegetattr(usage,prompt_tokens,None)completion_tokensusage.get(completion_tokens)ifisinstance(usage,dict)elsegetattr(usage,completion_tokens,None)total_tokensusage.get(total_tokens)ifisinstance(usage,dict)elsegetattr(usage,total_tokens,None)# print(f本次调用 token 统计输入{prompt_tokens}输出{completion_tokens}总计{total_tokens})# 解析 LLM 响应消息并把重复输出内容去重后打印msgresponse.choices[0].message dedupeddedupe_repeated_content(msg.content)print(fLLM 返回内容{deduped})ifmsg.tool_calls:print(LLM 返回 tool call)fortcinmsg.tool_calls:print(f tool_call_id:{tc.id})print(f name:{tc.function.name})print(f arguments:{tc.function.arguments})messages.append(msg)# 如果没有 tool call则认为已经获得最终回答ifnotmsg.tool_calls:returnmsg.content# 处理每个 tool call打印调用内容、执行工具、记录 Observationfortool_callinmsg.tool_calls:tool_nametool_call.function.name argsjson.loads(tool_call.function.arguments)print(LLM tool call 执行内容)print(f tool_call_id:{tool_call.id})print(f name:{tool_name})print(f arguments:{args})resulttool_map[tool_name](**args)print(ftool 执行结果{result})messages.append({role:tool,tool_call_id:tool_call.id,content:result})round_num1if__name____main__:answerrun_agent(帮我算一下 6 * 5 六 等于多少再计算这个结果乘以 2最后告诉我答案)print(\n)print(最终结果: answer)