1. 项目概览
system-hint 是《深入理解 AI Agent》第 2 章实验 2-8 的配套代码,主题是 Agent 状态栏(System Hint) :在每轮 LLM 调用前,把当前时间、系统状态、TODO 进度、工具调用计数、错误反馈等动态信息,以临时 role=user 消息追加到上下文末尾,帮助模型减少无限循环、提升状态感知和任务管理能力。
项目同时包含两类内容:
- 可交互 Agent Demo :通过
main.py、quickstart.py体验状态栏机制。 - 可复现实验框架 :通过
run_experiment_2_8.py运行冻结的 Kimi K3 matched campaign,对 disabled、timestamps、tool counter、TODO list、detailed errors、system state、combined 等条件进行对比。
1.1 学习价值
- 理解 ReAct Agent 中"系统提示词 + 动态上下文注入"的工程实现。
- 掌握如何把时间、状态、任务列表、工具计数、错误信息注入 LLM 上下文。
- 学习如何记录完整 trajectory,包括真实发送给 LLM 的
last_llm_messages。 - 了解消融实验如何设计:同一 case 在不同状态栏条件下交替执行、隔离沙箱、基于工具动作和文件系统状态评分。
- 对新手来说,这是一个从"会调 API"进阶到"会设计可观测、可调试、可评估 Agent"的典型项目。
1.2 解决的行业痛点
| 痛点 | 本项目对应机制 |
|---|---|
| Agent 多轮执行后忘记当前时间或任务进度 | 时间戳、TODO list 状态栏 |
| 工具反复调用同一参数导致死循环 | 工具调用计数器、循环预防提示 |
| 工具失败后模型不知道如何修正 | 详细错误信息、修复建议 |
| Agent 不了解当前目录、操作系统、Shell | 系统状态状态栏 |
| 调试时只能看到对话历史,看不到真实 LLM 输入 | trajectory 中记录 last_llm_messages |
| 实验结果不可复现、不可审计 | 冻结协议、隔离沙箱、哈希、checkpoint、resume |
1.3 前置知识要求
建议具备以下基础:
- Python 基础:函数、类、类型注解、
pathlib、json、argparse。 - LLM API 基本概念:system/user/assistant message、tool calling、多轮对话。
- ReAct Agent 基本流程:推理、调用工具、观察结果、继续推理。
- 命令行基础:创建虚拟环境、安装依赖、设置环境变量。
- 可选:了解 OpenAI SDK、Moonshot/Kimi API、pytest 风格测试。
2. 目录结构速览
根目录关键文件如下:
| 路径 | 作用 |
|---|---|
agent.py |
System-Hint Agent 核心实现,包含状态栏、工具执行、TODO、trajectory 保存 |
config.py |
配置加载,支持从环境变量读取 API Key、provider、model 等 |
main.py |
主 CLI 入口,支持交互、单任务、sample、preview、demo 等模式 |
quickstart.py |
快速开始脚本 |
run_experiment_2_8.py |
实验 2-8 冻结 campaign 运行器 |
experiment_protocol.json |
冻结实验协议、case 与 claim policy |
requirements.txt |
Python 依赖清单 |
env.example |
环境变量示例 |
run_sample.sh |
sample 运行脚本,具体内容未在解析摘要中发现 |
test_basic.py |
基础功能测试 |
test_hint_behavior.py |
验证 system hint 作为 user message 注入 |
test_malformed_tool_json.py |
畸形工具参数 JSON 回归测试 |
test_read_file.py |
读取文件相关测试,摘要未提供函数细节 |
test_trajectory_logging.py |
trajectory 日志测试,摘要未提供函数细节 |
test_experiment_2_8.py |
实验运行器关键逻辑测试 |
verify_trajectory.py |
trajectory 校验工具,摘要未提供函数细节 |
view_trajectory.py |
查看 trajectory 文件的工具 |
trajectory.json |
已生成的 trajectory 示例文件 |
test_hint_trajectory.json |
hint 行为测试相关 trajectory |
runs/exp2-8-kimi-k3-20260730-v1/ |
一次历史实验运行产物,包含 comparison、manifest、cases、sandboxes |
CHANGELOG.md |
版本变更记录 |
NOTES.md |
实现说明,与 week1/context pattern 对比 |
README.md |
项目说明与快速开始文档 |
runs/ 目录结构体现了实验框架的审计设计:
comparison.json:对比结果。experiment_protocol.json:本次运行使用的协议副本。manifest.json:运行清单。cases/:每个 case、每个条件的 JSON 结果。sandboxes/:每个 case 的隔离文件系统,包括initial_state.json、install_action.json、documents/、records/、artifacts/、resources/等。
3. 核心模块与职责
3.1 agent.py:Agent 核心
agent.py 是项目最重要的模块,模块说明为 System-Hint Enhanced AI Agent。
核心类:
| 类/函数 | 职责 |
|---|---|
TodoStatus(Enum) |
TODO 状态枚举 |
TodoItem |
单个 TODO 项的数据结构 |
ToolCall |
工具调用记录 |
SystemHintConfig |
System Hint 功能配置 |
SystemHintAgent |
Agent 主体,负责系统提示词、状态栏、工具执行、trajectory 保存 |
_reasoning_safe_temperature(model, requested) |
对推理模型使用安全 temperature,例如 kimi-k3/gpt-5 强制为 1 |
SystemHintAgent 主要方法:
| 方法 | 职责 |
|---|---|
__init__(api_key, provider, model, config, verbose) |
初始化模型、配置、状态 |
_init_system_prompt() |
初始化增强系统提示词 |
_get_system_state() |
获取当前目录、OS、shell 等系统状态 |
_get_timestamp() |
获取当前时间;默认使用真实系统时间 |
_advance_simulated_time(hours, minutes, seconds) |
演示用模拟时间推进 |
_save_trajectory(iteration, final_answer) |
保存每轮 trajectory |
_format_todo_list() |
格式化 TODO 列表 |
_get_system_hint() |
生成动态状态栏内容 |
_get_tools_description() |
生成工具描述 |
_execute_tool(tool_name, arguments) |
执行工具并返回增强反馈 |
从 CHANGELOG.md 可知:
- 默认模型为
kimi-k3。 provider="kimi"或"moonshot"都会解析到kimi-k3,除非显式--model覆盖。kimi-k3返回单独的reasoning_content,Agent 从content读取最终答案。- 推理模型调用使用
max_tokens=8192,并通过_reasoning_safe_temperature()强制temperature=1。 - assistant turn 通过
model_dump()回放,包含reasoning_content,以支持多轮工具循环。
3.2 config.py:配置加载
| 类/函数 | 职责 |
|---|---|
AgentConfig |
Agent 配置数据类 |
AgentConfig.from_env() |
从环境变量加载配置 |
AgentConfig.validate() |
校验配置 |
get_config(preset) |
根据 preset 获取配置 |
该模块依赖:
agentbook.providersdataclassesdotenvostyping
说明项目支持通过 .env 或环境变量配置 API Key 等参数。具体环境变量名称未在解析摘要中完整列出,需以 env.example 或源码为准。
3.3 main.py:CLI 与演示入口
main.py 是主入口,包含以下函数:
| 函数 | 职责 |
|---|---|
print_section(title) |
打印分节标题 |
print_result(result) |
打印任务结果 |
get_sample_task() |
获取示例任务 |
execute_single_task(task, config, verbose, provider, model) |
执行单个任务 |
interactive_mode() |
交互模式 |
demo_basic_features() |
演示基础功能 |
demo_tool_loop_prevention() |
演示工具循环预防 |
demo_comparison() |
演示对比 |
preview_status_bar(config) |
离线预览状态栏,不需要 API Key |
main() |
CLI 主函数 |
README 明确给出的离线预览命令:
bash
python main.py --mode preview
该模式会渲染五种技术:
- timestamps
- tool-call counter
- TODO list
- detailed errors
- system-state awareness
并支持关闭单项:
bash
python main.py --mode preview --no-timestamps
python main.py --mode preview --no-counter
python main.py --mode preview --no-todo
python main.py --mode preview --no-errors
python main.py --mode preview --no-state
3.4 run_experiment_2_8.py:实验运行器
该模块负责运行 Chapter 2 Experiment 2-8 的冻结 Kimi K3 campaign。
关键函数:
| 函数 | 职责 |
|---|---|
canonical_json(value) |
生成规范化 JSON |
sha256_bytes(value) |
计算字节 SHA256 |
sha256_file(path) |
计算文件 SHA256 |
utc_now() |
获取 UTC 时间 |
atomic_json(path, value) |
原子写入 JSON |
sandbox_hash(root) |
计算沙箱哈希 |
condition_order(suite, index) |
控制条件顺序,README 说明 arms alternate order |
case_prompt(suite, case) |
生成 case prompt |
initialize_sandbox(root, suite, case) |
初始化隔离沙箱 |
load_state(root) |
加载沙箱状态 |
function_tool(name, description, properties, required) |
构造 function tool 描述 |
tools_for(suite, features) |
根据 suite 和 feature 返回工具 |
status_message(features, state, counters, todos) |
生成实验状态栏消息 |
timestamp_wrap(features, timestamp, content) |
包装时间戳 |
execute_tool(...) |
执行实验工具 |
component_scores(...) |
基于工具事件和文件系统状态评分 |
validate_tool_protocol(messages) |
校验工具协议 |
accepted_receipt(call) |
生成接受回执 |
README 中给出的正式实验命令:
bash
python run_experiment_2_8.py \
--output runs/exp2-8-kimi-k3-$(date +%Y%m%d-%H%M%S)
实验特点:
- 每个 preregistered contrast 运行 5 个真实 Kimi K3 case。
- 对比条件包括:disabled、raw timestamps、guided timestamps、tool counter、TODO list、detailed errors、system state、all features combined。
- 每个 case 使用独立本地沙箱。
- 评分依据是工具动作和文件系统状态,而不是模型自我汇报。
- 每个 accepted response 和 tool event 后 checkpoint。
- 可 resume,不会重复生成已完成 case。
- 保留 response IDs、usage、raw protocol。
- usage 以人民币计价。
- 对所有证据做哈希,并扫描凭据。
3.5 测试与工具脚本
| 文件 | 作用 |
|---|---|
test_basic.py |
测试基础功能和命令执行 |
test_hint_behavior.py |
测试 system hint 被添加为 user message |
test_malformed_tool_json.py |
确保畸形工具参数 JSON 不会中断 ReAct loop |
test_experiment_2_8.py |
测试实验排序、时间戳目标、错误 gate、工具协议、沙箱隔离等 |
view_trajectory.py |
格式化查看 trajectory |
verify_trajectory.py |
校验 trajectory,具体函数未在摘要中发现 |
3.6 核心原理通俗解读
可以把 System Hint 理解为 Agent 的"行车仪表盘"。
普通 ReAct Agent 每轮只看到:
- system prompt
- 用户任务
- 历史对话
- 工具返回结果
但它经常不知道:
- 现在是第几轮?
- 某个工具是不是已经调用了很多次?
- 当前目录在哪里?
- 哪些子任务完成了?
- 上一次工具失败到底错在哪里?
System Hint 的做法是:在每轮调用 LLM 前,临时追加一条 user message:
text
=== SYSTEM STATE ===
Current Time: ...
Current Directory: ...
Tool Calls:
- read_file: 3
TODO:
1. [completed] ...
2. [in_progress] ...
Errors:
- Last error: ...
这条消息不是用户真实输入,而是运行时状态摘要。它的价值在于:
- 低成本注入状态:不需要重写整段 system prompt。
- 每轮动态更新:时间、计数、TODO 都能实时变化。
- 便于调试:trajectory 中可以看到模型真实收到的状态栏。
- 便于消融实验:可以单独开关 timestamp、counter、TODO、error、state。
4. 关键数据流与调用链
4.1 单次 Agent 任务执行流
根据 NOTES.md,项目沿用 ReAct loop,并在上下文管理、工具反馈、任务管理上增强。典型调用链如下:
- 用户通过 CLI 调用
main.py。 main()解析参数,确定模式:previewinteractivesinglesample- demo 模式
- 配置通过
config.py加载:AgentConfig.from_env()AgentConfig.validate()
- 创建
SystemHintAgent:- 读取 API Key、provider、model。
- 初始化
SystemHintConfig。 - 调用
_init_system_prompt()。
- 用户任务被加入 conversation history。
- 每轮 ReAct:
_get_system_hint()生成当前状态栏。- 将状态栏作为临时
role=user消息追加到发送给 LLM 的消息末尾。 - 保存
last_llm_messages,即真实发送给 LLM 的完整消息。 - 调用 LLM。
- 如果模型请求工具,调用
_execute_tool(tool_name, arguments)。 - 工具结果附带时间戳、调用编号、错误建议等。
- 更新 TODO、工具计数、系统状态。
_save_trajectory(iteration, final_answer)写入 trajectory。
- 检测到最终答案或达到最大迭代次数后结束。
4.2 System Hint 注入数据流
text
conversation_history
↓
_get_system_hint()
↓
messages_to_send = conversation_history + [user(system_hint)]
↓
self.last_llm_messages = messages_to_send
↓
LLM API
↓
assistant response / tool_calls
↓
tool result + status update
↓
conversation_history 更新
根据 CHANGELOG.md:
conversation_history只保存基础对话,不包含动态 system hints。last_llm_messages保存完整发送给 LLM 的消息数组,包括 system hint。- 这两个字段的区分是调试 Agent 行为的关键。
4.3 Trajectory 保存数据流
CHANGELOG.md 给出的 trajectory 结构示例包括:
timestampiterationprovidermodelconversation_historylast_llm_messagestool_callstodo_list
时间戳规则:
- 默认
simulate_time_delay = False。 _get_timestamp()使用datetime.now()。trajectory_data['timestamp']使用datetime.now().isoformat()。- 工具调用和 TODO 项时间戳也使用真实系统时间。
- 只有 demo 场景才可能使用模拟时间。
4.4 实验 2-8 数据流
text
experiment_protocol.json
↓
run_experiment_2_8.py 加载 suite/case
↓
condition_order(suite, index) 决定条件顺序
↓
initialize_sandbox(root, suite, case) 创建隔离沙箱
↓
case_prompt(suite, case) 生成任务
↓
tools_for(suite, features) 构造工具
↓
每轮:
status_message(features, state, counters, todos)
↓
LLM 响应
↓
validate_tool_protocol(messages)
↓
execute_tool(...)
↓
checkpoint 原子写入 JSON
↓
component_scores(...) 基于动作和文件系统评分
↓
comparison.json / manifest.json / cases/*.json / sandboxes/*
4.5 方案优劣对比表格
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 不使用状态栏 | 上下文短、实现简单 | 容易忘时间、忘进度、重复调用工具 | 简单单轮任务 |
| 时间戳状态栏 | 增强时间感知,适合多日/时序任务 | 增加少量上下文 | 日志分析、日程、时序排障 |
| 工具调用计数 | 可发现重复调用,辅助防循环 | 只能提示,不能强制停止 | 文件搜索、命令执行、多工具任务 |
| TODO list | 明确任务拆解和状态 | 需要模型遵守更新规则 | 多步骤复杂任务 |
| 详细错误 | 工具失败后更容易自纠 | 错误过长可能占用上下文 | 文件操作、命令执行、API 调用 |
| 系统状态 | 当前目录、OS、Shell 更明确 | 可能泄露环境信息,需注意脱敏 | 本地操作、开发助手 |
| 全部组合 | 状态最完整 | token 开销最大,提示更复杂 | 长任务、实验评估、生产 Agent 原型 |
4.6 流程易错节点标注
- 状态栏注入位置错误:必须作为临时 user message 追加到本轮上下文末尾,而不是永久写入 conversation history。
- 混淆
conversation_history与last_llm_messages:调试时要看last_llm_messages,否则看不到真实 system hint。 - 推理模型 temperature 错误 :kimi-k3/gpt-5 等推理模型通过
_reasoning_safe_temperature()强制 temperature=1。 - 工具协议不合法 :实验运行器会通过
validate_tool_protocol(messages)校验 call/result 之间不能插入非 tool 消息。 - 沙箱未隔离 :实验必须通过
initialize_sandbox()初始化独立目录,避免 case 互相污染。 - checkpoint/resume 误判:已完成 case 不会重新生成;如果想重跑,需要使用新的 output 目录或清理对应产物。
- 时间模拟误用:默认使用真实系统时间,模拟时间只用于 demo。
5. 关键类/函数速查表
5.1 Agent 核心
| 名称 | 类型 | 来源文件 | 关键说明 |
|---|---|---|---|
TodoStatus |
Enum | agent.py |
TODO 状态 |
TodoItem |
dataclass/class | agent.py |
TODO 项 |
ToolCall |
dataclass/class | agent.py |
工具调用记录 |
SystemHintConfig |
class | agent.py |
状态栏开关配置 |
SystemHintAgent |
class | agent.py |
Agent 主体 |
SystemHintAgent._get_system_hint() |
method | agent.py |
生成动态状态栏 |
SystemHintAgent._execute_tool() |
method | agent.py |
执行工具并增强反馈 |
SystemHintAgent._save_trajectory() |
method | agent.py |
保存 trajectory |
_reasoning_safe_temperature() |
function | agent.py |
推理模型 temperature 保护 |
5.2 配置与入口
| 名称 | 类型 | 来源文件 | 关键说明 |
|---|---|---|---|
AgentConfig |
class | config.py |
Agent 配置 |
AgentConfig.from_env() |
classmethod | config.py |
从环境变量加载 |
AgentConfig.validate() |
method | config.py |
校验配置 |
get_config(preset) |
function | config.py |
获取预设配置 |
main() |
function | main.py |
CLI 主入口 |
interactive_mode() |
function | main.py |
交互模式 |
preview_status_bar() |
function | main.py |
离线预览状态栏 |
execute_single_task() |
function | main.py |
单任务执行 |
5.3 实验运行器
| 名称 | 类型 | 来源文件 | 关键说明 |
|---|---|---|---|
canonical_json() |
function | run_experiment_2_8.py |
规范化 JSON,用于哈希/审计 |
sha256_bytes() |
function | run_experiment_2_8.py |
字节哈希 |
sha256_file() |
function | run_experiment_2_8.py |
文件哈希 |
atomic_json() |
function | run_experiment_2_8.py |
原子写 JSON |
sandbox_hash() |
function | run_experiment_2_8.py |
沙箱完整性哈希 |
condition_order() |
function | run_experiment_2_8.py |
控制实验条件顺序 |
initialize_sandbox() |
function | run_experiment_2_8.py |
初始化隔离沙箱 |
tools_for() |
function | `run_experiment_2_8.py | 根据 feature 生成工具 |
status_message() |
function | run_experiment_2_8.py |
实验状态栏消息 |
execute_tool() |
function | run_experiment_2_8.py |
执行实验工具 |
component_scores() |
function | run_experiment_2_8.py |
计算评分 |
validate_tool_protocol() |
function | run_experiment_2_8.py |
校验工具调用协议 |
5.4 测试与查看工具
| 名称 | 类型 | 来源文件 | 关键说明 |
|---|---|---|---|
test_basic_functionality() |
test | test_basic.py |
基础功能测试 |
test_command_execution() |
test | test_basic.py |
命令执行测试 |
test_hint_behavior() |
test | test_hint_behavior.py |
验证 hint 是 user message |
test_execute_task_survives_malformed_tool_arguments_json() |
test | test_malformed_tool_json.py |
畸形 JSON 不应中断循环 |
view_trajectory() |
function | view_trajectory.py |
查看 trajectory |
format_time() |
function | view_trajectory.py |
格式化 ISO 时间 |
6. 如何运行与调试
6.1 环境准备
README 提到应从仓库根目录使用 Chapter 2 共享环境,并在进入目录前激活:
Windows PowerShell:
powershell
.venv\Scripts\Activate.ps1
Windows cmd:
bat
.venv\Scripts\activate.bat
如果你在当前目录独立创建环境,可按通用 Python 流程操作:
bash
python -m venv .venv
激活后安装依赖:
bash
pip install -r requirements.txt
requirements.txt 的具体版本未在解析摘要中发现,因此不要在博客中臆造版本号。
6.2 配置环境变量
项目包含 env.example,但具体变量名未在解析摘要中列出。可确定的是:
config.py使用dotenv和os。AgentConfig.from_env()从环境变量加载配置。- 真实 LLM 调用需要对应 provider 的 API Key。
- 离线 preview 模式不需要 API Key。
建议操作:
- 复制
env.example为.env。 - 按文件中的提示填入 API Key。
- 若只运行 preview,可暂不配置 Key。
注意:具体变量名未在解析摘要中发现,请以仓库中的
env.example和config.py源码为准。
6.3 第一步:运行离线预览
执行目的:在不调用 LLM、不配置 API Key 的情况下理解状态栏到底给模型追加了什么。
bash
python main.py --mode preview
预期行为:
- 程序渲染五种状态栏技术:
- timestamps
- tool-call counter
- TODO list
- detailed errors
- system-state awareness
- 每种技术展示"without vs with"的对比。
- 打印追加到上下文末尾的完整 status message。
- 不会产生 API 调用费用。
正常控制台输出特征:
- 应出现分节标题。
- 应能看到类似
=== SYSTEM STATE ===的状态栏内容。 - 应能看到时间、工具计数、TODO、错误、系统状态等字段。
- 不应出现网络请求或 API Key 缺失错误。
可单独关闭某项:
bash
python main.py --mode preview --no-timestamps
python main.py --mode preview --no-counter
python main.py --mode preview --no-todo
python main.py --mode preview --no-errors
python main.py --mode preview --no-state
6.4 第二步:运行 sample 模式
README 和 NOTES 提到 sample 模式:
bash
python main.py --mode sample
执行目的:运行内置示例任务,观察多工具任务中 TODO、工具计数、错误反馈和 trajectory 的效果。
NOTES 中给出的 sample task 是分析 week1 和 week2 目录中的 AI Agent 项目,包括:
- 进入父目录访问 week1/week2。
- 列出 week1 项目文件夹。
- 读取关键文件。
- 列出 week2 项目文件夹。
- 读取 README。
- 创建综合分析文件。
预期生成文件:
- 根目录下可能生成或更新
trajectory.json。 - Agent 可能在文件系统中创建分析文件,具体文件名未在解析摘要中发现。
正常控制台输出特征:
- 应显示任务执行过程。
- 应显示工具调用和工具结果。
- 若启用状态栏,工具结果中可能出现调用编号,例如
Tool call #3 for 'read_file'。 - 最终应输出任务结果。
注意:该 sample task 依赖上级目录中的 week1/week2 项目结构;如果当前仓库环境不完整,可能出现文件找不到等错误。
6.5 第三步:单任务执行
NOTES 给出的命令形式:
bash
python main.py --mode single --task "Your task here"
执行目的:直接给 Agent 一个明确任务,适合最小化调试。
示例:
bash
python main.py --mode single --task "Read the README and summarize the key features."
预期行为:
- 程序加载配置。
- 创建
SystemHintAgent。 - 执行 ReAct loop。
- 输出最终答案。
- 保存 trajectory。
适用调试场景:
- 验证 API Key 是否生效。
- 验证某个工具是否能被正确调用。
- 验证 system hint 是否进入
last_llm_messages。 - 验证畸形工具参数是否会被容错处理。
6.6 第四步:交互模式
NOTES 给出的默认交互模式:
bash
python main.py
执行目的:连续输入任务,观察 Agent 在多轮对话中的状态栏变化。
预期行为:
- 程序进入交互式命令行。
- 用户可连续输入任务。
- TODO、工具计数、系统状态等应随对话推进更新。
- 每轮或每次任务后可能更新
trajectory.json。
退出交互模式的具体命令未在解析摘要中发现,通常可尝试 Ctrl+C、Ctrl+D 或输入常见退出词,但需以源码实现为准。
6.7 第五步:运行 quickstart
bash
python quickstart.py
执行目的:快速启动 Agent 体验。
该脚本包含 main() 函数并带有 Python main guard,但摘要未提供更详细参数和输出说明。运行前建议先查看脚本源码或使用:
bash
python quickstart.py --help
注意:
quickstart.py --help是否支持参数未在解析摘要中发现,需实际运行确认。
6.8 第六步:查看 trajectory
项目提供 view_trajectory.py:
bash
python view_trajectory.py trajectory.json
执行目的:格式化查看保存的 trajectory。
可查看的重点字段:
timestampiterationprovidermodelconversation_historylast_llm_messagestool_callstodo_list
调试建议:
- 先看
last_llm_messages,确认 system hint 是否真的发送给 LLM。 - 再看
tool_calls,确认工具名、参数、时间戳和错误信息。 - 最后看
conversation_history,区分基础对话和临时状态栏。
verify_trajectory.py 也存在,但摘要未提供函数和 CLI 用法,无法确定具体命令。
6.9 第七步:运行测试
可优先运行摘要中明确的测试文件:
bash
python test_basic.py
python test_hint_behavior.py
python test_malformed_tool_json.py
python test_experiment_2_8.py
如果项目使用 pytest,也可以尝试:
bash
pytest
但摘要未明确说明测试运行器,因此 pytest 是否为官方推荐方式未在解析摘要中发现。
测试覆盖的重点:
- 基础功能和命令执行。
- system hint 是否作为 user message 注入。
- 畸形工具参数 JSON 是否不会中断 ReAct loop。
- 实验条件顺序是否交替。
- timestamp objective 是否从 actions 派生。
- detailed error gate 是否要求失败旧名称和实际读取。
- tool protocol 是否拒绝 call/result 之间插入非 tool 消息。
- sandbox 初始化是否隔离并可哈希。
6.10 第八步:运行正式实验 2-8
README 给出的命令:
bash
python run_experiment_2_8.py \
--output runs/exp2-8-kimi-k3-$(date +%Y%m%d-%H%M%S)
Windows PowerShell 不支持上述 $(date +%Y%m%d-%H%M%S) 的 bash 写法,可手动指定目录:
powershell
python run_experiment_2_8.py --output runs/exp2-8-kimi-k3-manual-test
执行目的:运行冻结 matched campaign,生成可审计实验结果。
运行前检查:
- 已配置 Moonshot/Kimi API Key。
- 网络可访问对应 API。
experiment_protocol.json存在且未被随意修改。- output 目录不要与历史目录混用,建议使用新目录。
预期生成:
text
runs/<your-output>/
comparison.json
experiment_protocol.json
manifest.json
cases/
*.json
sandboxes/
<case-condition>/
initial_state.json
install_action.json
artifacts/
documents/
records/
resources/
正常运行特征:
- 每个 accepted response 后 checkpoint。
- 每个 tool event 后 checkpoint。
- 已完成 case 会 resume,不重复生成。
- 结果评分来自工具动作和文件系统状态。
- 证据文件会被哈希处理。
- 会扫描凭据,防止泄露。
费用与耗时:
- 该命令会调用真实 Moonshot
kimi-k3。 - 会产生 API 费用。
- 具体耗时、token 用量、费用金额未在解析摘要中发现。
6.11 结果对比模块
本仓库附带的历史运行目录为:
text
runs/exp2-8-kimi-k3-20260730-v1/
可查看其中的 comparison.json、manifest.json 和 cases/*.json,但不要把历史结果与你自己的新运行混为一谈。
7. 可扩展点与二次开发建议
7.1 新增状态栏字段
扩展位置:SystemHintAgent._get_system_hint()。
可新增字段:
- 当前预算/token 用量。
- 已用时间。
- 最近一次工具失败摘要。
- 当前任务完成百分比。
- 文件系统变更摘要。
- 外部系统状态,例如数据库连接、任务队列状态。
建议:
- 保持状态栏简洁,避免每轮追加大量文本。
- 对长文本做截断或分级展示。
- 对敏感信息脱敏。
- 在
SystemHintConfig中增加开关,方便消融实验。
7.2 新增工具
扩展位置:
- Demo Agent:
SystemHintAgent._execute_tool()与_get_tools_description()。 - 实验框架:
function_tool()、tools_for()、execute_tool()。
新增工具时需要同步考虑:
- tool schema 的 name、description、parameters。
- 参数校验。
- 错误返回格式。
- 工具调用计数。
- sandbox 权限边界。
- trajectory 记录。
- 评分规则是否需要更新。
7.3 新增 TODO 规则
扩展位置:
_init_system_prompt()中关于 TODO 的规则。_format_todo_list()的展示格式。TodoItem/TodoStatus数据结构。
可增强方向:
- 自动拆解复杂任务。
- 给 TODO 增加优先级。
- 给 TODO 增加依赖关系。
- 当工具失败时自动新增"修复子任务"。
- 当任务长期 in_progress 时提醒模型。
7.4 新增实验条件
扩展位置:
experiment_protocol.jsonrun_experiment_2_8.pytools_for()status_message()component_scores()condition_order()
建议流程:
- 在协议中注册新 feature。
- 明确该 feature 的状态栏内容。
- 明确该 feature 启用/禁用时工具行为是否变化。
- 增加对应 case。
- 增加评分逻辑。
- 增加测试,避免条件串扰。
- 使用新 output 目录运行,避免污染历史结果。
7.5 增强 trajectory 分析
当前 trajectory 已包含 last_llm_messages,这是很好的调试基础。可继续扩展:
- 增加 token usage 字段。
- 增加每次工具调用耗时。
- 增加状态栏版本号。
- 增加错误分类。
- 增加模型
reasoning_content的单独存储或开关。 - 编写轨迹 diff 工具,对比 disabled/enabled 条件。
注意:CHANGELOG.md 提到 assistant turn 会用 model_dump() 回放并包含 reasoning_content,但保存 trajectory 时是否完整落盘 reasoning_content 需以实际 _save_trajectory() 源码为准,摘要未明确全部字段。
7.6 增强安全与沙箱
实验运行器已经具备:
- 隔离沙箱。
- 证据哈希。
- 凭据扫描。
二次开发建议:
- 对 shell 命令增加白名单。
- 限制文件访问路径。
- 对网络访问进行开关控制。
- 对写入文件做大小限制。
- 对 API Key、token、密码做更严格的脱敏。
- 在 CI 中运行凭据扫描和沙箱哈希校验。
7.7 落地场景
| 场景 | 可落地方式 |
|---|---|
| 编程助手 | 注入当前目录、Git 分支、测试失败摘要、TODO |
| 运维排障 Agent | 注入系统状态、最近错误、命令执行计数 |
| 数据分析 Agent | 注入数据集路径、已加载表、分析步骤进度 |
| 客服 Agent | 注入工单状态、用户等级、最近处理记录 |
| 自动化测试 Agent | 注入测试进度、失败用例、重试次数 |
| 长流程业务 Agent | 注入审批状态、待办列表、时间节点 |
7.8 面试考点提炼
- 为什么 system hint 要作为临时 user message,而不是永久写入 conversation history?
conversation_history和last_llm_messages有什么区别?- 工具调用计数如何帮助减少 ReAct 死循环?
- TODO list 状态栏如何提升多步任务完成率?
- 详细错误信息应该包含哪些内容?过长怎么办?
- 如何设计消融实验验证状态栏有效?
- 为什么实验评分不能依赖模型自我汇报?
- 如何保证实验可复现、可审计?
- 推理模型如 kimi-k3/gpt-5 在 temperature、max_tokens、多轮消息回放方面有哪些注意点?
- trajectory 应该记录哪些字段才能支持事后调试?
8. 常见问题与排查清单
8.1 离线预览无法运行
【故障现象】执行 python main.py --mode preview 报错或没有输出五种状态栏对比。
【根因】可能是命令执行目录不对、Python 环境依赖未安装,或本地代码与摘要版本不一致。
【修复方案】
- 确认当前目录包含
main.py。 - 执行
pip install -r requirements.txt。 - 执行
python main.py --help查看是否支持--mode preview。 - 若参数不存在,以本地
main.py源码为准。
8.2 API Key 缺失或无效
【故障现象】运行 single、sample、interactive 或正式实验时出现认证失败、API Key 缺失或模型无法访问。
【根因】未配置 .env,环境变量未加载,或 Key 没有对应 provider/model 权限。
【修复方案】
- 复制
env.example为.env。 - 按
config.py和env.example要求填入正确变量。 - 确认激活的是同一个虚拟环境。
- 先用不需要 Key 的
python main.py --mode preview验证代码可运行。 - 再运行最小 single task 验证 API。
具体环境变量名未在解析摘要中发现,请查看本地
env.example与config.py。
8.3 找不到 week1/week2 目录
【故障现象】运行 sample task 时提示无法访问 week1、week2 或相关文件不存在。
【根因】NOTES 中的 sample task 假设上级目录存在 week1/week2 项目结构。
【修复方案】
- 确认仓库目录结构是否完整。
- 用
python main.py --mode single --task "..."执行不依赖 week1/week2 的任务。 - 或修改 sample task,使其指向当前目录中真实存在的文件。
8.4 System Hint 没有出现在对话历史中
【故障现象】查看 conversation_history 时找不到动态状态栏。
【根因】这是设计如此。根据 CHANGELOG.md,动态 system hint 不永久写入 conversation_history,而是临时追加到 last_llm_messages。
【修复方案】
- 查看 trajectory 中的
last_llm_messages。 - 使用
view_trajectory.py trajectory.json格式化查看。 - 调试时重点检查最后一条 user message 是否为状态栏。
8.5 Trajectory 文件未生成或内容不完整
【故障现象】运行任务后没有 trajectory.json,或文件中缺少 last_llm_messages、tool calls 等字段。
【根因】可能任务在初始化前失败、文件路径无写权限、代码版本较旧,或异常发生在保存前。
【修复方案】
- 确认当前目录有写权限。
- 先用 preview 模式确认程序可启动。
- 再用 single task 跑一个简单任务。
- 检查控制台异常堆栈。
- 确认
agent.py中_save_trajectory()已被调用。 - 若历史 trajectory 是旧版本生成,可能缺少新字段,需重新运行任务。
8.6 畸形工具参数导致循环中断
【故障现象】模型输出非法 JSON 工具参数后,Agent 直接崩溃或停止。
【根因】工具参数解析缺少容错,或异常没有被转换为工具反馈。
【修复方案】
- 运行
python test_malformed_tool_json.py确认回归测试是否通过。 - 检查
_execute_tool()或工具调用解析逻辑是否捕获 JSON 解析异常。 - 将错误以结构化工具结果返回给模型,让模型自行修正。
- 不要让一次参数解析错误终止整个 ReAct loop。
8.7 工具调用协议校验失败
【故障现象】实验运行中 validate_tool_protocol(messages) 报错或拒绝响应。
【根因】根据 test_experiment_2_8.py,tool call 与 tool result 之间不能插入非 tool 消息;消息顺序不符合协议。
【修复方案】
- 检查 assistant tool call 后是否立刻追加对应 tool result。
- 不要在 call/result 之间插入普通 assistant/user 消息。
- 检查多工具调用时 tool call ID 是否一一对应。
- 运行
python test_experiment_2_8.py定位具体协议测试。
8.8 实验 resume 后没有重新生成 case
【故障现象】重复执行 run_experiment_2_8.py --output ...,已完成 case 没有重新跑。
【根因】实验运行器设计为 checkpoint 后 resume,不会重复生成已完成 case。
【修复方案】
- 如果希望全新运行,使用新的
--output目录。 - 如果希望重跑某个 case,备份后删除该 case 对应 checkpoint 或使用新目录。
- 不要直接修改历史
runs/exp2-8-kimi-k3-20260730-v1/目录。
8.9 沙箱哈希不一致或证据被污染
【故障现象】实验审计时 sandbox hash 不匹配,或 case 结果疑似被其他运行修改。
【根因】多个运行共用同一沙箱目录,或运行后手动修改了 sandboxes 中的文件。
【修复方案】
- 每次实验使用新的 output 目录。
- 不要手动编辑
runs/.../sandboxes/下的文件。 - 使用
sandbox_hash()或测试逻辑校验完整性。 - 保留原始
manifest.json、comparison.json和cases/*.json。
8.10 推理模型多轮工具调用失败
【故障现象】使用 kimi-k3/gpt-5 等推理模型时,多轮工具调用报错或上下文回放失败。
【根因】推理模型可能返回 reasoning_content,对 temperature、max_tokens 或消息回放有特殊要求。
【修复方案】
- 确认使用
_reasoning_safe_temperature()处理 temperature。 - 对 kimi-k3 使用足够的
max_tokens,README 中提到为 8192。 - assistant turn 回放时使用
model_dump(),保留模型要求字段。 - 不要擅自删除
reasoning_content,除非确认 API 支持。
8.11 状态栏导致上下文过长
【故障现象】多轮任务后 token 用量快速上升,甚至超过模型上下文限制。
【根因】每轮状态栏、工具结果、错误详情、TODO 列表持续累积,历史对话未压缩。
【修复方案】
- 对错误详情做截断,verbose 模式才输出完整 traceback。
- 对 TODO 列表只保留当前相关项。
- 对工具结果做摘要。
- 为长任务增加历史压缩或滚动窗口。
- 在
SystemHintConfig中关闭不需要的状态栏功能。
8.12 Windows 下 bash 日期命令不可用
【故障现象】在 Windows PowerShell 或 cmd 中运行 README 的 $(date +%Y%m%d-%H%M%S) 命令报错。
【根因】该语法属于 bash/sh,不适用于 Windows 默认 shell。
【修复方案】
- 在 PowerShell/cmd 中手动指定输出目录:
powershell
python run_experiment_2_8.py --output runs/exp2-8-kimi-k3-manual
- 或在 Git Bash/WSL 中运行 README 原命令。
- 确保输出目录位于项目内,便于审计和清理。
8.13 测试命令不确定
【故障现象】不知道应该用 python test_xxx.py 还是 pytest。
【根因】解析摘要显示测试文件带有 Python 入口线索,但未明确官方测试运行器。
【修复方案】
- 先尝试直接运行:
bash
python test_basic.py
python test_hint_behavior.py
python test_malformed_tool_json.py
python test_experiment_2_8.py
- 如果项目根目录或 CI 配置中明确使用 pytest,再运行
pytest。 - 若某些测试文件没有函数摘要,例如
test_read_file.py、test_trajectory_logging.py,请查看源码确认其测试框架。