ATRULE 技术博客ATRULE 技术博客
首页
博客
文档
关于
首页
博客
文档
关于
  • 技术文章

    • VuePress 2.x 完全指南
    • Gemini3 & GPT5 & DeepSeek3:AI时代程序员的身份转变
    • Agent 架构选型指南:单智能体 vs 多智能体
    • Agent 工程师转型学习路线图 (Full-Stack to Agent Engineer)
    • Agent 工程师学习笔记
    • 📖 Agent 系统架构与工程实践面试速记卡片
    • Agent 流式对话前端踩坑记录
    • RAG 检索工程问题记录
    • Agent 后端问题记录(Koa / MongoDB)
    • LLM 调用与 Agent 编排问题记录
    • Electron 桌面端问题排查记录
    • AI Agent 全栈开发问题排查记录
    • ES2026 与 TypeScript 进阶问题记录
    • 浏览器渲染与 V8 内存问题记录
    • React 19 与 Vue 4 新内核问题记录
    • 前端工程化与微前端问题记录
    • 性能、安全与可观测性问题记录
    • 前端架构实战问题记录
  • 项目实战

    • Node.js + Koa 抖音直播弹幕Agent 五大核心模块(面试项目完整版,TS技术栈)★★★★★
    • Poiclaw 项目蓝图:自主编程实体
    • AI旅行助手

LLM 调用与 Agent 编排问题记录

Function Calling 不可信、Agent 会死循环、多 Agent 会互相坑——这些问题手册记录了实际的兜底方案。

问题一:Function Calling 输出幻觉参数,服务直接 500

现象:LLM 调工具时输出 "limit": "十"(中文数字)、漏必填字段、甚至编造不存在的工具名,Python 端解析直接抛异常。

原因:JSON Mode 只保证输出是合法 JSON,不保证字段名对、类型对、值合理。这是 LLM 的固有行为,必须工程兜底。

解决:五层兜底链,从强到弱逐级降级:

def parse_tool_call(llm_output, max_retries=3):
    for attempt in range(max_retries):
        try:
            # 层1:JSON Mode 保证合法 JSON
            # 层2:Pydantic Schema 验证(字段名/类型/必填 + 自动转类型)
            call = ToolCallSchema.model_validate(llm_output["tool_calls"][0])

            # 层3:工具名白名单 + 模糊匹配(容错拼写错误)
            if call.name not in TOOL_REGISTRY:
                matches = get_close_matches(call.name, TOOL_REGISTRY, n=1)
                if not matches:
                    raise ValueError(f"未知工具: {call.name}")
                call.name = matches[0]

            return call
        except ValidationError as e:
            # 层4:把验证错误喂回 LLM 重试(第二次通常能自己纠正)
            llm_output = retry_llm_with_error(e)
    # 层5:降级为自然语言回复,不让用户感知 500
    return None

关键认知:"limit": "十" 这类"类型可转换"的错误,Pydantic 自动转型能救;wikepedia 这类拼写错误,编辑距离模糊匹配能救;真正救不了的是"LLM 编造了不存在的字段"——只能重试 + 降级。

问题二:ReAct Agent 死循环,一晚上烧掉半个月预算

现象:Agent 连续 20 次调用同一个工具、同样的参数,token 一直烧。

原因:ReAct 循环的退出条件是"LLM 自己决定结束",但 LLM 可能陷入重复动作、或者一直说"我快好了"但永远不给最终答案。

解决:多重安全终止,按优先级检查:

def should_continue(state) -> str:
    # 1. 硬性上限:步数、token、耗时 三选一先到先停
    if state["step"] >= state["max_steps"]:
        return "force_answer"

    # 2. 幻觉检测:连续 3 次相同工具+相同参数,强制中断
    calls = state["tool_calls"]
    if len(calls) >= 3 and calls[-1] == calls[-2] == calls[-3]:
        return "force_answer"

    # 3. LLM 主动终止:输出 final_answer(唯一"正常退出"路径)
    if state["last_msg"].get("final_answer"):
        return "answer"

    return "act"

兜底:强制终止后不要丢弃中间结果——让 LLM 基于 state 里已有的工具输出,生成一个"不完整但诚实"的答案,比报错重试体验好得多。

问题三:LangGraph 并发节点写状态,数据悄悄丢了

现象:用 Send() 派发 10 个并行检索任务,各自往 state 的 results: list 里 append,最后 state 里只剩 1 条。

原因:LangGraph 并发节点的状态合并按字段类型决定——普通字段是"后到覆盖先到",没有合并修饰器的 list 字段会被覆盖而不是拼接。

解决:给字段加合并语义:

from typing import Annotated
import operator

class AgentState(TypedDict):
    # add 语义:并发节点的结果自动拼接,不丢
    results: Annotated[list, operator.add]
    # 普通字段:后写覆盖(适合单写场景)
    final_answer: str

延伸:并发变慢的三种根因——CPU 密集任务(GIL 锁死,并发=排队)、LLM API 限流(并发触发 429)、大 State 的合并开销。并发不是银弹。

问题四:多 Agent 流水线,A 发了邮件 B 才发现不该发

现象:Agent A 写邮件并直接发送 → Agent B 审核发现问题 → 但邮件已经发出去了,不可回滚。

原因:副作用操作放在了流水线中间,前面的 Agent 执行了不可逆操作,后面失败无法补偿。

解决:把副作用从 Agent 内部抽到流水线边界——Agent 只产出"决策",最后一个节点统一执行:

错误架构:A(写+发邮件) → B(审核) → C(归档)
正确架构:A(产出草稿) → B(审核) → 执行层(审核通过才发送)

规则:所有"写外部系统"的操作(发邮件、调付费 API、改数据库)都收口到流水线末端;必须中途执行的,准备补偿操作(如邮件撤回 API)。

问题五:1 万人同时问同一个问题,LLM 配额被瞬间打爆

现象:热点事件导致相同 query 洪峰,每条请求都打 LLM,配额秒没,后面全部 429。

解决:请求合并(singleflight)——相同 query 只调一次 LLM,结果缓冲后扇出给所有订阅者:

const pending = new Map() // key: hash(query)

async function coalesce(query) {
  const key = md5(query)

  if (pending.has(key)) {
    // 已有相同请求在生成 → 订阅等待
    return pending.get(key).promise
  }

  // 第一个请求:发起生成,结果广播
  const promise = callLLM(query).finally(() => pending.delete(key))
  pending.set(key, { promise })
  return promise
}

红线:合并 key 绝不能包含用户私有上下文,否则 A 的个性化结果会泄露给 B——只对"纯相同 query"合并,RAG 场景每人上下文不同就合并不了,要诚实接受这个边界。

小结

问题一句话方案
幻觉参数Schema 验证 + 模糊匹配 + 重试 + 降级,五层兜底
ReAct 死循环步数/token/重复动作三重安全终止
并发状态覆盖Annotated[list, operator.add] 合并语义
副作用不可回滚副作用收口到流水线末端统一执行
相同 query 洪峰singleflight 合并 + 结果扇出
最后更新: 2026/9/5 17:19
Prev
Agent 后端问题记录(Koa / MongoDB)
Next
Electron 桌面端问题排查记录