简介:本文从工程视角拆解AI编程Agent的核心构成,围绕“模型之外的一切”这一关键命题,系统梳理Prompt编排、工具调用、上下文管理、记忆系统与子Agent协调等模块的职责与协作方式,帮助开发者理解为何Agent能力必须依赖独立可迭代的工程层,以及如何在自己的项目中设计类似的Agent架构。
大语言模型的能力在过去两年里飞速提升,代码生成、逻辑推理、多语言理解等基准测试上的表现不断刷新。但当你真正把一个大模型放进真实的软件工程任务里,会发现一个尴尬的事实:它只能接收 token,输出 token。
它不知道刚才建议修改的那个文件到底改对了没有,不知道测试套件是否通过,不知道上一轮报错的具体堆栈信息被丢到了哪里。它甚至不知道自己已经连续尝试了五次相同的修复方案,而每次都以同样的方式失败。
这意味着,无论模型本身多强,要让它成为一个能实际“干活”的编程 Agent,光靠模型是不够的。必须在模型之外搭建一套工程脚手架,把模型的输出与真实世界的执行结果连接起来,形成闭环。这套脚手架,业界通常称之为 Harness 层。
用一个简洁的公式来表达:
Model + Harness = Agent
模型提供推理与生成能力,Harness 提供执行、反馈、记忆与控制能力。二者结合,才构成一个完整的编程 Agent。
如果把模型比作一台高性能发动机,那么 Harness 就是传动系统、仪表盘、冷却系统和方向盘的总和。没有它,发动机再强也无法驱动车辆前行。
从工程实现的维度看,Harness 层至少需要覆盖以下几个核心模块。
模型不会自动理解一个代码仓库的结构。它需要有人把代码库的目录树、关键模块的职责说明、项目的编码规范、当前任务的描述、历史对话的摘要等信息,整理成模型能够消化的输入格式。
这项工作远比“拼一个字符串”复杂。它涉及:
# 示意:上下文组装的基本逻辑def build_context(task, repo_index, conversation_history):relevant_files = repo_index.search(task.keywords, top_k=20)repo_structure = repo_index.get_tree(max_depth=3)project_rules = load_project_conventions()context = {"system": project_rules,"repo_tree": repo_structure,"relevant_code": [f.read_snippet() for f in relevant_files],"history_summary": summarize(conversation_history),"current_task": task.description}return format_for_model(context)
模型本身不能执行 shell 命令、不能读写文件、不能运行测试。Harness 层需要提供一套工具接口,把模型输出的“意图”翻译成真实的系统操作。
典型的工具集合包括:
关键在于,这些工具的执行结果必须被结构化地回传给模型,而不是简单的“成功/失败”。比如测试失败时,需要把失败的测试用例名、断言信息、堆栈跟踪都整理好,作为下一轮对话的输入。
一个真实的编程任务往往需要多轮修改才能完成。Harness 层需要设定合理的迭代策略:
多轮对话和大型代码库很容易撑爆模型的上下文窗口。Harness 需要具备摘要能力:
这是 Harness 最核心的价值之一。当测试失败时,Harness 需要:
# 示意:测试失败后的反馈组装def on_test_failure(test_result, model_context):feedback = {"failed_tests": test_result.failed_cases,"error_logs": test_result.stderr,"screenshot": test_result.screenshot_path,"previous_attempts": model_context.recent_diffs}model_context.append_feedback(feedback)return model_context
对于复杂的工程任务,单个 Agent 可能不够用。Harness 层可以支持:
一个自然的问题是:为什么不把这些逻辑直接写进模型里,让模型自己学会调用工具、管理上下文?
原因在于迭代速度的不匹配。
模型训练一次需要大量的计算资源和时间,周期通常以月为单位。而 Harness 层的工程实践迭代非常快——今天发现一种更好的上下文组织方式,明天就可以上线验证;这周发现某个工具接口设计不合理,下周就能重构。
如果把 Agent 逻辑写死在模型里,每次调整都需要重新训练,这在工程上不可接受。分离 Harness 层,意味着工程团队可以独立于模型团队快速试错、持续优化。
此外,Harness 层还承担了安全性、可控性和可观测性的职责。比如限制模型可以执行的命令范围、记录每一步操作的审计日志、在出现异常时及时熔断。这些都不是模型本身擅长的事情。
如果你正在设计自己的 AI 编程 Agent,以下几点值得参考:
第一,把工具接口设计成幂等且可组合的。 每个工具应该职责单一,输入输出明确,便于模型理解和组合调用。
第二,反馈信息要丰富但不过载。 回传给模型的错误信息需要包含足够的定位线索,但也要做适当的摘要和过滤,避免把无关的噪音塞进去。
第三,迭代控制要有硬性边界。 设定最大轮次、最大 token 消耗、最大执行时间等硬限制,防止失控。
第四,记忆系统要分层设计。 不是所有信息都值得记住,也不是所有记忆都需要每次都加载。按任务相关性动态管理记忆的存取。
第五,可观测性从一开始就要考虑。 记录每一轮的输入输出、工具调用结果、模型决策路径,便于调试和优化。
AI 编程 Agent 的能力上限,不仅取决于底层模型有多强,更取决于 Harness 层设计得有多好。Prompt 编排、工具调用、迭代控制、上下文摘要、测试反馈、记忆系统、子 Agent 协调——这些模块共同构成了“模型之外的一切”,也正是它们让一个只会输出 token 的模型,变成一个能真正完成工程任务的 Agent。
理解 Harness 层的职责与设计原则,对于任何想要构建或使用 AI 编程 Agent 的开发者来说,都是不可或缺的基础认知。