ai-agent-book 精选快照(<2MB 代码与文档,来自 github.com/bojieli/ai-agent-book)
Build latest book artifacts / build (push) Canceled after 0s
dependency resolution / resolve (3.11) (push) Canceled after 0s
dependency resolution / resolve (3.13) (push) Canceled after 0s
deploy-pages / build (push) Canceled after 0s
deploy-pages / deploy (push) Canceled after 0s
i18n consistency check / check (push) Canceled after 0s
provider adoption tests / test (chapter2/context-compression) (push) Canceled after 0s
provider adoption tests / test (chapter2/prompt-injection) (push) Canceled after 0s
provider adoption tests / test (chapter2/system-hint) (push) Canceled after 0s
provider adoption tests / test (chapter3/log-sanitization) (push) Canceled after 0s
web-search-agent tests / test (push) Canceled after 0s
web-search-agent tests / agentbook (push) Canceled after 0s

This commit is contained in:
2026-08-20 13:12:50 +00:00
commit b119135836
10275 changed files with 3284984 additions and 0 deletions
+240
View File
@@ -0,0 +1,240 @@
"""实验 5-11:对话式界面定制系统 —— 端到端演示与自动验证。
本 demo 在"无浏览器"的环境里,把可验证性落在【自然语言 → 代码修改被正确应用】的闭环上:
对每一条自然语言定制需求:
1) 调用真实 OpenAI,让 Agent 定位并改写前端源码(agent.customize);
2) 打印改动前后的 diff 片段(difflib),并把改动写回 frontend/src
3) 读回源码做断言,确认改动"确实符合需求"(颜色值/字体/文案按要求变化);
4) 运行 `npm run build`vite build),确认改动没有破坏应用(可编译通过)。
连续跑多轮(本例 3 轮),验证多轮迭代定制均生效且不破坏构建。
注意:真正"浏览器内 HMR 的视觉即时刷新"需手动 `npm run dev` + 打开浏览器查看;
本 demo 自动验证的是"代码修改被正确应用,且构建始终通过"
运行:
python demo.py # 跑全部 3 轮定制并做完整验证
python demo.py --quick # 只跑第 1 轮(省时,用于快速冒烟)
python demo.py --rounds 2 # 只跑前 2 轮
python demo.py --no-build # 跳过 vite build(仅验证"改动被正确应用"
python demo.py -h # 查看全部参数
"""
import sys
import shutil
import difflib
import argparse
import subprocess
from pathlib import Path
import agent
HERE = Path(__file__).resolve().parent
FRONTEND = HERE / "frontend"
BASELINE = HERE / "baseline" # 前端源码的初始快照,保证 demo 可重复运行
# ---------------------------------------------------------------------------
# 每一轮的定制需求 + 对应的验证函数。
# verify(sources) 接收 {相对路径: 改写后内容},返回 (是否通过, 说明)。
# ---------------------------------------------------------------------------
def _all_text(sources: dict) -> str:
return "\n".join(sources.values())
ROUNDS = [
{
"requirement": "把发送按钮和用户消息气泡的主题色从绿色改成蓝色,用 #2563eb 这个蓝。",
"verify": lambda s: (
"#2563eb" in _all_text(s).lower().replace("#2563EB".lower(), "#2563eb"),
"源码中出现蓝色值 #2563eb",
),
},
{
"requirement": "把整个界面的字体换成等宽字体(monospace)。",
"verify": lambda s: (
"monospace" in _all_text(s).lower(),
"源码中出现 monospace 等宽字体",
),
},
{
"requirement": "把顶部的标题文案改成“我的专属客服”。",
"verify": lambda s: (
"我的专属客服" in _all_text(s),
"源码中出现新标题文案“我的专属客服”",
),
},
]
def restore_baseline():
"""把 frontend/src 下的可编辑文件恢复为初始快照,保证可重复运行。"""
for rel in agent.EDITABLE_FILES:
src = BASELINE / rel
dst = FRONTEND / rel
dst.parent.mkdir(parents=True, exist_ok=True)
shutil.copyfile(src, dst)
def ensure_node_modules():
"""确保依赖已安装;首次 npm install 较慢属正常现象。"""
if (FRONTEND / "node_modules").exists():
return
print(">> 未发现 node_modules,正在执行 npm install(首次较慢,请耐心等待)…")
r = subprocess.run(["npm", "install"], cwd=FRONTEND)
if r.returncode != 0:
raise SystemExit("npm install 失败,请检查 Node/npm 环境。")
def run_build() -> bool:
"""运行 vite build,返回是否编译通过。"""
r = subprocess.run(
["npm", "run", "build"],
cwd=FRONTEND,
capture_output=True,
text=True,
)
tail = (r.stdout + r.stderr).strip().splitlines()
for line in tail[-6:]:
print(" | " + line)
return r.returncode == 0
def print_diff(rel: str, old: str, new: str):
"""打印一个文件改动前后的 unified diff 片段(最多若干行)。"""
diff = list(
difflib.unified_diff(
old.splitlines(),
new.splitlines(),
fromfile=f"a/{rel}",
tofile=f"b/{rel}",
lineterm="",
)
)
if not diff:
print(f" {rel} 无变化)")
return
shown = 0
for line in diff:
if line.startswith("+++") or line.startswith("---") or line.startswith("@@"):
print(" " + line)
elif line.startswith("+"):
print(" \033[32m" + line + "\033[0m") # 绿:新增
shown += 1
elif line.startswith("-"):
print(" \033[31m" + line + "\033[0m") # 红:删除
shown += 1
else:
continue # 省略上下文行,只看真正改动
if shown >= 20:
print(" …(diff 片段已截断)")
break
def parse_args(argv=None):
"""解析命令行参数:控制跑几轮、是否跳过构建。"""
parser = argparse.ArgumentParser(
description="实验 5-11:对话式界面定制系统 —— NL → 代码修改 闭环验证。"
"对每条自然语言 UI 定制需求,让 Agent 改写前端源码,"
"并断言改动生效、vite build 不被破坏。",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument(
"--quick",
action="store_true",
help="快速模式:只跑第 1 轮定制(等价于 --rounds 1)。",
)
parser.add_argument(
"--rounds",
type=int,
default=None,
metavar="N",
help=f"只跑前 N 轮定制(1..{len(ROUNDS)});默认跑全部。",
)
parser.add_argument(
"--no-build",
action="store_true",
help="跳过 vite build,仅验证'改动被正确应用'(更快,但不校验构建)。",
)
return parser.parse_args(argv)
def main(argv=None):
args = parse_args(argv)
# 决定本次运行的轮次数:--quick 优先,其次 --rounds,默认全部。
limit = len(ROUNDS)
if args.quick:
limit = 1
elif args.rounds is not None:
limit = max(1, min(args.rounds, len(ROUNDS)))
rounds = ROUNDS[:limit]
do_build = not args.no_build
print("=" * 72)
print("实验 5-11:对话式界面定制系统 —— NL → 代码修改 闭环验证")
print("=" * 72)
client, model = agent.build_client_and_model()
print(f"模型: {model}")
print(f"本次运行轮次: {limit}/{len(ROUNDS)} 构建验证: {'开启' if do_build else '关闭'}")
restore_baseline()
if do_build:
ensure_node_modules()
print("\n>> 基线构建校验(未定制前,确保应用本身可编译)…")
if not run_build():
raise SystemExit("基线构建失败,请先修复前端工程。")
print(" 基线构建:通过 ✅")
all_pass = True
for i, round_def in enumerate(rounds, 1):
req = round_def["requirement"]
print("\n" + "-" * 72)
print(f"{i} 轮 NL 定制需求:{req}")
print("-" * 72)
old_sources = agent.read_editable_sources(FRONTEND)
# 1) 调用 Agent(真实 OpenAI)得到改写方案
result = agent.customize(client, model, FRONTEND, req)
print(f"Agent 说明:{result.get('summary', '(无)')}")
# 2) 写回 + 打印 diff
changed = {}
for f in result["files"]:
rel = f["path"]
new_content = f["content"]
print(f"\n[改动文件] {rel}")
print_diff(rel, old_sources[rel], new_content)
(FRONTEND / rel).write_text(new_content, encoding="utf-8")
changed[rel] = new_content
# 3) 读回源码断言"改动符合需求"
current = agent.read_editable_sources(FRONTEND)
ok, desc = round_def["verify"](current)
print(f"\n断言:{desc} -> {'通过 ✅' if ok else '失败 ❌'}")
if not ok:
all_pass = False
# 4) 构建验证"没破坏应用"--no-build 时跳过)
if do_build:
print("构建验证(vite build):")
build_ok = run_build()
print(f" 构建结果:{'通过 ✅' if build_ok else '失败 ❌'}")
if not build_ok:
all_pass = False
else:
print("构建验证(vite build):已跳过(--no-build")
print("\n" + "=" * 72)
print(f"多轮定制总结:{'全部通过 ✅' if all_pass else '存在失败项 ❌'}")
print("提示:手动 `npm run dev` + 打开 http://localhost:5173 可看到 HMR 视觉即时生效。")
print("=" * 72)
return 0 if all_pass else 1
if __name__ == "__main__":
sys.exit(main())