《深入理解 AI Agent:设计原理与工程实践 》实验1-1上下文的关键作用

1. 项目概览

https://github.com/bojieli/ai-agent-book

这是一个配套《深入理解 AI Agent》第 1 章"实验 1-1:上下文的关键作用"的 Python 示例项目。仓库实现了一个支持多模型供应商、多工具调用、会话历史、上下文消融实验与结果分析的 Context-Aware AI Agent。

项目核心目标不是只做一个"能聊天"的 Agent,而是通过可控地移除上下文中的不同组成部分,观察 Agent 在复杂财务、预算、PDF 解析、货币换算、代码计算等任务中的行为变化,从而理解:

  • 历史消息为什么重要;
  • 推理内容是否会影响后续决策;
  • 工具调用定义缺失会造成什么后果;
  • 工具执行结果不可见时 Agent 如何退化;
  • 不同 LLM Provider 在工具调用和推理场景下的差异。

1.1 学习价值

  • 理解 Agent 上下文工程:项目将上下文拆成历史、推理、工具调用、工具结果等组件,并提供 5 种上下文模式进行消融。
  • 掌握 ReAct/Tool Calling 基本闭环:模型生成工具调用 → Agent 执行工具 → 工具结果回填 → 模型继续推理,直到给出最终答案。
  • 学习多 Provider 适配方式:支持 Doubao、SiliconFlow、Kimi、DeepSeek,且均通过 OpenAI-compatible API 接入。
  • 获得可运行的实验框架:不仅有交互式运行,还提供批量消融实验、结果 JSON、分析函数和报告生成入口。
  • 建立工程化测试意识:包含单元测试、回归测试、Provider 手动检查脚本、异常工具 JSON 容错测试。

1.2 解决的行业痛点

行业/开发痛点 本项目对应解决方式
Agent 效果不稳定,不知道是提示词、模型还是上下文导致 通过上下文消融实验隔离变量
多轮对话中 Agent 忘记之前工具调用或结果 保留完整历史模式,并对比 No History 模式
工具调用 JSON 异常导致循环中断 tests/test_malformed_tool_json.py 覆盖异常参数容错
不同模型供应商工具调用能力不一致 提供多 Provider 配置与手动检查脚本
复杂财务任务需要 PDF、汇率、计算、代码执行组合完成 内置 parse_pdfconvert_currencycalculatecode_interpreter
实验结果难以复现 run_experiment_1_1.py 生成 JSON、证据文件、哈希与版本信息

1.3 前置知识要求

建议读者具备以下基础:

  • Python 3.10+ 基础语法;
  • 虚拟环境与 pip install -r requirements.txt 的使用;
  • .env 环境变量配置;
  • LLM API Key 的基本申请与使用方式;
  • 对 OpenAI Chat Completions、tool calling、messages 结构有初步了解;
  • 知道 JSON、命令行参数、pytest 基本用法。

如果完全没有接触过 Agent,也可以先从"运行 quickstart → 阅读 agent.py → 执行单任务 → 再跑消融实验"的顺序学习。


2. 目录结构速览

主要目录与文件如下:

text 复制代码
.
├── README.md
├── agent.py
├── config.py
├── create_sample_pdf.py
├── env.example
├── main.py
├── requirements.txt
├── run_experiment_1_1.py
├── task_result_full.json
├── test_experiment_1_1.py
├── fixtures/
│   └── pdfs/
│       ├── sample_financial_report_q1_2024.pdf
│       └── simple_expense_report.pdf
├── tests/
│   ├── conftest.py
│   ├── test_agent.py
│   ├── test_code_interpreter.py
│   ├── test_malformed_tool_json.py
│   └── manual/
│       ├── _bootstrap.py
│       ├── check_conversation_history.py
│       ├── check_deepseek.py
│       ├── check_deepseek_quick.py
│       ├── check_default_provider.py
│       ├── check_doubao.py
│       ├── check_doubao_quick.py
│       ├── check_kimi.py
│       ├── check_kimi_quick.py
│       ├── check_pdf_task.py
│       ├── check_provider_config.py
│       ├── check_provider_switching.py
│       ├── check_simple_task.py
│       ├── demo_conversation.py
│       ├── quickstart.py
│       └── show_sample_tasks.py
└── validation/
    ├── latest.json
    └── real_20260729T153329Z/
        ├── evidence.json
        └── evidence.sha256

目录职责清单:

路径 职责
agent.py Agent 核心实现,包括上下文模式、工具注册、工具执行、消息构造、API 调用日志
config.py Provider、模型、API Key、目录与模型配置管理
main.py 主入口,支持单任务、交互模式、样例任务、消融实验与结果展示
run_experiment_1_1.py 精确复现书中五组上下文消融实验的脚本
create_sample_pdf.py 生成测试用 PDF 样例
tests/ pytest 自动化测试
tests/manual/ 手动冒烟检查脚本,用于验证 Provider、会话历史、PDF 任务等
fixtures/pdfs/ 预置 PDF 测试文件
validation/ 验证数据与证据文件,包含 JSON 与 SHA256
requirements.txt Python 依赖清单
env.example 环境变量示例文件

3. 核心模块与职责

3.1 agent.py:Agent 核心

agent.py 是整个项目最核心的文件,模块说明为"Context-Aware AI Agent with Tool Calls"。

它包含以下主要类:

类/函数 作用
ContextMode(Enum) 定义上下文消融模式
ToolCall 工具调用数据结构
AgentTrajectory 记录 Agent 执行轨迹
ToolRegistry 注册并执行工具
ContextAwareAgent 上下文感知 Agent 主体
_reasoning_safe_temperature(model, requested) 根据模型调整温度参数,避免某些推理模型参数不兼容

从 README 可知,项目包含 5 种上下文模式:

模式 含义 对 Agent 的影响
Full Context 完整上下文 同时保留历史、推理、工具调用、工具结果
No History 缺少历史工具调用跟踪 模型难以利用前序轮次信息
No Reasoning 不保留战略规划/推理内容 可能降低复杂任务规划能力
No Tool Calls 不能执行外部工具 无法读取 PDF、换算汇率、计算或执行代码
No Tool Results 看不到工具执行结果 模型可能继续猜测,而不是基于事实输出

ToolRegistry 中可用工具包括:

工具 方法 功能
PDF 解析 parse_pdf(url) 下载并提取 PDF 文本
货币转换 convert_currency(amount, from_currency, to_currency) 实时汇率换算
计算器 calculate(expression) 计算数学表达式
代码解释器 code_interpreter(code) 执行 Python 代码,处理复杂计算

ContextAwareAgent 的关键方法职责如下:

方法 职责
__init__ 初始化 API Key、上下文模式、Provider、模型、日志开关
_init_system_prompt 构造系统提示词
_get_tools_description 获取工具定义,供模型进行 tool calling
_prepare_assistant_message 准备 assistant 消息
_reasoning_content 提取或处理模型推理内容
_json_snapshot 生成可序列化 JSON 快照
_build_context 根据上下文模式构造消息上下文
_log_request_response 记录每次 API 请求与响应
_execute_tool 根据工具名和参数执行本地工具
_prepare_messages_for_api 整理发送给 API 的 messages

3.2 config.py:配置管理

config.py 负责统一管理不同 Provider 的 API Key、默认模型、配置校验和目录创建。

Config 类主要方法:

方法 作用
get_api_key(cls, provider) 获取指定 Provider 的 API Key
get_default_model(cls, provider) 获取指定 Provider 的默认模型
validate(cls, provider) 校验 Provider 配置是否可用
create_directories(cls) 创建运行所需目录
get_model_config(cls) 获取模型配置
print_config(cls) 打印当前配置

README 中列出的默认模型:

Provider 默认模型 特点
Doubao doubao-seed-1-6-thinking-250715 默认 Provider,适合中英文推理
SiliconFlow Qwen/Qwen3.5-397B-A17B 适合复杂推理任务
Kimi kimi-k3 推理模型,温度被强制为 1,适合多轮和推理
DeepSeek deepseek-v4-flash 高性价比工具调用模型,可切换 deepseek-v4-pro

3.3 main.py:主程序与消融实验入口

main.py 是日常运行最常用的入口,支持:

  • 单任务运行;
  • 交互式对话;
  • 样例 PDF 检查;
  • 批量消融实验;
  • 结果表格打印;
  • 对比矩阵;
  • 可视化;
  • 报告生成。

关键函数和类:

名称 作用
run_single_task(...) 运行单个任务
ensure_sample_pdfs() 确保样例 PDF 存在
get_sample_tasks() 获取样例任务
get_ablation_cases(num_cases) 获取消融实验用例
run_ablation_study(...) 运行批量消融实验
interactive_mode(...) 交互式模式
main() 命令行入口
AblationTestSuite 消融实验套件
AblationTestSuite.run_single_test(...) 单次测试
AblationTestSuite.run_ablation_study(...) 执行多模式多用例实验
AblationTestSuite.analyze_results(...) 分析结果
AblationTestSuite.print_results_table(...) 打印结果表
AblationTestSuite.print_comparison_matrix(...) 打印对比矩阵
AblationTestSuite.visualize_results(...) 可视化结果
AblationTestSuite.generate_report(...) 生成报告

3.4 run_experiment_1_1.py:书中实验复现脚本

该文件模块说明为"Run the exact five-arm context ablation from book/chapter1.md",即用于复现书中五组上下文消融实验。

它比 main.py 更强调实验可复现性,包含:

函数 作用
utc_now() 获取 UTC 时间
git_value(*args) 获取 Git 信息
package_version(distribution) 获取依赖包版本
resolve_key(provider) 解析 Provider API Key
tool_call_dict(call) 将工具调用转为字典
call_signatures(tool_calls) 提取工具调用签名
response_message(turn) 获取响应消息
request_roles(turn) 获取请求中的角色序列
evaluate_context_contract(mode, turns) 评估上下文契约是否符合模式要求
normalized_number_text(value) 归一化数字文本
summarize_arm(mode, result, elapsed) 汇总单组实验结果
token_usage(arms) 汇总 Token 使用情况
analyze(arms) 分析五组实验
write_json(path, payload) 写入 JSON 结果
main() 命令行入口

3.5 create_sample_pdf.py:样例 PDF 生成

该文件用于生成测试 PDF,包含两个函数:

函数 作用
create_financial_report() 创建财务报告 PDF
create_simple_expense_report() 创建简单费用报告 PDF

仓库中已经存在:

text 复制代码
fixtures/pdfs/sample_financial_report_q1_2024.pdf
fixtures/pdfs/simple_expense_report.pdf

如果文件缺失,可以运行该脚本重新生成。具体命令参数未在解析摘要中发现,但文件包含 python_main_guard,通常可通过:

bash 复制代码
python create_sample_pdf.py

尝试执行。

3.6 测试模块

自动化测试文件:

文件 作用
tests/test_agent.py 测试工具注册、上下文模式、消融场景、轨迹重置
tests/test_code_interpreter.py 测试代码解释器工具
tests/test_malformed_tool_json.py 回归测试:工具参数 JSON 异常不能中断 ReAct 循环
test_experiment_1_1.py 测试实验 1-1 的上下文契约

手动检查脚本:

脚本 用途
tests/manual/quickstart.py 快速开始
tests/manual/check_simple_task.py 简单任务冒烟
tests/manual/check_pdf_task.py PDF 解析与货币换算任务
tests/manual/check_conversation_history.py 检查会话历史持久化
tests/manual/demo_conversation.py 演示会话历史
tests/manual/check_provider_config.py 检查 Provider 配置
tests/manual/check_provider_switching.py 检查 Provider 切换
tests/manual/check_default_provider.py 检查默认 Provider 是否为 Doubao
tests/manual/check_doubao.py Doubao 完整检查
tests/manual/check_doubao_quick.py Doubao 快速检查
tests/manual/check_kimi.py Kimi 完整检查
tests/manual/check_kimi_quick.py Kimi 快速检查
tests/manual/check_deepseek.py DeepSeek 完整检查
tests/manual/check_deepseek_quick.py DeepSeek 快速检查
tests/manual/show_sample_tasks.py 展示样例任务

3.7 核心原理通俗解读

可以把这个 Agent 理解成一个"会查资料、会用计算器、会写代码的实习生"。

它的工作流程类似下面的循环:

  1. 用户提出任务,例如"读取这份财务 PDF,把美元金额换算成人民币并汇总"。
  2. Agent 先看系统提示词、历史消息和工具列表。
  3. 如果需要 PDF,它调用 parse_pdf
  4. 工具返回 PDF 文本后,Agent 再决定是否调用 convert_currency
  5. 如果金额较多或逻辑复杂,它可能调用 code_interpreter 写 Python 计算。
  6. 所有工具结果回到对话上下文后,Agent 生成最终答案。

上下文消融实验的本质就是:

  • 不让它看历史,看它是否忘事;
  • 不让它保留推理,看它是否缺少规划;
  • 不给它工具定义,看它是否无法调用工具;
  • 不给它工具结果,看它是否会"凭空回答"。

这也是项目最值得学习的地方:它把"上下文为什么重要"从抽象概念变成了可运行、可对比、可验证的实验。


4. 关键数据流与调用链

4.1 单任务执行主链路

以运行一个复杂财务任务为例,典型调用链如下:

text 复制代码
命令行 / main.py
  ↓
main()
  ↓
run_single_task(api_key, task, context_mode, provider, model, output)
  ↓
ContextAwareAgent(...)
  ↓
agent._init_system_prompt()
  ↓
agent._get_tools_description()
  ↓
agent._prepare_messages_for_api()
  ↓
LLM Chat Completions API
  ↓
模型返回 assistant message / tool_calls
  ↓
agent._execute_tool(tool_name, arguments)
  ↓
ToolRegistry.parse_pdf / convert_currency / calculate / code_interpreter
  ↓
工具结果追加到上下文
  ↓
再次请求 LLM
  ↓
循环直到无工具调用,输出最终答案
  ↓
写入 output JSON / 控制台展示

4.2 工具调用数据流

工具调用过程中的数据结构大致如下:

text 复制代码
用户任务
  ↓
messages: [system, user, ...history]
  ↓
模型返回 tool_calls
  ↓
ToolCall(tool_name, arguments)
  ↓
ToolRegistry 分发
  ↓
工具执行结果
  ↓
tool result message 回填 messages
  ↓
AgentTrajectory 记录轨迹
  ↓
下一轮模型推理

涉及的关键方法:

阶段 方法
准备工具描述 _get_tools_description
准备消息 _prepare_messages_for_api
构造上下文 _build_context
执行工具 _execute_tool
记录请求响应 _log_request_response
保存轨迹 AgentTrajectory

4.3 消融实验数据流

批量消融实验链路:

text 复制代码
main.py / run_experiment_1_1.py
  ↓
读取任务或内置实验用例
  ↓
遍历 context_modes
  ↓
对每个模式创建 ContextAwareAgent
  ↓
执行同一任务
  ↓
收集结果、耗时、Token、工具调用、消息轨迹
  ↓
evaluate_context_contract / analyze_results
  ↓
输出表格、对比矩阵、JSON 报告

run_experiment_1_1.py 还会记录:

  • UTC 时间;
  • Git 信息;
  • 包版本;
  • 请求角色;
  • 工具调用签名;
  • Token 使用;
  • 证据 JSON;
  • SHA256 哈希。

这些信息有助于实验复现和结果校验。

4.4 五组上下文方案优劣对比

方案 优点 缺点 适合观察的问题
Full Context 信息最完整,Agent 能力最强 Token 成本最高,可能引入冗余历史 作为基线组
No History 节省部分上下文,降低历史干扰 容易忘记前序工具调用和用户约束 历史消息对多轮任务的影响
No Reasoning 减少推理内容占用,输出可能更直接 复杂任务规划能力下降 推理内容对工具选择和任务分解的影响
No Tool Calls 可模拟纯文本模型或无工具场景 无法读取 PDF、计算、换算汇率 工具调用对任务完成的必要性
No Tool Results 可验证模型是否会盲目猜测 Agent 缺少事实依据,答案容易错误 工具结果对最终答案可信度的影响

4.5 流程易错节点标注

节点 常见错误 影响 建议
API Key 读取 .env 未配置或 Provider 名错误 无法调用模型 使用 check_provider_config.py 检查
模型参数 Kimi/DeepSeek 等推理模型对温度、max_tokens 有要求 请求报错或输出被截断 使用 _reasoning_safe_temperature,不要随意改参数
工具参数 JSON 模型返回 malformed JSON ReAct 循环中断 参考 test_malformed_tool_json.py 的容错逻辑
PDF 解析 URL 不可访问或 PDF 格式异常 工具返回错误 先用 fixtures/pdfs 中本地样例验证
货币转换 外部汇率服务不可用 金额换算失败 检查网络,必要时使用 code_interpreter 做固定汇率计算
代码解释器 执行了不安全代码或依赖缺失 本地运行失败或异常 只在沙箱/可信环境运行,避免执行未知代码
上下文模式 错误理解 No Tool Calls / No Tool Results 实验结论偏差 结合 evaluate_context_contract 验证消息契约
结果保存 输出目录不存在 JSON 写入失败 先运行配置中的目录创建逻辑

5. 关键类/函数速查表

5.1 agent.py

类/函数 类型 关键说明
ContextMode Enum 定义 Full、No History、No Reasoning、No Tool Calls、No Tool Results 等模式
ToolCall dataclass 表示一次工具调用
AgentTrajectory 保存 Agent 执行轨迹
ToolRegistry.parse_pdf(url) 方法 下载并解析 PDF
ToolRegistry.convert_currency(amount, from_currency, to_currency) 方法 货币换算
ToolRegistry.calculate(expression) 方法 数学表达式计算
ToolRegistry.code_interpreter(code) 方法 执行 Python 代码
ContextAwareAgent.__init__ 方法 初始化 Agent
ContextAwareAgent._init_system_prompt 方法 构造系统提示词
ContextAwareAgent._get_tools_description 方法 返回工具 schema/描述
ContextAwareAgent._build_context 方法 根据模式裁剪上下文
ContextAwareAgent._execute_tool 方法 分发并执行工具
ContextAwareAgent._prepare_messages_for_api 方法 构造 API 请求消息
ContextAwareAgent._log_request_response 方法 记录请求响应日志
_reasoning_safe_temperature 函数 为推理模型调整温度

5.2 config.py

类/函数 类型 关键说明
Config.get_api_key class method 获取 Provider API Key
Config.get_default_model class method 获取默认模型
Config.validate class method 校验配置
Config.create_directories class method 创建目录
Config.get_model_config class method 获取模型配置
Config.print_config class method 打印配置

5.3 main.py

类/函数 类型 关键说明
run_single_task 函数 运行单个任务
ensure_sample_pdfs 函数 确保样例 PDF 存在
get_sample_tasks 函数 返回样例任务
get_ablation_cases 函数 返回消融实验用例
run_ablation_study 函数 运行消融实验
interactive_mode 函数 交互式对话
main 函数 CLI 入口
AblationTestSuite.create_complex_financial_task 方法 创建复杂财务任务
AblationTestSuite.create_multinational_budget_task 方法 创建跨国预算任务
AblationTestSuite.run_single_test 方法 执行单次测试
AblationTestSuite.run_ablation_study 方法 执行消融套件
AblationTestSuite.analyze_results 方法 分析结果
AblationTestSuite.print_results_table 方法 打印结果表
AblationTestSuite.print_comparison_matrix 方法 打印对比矩阵
AblationTestSuite.visualize_results 方法 可视化结果
AblationTestSuite.generate_report 方法 生成报告

5.4 run_experiment_1_1.py

函数 关键说明
utc_now 生成 UTC 时间戳
git_value 获取 Git 信息
package_version 获取包版本
resolve_key 解析 API Key
tool_call_dict 工具调用转字典
call_signatures 提取工具调用签名
response_message 获取响应消息
request_roles 提取请求角色
evaluate_context_contract 校验上下文模式契约
normalized_number_text 归一化数字
summarize_arm 汇总单组实验
token_usage 汇总 Token
analyze 分析实验结果
write_json 写入 JSON
main CLI 入口

6. 如何运行与调试(基于摘要推断,无法确定则说明)

注意:以下命令基于 README 预览、文件入口线索和 Python 项目常规结构整理。未在解析摘要中明确出现的参数会标注"未在解析摘要中发现"。

6.1 环境准备

第 1 步:进入项目目录

目的:进入本章上下文实验项目。

bash 复制代码
cd D:\组内产品\ai教育\ai-agent-book-main\ai-agent-book-main\chapter1\context

如果你使用 Windows PowerShell,路径也可以写成:

powershell 复制代码
cd "D:\组内产品\ai教育\ai-agent-book-main\ai-agent-book-main\chapter1\context"

第 2 步:准备 Python 环境

README 中写明前置要求为:

text 复制代码
Python 3.10+

建议创建虚拟环境:

bash 复制代码
python -m venv .venv

Windows 激活:

bash 复制代码
.venv\Scripts\activate

Linux/macOS 激活:

bash 复制代码
source .venv/bin/activate

README 预览中还提到"Recommended from the repository root: use the shared Chapter 1 environment",说明书籍配套仓库可能推荐在章节目录上层使用共享环境。如果你的仓库根目录已有统一环境,应优先按书籍说明激活共享环境,再进入本目录。

第 3 步:安装依赖

目的:安装 Agent、PDF、OpenAI SDK、环境变量、表格输出等依赖。

bash 复制代码
pip install -r requirements.txt

已知导入依赖包括:

  • PyPDF2
  • openai
  • python-dotenv
  • requests
  • reportlab
  • tabulate

其中 reportlab 用于 create_sample_pdf.py 生成 PDF,tabulatemain.py 中用于表格输出。

第 4 步:配置 .env

目的:配置至少一个 LLM Provider 的 API Key。

仓库提供了:

text 复制代码
env.example

可复制为 .env

Windows PowerShell:

powershell 复制代码
Copy-Item env.example .env

或者CMD:

复制代码
copy env.example .env

Linux/macOS:

bash 复制代码
cp env.example .env

然后编辑 .env,填入对应 Provider 的 Key。支持的 Provider 包括:

Provider API Key 获取地址
SiliconFlow https://siliconflow.cn
Doubao https://www.volcengine.com/
Kimi https://platform.moonshot.cn/
DeepSeek https://platform.deepseek.com/api_keys

具体环境变量名称未在解析摘要中完整展示,请以 env.exampleconfig.py 实际内容为准。

注意,默认使用API 为Doubao,需要根据实际修改。

bash 复制代码
# LLM Provider Configuration (siliconflow, doubao, kimi, moonshot, deepseek, or zhipu)
LLM_PROVIDER=doubao

6.2 检查默认 Provider

目的:确认默认 Provider 是否为 上述 env 文件中设定的 模型。

运行:

bash 复制代码
python tests/manual/check_default_provider.py

如果需要测试其他配置是否通过,如deepseek:

bash 复制代码
python tests/manual/check_deepseek.py

6.3 快速开始

目的:用最小任务验证 Agent 是否能正常调用模型。

运行:

bash 复制代码
python tests/manual/quickstart.py

该脚本导入了:

  • _bootstrap
  • agent
  • config
  • os
  • sys

预期效果:

  • 脚本会把项目根目录加入 Python 路径;
  • 读取配置;
  • 初始化 Agent;
  • 发起一次简单模型调用。

正常控制台输出特征未在解析摘要中发现。如果出现 API Key 缺失、模型不存在或网络错误,请参考第 8 节排查。目前,测试脚本内部硬编码参数被写死,仅能使用豆包。

6.4 检查简单任务

目的:排除复杂 PDF、多工具链路的影响,先验证基础对话和 Agent 循环。

运行:

bash 复制代码
python tests/manual/check_simple_task.py

该脚本包含 test_simple_task(),并导入了 time,可能用于简单计时或等待。

预期效果:

  • Agent 能完成一个简单任务;
  • 控制台应展示任务执行过程或最终结果;
  • 不应出现工具参数解析异常。

具体输出内容未在解析摘要中发现。

6.5 检查 PDF 与货币换算任务

目的:验证 parse_pdfconvert_currency 工具链路。

运行:

bash 复制代码
python tests/manual/check_pdf_task.py

该脚本包含:

text 复制代码
test_pdf_with_currencies()

预期效果:

  • Agent 读取 PDF;
  • 提取财务文本;
  • 根据任务需要调用货币转换;
  • 输出汇总或换算结果。

仓库中已有 PDF:

text 复制代码
fixtures/pdfs/sample_financial_report_q1_2024.pdf
fixtures/pdfs/simple_expense_report.pdf

如果 PDF 文件缺失,可运行:

bash 复制代码
python create_sample_pdf.py

运行后预期会重新生成样例 PDF。生成路径和控制台提示未在解析摘要中发现,需以脚本实际输出为准。

6.6 检查会话历史

目的:验证多轮对话中历史消息是否被保留。

运行:

bash 复制代码
python tests/manual/check_conversation_history.py

或运行演示脚本:

bash 复制代码
python tests/manual/demo_conversation.py

预期效果:

  • Agent 在第二轮对话中能够引用第一轮上下文;
  • 可用于对比 Full Context 与 No History 模式的差异。

6.7 检查不同 Provider

Doubao

bash 复制代码
python tests/manual/check_doubao.py

快速检查:

bash 复制代码
python tests/manual/check_doubao_quick.py

Kimi

bash 复制代码
python tests/manual/check_kimi.py

快速检查:

bash 复制代码
python tests/manual/check_kimi_quick.py

DeepSeek

bash 复制代码
python tests/manual/check_deepseek.py

快速检查:

bash 复制代码
python tests/manual/check_deepseek_quick.py

这些脚本通常覆盖:

  • 基础对话;
  • 工具调用;
  • 货币转换;
  • 模型信息。

具体测试项以 check_deepseek.pycheck_kimi.py 中的函数为准。

6.8 运行主程序

main.py 提供 argparse 入口。可先查看帮助:

bash 复制代码
python main.py --help

解析摘要中未列出完整 CLI 参数,因此以下运行方式需以 --help 实际输出为准。

常见能力包括:

  • 单任务;
  • 交互模式;
  • 批量消融;
  • 指定 Provider;
  • 指定模型;
  • 指定输出文件。

先执行 python main.py --help,支持示例:

6.9 运行消融实验

书中实验复现脚本:

bash 复制代码
python run_experiment_1_1.py --help

该脚本支持 argparse,建议先查看帮助再运行。

笔者使用的是Deepseek的API,修改参数:

text 复制代码
    parser.add_argument("--provider", default="deepseek", choices=sorted(KEY_ENV))
    parser.add_argument("--model", default="deepseek-v4-flash")

增加环境配置导入:

text 复制代码
from dotenv import load_dotenv
import os
# 加载当前目录下的.env文件
load_dotenv()

运行python run_experiment_1_1.py后结果如:

运行后生成:

  • JSON 结果文件;
  • 实验证据文件;
  • SHA256 校验文件;
  • 控制台分析结果。

项目设计了实验证据留存机制,仓库中目录:

text 复制代码
validation/
├── latest.json
└── real_20260729T153329Z/
    ├── evidence.json
    └── evidence.sha256

6.10 运行自动化测试

目的:验证核心工具、上下文模式、异常 JSON 容错和实验契约。

运行全部测试:

bash 复制代码
pytest

也可运行指定文件:

bash 复制代码
pytest tests/test_agent.py
pytest tests/test_code_interpreter.py
pytest tests/test_malformed_tool_json.py
pytest test_experiment_1_1.py

预期效果:

  • test_agent.py 验证计算器、货币转换、PDF 解析结构、上下文构建、工具执行、轨迹重置;
  • test_code_interpreter.py 验证代码解释器;
  • test_malformed_tool_json.py 验证异常工具参数 JSON 不会中断 Agent;
  • test_experiment_1_1.py 验证五组上下文模式的消息契约。

6.11 调试建议

调试目标 建议方式
确认配置是否读取 运行 check_provider_config.py
确认默认 Provider 运行 check_default_provider.py
确认模型是否可用 运行对应 Provider 的 quick 脚本
确认工具是否正常 运行 check_pdf_task.pypytest tests/test_agent.py
确认上下文是否符合模式 运行 pytest test_experiment_1_1.py
查看请求响应 使用 ContextAwareAgent(..., verbose=True),具体参数名以代码为准
定位工具 JSON 异常 参考 tests/test_malformed_tool_json.py
复现实验 使用 run_experiment_1_1.py 并保存 JSON 输出

7. 可扩展点与二次开发建议

7.1 新增工具

项目的工具集中在 ToolRegistry 中。新增工具的一般步骤:

  1. ToolRegistry 中新增方法,例如 search_web(query)
  2. _get_tools_description 中补充工具 schema。
  3. _execute_tool 中增加工具名到方法的分发。
  4. tests/test_agent.py 中添加单元测试。
  5. 如果工具依赖外部服务,增加手动检查脚本。
  6. 更新 README 或实验文档。

建议工具示例:

  • 网页搜索;
  • 数据库查询;
  • Excel/CSV 解析;
  • 邮件发送;
  • 内部知识库检索;
  • 汇率缓存;
  • 单位换算。

7.2 新增 Provider

项目已支持 OpenAI-compatible API,多 Provider 接入成本较低。扩展步骤:

  1. config.py 中增加 Provider 名称、base URL、默认模型;
  2. .env.example 中增加对应 API Key 示例;
  3. 增加 tests/manual/check_xxx.pycheck_xxx_quick.py
  4. 验证工具调用格式是否与 OpenAI SDK 兼容;
  5. 检查推理模型是否需要特殊 temperature、max_tokens;
  6. 运行 check_provider_switching.py 验证切换能力。

7.3 新增上下文模式

当前 5 种模式围绕历史、推理、工具调用、工具结果展开。可以继续扩展:

新模式 说明
System Prompt Only 只保留系统提示词和当前用户问题
Recent K Turns 只保留最近 K 轮对话
Tool Result Summary 工具结果压缩为摘要
Retrieved Context Only 只保留检索结果,不保留完整历史
No System Prompt 移除系统提示词
Structured Memory 将历史转为结构化记忆

扩展时需要同步修改:

  • ContextMode
  • _build_context
  • _prepare_messages_for_api
  • evaluate_context_contract
  • test_experiment_1_1.py 或新增测试。

7.4 增强实验评估

当前项目已有结果分析、Token 统计、上下文契约校验。可进一步增加:

  • 最终答案正确性自动评分;
  • 工具调用准确率;
  • 冗余工具调用次数;
  • 平均轮次;
  • 失败类型分类;
  • 多次运行取平均值;
  • 不同模型横向对比;
  • Markdown/HTML 报告导出;
  • 成本估算。

7.5 提升安全性

code_interpreter 可执行 Python 代码,二次开发时应特别注意:

  • 不要直接暴露到公网;
  • 使用容器或沙箱隔离;
  • 限制文件系统访问;
  • 限制网络访问;
  • 设置超时时间;
  • 禁止危险模块,如 os.systemsubprocesssocket 等;
  • 对用户输入和模型生成代码做安全审计。

7.6 改进可观测性

建议增加:

  • 结构化日志;
  • 每轮 tool call 耗时;
  • API 重试次数;
  • 工具异常分类;
  • Prompt/Response 落盘;
  • Trace ID;
  • OpenTelemetry 或 Langfuse 等追踪系统集成。

7.7 落地场景

场景 落地方式
财务报表分析 使用 PDF 解析 + 货币转换 + 代码解释器汇总
跨国预算编制 多币种预算统一换算并生成表格
费用报销审核 解析费用 PDF/票据,计算合计并校验规则
教学实验 演示上下文各组成部分对 Agent 表现的影响
模型选型 同一任务横向比较 Doubao、Kimi、DeepSeek、SiliconFlow
Agent 评测平台 将本项目改造成最小化 Agent eval harness
企业内部知识库助手 新增检索工具,对比不同上下文策略

7.8 面试考点提炼

考点 可结合项目回答的要点
Agent 的基本循环 用户输入 → 模型推理 → tool call → 工具执行 → 结果回填 → 最终答案
上下文工程 历史、推理、工具定义、工具结果分别影响什么
消融实验 控制变量,比较 Full Context 与缺失组件模式
Tool Calling 工具 schema、参数解析、异常 JSON 容错
多模型适配 OpenAI-compatible API、Provider 配置、模型默认值
ReAct 退化分析 无工具结果时模型可能幻觉,无历史时容易遗忘
Token 成本 完整上下文效果好但成本高,摘要/滑动窗口可降本
可复现实验 保存 JSON、Git 信息、依赖版本、证据哈希
安全问题 代码解释器必须沙箱化
评测指标 正确率、工具调用次数、轮次、耗时、Token、失败率

8. 常见问题与排查清单

8.1 API Key 未配置或读取失败

【故障现象】运行 quickstart.pymain.py 或 Provider 检查脚本时提示 API Key 缺失、认证失败或无法初始化 Agent。

【根因】.env 文件不存在、Key 未填写、Provider 名称与配置不匹配,或环境变量未被 python-dotenv 加载。

【修复方案】

  1. 确认项目根目录存在 .env

  2. env.example 复制生成 .env

  3. config.py 中要求填写对应 Provider 的 Key;

  4. 运行:

    bash 复制代码
    python tests/manual/check_provider_config.py
  5. 再运行对应 Provider 的 quick 脚本验证。

8.2 默认 Provider 不符合预期

【故障现象】未指定 Provider 时,程序没有使用 Doubao,或提示某个 Provider 配置缺失。

【根因】本地配置覆盖了默认值,或 config.py 中默认 Provider 逻辑与预期不一致。

【修复方案】

  1. 运行:

    bash 复制代码
    python tests/manual/check_default_provider.py
  2. 检查 .env 中是否设置了默认 Provider;

  3. 如需显式指定,运行命令时传入 Provider 参数,具体参数名以 python main.py --help 为准。

8.3 模型名称不可用或已废弃

【故障现象】API 返回 model not found、invalid model 或类似错误。

【根因】使用了错误模型 ID、旧别名,或当前账号没有该模型权限。README 中提到 DeepSeek 旧别名 deepseek-chat / deepseek-reasoner 已废弃,建议使用 V4 ID。

【修复方案】

  1. 优先使用 README 中列出的默认模型;
  2. DeepSeek 使用 deepseek-v4-flashdeepseek-v4-pro
  3. Kimi 使用 kimi-k3
  4. Doubao 使用 doubao-seed-1-6-thinking-250715
  5. SiliconFlow 使用 Qwen/Qwen3.5-397B-A17B
  6. 通过 --model 参数指定模型,实际参数名以 --help 为准。

8.4 温度或 max_tokens 参数报错

【故障现象】调用 Kimi、DeepSeek 等推理模型时提示 temperature、max_tokens 或 thinking 输出相关参数错误。

【根因】不同推理模型对采样参数和输出长度有特殊要求。README 中提到 Kimi K3 会强制 temperature 为 1,并设置足够大的 max_tokens

【修复方案】

  1. 不要随意绕过 _reasoning_safe_temperature
  2. 使用项目默认模型配置;
  3. 如自定义模型,在 config.py 中补充该模型的参数规则;
  4. 运行对应 Provider 的检查脚本确认参数兼容性。

8.5 工具调用 JSON 解析失败导致循环中断

【故障现象】模型返回工具调用后,程序因参数 JSON 格式错误而异常退出。

【根因】模型可能输出 malformed JSON,而 Agent 没有对异常参数做容错。

【修复方案】

  1. 先运行回归测试:

    bash 复制代码
    pytest tests/test_malformed_tool_json.py
  2. 确认 _execute_tool 或 Agent 主循环中对 JSON 解析异常进行捕获;

  3. 将错误信息作为工具结果或 assistant 可观察信息返回,让模型自我修正;

  4. 不要因为单次工具参数错误直接终止整个 ReAct 循环。

8.6 PDF 解析失败

【故障现象】Agent 调用 parse_pdf 后无法提取文本,或提示 PDF 下载/读取失败。

【根因】URL 不可访问、网络受限、PDF 文件损坏、PDF 是扫描件图片、本地样例文件缺失。

【修复方案】

  1. 先使用仓库自带 PDF:

    text 复制代码
    fixtures/pdfs/sample_financial_report_q1_2024.pdf
    fixtures/pdfs/simple_expense_report.pdf
  2. 运行:

    bash 复制代码
    python tests/manual/check_pdf_task.py
  3. 如果样例 PDF 缺失,运行:

    bash 复制代码
    python create_sample_pdf.py
  4. 对扫描件 PDF,需要额外 OCR 能力,当前摘要中未发现内置 OCR 模块。

8.7 货币转换工具失败

【故障现象】convert_currency 报错、返回空值或结果不符合预期。

【根因】外部汇率服务不可用、网络受限、货币代码错误、金额格式不正确。

【修复方案】

  1. 检查网络连接;
  2. 确认货币代码如 USDCNY 等是否正确;
  3. 使用 pytest tests/test_agent.py 验证货币转换基础逻辑;
  4. 如果外部服务不稳定,可扩展本地缓存或固定汇率 fallback;
  5. 复杂汇总可让 Agent 改用 code_interpreter 计算。

8.8 代码解释器执行失败

【故障现象】code_interpreter 工具执行 Python 代码时报错,或结果与预期不一致。

【根因】生成代码引用了未安装依赖、运行目录不对、代码本身有 bug,或被安全策略限制。

【修复方案】

  1. 运行:

    bash 复制代码
    pytest tests/test_code_interpreter.py
  2. 检查 requirements.txt 是否已安装;

  3. 在可信环境中单独执行模型生成的代码片段;

  4. 为代码解释器增加超时、异常捕获和依赖白名单;

  5. 不要在生产环境直接执行不可信代码。

8.9 No History 模式表现异常

【故障现象】Agent 在 No History 模式下仍似乎能看到历史,或者 Full Context 模式下反而忘记历史。

【根因】上下文构建逻辑不符合模式契约,或消息裁剪位置不正确。

【修复方案】

  1. 运行:

    bash 复制代码
    pytest test_experiment_1_1.py
  2. 重点检查 _build_context_prepare_messages_for_api

  3. 使用 evaluate_context_contract 验证每轮请求中的角色和消息;

  4. 打开 verbose 日志查看实际发送给 API 的 messages。

8.10 No Tool Calls / No Tool Results 模式不符合预期

【故障现象】No Tool Calls 模式下模型仍调用工具,或 No Tool Results 模式下模型仍看到工具结果。

【根因】工具描述未被移除,或工具结果消息仍被加入 API 请求。

【修复方案】

  1. 检查 _get_tools_description 是否根据 ContextMode 控制工具字段;
  2. 检查 _build_context 是否过滤 tool result;
  3. 使用 test_full_contract_uses_raw_followup_contexttest_no_tool_results_requires_literal_hidden_observations 等测试验证;
  4. 保存请求 JSON,确认发送给模型的 tools 字段和 messages 内容。

8.11 Provider 切换失败

【故障现象】从 Doubao 切换到 Kimi/DeepSeek/SiliconFlow 后请求失败。

【根因】不同 Provider 的 base URL、模型名、API Key、温度参数或工具调用格式存在差异。

【修复方案】

  1. 运行:

    bash 复制代码
    python tests/manual/check_provider_switching.py
  2. 分别运行目标 Provider 的完整检查脚本;

  3. 检查 config.py 中 Provider 配置;

  4. 确认对应 .env 中 Key 已填写;

  5. 先用 quick 脚本验证,再跑复杂任务。

8.12 手动脚本无法导入 agentconfig

【故障现象】运行 tests/manual/*.py 时出现 ModuleNotFoundError: No module named 'agent'

【根因】手动脚本位于子目录中,直接运行时 Python 路径可能不包含项目根目录。

【修复方案】

  1. 确认脚本导入了 _bootstrap

  2. _bootstrap.py 中提供了 add_project_root(),应确保它被调用;

  3. 从项目根目录运行脚本,例如:

    bash 复制代码
    python tests/manual/quickstart.py
  4. 不要只在 tests/manual 目录中直接运行而绕过路径初始化。

8.13 测试依赖真实 API 导致失败

【故障现象】运行 pytest 时某些测试因网络、API Key 或模型调用失败。

【根因】部分测试可能是集成测试或手动测试,需要真实 Provider 环境。摘要中未明确所有测试是否已 mock。

【修复方案】

  1. 先运行不依赖外部服务的单元测试;
  2. 配置好 API Key 后再运行集成测试;
  3. 对需要联网的测试使用标记或单独运行;
  4. 参考 unittest.mocktests/test_agent.pytests/test_malformed_tool_json.py 中的用法扩展 mock 测试。

8.14 输出文件或报告未生成

【故障现象】运行消融实验后没有找到 JSON、报告或可视化结果。

【根因】未指定输出路径、目录不存在、命令参数不完整,或运行过程中提前失败。

【修复方案】

  1. 运行:

    bash 复制代码
    python main.py --help
    python run_experiment_1_1.py --help
  2. 查看输出参数说明;

  3. 先调用 Config.create_directories() 或确保程序自动创建目录;

  4. 检查控制台是否有异常堆栈;

  5. 确认当前用户对项目目录有写入权限。

8.15 实验结果不可复现

【故障现象】两次运行结果差异很大,或无法与 validation/ 中证据对齐。

【根因】LLM 输出具有随机性、外部汇率变化、PDF/网络内容变化、模型版本更新、依赖版本不同。

【修复方案】

  1. 使用 run_experiment_1_1.py 记录完整实验信息;
  2. 保存 Git 信息、依赖版本、时间戳和结果 JSON;
  3. 对外部工具结果做缓存或 mock;
  4. 多次运行取平均值;
  5. 使用 evidence.sha256 校验证据文件是否被修改;
  6. 记录模型 ID、Provider、temperature、max_tokens 等参数。
相关推荐
大模型丫丫1 小时前
MCP协议开发实战:从零搭建AI Agent工具链
人工智能
wangxin2081 小时前
大模型稀疏注意力和MoE的宽度丢失与多智能体的维度补充
人工智能·ai·多智能体·管理学·组织管理·coordclaw·稀释注意力
ZEB11061 小时前
深耕矿山智能赛道 长沙迪迈科技以持续技术创新赋能矿业高质量转型
人工智能·科技·制造
一碗白开水一1 小时前
入门实践工程四:基于 PyTorch 的手写数字识别(MNIST 图像分类)|附:环境依赖环境及工程源码
人工智能·pytorch·分类
A15362551 小时前
2026 电商物流系统推荐:多渠道仓配履约数字化选型指南
大数据·数据库·人工智能
SEO_juper1 小时前
2026年Schema自动注入实战:用Python批量给1000个页面加上JSON-LD,AI引用率实测提升38%
人工智能·python·json·seo·独立站
雪的季节1 小时前
不安装YOLO只安装 PyTorch,加载已有yolo数据,从无到有创建模型训练数据并加载使用(重要)
人工智能·pytorch·yolo
超智算科技1 小时前
超智算领衔协办“NVIDIA创业企业展示·西安站”,全栈AI服务赋能行业生态协同发展
大数据·网络·人工智能·物联网·百度
云端漫步19872 小时前
HarmonyOS NEXT AI 智能生活助手:统一 AIService 封装
人工智能·华为·生活·harmonyos