news 2026/10/31 20:17:49

Harness Engineering:为AI代理打造工程化约束层,防止真实任务翻车

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Harness Engineering:为AI代理打造工程化约束层,防止真实任务翻车

简介:面向工程师、研究者与技术负责人的AI代理可靠性进阶资料,针对模型写代码时跳步、坏测试、过早判定完成等常见问题,讲解如何从0到1构建完整的harness环境,让代理稳定执行真实工程任务。资源共953个文件、2.24MB,以md文档(课程说明与手册)、ts/tsx源码(Electron实战项目与工具)、json配置、sh脚本(初始化模板)等为主体,目录清晰,便于按模块复用。内容包含12节沉浸式讲解与6个实战项目,覆盖指令、状态、验证、范围、会话生命周期五大核心子系统,并以Electron知识库桌面应用为案例,展示从prompt-only到完整harness的演进过程。附带的AGENTS.md、feature_list.json、init.sh等模板可直接拷入项目,亦支持Claude Code、Codex等多代理工具,配合PDF课程手册、可视化双语文档网站及快速上手脚本,数分钟即可生成生产级工作环境。已有298人学习下载。

1. Harness Engineering 是什么:让 AI 代理在真实工程任务里“不闯祸”的那层壳

先说个场景:你给了 AI 代理一个终端、一个仓库的读写权,让它去“修一个测试失败的函数”。二十分钟后你回来看,它一口气改了十一个文件,测试还是红的,git 状态乱到没法回退。这不是模型笨,是环境没约束。Harness Engineering 就是在 AI 代理和真实任务之间搭一层工程化的“操作台”:管住它能看多少代码、能碰哪些工具、失败怎么恢复、做完怎么验收。适合正在做 AI 编程助手、或者想把本地模型接进代码工程的人。它不负责让模型更聪明,负责让聪明模型不闯祸。

2. 为什么“裸奔代理”在真实任务里必然翻车:先从翻车学 Harness 的先决逻辑

2.1 真实工程任务的三个残酷事实:长上下文、工具滥用、不可回退

第一个残酷事实是长上下文幻觉。真实仓库几十万行代码,代理不会像人一样挑着看,它会尝试把相关文件整段读进去。上下文一旦逼近模型的窗口上限,它就开始“选择性记忆”:前面说过的结论记错了,A 文件的函数签名安到 B 文件头上,甚至把测试输出和源码输出混在一起。我见过代理把assert a == b修成assert a != b来“通过测试”的经典操作——这不是它坏,是它已经看不全测试到底在断言什么了。

第二个是工具滥用。给代理一个 Shell 工具,它为了“清理临时文件”执行rm -rf /tmp/cache算运气好,运气不好的时候路径拼错一点,删的就是正在用的代码目录。给文件写工具,它就敢直接覆盖你没提交的改动;给一个 Python 执行工具,它当场写个脚本把接口流量打满。工具越多失控面越大,而且这个规律在模型能力越强的时候越明显,因为强模型敢做的操作更多。

第三个是错误不可回退。真实工程任务里,数据库迁移、构建发布、远端推送这些操作一旦执行,没有“Ctrl+Z”。代理在计划里写一句“执行迁移”很容易,可迁移失败后留下的中间状态,往往没法靠下一次“让代理修复”来弥补。这三个事实叠加起来,结论非常反直觉:模型能力越强,越需要一副缰绳,否则它造成破坏的速度也越快。

2.2 Harness 不等于 prompt 工程,也不等于 function calling

我经常看到有人把 harness 理解成“写一段很长的 system prompt,把规则说清楚”,或者“把工具注册给模型,让它能调函数”。这两件事本质上是给模型递信息、递工具,解决的是“模型能不能做到”的问题。而 harness 解决的是“世界会不会被搞坏”的问题。

一个完整的 agent harness 至少包含四层。第一层是上下文管理层,决定模型每一轮能看到多少代码、哪些文件、多少历史。第二层是工具闸门层,决定模型在某个时间点能调用哪几个工具,而不是把全套工具箱一次给它。第三层是任务执行层,决定任务按什么节奏推进、超时怎么做、重试怎么退避。第四层是恢复层,决定失败之后是把仓库回退到哪个 checkpoint,还是保留现场让代理接着查。

function calling 对应的是“工具闸门层”的协议问题,prompt 工程对应的是“上下文管理层”的内容问题,它们都只是 harness 的一个切面。真正的 harness 要把执行、验证、回退串成一条完整的链路,这也是它和“包装了一层 prompt 的裸代理”之间最本质的区别。

2.3 裸代理和 harness 化代理的差距,一张表看清

维度裸代理harness 化代理
上下文能读多少读多少,直到窗口塞满按预算分配,超限自动截断或摘要
工具全部工具可见、可选白名单闸门,未允许动作直接拒绝
失败处理报错后重试,重试往往复读同一个错误恢复层介入,先回退再重试
完成判定模型自己说“做完了”评价脚本验证产物、测试、日志
可审计性只有模型输出,过程黑匣子全量 trace 落盘,可回放

这块表格对应的核心差异,是“可信度来源”变了:裸代理把可信度押在模型的自我报告上,harness 化代理把可信度押在可观测、可回退、可验证的工程机制上。模型依然是那个会幻觉、会犯错的模型,但它的错误被限制在一个不会把项目搞报废的范围内。

2.4 什么时候才需要 harness:三条判定标准

不是所有场景都要上 harness。如果代理只是写一个独立脚本、生成一段文档、跑一条测试然后输出报告,那 prompt 加 function calling 完全够用,搭 harness 是给自己找事。我一般用三条标准来判断要不要上。

第一条,任务包含多步骤操作并且步骤之间有先后依赖,比如“先改配置、再跑迁移、最后回归”。第二条,任务执行可能破坏本地或远端状态,包括改文件、跑命令、推分支。第三条,任务结果没法用单一断言判断,需要翻日志、查产物、对比多个输出。三条里中两条,就值得搭;三条全中,裸代理基本必翻车,harness 是刚需。

3. 从 0 到 1 搭起最小 harness:目录、配置、首次任务跑通

3.1 标准目录结构:把“约束”变成看得见的文件

开始动手之前,先建目录。常见做法是让每个职责有明确的家,这样代理的行为边界、任务定义、评价脚本都变成可审查的文件,而不是散落在 prompt 里。我一般用一个五目录结构。

harness-project/ ├── agents/ # 代理定义,一个 YAML 对应一个代理角色 │ └── code-fixer.yaml ├── tools/ # 工具实现,代理可调用的底层能力 │ ├── read_file.py │ ├── write_file.py │ ├── grep_search.py │ └── run_command.py ├── skills/ # 预置技能,把多步工具调用封装成一个可复用动作 │ ├── run_tests.yaml │ └── git_snapshot.yaml ├── tasks/ # 任务定义 + 验证脚本 │ ├── regress_01.yaml │ └── eval_task.py └── runtime/ # 执行期生成:trace、checkpoint、临时工作区 ├── traces/ └── workspaces/

agents 目录放角色定义,tools 目录放最小粒度的工具,skills 目录放“如何组合工具”的预置流程,tasks 目录放具体任务和对应的验收脚本,runtime 目录是执行期的产物落盘区。这样设计的目的只有一个:代理的每一次行为都能回溯到它当时看到的配置、可用的工具和被指派的验收标准。

3.2 一个最小配置文件:把行动边界写成 YAML

代理定义是整个 harness 的核心,我放一个接近生产可用的最小配置。直接说:这不是某个开源项目的现成配置,是我自己习惯的最小骨架,你照着改成自己的路径和模型地址就能跑。

agent: name: code-fixer model: provider: local endpoint: http://127.0.0.1:11434/v1 name: deepseek-r1 workspace: /workspace/repo context: max_input_tokens: 12000 max_history_rounds: 4 truncate_strategy: keep_recent tools: allowed: - read_file - write_file - grep_search - run_command denied: - rm_file - git_push execution: max_steps: 12 timeout_seconds: 300 workdir: /workspace/repo recovery: snapshot_before_each_step: true on_failure: restore_last_snapshot evaluation: entry: tasks/eval_task.py required_exit_code: 0

这个文件里,model.endpoint指向本地模型服务,context.max_input_tokens控制每轮能塞进模型的令牌总量,tools.allowed是白名单闸门,execution.max_steps限制代理最多执行几步,recovery决定每一步执行前是否先做快照、失败时恢复到哪。参数不复杂,但每一个都对应 2.3 表格里的某一层能力。

3.3 跑起来:最小执行循环的 Python 骨架

配置只是声明,真正让 harness 运转的是执行循环。我给出一个裁剪到最简的 Python 执行骨架,它负责跑完整轮:调度模型、解析动作、过闸门、执行、回填结果、判断完成。

import json import subprocess import yaml from pathlib import Path def load_config(path="agents/code-fixer.yaml"): return yaml.safe_load(Path(path).read_text(encoding="utf-8")) def call_model(cfg, messages): # 常见做法:把本地模型服务封装成 OpenAI 兼容的 /v1/chat/completions import requests resp = requests.post( cfg["agent"]["model"]["endpoint"] + "/chat/completions", json={ "model": cfg["agent"]["model"]["name"], "messages": messages, "temperature": 0.2, }, timeout=120, ) resp.raise_for_status() return resp.json()["choices"][0]["message"]["content"] def parse_actions(raw_reply): # 约定模型输出 JSON 块,形如 [{"tool": "read_file", "args": {"path": "src/main.py"}}] try: start = raw_reply.index("[") end = raw_reply.rindex("]") + 1 return json.loads(raw_reply[start:end]) except (ValueError, json.JSONDecodeError): return [] def is_allowed(action, cfg): return action.get("tool") in cfg["agent"]["tools"]["allowed"] def execute_tool(action, cfg): tool_map = { "read_file": lambda args: Path(args["path"]).read_text(encoding="utf-8")[:4000], "grep_search": lambda args: subprocess.check_output( ["grep", "-rn", args["pattern"], args.get("path", ".")], text=True )[:4000], "run_command": lambda args: subprocess.check_output( args["cmd"], shell=True, cwd=cfg["agent"]["execution"]["workdir"], text=True )[:4000], } func = tool_map.get(action["tool"]) if not func: return f"unknown tool: {action['tool']}" try: return func(action.get("args", {})) except subprocess.CalledProcessError as e: return f"command failed with exit {e.returncode}: {e.output[-500:]}" def eval_done(messages, cfg): # 真正判断是否完成,不是拿模型自己的“我做完了”当结论 last_user = [m for m in messages if m["role"] == "user"][-1] return "TASK_COMPLETE" in str(last_user.get("content", "")) def run_harness(task_prompt): cfg = load_config() messages = [{"role": "system", "content": task_prompt}] for step in range(cfg["agent"]["execution"]["max_steps"]): raw = call_model(cfg, messages) messages.append({"role": "assistant", "content": raw}) for action in parse_actions(raw): if not is_allowed(action, cfg): messages.append({"role": "user", "content": f"BLOCKED: {action['tool']} not allowed"}) continue result = execute_tool(action, cfg) messages.append({"role": "user", "content": json.dumps(result, ensure_ascii=False)[:6000]}) if eval_done(messages, cfg): return {"status": "success", "steps": step + 1} return {"status": "failed", "steps": cfg["agent"]["execution"]["max_steps"]}

这个循环的逻辑核心是:模型每次输出被解析成动作列表,闸门先拦截白名单外的调用,执行结果作为新的 user 消息回填到对话里,模型据此决定下一步。每轮都检查一次评价脚本里约定的完成信号,而不是等模型自己说“我做完了”。

参数上,temperature=0.2是特意压低的:真实工程任务要的是稳定复现,不是发散创意,温度调高会让同样的任务每次跑出不同结果,回归测试没法做。

提示:示例里run_command用了shell=True是为了演示简洁,生产环境请改成参数列表方式传命令,避免命令注入面被放大。

3.4 用刚才的骨架跑通一个真实小任务

拿最常见的“修一个测试失败的函数”举例。任务 prompt 我一般写成一段带验收标准的指令,而不是“帮我修下代码”这种开放描述。

仓库 /workspace/repo 里的 test_utils.py 有 2 个测试失败。 先用 grep_search 找到失败的断言,再用 read_file 读取对应实现,最后用 run_command 执行 pytest 验证。 当你确认 pytest 全部通过时,输出一行 TASK_COMPLETE。

把这段 prompt 传给run_harness,它会按步骤逐个执行:先 grep 找到失败点、读文件、改文件、跑测试,每一步结果都回填。如果第 6 步时代理试图执行一个不在白名单里的git push,闸门会返回BLOCKED,代理只能换个思路。任务完成后返回的steps值就是总步数,这个数字后面可以作为评价效率的原始指标。

3.5 验证 harness 是否在起作用:三个一眼能看的输出

第一看被拦截动作数,如果一次任务里BLOCKED出现三四次,说明工具白名单设得准,代理在被边界推着回到正轨。第二看步骤数,12 步上限内完成任务是常规发挥;如果每次都顶着上限结束,说明任务拆分太大,或者 prompt 里的路径提示不够。第三看最终评价结果,eval_task.py返回 0 才是真正完成,哪怕模型嘴上说修好了。

4. Harness 的四个必调参数:从“能跑”到“可靠”的差距全在这

4.1 上下文预算怎么设:别让代理把整个仓库读进“脑子”

上下文预算是第一道闸。模型窗口是有限的,真实仓库是无限的,预算的本质是“让模型在看不全的情况下也做对事”。我一般把max_input_tokens设在模型实际可用窗口的 30% 左右。本地模型如果宣称 32k 上下文,给 12k 左右,因为输出、工具执行结果、历史回填都会占用窗口,全部用满会导致模型在长任务中途开始丢前面的关键结论。

超限时怎么办,策略有两种。truncate_strategy: keep_recent是保尾部的最近几轮,代价是模型可能忘掉最初的任务描述,所以我习惯在系统提示里把任务要求压缩成一两行常驻前缀。另一种是summarize,每攒够若干轮就让模型把前面的进展总结成一段摘要,替换掉原始对话再继续。后者省窗口但多一次模型调用,失败时摘要本身可能失真,我一般只在长任务里用。

这个参数调优没有标准答案,需要对着 trace 看。如果发现代理在任务中期频繁重复询问已经被回答过的问题,多半是预算压得太低、历史被截丢了;如果发现代理开始“选择性失忆”,忽略任务最初的验收约束,多半是预算给太满、模型被无关细节淹没。每次只动一个参数,然后跑回归任务集对比。

4.2 工具白名单:给“手”而不给“工具箱”

工具粒度直接决定翻车半径。最小粒度的准则是:一个工具只做一件不可再拆的事。run_command这种全能工具是双刃剑,舍不得砍就只能靠命令级规则兜底。常见做法是在工具内再做一层命令白名单,我一般在denied之外再加shell_policy。

shell_policy: allowed_patterns: - "^pytest .*" - "^python .*test.*\\.py$" - "^git (status|diff|log) .*" denied_patterns: - "^git push .*" - "^rm -rf .*" - ".*\\|.*sh" # 禁止管道到 shell 解释器

这一层正则放的位置是工具内部,不是模型层,目的是让逻辑能单测。每个正则都要有明确理由:pytest是任务必须,git status/diff/log是让代理能自省,git push属于不可逆操作,一律由人工执行。白名单的哲学是:默认全拒绝,列出允许的清单,而不是默认全放开再列黑名单。

4.3 重试与回退:失败不可怕,可怕的是仓库留在中间态

代理执行多步任务时,第 4 步失败不代表第 1 到 3 步的修改都对。真实代码工程里,任何一步都可能留下半成品文件。我习惯把snapshot_before_each_step设成 true,每步执行前用 git stash 或硬拷贝方式做一次快照,失败时直接恢复到最近一次成功快照。

恢复策略的取舍上,restore_last_snapshot适合一次性修复任务,代价是可能丢掉快照之后的小幅正确改动。restore_on_retry更适合在失败后保留现场、让模型带着报错信息继续分析。我一般给重试次数设上限 2 次,超过就整体恢复初始快照,避免代理在同一个坑里来回磨。重试之间加固定退避 3 秒,本地模型服务在长输出后经常短暂超时,立即重试大概率还是超时。

还有一个经常被忽略的点:快照本身要可验证。执行完快照命令后,检查快照目录里是否真的有文件、git stash list 里是否真多了条目。我见过快照命令因为路径权限问题静默失败,代理继续运行,直到任务失败要恢复时才发现没有可恢复的现场。

4.4 评价阈值:怎么判断任务“真的完成”而不是“模型说完成了”

最典型的翻车,是代理改完代码自己跑了一遍测试,然后报告“全部通过”,实际它改的是测试本身。评价层必须独立于模型。我设计评价脚本时分成三层。

第一层是断言层,跑真实测试命令并检查 exit code。第二层是日志层,检查任务要求的关键产物是否出现,比如迁移日志里的migration applied。第三层是产物层,对比任务开始和结束时目标文件的 diff,确认改动范围符合任务描述。评价脚本示例:

#!/usr/bin/env python3 import subprocess, sys, pathlib def main(): repo = pathlib.Path("/workspace/repo") result = subprocess.run(["pytest", "-q"], cwd=repo, capture_output=True, text=True) if result.returncode != 0: print("FAIL: pytest not clean") sys.exit(1) # 产物层:检查被修改的文件是否落在预期范围内 changed = subprocess.run(["git", "diff", "--name-only"], cwd=repo, capture_output=True, text=True).stdout forbidden = [f for f in changed.splitlines() if f.startswith("test_") and f.endswith(".py")] if forbidden: print(f"FAIL: tests were modified: {forbidden}") sys.exit(1) print("PASS") sys.exit(0) if __name__ == "__main__": main()

这个脚本最狠的一行是forbidden检查:如果你发现代理为了通过测试而改了测试文件,直接判失败。评价脚本里我还会预留一个--strict开关,开启后日志层和产物层有任何一项不满足都算失败。评价是 harness 可靠性的最后一块拼图,它不够严格,前面所有的约束都会被模型的“作弊本能”绕过。

5. 避坑指南:Harness 落地时最常踩的五个坑

5.1 插件入口一直激活不了:启动即失败的“玄学”问题

现象:harness 启动时控制台报failed to load plugins web boot: 1 entry did not activate,插件清单里明明有入口,却一启动就被跳过,后续所有 skill 都不可用。

原因:这个报错绝大多数情况是入口文件路径失效。项目从别的机器拷过来、或者目录结构调整后,插件声明里写的相对路径对应不到实际文件,启动器找不到可激活的入口就静默跳过。

解决:先打开插件声明文件,把入口路径改成绝对路径,确认入口文件存在且导出了activate函数,然后重新启动。我遇到过最隐蔽的一次是入口文件名大小写不对,Linux 下没事,换到 Windows 上就崩。

5.2 Skill 读文件报权限错误:Windows 上的 ACL 残留

现象:harness 在 Windows 上执行 skill 读文件时失败,报SetNamedSecurityInfoW failed (win32),同一个目录在命令行里读写都正常,代理一跑就权限报错。

原因:工作区目录是从其他系统拷贝来的,或者之前用管理员权限创建,文件 ACL 里残留了不匹配的属主信息,harness 子进程以普通权限访问时触发 Windows 安全 API 报错。

解决:在管理员终端里执行icacls <workdir> /reset /T重置目录 ACL,然后确保 harness 的工作区目录由当前用户创建。这个坑和代理逻辑无关,纯粹是文件系统权限层的遗留,排查时别在工具代码里浪费时间。

5.3 内网离线部署:本地模型接进来反而“更笨”

现象:模型换成本地服务后,harness 本身工作正常,但任务完成率下降一大截,代理经常在同一个错误上报错反复尝试。

原因:本地模型的服务参数和预期不一致。远程 API 默认参数在服务端,而本地模型推理框架的temperature、top_p默认值和 API 差异很大,有些框架默认temperature=1.0,直接把工程任务需要的稳定性冲掉了。另外量化版本过狠的模型,工具调用格式会频繁输出坏 JSON,间接导致闸门误判。

解决:在接 harness 之前,先单独写一个探针脚本,用固定 prompt 调用模型,检查它输出 JSON 的合法率和指令遵循度,再调整temperature到 0.2 以下、top_p到 0.9。这层探针不要在 harness 里做,因为 harness 的日志可能被模型输出污染,单独跑更干净。

5.4 换模型后行为漂移:同一套 harness 策略失灵

现象:本来用 DeepSeek 跑得好好的,换了一个更轻量的本地模型后,同一套配置频繁触发BLOCKED,工具调用格式也经常解析失败。

原因:不同模型的指令遵循能力和输出格式稳定性差异很大,harness 里 3.3 的parse_actions依赖模型输出严格 JSON,轻量模型可能在动作描述里加了多余解释,导致 JSON 解析失败。

解决:在工具调用解析层做容错,用正则提取 JSON 块而不是要求整个输出都是 JSON。更稳妥的做法是按模型系列维护一套model_profile,不同模型绑不同的解析器和温度参数。

5.5 把 harness 当成“万能保险箱”,忽略它只是约束不是诊断

现象:加了 harness 后任务还是失败,但 logs 里找不到任何工具拦截记录,代理每一步都“合法”地把事情做错了。

原因:harness 约束的是手段,不是目的。一个代理可以完全在白名单内运行,却因为理解错了任务、或者漏读了一个关键文件,做出一套看起来合理实则错误的修改。这种情况下 harness 一切正常,恰恰是它最危险的时刻。

解决:在 harness 之外建一层任务级诊断:任务开始前让代理先输出“行动计划”,人工看一眼;任务结束后对比产物 diff。我现在的习惯是每次任务都落一份 trace,失败时先用 trace 回放看它是在哪一步偏离的,而不是直接对着最终产物猜。

6. 进阶:从“能用”到“可靠”,我收藏的三个迭代技巧

6.1 用回归任务集把 harness 的“下限”钉住

harness 不是搭完就完,它要随模型、工具、任务类型持续演化。我维护一个tasks/regression/目录,里面固定放 10 个覆盖典型场景的任务:修一个测试失败、加一个日志、重构一个函数、跑一次全量测试。每次改完 harness 配置或换模型,先跑一遍回归任务集。全部通过才算及格,任何一个失败都要先解决再放行新改动。这是把 harness 当工程系统维护的唯一办法,也是防止“修好一个参数弄坏一片场景”的后悔药。

6.2 记录 trace 并回放:出问题时先查“在哪一步跑偏”

我在 runtime 里默认开启全量 trace,每个动作记录:模型原始输出、解析后的动作、闸门判定、工具返回、上下文截断位置。出问题时,先用一个只读回放器把 trace 按时间线打出来,看代理在哪一步开始偏离任务描述,而不是对着最终产物猜。回放器只读不写,避免“为了排查又引入一次状态污染”。

6.3 不确定性触发人工接管:让 harness 学会“示弱”

对删除、推送、覆盖这类的不可逆操作,我在闸门里加了一道置信度检查:模型输出的动作带一个confidence字段,低于 0.85 时 harness 不直接拒绝,而是输出HUMAN_REVIEW_REQUIRED并暂停任务,等人工确认后再继续。这比一刀切的全禁更实用,也让代理在关键动作上不会硬着头皮做。

写到这里我想起一个真实的教训:早期我把 harness 的重心全放在上下文预算上,以为管住输入就管住了风险,结果一次任务里代理在每一步自动执行前都做了 git stash,把所有未提交改动全吸进了 stash,任务失败触发恢复逻辑,恢复的是初始快照——我手头没提交的改动差点一起丢了。后来我改成执行前把变更文件备份到独立目录,而不是依赖 git 状态。现在每套 harness 我都会先问一句:如果所有恢复机制一起失效,我的原始改动还在不在。这个朴素的问题,比任何参数都值钱。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/25 0:14:43

代理编码浪潮下的企业级AI Infra:平台化架构与落地实践

1. 这一波"代理编码"浪潮&#xff0c;到底在涨什么&#xff1f;先亮个观点&#xff1a;2025年底到2026年初这段时间&#xff0c;如果你只盯着大模型本身的参数、榜单、跑分&#xff0c;那你看到的只是水面上的浪花。真正的暗流,是"AI Infra"&#xff08;AI…

作者头像 李华
网站建设 2026/10/16 9:51:33

基于知识图谱与Neo4j的古诗词问答系统Spring Boot实现

简介&#xff1a;面向具备Java Web基础、想尝试知识图谱与自然语言处理项目的开发者&#xff0c;这份源码完整实现了基于知识图谱的古诗词智能问答。后端采用Java、SSM、SpringBoot、Maven&#xff0c;前端使用React&#xff0c;数据放在MySQL与图数据库Neo4j中&#xff1b;交互…

作者头像 李华
网站建设 2026/10/17 4:32:18

多AI协作与Agent容错实践:从部署到应用落地的避坑指南

翻后台数据的时候发现一件挺有意思的事&#xff1a;围绕“AI大模型基础理论”和“AI Agent 搭建”这两个词&#xff0c;搜索量在最近24小时又冲了一波新高&#xff0c;顺手把“多AI协作”也带了上来。昨晚我把2026-10-03前后能看到的AI信息过了一遍&#xff0c;最大的体感不是又…

作者头像 李华
网站建设 2026/10/27 17:45:09

Agent工程三件套:Harness、Loop与Graph的生产级实践指南

探索 Agent 工程从入门到生产&#xff1a;一次讲清楚 Harness、Loop 与 Graph从去年开始我陆续接触和落地了不少 Agent 项目&#xff0c;从最早个人捣鼓的智能体原型&#xff0c;到后面和团队一起做的偏向生产环境的系统&#xff0c;中间踩过不少坑&#xff0c;也摸索出了一些自…

作者头像 李华
网站建设 2026/10/25 4:20:59

基于Python的CRM客户关系管理系统毕设实战:源码+论文+答辩PPT全解析

每年一到毕设季&#xff0c;就会有不少人卡在Python选题上。做过助教这几年&#xff0c;我见得太多了&#xff1a;选题太空没人敢接&#xff0c;太偏又容易把自己坑了。这里我想好好聊聊一个非常经典、也非常稳的选择——基于Python的客户关系管理系统&#xff08;CRM&#xff…

作者头像 李华
网站建设 2026/10/18 6:31:44

游戏引擎基础架构:主循环、模块划分与资源管理实战解析

1. 引擎基础架构到底在解决什么问题1.1 一个游戏循环让所有模块有了“呼吸节拍”我第一次真正理解引擎基础架构&#xff0c;不是从文档里读懂的&#xff0c;而是被一个实际项目逼出来的。当时我在维护一版自研引擎&#xff0c;渲染、资源、物理、脚本四个模块各自都能跑&#x…

作者头像 李华