
你的 AI 并不蠢——它只是少了一套框架
AI AGENT SYSTEM DESIGN
有个创业者朋友最近跟我抱怨,说他花了两个月调一个大模型 agent,结果上线第一天就崩了。"这模型根本不靠谱,"他说,"我让它写一份市场分析,做到第七步就开始胡编数据,第十步直接输出了一堆乱码。"
我问他:"你用什么约束它?"
他愣了一下。"约束?什么约束?我就是给了它一个 prompt,让它自己跑。"
这不是他的问题。这是大多数人在 AI 时代犯的同一个错误。
01问题的根源不在马,在缰绳
过去两年,行业形成了一种默契:AI 出故障,是因为提示词不够好。"再精准一点,"大家想,"再加点约束在 prompt 里。"但对于需要自主执行多步任务的人来说,这条路走到某个地方就过不去了。
问题的本质不是模型能力不够,而是你的系统设计少了执行层。
一个真正的生产级 agent 系统,模型不是终点——它是一匹马。你需要的不只是骑术,还需要一副缰绳。
02约束,而不是指令
怎么让模型输出合法的 JSON?多数人的做法是这样:
# 多数人的做法:祈祷prompt = """请以合法的 JSON 格式返回结果,示例:{"name": "xxx", "price": 100}一定要确保格式正确,不要出错。"""
结果模型有时候输出 {"name": "xxx", "price": "100"}——字符串而不是数字。你的下游代码一跑就崩,但你不知道哪里错了。
真正有效的是代码能执行的那种约束:
# 少数人的做法:代码强制from jsonschema import validate, ValidationErrorschema = { "type": "object", "properties": { "name": {"type": "string"}, "price": {"type": "number"} # 明确要求是数字,不是字符串 }, "required": ["name", "price"]}try: validate(instance=model_output, schema=schema)except ValidationError as e: # 直接打回去重试,不让错误继续传播 model_output = retry_with_feedback(model_output, e.message)
这不是语言模型的问题,是工程的基本逻辑。提示词里说"请"字是没有任何工程意义的。
同样的逻辑可以推广到整个系统:
你在 prompt 里写:"不要让 agent 重复调用工具""确保每次搜索返回相关结果""不要让 agent 忘记上下文"正确做法:在编排层设置最大调用次数,超限直接停止工具层加 BM25 排序,只返回 top-k 结果状态外化到磁盘,每个 step 写入 state.json
约束的意思是:代码能做到的,别拜托模型自觉。
03你不能让模型自己给自己打分
有个反直觉的现象:让 AI 评价自己的工作,它往往打分很高。不是因为它骄傲,而是因为它不知道自己错了——评判者和生成者共享同一套权重。
这和人类不一样。人类评审代码的时候,就算完全沿用生成者的思路,也知道最终产出的代码能不能跑。模型不知道。
所以评估层必须独立,而且必须执行。你不能只是让它"看看输出对不对",你得让它真的去跑、去验证:
# 差的做法:让模型自评rating = llm.evaluate("这段代码写得怎么样?")# 模型永远说"写得很好"
# 好的做法:独立评估 + 实际执行def evaluate_code(output): # 1. 模式验证:格式对不对 try: validate_json_schema(output) except: return "FAIL", "JSON 格式错误" # 2. 实际执行:代码能不能跑 result = subprocess.run(["python", output["script_path"]], capture_output=True) if result.returncode != 0: return "FAIL", f"运行时错误: {result.stderr}" # 3. 单元测试:逻辑对不对 test_result = subprocess.run(["pytest", output["test_path"]]) if test_result.returncode != 0: return "FAIL", f"测试未通过" return "PASS", "代码正确执行"
评估必须执行,不能只是判断。
04上下文太满,模型就开始走神
当上下文窗口用到 70% 以上,很多模型会开始跳过步骤、草草收尾。它不是累了,但是表现得像累了。
解决方式:强制上下文重置。
# 监控上下文使用率,超70%就重启if (tokens_used / max_context) > 0.7: # 保存状态到磁盘 save_state_to_disk(state) # 终止当前实例 terminate_current_instance() # 用干净上下文重启 new_agent = launch_fresh_agent(state)
这像给电脑重装系统——在一个越来越臃肿的系统上打补丁,不如重启一个干净的。
05七层是个目标,不是起点
说了七层框架,你可能觉得这是大公司的专利。不是。最小可行版本半天能搭出来:
# 四个组件,半天能搭完# 1. state.json——跟踪任务状态,崩了能从断点恢复class TaskState: def __init__(self): self.state = {"status": "pending", "completed_steps": []} def save(self): with open("state.json", "w") as f: json.dump(self.state, f)# 2. 重试包装器——失败只重试当前 step,不拖累全流程@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1))def safe_tool_call(tool_fn, *args): return tool_fn(*args)# 3. Schema 验证器——格式错误直接打回,不让错误传播def validate_and_retry(output): try: validate(instance=output, schema=schema) return output except ValidationError: return retry_with_feedback(output, error_feedback)# 4. 工具输出截断——硬限制 token,不让上下文爆炸def truncate_tool_output(raw_output, max_tokens=3000): return raw_output[:max_tokens] # 简单但有效的截断
做到了这些,你的 agent 就有了最基础的缰绳。然后你才有资格让它变得更聪明。
未来属于会造缰绳的人
模型的参数每年都在涨。未来几年,它们能自主完成的任务会越来越复杂。
但当模型能替你写代码的时候,你的价值不在于 prompt 写得有多好,而在于告诉它什么时候该写、什么时候该停、失败了该怎么恢复。
这不是提示词的艺术。这是系统设计的艺术。
未来十年最成功的人,不是 prompt 写得最好的人——是能在模型周围造出可靠系统的人。
就像汽车发明之后,最重要的不只是开车的人——还有造刹车系统的人。
而刹车,是用代码写的。
— END —
夜雨聆风