本仓库实现一个受 Tau 分层思想启发、用一个最小可运行的Harness工程的示例。
作者本人知识水平有限,这是在学习过程中通过整理的笔记设计好章节和内容,然后交由AI进行内容审查生成的Jupyter Notebook。 在各个Jupyter中的实现可能有不够优雅的地方。并且对于 Tau 的理解也可能有偏差,欢迎大家在 Issues 中提出问题和建议。
01_tau_architecture_and_boundaries.ipynb:理解 Agent 组成、分层边界与数据流;02_core_types_and_provider_layer.ipynb:学习 Message、Transcript、工具关联与 Provider 协议,并生成provider_model.py;03_agent_loop_tools_and_errors.ipynb:学习 Run/Turn、事件、工具执行和错误语义,并生成agent_loop.py;04_agent_harness_and_lifecycle.ipynb:学习跨运行状态、快照、Listener、重叠保护与取消,并生成harness.py。
完成四章后,可以运行 deepseek_harness_demo/,观察同一套最小模块怎样组合成真实 DeepSeek Harness 应用。
provider_model.py ← agent_loop.py ← harness.py
02 03 04
三个实现文件位于 minimal_harness/,只使用 Python 3.12 标准库。
在本目录执行:
uv venv --python 3.12 .venv
uv pip install --python .\.venv\Scripts\python.exe jupyterlab nbconvert ipykernel.\.venv\Scripts\jupyter-lab.exeNotebook 不需要 API Key,也不会导入 tau-main/src。02–04 章按顺序执行时,会把各章展示的模块源码写入 minimal_harness/。
deepseek_harness_demo/ 不是另一套教学用 Loop,而是直接复用 minimal_harness 中的数据模型、Agent Loop 和 AgentHarness,并补上真实 Provider、Tool 与终端入口:
终端 TUI(app.py)
│ prompt / AgentEvent
▼
AgentHarness 持有 Transcript 和运行状态
│
▼
run_agent_loop 驱动“模型 → 工具 → 模型”循环
├── DeepSeekProvider 调用 Chat Completions API
└── calculate Tool 执行受限的基础算术
各文件的职责如下:
| 文件 | 职责 |
|---|---|
deepseek_provider.py |
把中立 Message、ToolSpec 转换为 DeepSeek JSON,并把响应转换回 AssistantMessage、ToolCall |
calculator_tool.py |
使用 AST 白名单计算基础算术,拒绝函数调用、属性访问和任意 Python 代码 |
app.py |
读取终端输入,调用 harness.prompt(),并渲染完整 AgentEvent 流 |
tests/test_smoke.py |
通过本地脚本响应验证“模型 → ToolCall → ToolResult → 模型”完整链路,不访问网络 |
示例与 Notebook 共用前面创建的 .venv,TUI 本身没有额外第三方依赖。在当前 PowerShell 会话中设置 API Key 后启动:
$env:DEEPSEEK_API_KEY = "你的 API Key"
# 可选:默认值为 deepseek-v4-flash
$env:DEEPSEEK_MODEL = "deepseek-v4-flash"
.\.venv\Scripts\python.exe -m deepseek_harness_demo进入界面后可以输入:
请计算 (17 + 25) * 3,并解释计算顺序。
预期流程是 DeepSeek 先请求 calculate,Loop 执行工具并把结果追加到 Transcript,然后再次调用 DeepSeek 获得最终回答。可用命令包括 /help、/history、/new 和 /exit。
为了观察 Harness 的真实运行过程,TUI 默认输出:
- Provider 请求和响应摘要,但不输出 API Key 或完整 HTTP 正文;
run_start、turn_start、message、tool_start、tool_end、turn_end、run_end;- 工具名称、参数和结构化结果;
- 每次运行前后的 Transcript 长度与
is_running。
下面的测试使用注入的本地 DeepSeek 响应,不产生网络请求或 API 费用:
.\.venv\Scripts\python.exe -m unittest discover -s deepseek_harness_demo/tests -v更详细的实现说明见 deepseek_harness_demo/README.md。
$notebooks = @(
"01_tau_architecture_and_boundaries.ipynb",
"02_core_types_and_provider_layer.ipynb",
"03_agent_loop_tools_and_errors.ipynb",
"04_agent_harness_and_lifecycle.ipynb"
)
foreach ($notebook in $notebooks) {
& .\.venv\Scripts\jupyter-nbconvert.exe `
--to notebook --execute --inplace $notebook `
--ExecutePreprocessor.timeout=180
if ($LASTEXITCODE -ne 0) { throw "Notebook failed: $notebook" }
}