首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >AI Agent 不是"套壳聊天":从工具调用到执行闭环的工程化拆解,附可运行代码

AI Agent 不是"套壳聊天":从工具调用到执行闭环的工程化拆解,附可运行代码

原创
作者头像
资源大佬 jzit-top
发布于 2026-10-17 16:00:15
发布于 2026-10-17 16:00:15
680
举报

AI Agent 的专业内核不是"给大模型加个prompt",而是构建一个能感知、能决策、能行动、能反思、能兜底的闭环系统。核心组件是:工具层(Tool)、记忆层(Memory)、规划层(Planner)、执行循环(Agent Loop)、护栏(Guardrail)与可观测性(Tracing)。下面逐层给可运行代码。

一、工具定义:Schema是Agent的"手"

Agent 能做什么,完全由工具Schema决定。用JSON Schema严格约束参数,模型才能稳定调用。

代码语言:javascript
复制
# tools.py
import json, httpx

TOOLS = [{
  "type": "function",
  "function": {
    "name": "search_docs",
    "description": "检索内部知识库,返回最相关文档片段",
    "parameters": {
      "type": "object",
      "properties": {
        "query": {"type": "string", "description": "检索关键词"},
        "top_k": {"type": "integer", "minimum": 1, "maximum": 10, "default": 3}
      },
      "required": ["query"]
    }
  }
}]

def search_docs(query: str, top_k: int = 3):
    r = httpx.post("http://kb.internal/search", json={"q": query, "k": top_k}, timeout=10)
    r.raise_for_status()
    return r.json()["hits"]

TOOL_IMPL = {"search_docs": search_docs}

工程约束:工具描述要写清"什么时候用、返回什么",参数用enum/minimum锁死范围。工具执行必须带超时和异常捕获,Agent不能因为一个工具挂了就整体崩溃。

二、Agent Loop:ReAct循环是骨架

感知→决策→行动→观察→再决策,直到任务完成或达到步数上限。

代码语言:javascript
复制
# agent_loop.py
import json, openai

def run_agent(goal: str, max_steps: int = 8):
    messages = [
        {"role": "system", "content": "你是任务型Agent。优先调用工具获取事实,不要编造。完成后输出FINAL。"},
        {"role": "user", "content": goal}
    ]
    trace = []
    for step in range(max_steps):
        resp = openai.chat.completions.create(
            model="gpt-4o", messages=messages, tools=TOOLS, tool_choice="auto")
        msg = resp.choices[0].message

        if not msg.tool_calls:                      # 无工具调用 → 认为完成
            trace.append({"step": step, "action": "final", "content": msg.content})
            return msg.content, trace

        messages.append(msg)                        # 记录模型的工具调用意图
        for call in msg.tool_calls:
            name = call.function.name
            args = json.loads(call.function.arguments)
            try:
                result = TOOL_IMPL[name](**args)    # 执行工具
            except Exception as e:
                result = {"error": str(e)}          # 错误回喂给模型自我修正
            trace.append({"step": step, "tool": name, "args": args, "result": result})
            messages.append({"role": "tool", "tool_call_id": call.id,
                             "content": json.dumps(result, ensure_ascii=False)})
    return "达到最大步数,任务未完成", trace

关键点:工具错误必须回喂给模型,让它决定重试、换工具还是放弃;max_steps是成本护栏,防止死循环烧token。

三、记忆:短期靠上下文,长期靠检索

上下文窗口有限,长任务必须做记忆管理:短期记忆存最近N轮,长期记忆落向量库按需召回。

代码语言:javascript
复制
# memory.py
class AgentMemory:
    def __init__(self, max_short=10):
        self.short, self.max_short = [], max_short

    def add(self, role, content):
        self.short.append({"role": role, "content": content})
        if len(self.short) > self.max_short:          # 滑窗淘汰
            evicted = self.short.pop(0)
            self._persist(evicted)                    # 归档到长期记忆

    def recall(self, query, k=3):
        # 从向量库召回相关历史,拼进上下文
        return vector_db.search(query, k=k)

    def _persist(self, item):
        vector_db.upsert(item)

专业点:记忆写入要做去重和摘要,否则长期库充满重复片段,召回质量下降;召回结果要带时间戳,模型才能判断信息新旧。

四、规划与反思:让Agent"先想后做"

复杂任务先拆解成子任务,执行后自检,失败则重规划。

代码语言:javascript
复制
# planner.py
PLAN_PROMPT = """把目标拆成不超过5个可执行子任务,输出JSON:
{"subtasks":[{"id":1,"desc":"...","done":false}]}"""

def reflect(goal, trace, result):
    resp = openai.chat.completions.create(model="gpt-4o", messages=[
        {"role":"system","content":"你是质检员。判断结果是否满足目标,不满足则指出缺什么。"},
        {"role":"user","content":f"目标:{goal}\n执行轨迹:{trace}\n结果:{result}"}
    ])
    return resp.choices[0].message.content   # 返回"PASS"或修改建议

工程约束:反思要限定次数(如最多2轮),否则"反思→重试→再反思"会无限消耗;反思结论要结构化(PASS/FAIL+原因),便于程序判断。

五、护栏与可观测性:上线的前提

代码语言:javascript
复制
# guardrail.py
def guard(action, args):
    if action == "search_docs" and len(args.get("query","")) > 200:
        raise ValueError("query过长")
    if action in {"delete_user","transfer_money"}:   # 高危操作需人工确认
        return "NEED_HUMAN_APPROVAL"
    return "OK"

def trace_span(trace, step):
    # 每步落结构化日志:耗时、token、工具、结果摘要
    log.info({"step": step, "tokens": step_tokens, "tool": trace[-1].get("tool")})

生产级Agent必须有三道护栏:输入护栏(prompt注入检测)、行动护栏(高危操作人工确认)、输出护栏(敏感信息脱敏)。配合全链路trace,才能定位"哪一步决策错了"。

六、评估:没有评测集的Agent等于没做

代码语言:javascript
复制
# eval.py
CASES = [{"goal":"查A产品的退款政策","expect_tool":"search_docs","expect_kw":"7天"}]

def evaluate(agent_fn):
    passed = 0
    for c in CASES:
        ans, trace = agent_fn(c["goal"])
        ok = c["expect_kw"] in ans and any(t.get("tool")==c["expect_tool"] for t in trace)
        passed += ok
    return passed / len(CASES)   # 工具选择正确率 + 答案命中率

评测要覆盖工具选择准确率、任务完成率、步数效率、幻觉率四个维度,每次改prompt或换模型都跑一遍回归。

总结:AI Agent 的专业度不在prompt写得多花,而在工具Schema严格、循环有步数护栏、错误能回喂、记忆会淘汰、反思限次数、高危操作有人工确认、全链路可trace、有评测集回归这八件事。能给别人讲清楚"工具报错后Agent怎么自愈""为什么反思不能无限循环",你就抓住了Agent工程的命门。觉得有用点赞收藏,需要完整工程目录留言。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、工具定义:Schema是Agent的"手"
  • 二、Agent Loop:ReAct循环是骨架
  • 三、记忆:短期靠上下文,长期靠检索
  • 四、规划与反思:让Agent"先想后做"
  • 五、护栏与可观测性:上线的前提
  • 六、评估:没有评测集的Agent等于没做
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档