
文档教程人工智能大模型AI Agent【免费下载链接】12-factor-agentsWhat are the principles we can use to build LLM-powered software that is actually good enough to put in the hands of production customers?项目地址https://gitcode.com/GitHub_Trending/12/12-factor-agents点击查看免费下载导读本文基于 workshops/2025-07-16/hack/testing.md系统介绍如何为一套 Jupyter Notebook 工作坊用walkthroughgen_py.py把 YAML 配置生成 Python 版 notebook构建完整的自动化测试框架在本地模拟 Google Colab 环境执行 notebook、用专用工具检查单元格输出、针对 BAMLBoundary Markup Language运行期日志捕获这一具体场景编写端到端测试。读完本文你将掌握生成 → 执行 → 分析 → 报告的 notebook 测试迭代闭环并可以直接复制一套最小化测试模板用于验证任意 notebook 功能库集成、环境准备、输出格式化、错误处理等。1. 测试框架总览一条完整的迭代闭环该框架围绕 Jupyter Notebook 的执行验证设计核心循环包含四个阶段Generate生成——用 YAML 配置或模板生成带特定功能的测试 notebookExecute执行——在模拟 Google Colab 的干净虚拟环境中逐单元格执行Analyze分析——检查执行后的 notebook 是否出现预期的输出与行为Report报告——给出明确的 pass/fail 结论失败时可定位到具体单元格。这套思路与仓库中真实工作坊的构建方式完全吻合walkthroughgen_py.py把 walkthrough.yaml 描述的章节步骤转换成 notebookconvert_walkthrough_to_notebook而测试框架保证每次转换和每次 BAML 集成的改动都能被快速验证。框架由三个核心工具组成工具职责仓库路径test_notebook_colab_sim.sh在全新虚拟环境中模拟 Colab 执行 notebookworkshops/2025-07-16/test_notebook_colab_sim.shinspect_notebook.py查看单元格源码、输出类型、报错 tracebackworkshops/2025-07-16/hack/inspect_notebook.pyanalyze_log_capture.py针对 BAML 日志捕获做结构化断言分析workshops/2025-07-16/hack/analyze_log_capture.py2. 核心组件一Notebook 模拟器test_notebook_colab_sim.sh2.1 它做了什么脚本位于仓库根目录 workshops/2025-07-16/test_notebook_colab_sim.sh执行流程分三部分环境准备创建带时间戳的测试目录./tmp/test_YYYYMMDD_HHMMSS/在该目录内用python3 -m venv venv创建全新 Python 虚拟环境pip install --quiet notebook nbconvert ipykernel安装 Jupyter 依赖。notebook 执行把被测 notebook 复制为test_notebook.ipynb拷入干净环境生成一个run_notebook.py使用nbconvert.preprocessors.ExecutePreprocessor运行所有单元格模拟 Colab 的逐格执行两个关键点执行前必须激活虚拟环境source venv/bin/activate python run_notebook.py否则执行会静默失败执行后的 notebook 必须显式写回磁盘——ExecutePreprocessor默认只在内存中修改 notebook 对象不落盘则后续分析无从谈起。源码中通过nbformat.write(nb, f)显式保存带输出的结果。验证收尾检查是否生成了baml_src/目录及baml_client/并区分 Python 客户端__init__.py与 TypeScript 客户端*.ts后者说明生成方向错误保留测试目录供人工检查输出最终目录结构报告成功/失败。2.2 使用方法./test_notebook_colab_sim.sh your_notebook.ipynb脚本会自动执行全部单元格、保留测试目录、展示最终目录结构、报告执行成功与否。注意脚本还会透传OPENAI_API_KEY环境变量以便需要真实模型调用的单元格在本地也能运行。3. 核心组件二输出检查器inspect_notebook.pyinspect_notebook.py是一个调试利器源码见 workshops/2025-07-16/hack/inspect_notebook.py它直接解析执行后的 notebook JSON提供展示每个代码单元格的源码与执行计数execution_count列出所有输出类型stream、execute_result、error、display_data高亮输出文本中的关键词模式默认关注BAML、Parsed、Response、Error、Exception对error类型输出展示ename、evalue与 traceback 末几行支持按关键字过滤单元格聚焦调试。三种典型用法# 检查所有单元格 python3 inspect_notebook.py path/to/notebook.ipynb # 按关键字过滤只看相关内容 python3 inspect_notebook.py path/to/notebook.ipynb keyword # 专门查找错误 python3 inspect_notebook.py path/to/notebook.ipynb error输出示例 CELL 0 (code) SOURCE: import sys print(Hello!) print(Error!, filesys.stderr) OUTPUTS (2 outputs): Output 0: typestream Text length: 7 chars Hello!... Output 1: typestream Text length: 7 chars Error!... Found patterns: [Error]4. Notebook 测试的关键洞察与通用调试步骤4.1 五个容易踩坑的关键点虚拟环境激活至关重要——未激活 venv 时执行会静默失败报错极不直观输出持久化必须显式——ExecutePreprocessor只改内存中的 notebook 对象必须nbformat.write()落盘检查执行计数——execution_count为null说明该单元格从未被执行过这是判断单元格到底跑没跑的第一信号区分输出类型——streamstdout/stderr 文本、execute_result、error、display_data结构各不相同分析脚本要分别处理环境变量透传——本地测试若涉及真实 LLM 调用需确保OPENAI_API_KEY已设置模拟器脚本对此有显式提示。4.2 通用调试三步法第一步验证基本执行情况直接读 JSON 里的执行计数python3 -c import json nb json.load(open(path/to/notebook.ipynb)) print(Execution counts:, [cell.get(execution_count) for cell in nb[cells] if cell[cell_type]code]) 第二步检查执行错误python3 inspect_notebook.py path/to/notebook.ipynb error第三步按预期输出模式检索python3 inspect_notebook.py path/to/notebook.ipynb your_pattern5. 如何编写自定义测试最小模板5.1 最小测试 notebookJSON 模板直接构造一个 nbformat v4 的 notebook 文件即可起步仓库中已有现成示例 workshops/2025-07-16/hack/minimal_test.ipynb。通用模板如下{ cells: [ { cell_type: code, execution_count: null, metadata: {}, outputs: [], source: [ # Test basic execution\n, print(Hello from notebook!)\n, \n, # Test file creation\n, with open(test.txt, w) as f:\n, f.write(Test successful\\n)\n, \n, # Test error handling\n, try:\n, result your_function_to_test()\n, print(fResult: {result})\n, except Exception as e:\n, print(fError: {e}) ] } ], metadata: { kernelspec: { display_name: Python 3, language: python, name: python3 } }, nbformat: 4, nbformat_minor: 4 }5.2 测试脚本模板bash把生成 → 模拟执行 → 分析 → 断言串成一条命令#!/bin/bash set -e echo Testing [Your Feature]... # 清理上次测试产物 rm -f test_notebook.ipynb # 准备被测 notebook cp your_test_notebook.ipynb test_notebook.ipynb # 在模拟器中执行 echo Running test in sim... ./test_notebook_colab_sim.sh test_notebook.ipynb # 定位最新一次执行的 notebook NOTEBOOK_DIR$(ls -1dt tmp/test_* | head -1) NOTEBOOK_PATH$NOTEBOOK_DIR/test_notebook.ipynb # 分析结果 echo Analyzing results... python3 inspect_notebook.py $NOTEBOOK_PATH your_search_term # 自定义断言逻辑 python3 -c import json with open($NOTEBOOK_PATH) as f: nb json.load(f) # 在这里写你的断言逻辑 success check_for_expected_outputs(nb) if success: print(✅ PASS: Test succeeded!) else: print(❌ FAIL: Test failed!) exit(1) echo Cleaning up... rm -f test_notebook.ipynb注意脚本模板中check_for_expected_outputs需要替换为针对你被测功能的真实断言。目录定位约定ls -1dt tmp/test_* | head -1依赖模拟器保留时间戳目录的行为。6. 实战用例BAML 日志捕获测试6.1 问题背景BAML 通过 FFI 绑定调用 Rust 二进制运行期日志输出到stderr而非 stdout。当工作坊把 BAML 集成进 notebook 后需要验证在 Jupyter 单元格环境中不同的日志捕获方法能否真正拦截到这些 stderr 日志。这正是生成 → 执行 → 分析 → 报告闭环的一个具体应用。6.2 测试配置simple_log_test.yaml用 YAML 声明一个最小 BAML 调用测试场景步骤类型与walkthroughgen_py.py的process_step逻辑workshops/2025-07-16/walkthroughgen_py.py一一对应title: BAML Log Capture Test text: Simple test for log capture sections: - title: Log Capture Test steps: - baml_setup: true # 插入 BAML 环境准备单元格 - fetch_file: src: walkthrough/01-agent.baml dest: baml_src/agent.baml - file: src: ./simple_main.py # 插入被测主函数源码 - text: Testing log capture with show_logstrue: - run_main: args: What is 22? show_logs: true其中fetch_file负责把 walkthrough/01-agent.baml 拉取为baml_src/agent.baml模拟 Colab 从远程获取 BAML 文件的场景run_main生成调用主函数的单元格。6.3 被测函数simple_main.pydef main(messageWhat is 22?): Simple main function that calls BAML directly client get_baml_client() # Call the BAML function - this should generate logs result client.DetermineNextStep(fUser asked: {message}) print(fInput: {message}) print(fResult: {result}) return resultget_baml_client()是仓库为规避 Google Colab 导入缓存问题而引入的全局工作模式见 workshops/2025-07-16/CLAUDE.md 中的说明notebook 单元格之间共享全局命名空间函数在单元格中定义后即可直接调用无需模块级导入。6.4 日志捕获实现IPythoncapture_output()当前工作实现位于walkthroughgen_py.py的run_with_baml_logs函数中核心思路是先确保BAML_LOGinfo环境变量已设置再用 IPython 的capture_output()上下文管理器同时捕获 stdout 与 stderrdef run_with_baml_logs(func, *args, **kwargs): Test log capture using IPython capture_output # Ensure BAML_LOG is set if BAML_LOG not in os.environ: os.environ[BAML_LOG] info print(f[LOG CAPTURE TEST] Running with BAML_LOG{os.environ.get(BAML_LOG)}...) # Capture both stdout and stderr with capture_output() as captured: result func(*args, **kwargs) # Display captured outputs if captured.stdout: print( Captured Stdout ) print(captured.stdout) if captured.stderr: print( Captured BAML Logs ) print(captured.stderr) else: print( No BAML Logs Captured ) print( Function Result ) print(result) return result捕获结果会按 Captured Stdout / Captured BAML Logs / Function Result 三个段落输出便于后续脚本做模式匹配。6.5 主测试脚本test_log_capture.sh仓库中已落地为可执行脚本 workshops/2025-07-16/hack/test_log_capture.sh#!/bin/bash set -e echo Testing BAML Log Capture... # 用 YAML 配置生成测试 notebook echo Generating test notebook... uv run python walkthroughgen_py.py simple_log_test.yaml -o test_capture.ipynb # 在 Colab 模拟器中执行 echo Running test in sim... ./test_notebook_colab_sim.sh test_capture.ipynb # 找到执行后的 notebook NOTEBOOK_DIR$(ls -1dt tmp/test_* | head -1) NOTEBOOK_PATH$NOTEBOOK_DIR/test_notebook.ipynb echo Analyzing results from $NOTEBOOK_PATH... # 先用检查器看调试信息 echo Dumping debug info... python3 inspect_notebook.py $NOTEBOOK_PATH run_with_baml_logs # 再做结构化断言分析 echo Running log capture analysis... python3 analyze_log_capture.py $NOTEBOOK_PATH echo Cleaning up... rm -f test_capture.ipynbuv run python依据 workshops/2025-07-16/pyproject.toml 声明的依赖baml0.19.1、jupyter1.1.1、nbformat5.10.4、pyyaml6.0.2运行。6.6 分析脚本analyze_log_capture.py分析脚本workshops/2025-07-16/hack/analyze_log_capture.py承担最终断言逻辑清晰#!/usr/bin/env python3 import json import sys import os def check_logs(notebook_path): Check if BAML logs were captured in the notebook with open(notebook_path) as f: nb json.load(f) found_log_pattern False found_capture_test False for i, cell in enumerate(nb[cells]): if cell[cell_type] code and outputs in cell: source .join(cell.get(source, [])) if run_with_baml_logs in source: found_capture_test True print(fFound log capture test in cell {i}) # Check outputs for BAML logs for output in cell[outputs]: if output.get(output_type) stream and text in output: text .join(output[text]) # Look for the specific BAML log pattern if ---Parsed Response (class DoneForNow)--- in text: found_log_pattern True print(f✅ FOUND BAML LOG PATTERN in cell {i} output!) return found_capture_test, found_log_pattern # Run analysis and return pass/fail capture_test_found, log_pattern_found check_logs(sys.argv[1]) if not capture_test_found: print(❌ FAIL: No log capture test found in notebook) sys.exit(1) if log_pattern_found: print(✅ PASS: BAML logs successfully captured in notebook output!) sys.exit(0) else: print(❌ FAIL: BAML log pattern not found in captured output) sys.exit(1)断言逻辑分两层先确认 notebook 里确实存在run_with_baml_logs测试单元格防止根本没测再在stream输出中检索 BAML 的关键日志标记---Parsed Response (class DoneForNow)---用它确认 BAML 调用成功完成且日志被捕获。DoneForNow正是 BAML 定义的 agent 终止类见 walkthrough/01-agent.baml因此该模式出现即代表一次完整的 agent 决策已执行。6.7 预期输出流成功场景$ ./test_log_capture.sh Testing BAML Log Capture... Generating test notebook... Generated notebook: test_capture.ipynb Running test in sim... Creating clean test environment in: ./tmp/test_20250716_191106 Test directory will be preserved for inspection Creating fresh Python virtual environment... Installing Jupyter dependencies... Running notebook in clean environment... ✅ Notebook executed successfully! Executed notebook saved with outputs Analyzing results from tmp/test_20250716_191106/test_notebook.ipynb... Dumping debug info... Found log capture test in cell 11 OUTPUTS (3 outputs): Output 0: typestream Text length: 49 chars [LOG CAPTURE TEST] Running with BAML_LOGinfo...... Output 1: typestream Text length: 1272 chars 2025-07-16T19:11:22.445 [BAML [92mINFO[0m] [35mFunction DetermineNextStep[0m... Found patterns: [BAML, Parsed, Response] Running log capture analysis... Found log capture test in cell 11 ✅ FOUND BAML LOG PATTERN in cell 11 output! ✅ PASS: BAML logs successfully captured in notebook output! Cleaning up...从输出可以看到BAML 日志带 ANSI 颜色转义码[92m、[0m且以BAML INFO Function DetermineNextStep前缀标识。7. BAML 场景专属经验总结针对 BAML 日志捕获测试中沉淀了五条核心经验BAML 日志走 stderr——由于 FFI 绑定到 Rust 二进制日志不会出现在 stdout捕获必须同时覆盖 stderr必须设置BAML_LOGinfo——该环境变量控制 BAML 日志的详细程度不设置则没有日志可捕获日志含 ANSI 颜色码——[92m、[35m、[0m等转义序列会被捕获进输出文本断言匹配时要能容忍这些字符用特征模式判定成功——---Parsed Response (class DoneForNow)---出现即代表 BAML 函数调用完成且日志被捕获IPythoncapture_output()在 notebook 上下文有效——它能成功拦截 stderr是当前可用的捕获手段。8. 迭代闭环与框架复用这套框架最大的价值在于快速迭代改一处实现、跑一次脚本、立刻得到 pass/fail 反馈。针对 BAML 日志捕获的迭代流程修改walkthroughgen_py.py中的run_with_baml_logs实现运行./test_log_capture.sh获取即时 pass/fail 反馈必要时调试——用inspect_notebook.py深入查看具体单元格输出重复直至实现可用。同一模式完全可以迁移到任何 notebook 功能验证库集成、环境准备、输出格式化、错误处理等。需要验证什么就在最小模板里放进什么再按生成 → 执行 → 分析 → 报告闭环跑一遍即可。配合仓库中 workshops/2025-07-16/walkthrough.yaml 的章节定义与 workshops/2025-07-16/walkthroughgen_py.py 的生成逻辑这套测试体系保证了从 YAML 配置到最终workshop_final.ipynb的每个环节都可验证、可回归。赞分享文档教程人工智能大模型AI Agent【免费下载链接】12-factor-agentsWhat are the principles we can use to build LLM-powered software that is actually good enough to put in the hands of production customers?项目地址https://gitcode.com/GitHub_Trending/12/12-factor-agents点击查看免费下载相关推荐ESP32 Arduino Core 中的 Unity 框架验证测试从断言宏到 CI 冒烟测试全解析ESP32 Arduino Core 中的 Unity 框架验证测试从断言宏到 CI 冒烟测试全解析 导读 Unity 是 ESP32 Arduino cor前端UI组件RenderDoc CLI 测试方案全解析从 Mock 单元测试到真实 .rdc 捕获的 E2E 验证RenderDoc CLI 测试方案全解析从 Mock 单元测试到真实 .rdc 捕获的 E2E 验证 本篇技术指南以 renderdoc/agent har人工智能AI AgentAI 技能工具调用CLIPath of Building PoE23大核心功能解锁流放之路2构建新境界Path of Building PoE23大核心功能解锁流放之路2构建新境界 你是否还在为复杂的装备搭配而头疼还在为天赋树优化而反复试错Path of桌面应用游戏开发上一篇5分钟快速上手MouseTooltipTranslator网页、图片、整篇PDF悬停一下就翻好下一篇B站视频下载指南BilibiliDown 完整实操教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考