前言

Agent 这个词很容易被讲玄。我的理解很简单:普通聊天模型主要是在回答问题,而 Agent 需要围绕目标做计划、调用工具、观察结果,再继续下一步。它不是只说“应该怎么做”,而是尽量真的把事情往前推进。

例如“帮我分析这个仓库的启动方式并修一个报错”,一个 Agent 可能会先列目录、读 README、运行测试、定位错误、改代码、再次验证。这里的关键不是模型说得多聪明,而是它能在环境里行动。

Agent 的基本循环

一个常见循环是 Plan、Act、Observe、Reflect。先根据目标制定下一步,然后调用工具执行,接着读取工具返回的结果,再决定是否继续。ReAct 论文里提出把 reasoning traces 和 actions 交织起来,让模型边推理边行动,这个思路后来影响了很多 Agent 框架。

这个循环看着简单,工程上却很考验边界。工具调用失败怎么办?执行结果太长怎么办?模型连续走偏怎么办?这些都需要框架层处理,而不能只靠一句“你要认真思考”。

工具设计比模型更重要

Agent 的能力很大程度取决于工具。工具命名要清楚,入参要结构化,输出要可读,权限要收紧。比如 delete_file 这种工具一定要谨慎,最好先做 dry-run 或要求二次确认。

我更倾向先给 Agent 提供只读工具和低风险操作:搜索代码、读取文件、运行测试、查询日志。等观察链路稳定后,再逐步开放写入和部署动作。

如何判断一个 Agent 靠谱

不能只看它回答像不像人,而要看它能不能稳定完成任务。可以准备一组固定任务:查资料、改一个小 bug、生成一份报告、根据日志定位异常。每个任务都要有明确的成功标准。

另外要保留轨迹日志。Agent 每一步为什么调用这个工具、拿到了什么观察结果、基于什么继续下一步,都应该能追溯。没有轨迹的 Agent 很难调试,也很难让用户信任。

任务拆解要可执行

好的计划不是一串空泛动词,比如“分析项目、优化代码、完善文档”。这些话人看着舒服,但工具无法执行。更好的拆解应该接近操作步骤:读取 README、搜索 TODO、运行测试、修改某个文件、再次运行测试、生成总结。

目标:修复登录接口 500

可执行计划:
1. 搜索最近的错误日志,定位异常堆栈
2. 根据堆栈打开对应文件
3. 查找相关测试或复现入口
4. 修改最小代码
5. 运行相关测试
6. 汇总变更和风险

不可执行计划:
- 深入分析登录模块
- 优化异常处理
- 提升系统稳定性

这也是为什么很多 Agent 框架会强调 task decomposition。不是为了让模型显得更会思考,而是为了把复杂目标拆成可执行、可观察、可验证的小块。

一个最小 Agent 循环

下面是一个最小化伪代码。它没有复杂框架,只展示 Agent 的骨架:模型决定 action,系统执行工具,观察结果再喂回模型。

MAX_STEPS = 8

def run_agent(goal):
    messages = [
        {"role": "system", "content": "你是一个谨慎的任务执行助手。"},
        {"role": "user", "content": goal},
    ]

    for step in range(MAX_STEPS):
        decision = llm.plan_next_action(messages, tools=TOOLS)
        if decision.type == "finish":
            return decision.final_answer

        if decision.tool_name not in TOOLS:
            messages.append({"role": "tool", "content": "unknown tool"})
            continue

        result = TOOLS[decision.tool_name](**decision.arguments)
        messages.append({
            "role": "tool",
            "name": decision.tool_name,
            "content": result.to_json()
        })

    return "已达到最大执行步数,需要人工确认下一步。"

真实系统还要有权限检查、工具超时、重试策略、成本控制、人工确认和审计日志。但核心循环就是这样:计划、行动、观察,然后继续。理解这个骨架,比一开始研究一堆框架名更重要。

记忆和状态不要混在一起

Agent 系统里经常提 memory,但我觉得要先区分两件事:任务状态和长期记忆。任务状态是这次任务已经做了什么、工具返回了什么、下一步要做什么;长期记忆是跨任务复用的偏好、经验和知识。

{
  "task_id": "fix-login-500",
  "steps": [
    {
      "tool": "search_logs",
      "args": { "keyword": "NullPointerException" },
      "result": { "matches": 3 },
      "status": "ok"
    }
  ],
  "constraints": ["不改数据库结构", "只修复登录接口"],
  "done": false
}

有了这种状态记录,Agent 即使中断也能恢复;任务失败时,也能复盘是第几步出了问题。对于执行型系统来说,可回放性非常关键。

小结

Agent 是把模型能力和工具执行结合起来的工程系统。它的难点不只是 prompt,而是工具边界、任务拆解、记忆管理、失败恢复和验证闭环。独立开发者做 Agent,最好从一个窄场景开始,比如“自动整理 issue”或“代码仓库问答+小修复”,不要一上来就做全能助手。

参考资料:ReAct: Synergizing Reasoning and Acting in Language Models