术语先于直觉出现
-第一次看到 LCEL、ReAct 或 Checkpointer 时,定义本身并不能告诉你它为什么存在。
-diff --git a/.env.example b/.env.example
index 4df18d8..c8724e5 100644
--- a/.env.example
+++ b/.env.example
@@ -1,29 +1,8 @@
-# ── 必填:DashScope(通义千问)────────────────────────────────────
-# 注册地址:https://dashscope.aliyuncs.com
-DASHSCOPE_API_KEY=your_dashscope_api_key_here
-DASHSCOPE_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
-
-# ── 可选:覆盖默认模型 ID(默认 qwen-plus)────────────────────────
-# 公网 DashScope 可用:qwen-plus / qwen-max / qwen-turbo
-# DASHSCOPE_MODEL=qwen-plus
-
-# ── 必填:LangSmith 可观测性(免费注册)──────────────────────────
-# 注册地址:https://smith.langchain.com
-LANGCHAIN_TRACING_V2=true
-LANGCHAIN_API_KEY=your_langsmith_api_key_here
-LANGCHAIN_PROJECT=study
-
-# ── 可选:阿里云 OSS(仅 04_project/ 综合项目中用到)──────────────
-# ALIYUN_ACCESS_KEY_ID=your_aliyun_access_key_id
-# ALIYUN_ACCESS_KEY_SECRET=your_aliyun_access_key_secret
-# OSS_BUCKET=your_oss_bucket_name
-# OSS_ENDPOINT=https://oss-cn-xxx.aliyuncs.com
-
-# ── 可选:请求超时与重试 ───────────────────────────────────────────
-# VL_TIMEOUT=6000
-# VL_CONNECT_TIMEOUT=1200
-# VL_MAX_RETRIES=2
-# VL_RETRY_DELAY=5
-
-# ── 可选:代理 ────────────────────────────────────────────────────
-# HTTPS_PROXY=http://127.0.0.1:7890
+# Offline verify does not read this file.
+# Only copy to .env when running an explicitly selected live provider experiment.
+MODEL_PROVIDER=
+MODEL_NAME=
+MODEL_API_KEY=
+MODEL_BASE_URL=
+LANGSMITH_API_KEY=
+LANGSMITH_PROJECT=agent-engineering-lab
diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md
index 1237336..f3d16ea 100644
--- a/.github/ISSUE_TEMPLATE/bug.md
+++ b/.github/ISSUE_TEMPLATE/bug.md
@@ -1,35 +1,45 @@
---
-name: 报错 / Bug
-about: 跑 final/ 或 _scratch/ 时遇到代码报错,且 docs/debug-recipes.md 里没列
+name: Bug / Regression
+about: 报告可复现的合同、runtime、grader、课程或部署问题
title: "[Bug] "
labels: bug
assignees: ''
---
-## 报错来自哪个文件
+## 失败位于哪一层
-- 文件:`final/01_langchain/0X_xxx.py` 或 `_scratch/my_xxx.py`
-- 当时跑的命令:`python final/...` / `python -c "..."`
+- [ ] install / lock
+- [ ] domain contract
+- [ ] tool / retrieval / memory
+- [ ] Workflow / LangChain / LangGraph / Deep Agents
+- [ ] dataset / grader / gate
+- [ ] curriculum / site
+- [ ] deployment
-## 我以为会发生什么
+## 最小复现
-(1-2 句话讲你的预期。这一步比 traceback 更重要——暴露你的心智模型在哪卡住)
+```bash
+# 不含凭证和本机私密路径
+```
-## 实际报错
+涉及 eval 时请填写 suite、case_id、runtime、trial 和 dataset version。
-```
-[贴报错最后 5-10 行 traceback,删掉 path 里你不想公开的部分]
-```
+## 预期行为
-## 已经试过什么
+说明你依据的合同、测试或文档。不要只写“应该成功”。
-- [ ] 检查了 [docs/debug-recipes.md](../../docs/debug-recipes.md) 没有匹配条目
-- [ ] 跑了 `pip show langchain` 看版本(贴版本号在下方)
-- [ ] 用了 [万能诊断 prompt](../../docs/debug-recipes.md#万能诊断-prompt) 问 AI 但没解决
+## 实际行为
+
+贴最小错误片段、`RunStatus`、`termination_reason` 或 grader 四态结果。删除 token、真实用户数据和内部地址。
## 环境
-- Python:`python --version` 输出
-- LangChain:`pip show langchain` 的 Version 行
-- OS:Mac / Win / Linux
-- 网络:公网 / 公司 / VPN
+- source commit:
+- Python:
+- `uv.lock` 是否未修改:
+- OS:
+- 是否需要外部 provider:
+
+## 回归资产建议
+
+这个问题应进入 unit test、contract test、capability case、regression case 还是 adversarial case?
diff --git a/.github/ISSUE_TEMPLATE/enhancement.md b/.github/ISSUE_TEMPLATE/enhancement.md
index 1369776..51c35cb 100644
--- a/.github/ISSUE_TEMPLATE/enhancement.md
+++ b/.github/ISSUE_TEMPLATE/enhancement.md
@@ -1,23 +1,31 @@
---
-name: 改进建议 / Enhancement
-about: 教程内容 / 文档结构 / 工具链改进
-title: "[Enhancement] "
+name: Capability proposal
+about: 提议新能力、实验或工程合同
+title: "[Capability] "
labels: enhancement
assignees: ''
---
-## 改进什么
+## 要解决的真实任务
-(具体到文件 / 段落。例:"tutorial/week-3-langgraph/02_conditional_edges.md 任务 3 的 prompt 太长,建议拆成 2 个小 prompt")
+输入、用户可见结果和失败成本是什么?
-## 为什么需要改
+## 无 Agent 基线
-(背后的真问题。零基础视角更值钱)
+普通程序或固定 Workflow 为什么不够?请给已观察证据,不要只写“更智能”。
-## 你的方案
+## 最小能力增量
-(如果有具体建议直接贴;如果只是发现问题不需要给方案)
+需要新增哪个合同、工具、状态、runtime 或 adapter?哪些未来扩展不在本次范围?
-## 关联资源
+## 验收
-(可选:相关 issue / 官方文档链接 / 你看到别的项目怎么做的)
+- capability case:
+- regression / adversarial case:
+- 预算与权限:
+- 预期轨迹:
+- rollback / stop condition:
+
+## UNKNOWN
+
+哪些外部行为、成本或模型质量当前还不能验证?
diff --git a/.github/ISSUE_TEMPLATE/learning_block.md b/.github/ISSUE_TEMPLATE/learning_block.md
index 8f61661..35bf53e 100644
--- a/.github/ISSUE_TEMPLATE/learning_block.md
+++ b/.github/ISSUE_TEMPLATE/learning_block.md
@@ -1,32 +1,28 @@
---
-name: 卡点反馈 / Learning Block
-about: 走某篇 tutorial 时卡住超过 30 分钟,且不是代码报错(是讲解不清 / 任务卡设计问题)
-title: "[卡点] "
-labels: learning-feedback
+name: Lab learning block
+about: 某个实验的概念、任务或失败报告不够清楚
+title: "[Lab Block] "
+labels: learner-friction
assignees: ''
---
-## 卡在哪一篇
+## Lab
-- tutorial 路径:`tutorial/week-X-xxx/0Y_xxx.md`
-- 任务卡编号:任务 N
+- Lab ID:
+- 当前步骤:Frame / Predict / Build / Break / Trace / Evaluate / Reflect / Promote
-## 卡点描述
+## 我原本预测
-(你卡了多久?卡在什么地方?是看不懂解释 / 不知道怎么 prompt / AI 给的回答没帮上 / 通关条件无法验证 / 其他)
+写下你以为会发生的节点、工具、状态或结果。
-## 我已经试过
+## 实际观察
-- [ ] 用任务卡里给的 prompt 问 AI(但没用 / 跑偏 / AI 答不准)
-- [ ] 翻了 [docs/concepts.md](../../docs/concepts.md) 找概念
-- [ ] 翻了 [docs/prompts-cheatsheet.md](../../docs/prompts-cheatsheet.md) 找其他 prompt 模板
-- [ ] 重启对话从头来过([心法 4](../../HOW_TO_LEARN_WITH_AI.md))
+贴可观察 Trace、case_id 或错误,不要贴隐藏推理和凭证。
-## 你觉得 tutorial 怎么改能不卡
+## 卡点
-(这部分对仓库改进最有用——不卡的同学没法告诉我们盲点在哪。即使是模糊的"我希望任务 2 之前先有个更小的练习"也很有价值)
+哪个概念或任务说明让你无法继续?你尝试了什么?
-## 你的背景(帮我们判断卡点是普遍问题还是个例)
+## 建议
-- Python 经验:< 1 月 / 1-6 月 / 6 月+
-- LLM 应用经验:第一次 / 看过文档但没写过 / 自己写过 demo
+更好的类比、反例、失败样例或验收提示是什么?
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index c74b1a5..b158c03 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -1,28 +1,31 @@
-## 这个 PR 改了什么
+## What changed
-(1-3 句话。例:"给 docs/debug-recipes.md 加了 langchain-core 1.4 的 PydanticUserError 报错条目")
+说明用户可见行为和涉及的合同/runtime/dataset/lab。
-## 为什么这么改
+## Why
-(动机 / 撞到的真实场景)
+根因或已观察问题是什么?为什么更小方案不够?
-## 改的类型
+## Evidence
-- [ ] 修 bug / 报错
-- [ ] 加新报错到 debug-recipes.md
-- [ ] 加新 prompt 到 prompts-cheatsheet.md
-- [ ] 加新概念到 concepts.md
-- [ ] tutorial 内容修订(具体哪一篇)
-- [ ] 工程化(CI / build / config)
-- [ ] 其他
+- [ ] `uv sync --frozen`
+- [ ] `uv run agent-lab verify`
+- [ ] `bundle exec jekyll build`
+- [ ] `uv run python scripts/check_site.py --built _site`
+- [ ] `bundle exec htmlproofer _site --disable-external --no-enforce-https --swap-urls '^/langchain-langgraph-langsmith-tutorial:'`
-## 自检
+列出新增/变化的 case_id,以及修复前后的结果。不要只写“测试通过”。
-- [ ] 改的 markdown 本地预览过没格式问题
-- [ ] 内部链接(`.md` / 相对路径)能跳通
-- [ ] 没动 `final/*.py`(除非是 langchain 升级兼容性修复)
-- [ ] 没引入新的 secret / API key
+## Behavior delta
-## 相关 issue
+| Dataset / case | Before | After | Evidence |
+|---|---|---|---|
+| | | | |
-Closes #
+## Risk and rollback
+
+权限、数据、成本、延迟、兼容性和回滚路径。
+
+## UNKNOWN
+
+明确写出未执行的 live provider、online eval、Agent Server 或 production verification。
diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
index 44c4489..e178461 100644
--- a/.github/workflows/pages.yml
+++ b/.github/workflows/pages.yml
@@ -1,4 +1,4 @@
-name: Deploy GitHub Pages
+name: Verify and Deploy GitHub Pages
on:
push:
@@ -15,34 +15,74 @@ concurrency:
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
- build:
+ python:
+ name: Python ${{ matrix.python-version }}
runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ python-version: ['3.11', '3.13']
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+ - name: Setup uv and Python
+ uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
+ with:
+ version: '0.11.28'
+ python-version: ${{ matrix.python-version }}
+ enable-cache: true
+
+ - name: Install locked environment
+ run: uv sync --frozen --python ${{ matrix.python-version }}
+
+ - name: Run complete offline gate
+ run: uv run agent-lab verify
+
+ - name: Build verification passport
+ if: matrix.python-version == '3.13'
+ run: uv run agent-lab passport --suite fast --output verification-passport.json
+
+ - name: Upload verification evidence
+ if: matrix.python-version == '3.13'
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: verification-evidence
+ path: |
+ verification-passport.json
+ evals/reports/fast.json
+ if-no-files-found: error
+
+ site:
+ name: Build Pages artifact
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+
+ - name: Setup uv and Python
+ uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
+ with:
+ version: '0.11.28'
+ python-version: '3.13'
+ enable-cache: true
+
+ - name: Install locked environment
+ run: uv sync --frozen
+
- name: Setup Ruby
uses: ruby/setup-ruby@d45b1a4e94b71acab930e56e79c6aa188764e7f9 # v1.316.0
with:
ruby-version: '3.3'
bundler-cache: true
- - name: Check Python reference syntax
- run: python3 -m compileall -q final
-
- - name: Check showcase source contract
- run: ruby scripts/check-showcase.rb
-
- - name: Check task-lab behavior
- run: node scripts/test-tutorial-lab.mjs
-
- name: Build with Jekyll
env:
JEKYLL_ENV: production
run: bundle exec jekyll build
- - name: Check rendered showcase contract
- run: ruby scripts/check-showcase.rb --built _site
+ - name: Check rendered V2 contract
+ run: uv run python scripts/check_site.py --built _site
- name: Check internal links
run: >
@@ -51,16 +91,17 @@ jobs:
--no-enforce-https
--swap-urls '^/langchain-langgraph-langsmith-tutorial:'
- - name: Upload artifact
+ - name: Upload Pages artifact
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
deploy:
+ name: Deploy production Pages
if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/master')
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
- needs: build
+ needs: [python, site]
permissions:
pages: write
id-token: write
diff --git a/.gitignore b/.gitignore
index a26e6dd..ace6ba9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,12 +1,16 @@
# 敏感配置(绝不提交真实 Key)
.env
+# uv / Python environment
+.venv/
+
# Python 编译产物
__pycache__/
*.pyc
*.pyo
*.pyd
.Python
+.coverage
# 打包产物
*.egg-info/
@@ -34,6 +38,11 @@ _site/
.jekyll-metadata
vendor/
+# 运行时评测与验证产物
+evals/reports/*.json
+verification-passport.json
+.langgraph_api/
+
# 学习者主战场——你写的代码不进 git
_scratch/*
# 但保留 README 和 journal 目录骨架 + 作者提供的示例日志
diff --git a/.python-version b/.python-version
new file mode 100644
index 0000000..24ee5b1
--- /dev/null
+++ b/.python-version
@@ -0,0 +1 @@
+3.13
diff --git a/404.md b/404.md
index f1d5373..9899106 100644
--- a/404.md
+++ b/404.md
@@ -1,10 +1,10 @@
---
layout: default
title: Page not found
-description: 请求的教程页面不存在;返回课程入口继续学习。
+description: 请求的 Agent Engineering Lab 页面不存在。
permalink: /404.html
---
# 页面没有找到
-这个地址可能已移动。你可以返回 [教程首页]({{ '/' | relative_url }})、浏览 [4 周课程]({{ '/tutorial/' | relative_url }}),或前往 [Jason Hub](https://estelledc.github.io/)。
+这个地址可能来自 V1 教程。你可以返回 [V2 首页]({{ '/' | relative_url }})、浏览 [实验路径]({{ '/labs/' | relative_url }}),或打开 [`v1-legacy`](https://github.com/estelledc/langchain-langgraph-langsmith-tutorial/tree/v1-legacy)。
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..48b627a
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,11 @@
+# Agent Engineering Lab 工作约定
+
+- 中文环境,结论先行;先解释任务合同,再谈框架 API。
+- `src/agent_lab/domain/` 不得依赖 LangChain、LangGraph、LangSmith 或模型提供商。
+- 默认路径必须离线、无 API Key 可运行。在线模型、LangSmith、Deep Agents 和持久化后端都是可选扩展。
+- 工具输入、输出、错误、权限、副作用和幂等语义必须显式建模。
+- 不可信内容只能进入 `Evidence`,不得直接升级为事实或长期记忆。
+- 评测结果只允许 `PASS / FAIL / UNKNOWN / ERROR`;基础设施错误不得折算成质量分。
+- 修改行为时同步补充确定性测试或回归样例。先跑最小测试,交付前跑 `uv run agent-lab verify`。
+- 不提交凭证、内部地址、本机绝对路径、真实用户数据或未经筛选的生产 Trace。
+- V1 已冻结在 `v1-legacy`;只修安全或迁移入口,不在 `legacy/v1/` 继续扩课。
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b6834f6..9a2e7a0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,18 @@
## [Unreleased]
+### Changed
+
+- 重定位为 Agent Engineering Lab,课程从框架 API 路径改为 15 个核心实验与 10 个前沿实验。
+- V1 冻结到 `v1-legacy`,旧教程保存在 `legacy/v1/`。
+- 安装合同迁移到 `pyproject.toml` + `uv.lock`,默认离线且无需 API Key。
+- 新增 framework-neutral `RunRequest / Evidence / Citation / RunResult` 合同。
+- 新增 Workflow、LangChain `create_agent` 和 LangGraph runtime 边界。
+- 删除模型可控 `eval()` 路径,使用受限 AST 计算器。
+- 模拟搜索改为明确的版本化 fixture search。
+- 新增 capability、regression、adversarial、tool-contract 数据集与四态 grader。
+- 新增严格 fast suite、verification passport、课程生成器和统一 CI/Pages 门禁。
+
---
## [1.1.0] — 2026-05-30
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e73265c..14ca9b8 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,108 +1,46 @@
-# Contributing — 怎么给本仓库贡献
+# Contributing
-> 你卡的地方就是本仓库下次该补的地方。Issue / PR 都欢迎,下面说清"该往哪贡献"。
+最有价值的贡献不是再加一个框架示例,而是把真实失败变成可复现合同。
----
+## 适合提交的改动
-## 三种贡献方式(按工作量从小到大)
+- 新的 capability case:证明目标能力还缺什么。
+- 新的 regression case:固定已经观察和修复的失败。
+- 工具合同修复:input/output、错误、权限、副作用或幂等语义。
+- Grader 修复:减少假通过、假失败、UNKNOWN 或 evaluator ERROR。
+- 实验改进:让学习者能独立预测、打破、Trace 和解释行为。
+- 兼容性修复:包含 fresh install 和受影响 runtime 的验证证据。
-### 1. 提 Issue(5 分钟)
+## 不直接接受
-最有价值的 issue 类型:
+- 只增加 provider 示例,没有独立任务和验收。
+- 把 fixture、单次模型试验或 CI 构建写成生产成功。
+- 用 LLM Judge 检查 schema、权限、预算、工具次数或引用存在性。
+- 将真实 API Key、未脱敏 Trace、个人数据或内部地址提交到仓库。
+- 让核心领域模型依赖 MCP、Deep Agents 或具体 provider。
-- **[卡点反馈](.github/ISSUE_TEMPLATE/learning_block.md)**:你走某篇 tutorial 卡住超 30 分钟(不是代码报错,是讲解不清)。模板会问你"你觉得怎么改"——这是仓库改进最重要的输入
-- **[报错](.github/ISSUE_TEMPLATE/bug.md)**:跑 `final/` 或 `_scratch/` 撞到 [docs/debug-recipes.md](docs/debug-recipes.md) 没列的报错
-- **[改进建议](.github/ISSUE_TEMPLATE/enhancement.md)**:教程结构 / 工具链 / 文档建议
+## 本地流程
-### 2. 提 PR 加内容(30 分钟 - 2 小时)
+```bash
+uv sync --frozen
+uv run agent-lab verify
+bundle exec jekyll build
+uv run python scripts/check_site.py --built _site
+```
-最受欢迎的 PR 类型:
+改课程元数据后运行:
-- **加新报错到 [docs/debug-recipes.md](docs/debug-recipes.md)**:你撞到 + 修好的报错——大概率别人也会撞
-- **加新 prompt 到 [docs/prompts-cheatsheet.md](docs/prompts-cheatsheet.md)**:你沉淀的私房 prompt
-- **加新概念到 [docs/concepts.md](docs/concepts.md)**:你被某个术语卡过,写了个好类比
-- **完成 [docs/challenges.md](docs/challenges.md) 后写卡点日志**:PR 你的 `_scratch/journal/challenge-N-<日期>.md` 让别人参考
+```bash
+uv run python scripts/generate_curriculum.py
+uv run python scripts/check_curriculum.py
+```
-### 3. 提 PR 改 tutorial 主体(半天 +)
+## PR 必须回答
-- **拆某篇 tutorial 的任务**:发现某篇任务卡密度太高 / 太低,提议重新切分
-- **加新一篇 tutorial**:覆盖现有 14 篇没讲到的话题(structured output / streaming 进阶 / async 等)。**先开 issue 讨论**再写
+1. 哪个可观察行为发生变化?
+2. 根因在哪一层:合同、工具、上下文、状态、runtime、provider 还是 evaluator?
+3. 哪个 test 或 dataset case 在修复前会失败?
+4. 哪些结果仍然是 `UNKNOWN`?
+5. 成本、延迟、权限或维护复杂度是否增加?
----
-
-## PR 流程
-
-1. **fork 本仓库**到你的 GitHub
-2. **建分支**:`git checkout -b add-debug-recipe-pydantic-error`
-3. **改文件**:注意约束(见下方)
-4. **本地校验**:
- ```bash
- # markdown 链接校验
- python3 -c "
- import re, pathlib
- broken = []
- for p in pathlib.Path('.').rglob('*.md'):
- if '_scratch' in str(p) or '.venv' in str(p): continue
- text = p.read_text()
- for m in re.finditer(r'\[([^\]]+)\]\(([^)]+)\)', text):
- link = m.group(2).split('#')[0]
- if link.startswith(('http', '#', 'mailto')) or not link: continue
- target = (p.parent / link).resolve()
- if not target.exists():
- broken.append(f'{p}: {link}')
- print('\n'.join(broken) if broken else 'all links ok')
- "
- ```
-5. **提 PR**,按 [pull_request_template.md](.github/pull_request_template.md) 填
-
----
-
-## 必须遵守的约束
-
-### 内容层面
-
-- ✅ **零基础视角**:术语首次出现配日常类比;不假设读者懂 LLM/Embedding/Agent 等
-- ✅ **结论先行**:每段第一句给结论
-- ✅ **列表 > 段落**:能列点不写段
-- ❌ **不用 emoji**:保持仓库整体风格
-- ❌ **不用装饰边框**:不要 `═══` 之类的 ASCII art
-
-### 文件层面
-
-- ✅ 改 `tutorial/*.md` / `docs/*.md` —— 教学主体
-- ✅ 加 `_scratch/journal/example-*.md` —— 真实日志样例(白名单已加)
-- ❌ **不改 `final/*.py`**——那是参考答案。除非是 langchain 升级兼容性修复,且必须更新 [docs/test-runs.md](docs/test-runs.md)
-- ❌ **不引入新依赖**——除非有强理由,且要更新 `requirements.txt` + 跑过所有 final
-- ❌ **不提交 `.env` / 任何 API key**——pre-commit hook 会拦但别测试它
-
-### 代码层面(如果改 final)
-
-- 必须真实跑过你改的 .py,把输出贴在 PR 描述里
-- 必须更新 [docs/test-runs.md](docs/test-runs.md) 对应行
-- 跨文件改动(影响多个 final)请先开 issue 讨论
-
----
-
-## 怎么写 issue 才有用
-
-❌ 不好的 issue:
-
-> "tutorial 看不懂"
-
-✅ 好的 issue:
-
-> "tutorial/week-3-langgraph/02_conditional_edges.md 任务 3 我卡了 40 分钟。
-> 卡点是 add_conditional_edges 的第三个参数(mapping dict),任务卡只说'跟条件函数返回值对应',
-> 但没解释为什么要分两层——条件函数返回 'use_tool',mapping 把它翻成 'tool_node'。
-> 我觉得加一句'你可以理解成路由表:条件函数返回'路由 key',mapping 决定 key 跳哪个节点'会更清楚。
-> 我的背景:6 个月 Python,第一次写 LangGraph"
-
----
-
-## 联系方式
-
-- 紧急问题:开 issue 加 `urgent` label
-- 一般讨论:[Discussions](https://github.com/estelledc/langchain-langgraph-langsmith-tutorial/discussions) (如开启)
-- 邮件:见 commit author email
-
-感谢你的贡献——零基础视角对本仓库比工程师视角更值钱。
+提交前不要宽泛暂存。只把本 PR 的文件加入 commit。
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..8ac99a2
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,33 @@
+.PHONY: sync format lint typecheck test eval curriculum-check site-check verify site
+
+sync:
+ uv sync --frozen
+
+format:
+ uv run ruff format src tests scripts
+ uv run ruff check --fix src tests scripts
+
+lint:
+ uv run ruff format --check src tests scripts
+ uv run ruff check src tests scripts
+
+typecheck:
+ uv run mypy src/agent_lab
+
+test:
+ uv run pytest --cov=agent_lab --cov-report=term-missing --cov-fail-under=85
+
+eval:
+ uv run agent-lab eval --suite fast
+
+curriculum-check:
+ uv run python scripts/check_curriculum.py
+
+site-check:
+ uv run python scripts/check_site.py
+
+verify:
+ uv run agent-lab verify
+
+site:
+ bundle exec jekyll build
diff --git a/README.md b/README.md
index 2fedae6..c27abb4 100644
--- a/README.md
+++ b/README.md
@@ -1,316 +1,162 @@
---
layout: default
-title: LangChain Tutorial Zero
-description: 一套面向初学者的中文 AI 辅助编程教程:用任务卡、苏格拉底式 prompt、可执行参考与卡点日志学习 LangChain、LangGraph 和 LangSmith。
-image: /assets/og-tutorial-zero.png
-last_modified_at: 2026-07-11
+title: Agent Engineering Lab
+description: 面向中文开发者的 Agent Systems Engineering 可执行实验室:用任务合同、证据、Trace、Dataset、Eval 和 Regression 证明 Agent 行为。
+image: /assets/og-agent-engineering-lab.png
+last_modified_at: 2026-07-28
---
- LangChain Tutorial Zero 面向刚接触 AI 应用开发的中文学习者。你不会从复制完整答案开始,而会沿着 16 篇任务卡,在自己的 English summary. A Chinese, beginner-oriented learning system for LangChain, LangGraph, and LangSmith. Sixteen guided lessons pair Socratic AI prompts with hands-on tasks, executable references, self-checks, and a learning journal.把 AI 从“答案机”,变成你的编程学习搭档。
- _scratch/ 里动手、对照、解释,再把卡点留下来。
这不是装饰性的 demo。它复刻第一课的最小节奏:用类比定位角色、补一处代码、自检,再写下一句能复用的理解。
-地铁类比 Prompt 是目的地说明,模型客户端是把这张说明送进模型、再把回复带回来的列车。
- - - -官方文档擅长告诉你 API 是什么,却默认你已经理解 Agent、State、Trace 等上下文;聊天机器人又很容易直接交付一段完整代码,让“能运行”掩盖“没理解”。
-第一次看到 LCEL、ReAct 或 Checkpointer 时,定义本身并不能告诉你它为什么存在。
-复制代码能让终端变绿,却没有暴露自己的心智模型,也没有留下可迁移的判断。
-LangChain 1.x 的拆包和 API 变化会让旧教程报错,必须把依赖版本、修复和运行记录放在一起。
-教程把 AI 放在“陪练”位置。它可以换类比、拆小问题、提供候选根因,但关键代码、差异判断和学习日志由学习者完成。
-先说清概念在解决什么问题,再把实现拆成 3–5 个可回答的小步骤。
-自己的代码只写进 _scratch/;任务卡提供约束,不直接交付完整答案。
对照 final/ 时先判断差异是否影响结果,再由学习者自己修正。
把“原来如此”、有效 prompt 和未解决问题写入 journal,变成下一次可复用的经验。
-“周”是内容分组,不是完成承诺。每篇的分钟数是仓库中的学习节奏估算,真实耗时取决于 Python 基础、网络和 API 权限。
-公开证据区分当前静态检查与 2026-05-29 的历史 API 实测;需要外部凭证的行为不会被本站构建冒充为已重新验证。
-历史记录逐项列出耗时、输出与限制。PARTIAL 来自本机 SSL 环境,SKIP 来自 embedding 权限;本次前端重构没有把它们重新宣称为通过。
- 查看真实运行记录 -requirements.txt 固定 LangChain 1.3.2、LangGraph 1.2.2 与 LangSmith 0.8.7;迁移原因保留在测试档案。
Pages 发布前会核对课程数量、元数据、唯一 H1、内部链接,并对全部参考 Python 文件执行语法编译检查。
- CI · source + rendered output -_scratch/ 写自己的版本。
- 先读 HOW_TO_LEARN_WITH_AI.md,理解为什么不直接向 AI 要完整代码。
-按 SETUP.md 建立虚拟环境与本地 .env;真实 API Key 不进入仓库。
从 01_hello_llm.md 开始,把自己的实现写进 _scratch/。
面向框架初学者,不代替 Python 基础;至少应能阅读函数、列表、字典与异常信息。
-示例固定在仓库声明的 1.x 版本,不承诺跟随 LangChain 最新 API;升级需要重新跑批。
-完整运行依赖 DashScope、LangSmith、网络与模型权限;API 费用、延迟和可用性不由本仓库控制。
-