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

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

2026年很多Agent产品爆火了,从OpenClaw到Hermes,再到Codex、Workbuddy等,这些Agent突然闯入了我们的工作和生活中。人们都在谈Agent,那Agent到底是什么?NVIDIA GTC 台北2026中,黄仁勋给出了以下解释:Agent=LLM+Harness。谈一下我的理解,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模式,即Reasoning+Act,可以理解为边思考边行动。ReAct模式是常见的Agent推理执行模式,通常分为以下步骤:

  1. Thought(思考):LLM理解任务并拆解任务,判断下一步操作
  2. Action(行动):Harness使用工具完成相应的任务
  3. Observation(观察):程序将工具执行返回给LLM,LLM基于结果判断下一步
  4. Repeat(循环):重复1-3,直到LLM认为任务已完成并给出最终答案

对应前边我们提到的Agent=LLM+Harness,Agent能力上限不仅仅取决于LLM,还取决于Harness的设计,以及LLM+Harness这个套餐适配程度。之前看到一个观点,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** ✅

代码执行过程分析

在这个代码执行过程中,我们来分析一下:

  1. Thought阶段: LLM接收到用户的指令:"帮我算一下 6 * 5 + 六 等于多少,再计算这个结果乘以 2,最后告诉我答案"以及tool定义后,LLM判断需要执行计算,返回了第一个tool call
  2. Action阶段: 程序调用eval来执行tool call,生成结果
  3. Observation阶段:程序将结果追加到messages中,用于LLM后续思考
  4. Thought阶段:LLM读取上一轮Observation,发现任务未完成,返回第二个tool call
  5. Action阶段:程序调用eval来执行tool call,生成结果
  6. Observation阶段:程序将结果追加到messages中,用于LLM后续思考
  7. Final Answer阶段:LLM读取上一轮Observation,判断任务已完成,直接生成最终答案

最后

本文我们了解了Agent是什么以及它的工作原理,纸上得来终觉浅,真正上手后还能体会到Agent与LLM的不同。最后我来推荐几个用的还不错的Agent:

  1. Codex,推荐指数5星,拥有Computer Use、浏览器操作功能的桌面Agent,既可完成工作也可以编写代码,免费用户有额度,订阅用户经常会重置用量(好评)
  2. WorkBuddy,推荐指数4星半,腾讯家的桌面Agent,有免费额度可用,可以用于工作和生活中,容易上手,推荐所有人使用,是当前国内最热的Agent之一
  3. Github Copilot(程序开发),推荐指数4星半,有免费额度,作为IDE插件,代码补全很好用,也可以对代码提问
  4. Claude Code(程序开发),推荐指数4星,定位是开发者工具,编程领域强大,缺点是需要购买LLM、对普通办公用户不太友好。但是,如果你是开发者并已经订阅了Coding Plan,那它的推荐指数可以给到5星,Claude Code已经成为CLI编程Agent的标杆产品。

附源码

importosimportjsonfromopenaiimportOpenAI client=OpenAI(api_key=os.getenv("DEEPSEEK_API_KEY"),base_url="https://api.deepseek.com")defcalculator(expression:str)->str:try:result=eval(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(f"content:{m.get('content')}")ifm.get("tool_call_id"):print(f"tool_call_id:{m.get('tool_call_id')}")else:print(f"content:{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:normalized=content.strip()ifnotnormalized:returncontentiflen(normalized)%2==0:first_half=normalized[:len(normalized)//2].strip()second_half=normalized[len(normalized)//2:].strip()iffirst_halfandfirst_half==second_half:returnfirst_half lines=normalized.splitlines()iflen(lines)%2==0:half=len(lines)//2first_half_lines=[line.rstrip()forlineinlines[:half]]second_half_lines=[line.rstrip()forlineinlines[half:]]iffirst_half_lines==second_half_lines:return"\n".join(first_half_lines).strip()paragraphs=[p.strip()forpinnormalized.split("\n\n")ifp.strip()]iflen(paragraphs)%2==0:half=len(paragraphs)//2ifparagraphs[:half]==paragraphs[half:]:return"\n\n".join(paragraphs[:half])returncontentdefbuild_full_prompt(messages,tools=None):"""构建完整 prompt 文本,包含 messages 和 tools 定义"""prompt_chunks=[]fori,minenumerate(messages,1):ifisinstance(m,dict):role=m.get("role")content=m.get("content","")else:role=m.role content=m.content prompt_chunks.append(f"[{i}]{role}\n{content}")ifisinstance(m,dict)andm.get("tool_call_id"):prompt_chunks.append(f"tool_call_id:{m['tool_call_id']}")iftools:prompt_chunks.append("\n=== tools definitions ===")fortoolintools:prompt_chunks.append(json.dumps(tool,ensure_ascii=False,indent=2))return"\n".join(prompt_chunks)defrun_agent(user_input:str):messages=[{"role":"system","content":"你是一个简洁的 Agent。需要计算时使用 calculator 工具。"},{"role":"user","content":user_input}]round_num=1whileTrue:print(f"\n=== 第{round_num}次调用 ===")print(build_full_prompt(messages,tools=tools))response=client.chat.completions.create(model="deepseek-v4-flash",messages=messages,tools=tools,tool_choice="auto")# 提取调用返回的 token 统计信息,方便后续调试和成本分析usage=getattr(response,"usage",None)ifusageisNoneandisinstance(response,dict):usage=response.get("usage",{})prompt_tokens=usage.get("prompt_tokens")ifisinstance(usage,dict)elsegetattr(usage,"prompt_tokens",None)completion_tokens=usage.get("completion_tokens")ifisinstance(usage,dict)elsegetattr(usage,"completion_tokens",None)total_tokens=usage.get("total_tokens")ifisinstance(usage,dict)elsegetattr(usage,"total_tokens",None)# print(f"本次调用 token 统计:输入={prompt_tokens},输出={completion_tokens},总计={total_tokens}")# 解析 LLM 响应消息,并把重复输出内容去重后打印msg=response.choices[0].message deduped=dedupe_repeated_content(msg.content)print(f"LLM 返回内容:{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_name=tool_call.function.name args=json.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}")result=tool_map[tool_name](**args)print(f"tool 执行结果:{result}")messages.append({"role":"tool","tool_call_id":tool_call.id,"content":result})round_num+=1if__name__=="__main__":answer=run_agent("帮我算一下 6 * 5 + 六 等于多少,再计算这个结果乘以 2,最后告诉我答案")print("\n============================================")print("最终结果: "+answer)

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

相关文章:

  • 企业数字化转型 AI 智能体解决方案哪家强? 2026全球主流Agent架构实测对比与落地指南
  • 2026年程序员学量化开发,先慢下来理清规则
  • aily blockly IDE尝鲜封神,实战硬伤尽显
  • Transformer组件级工程指南:从Attention实现到显存优化
  • 反序列化漏洞:从原理到防护的深度解析
  • 数据解封装:一条网络消息,怎样从网卡走到你的程序
  • 技术实现:如何利用Sherlock.js构建自然语言事件解析解决方案
  • RAG创新了,MCompassRAG装上了语义指南针
  • Faster-Whisper-GUI技术适配突破:日语语音识别6.3倍性能提升的实现路径
  • 如何免费制作专业PPT:PPTist在线演示文稿工具终极指南
  • 对话聊天(Chatbot)
  • LangGraph图编排底层原理:状态、节点与边的工程实践
  • 蓝速科技 10.1 寸会议预约门牌:小尺寸终端的大场景智慧落地方案
  • PVE Tools终极指南:让Proxmox VE管理变得简单高效的完整工具箱
  • LLM混合架构优化:量化、剪枝与蒸馏的工程化协同
  • 近期碎片0625
  • 一个传统企业老板的自白
  • TrollInstallerX:基于双漏洞利用机制的TrollStore部署方案
  • 从CWE到CVE:构建主动安全防御体系的核心逻辑与实践
  • RuntimeError: CUDA out of memory warming up sampler with 64 dummy requests——vLLM V1 引擎 OOM 排障指南
  • 被坑惨了!TypeScript 类型体操实战:我用 3 行代码干掉了 2000 行的 if-else
  • 从零构建异构高性能计算集群:Kubernetes与Ceph实战指南
  • ChatGPT嵌入DAM系统:自然语言驱动数字资产智能操作
  • 深圳市弹簧微久智造蜘蛛手编带机供应商
  • Linux命令-pwconv(从 /etc/passwd 创建 /etc/shadow 影子密码)
  • FRSM V6 Dense MoE vs Transformer — 全维度技术报告
  • 最新量化实现别急着扩功能,先跑通 API 小流程
  • 【读书笔记】《跨越不可能》
  • 智能工程师中的方案设计与优化分析
  • 福州全屋定制售后真相:为什么本地品牌比连锁大牌更靠谱?