harness — Autonomous Chat
harness 是 niuma_code 的默认模式。无需任何命令,直接描述任务即可——LLM 在工具循环中自主探索完成。
How It Works
You type a task → LLM reads files → Edits code → Runs commands → Checks results → Done
模型在 tool-use 循环中自主决策:调用工具、评估结果、决定继续或停止。没有预先规划——你的初始输入越清晰,效果越好。
Architecture
harness 采用三层架构:
ChatService (对话编排: 召回→对话→更新)
└── HarnessEngine (工具循环内核)
├── StreamEngine (单轮流式传输 + watchdog 重连)
└── ToolExecutor (工具权限检查 + 批量执行)
HarnessEngine 是核心引擎,负责:
- 构建请求(注入工具定义 + 系统 prompt)
- 调用 StreamEngine 发起流式请求
- 若 LLM 返回 tool_use → ToolExecutor 执行工具 → 将结果追加到消息 → 重复
- 若 LLM 返回纯文本 → 循环结束,输出最终回复
Tool Categories
| Category | Tools | Description |
|---|---|---|
| Knowledge Graph | kg_find_symbol, kg_list_classes, kg_get_callers |
代码结构查询 |
| Bash | execute_bash |
Shell 命令执行(含权限门) |
| File | read_file, write_file, edit_file, glob_files, grep_content |
文件读写与搜索 |
| Web Search | web_search |
联网搜索(中继 API 服务端执行) |
| Sub-agent | spawn_subagent |
启动子代理处理独立子任务 |
首轮默认使用全量工具,LLM 自行决策调用哪些。
Loop Control
自然停止
LLM 不返回 tool_use 块时,循环自然结束。
死循环检测
连续 3 轮工具调用签名(工具名+入参)完全相同 → 判定原地打转 → 自动停止,进入总结阶段。
用户取消
按 Esc 或 Ctrl+C 随时取消生成,保留已输出的部分回复。
Error Handling
API 错误自动重试
| Failure | Response |
|---|---|
| Network stall (no events) | Watchdog 检测后自动重连 |
| Single round timeout | Watchdog 检测后自动重连 |
| Transient error (429/5xx/连接失败) | 指数退避重试(封顶 120s) |
| Message structure error | 清理消息后重试 |
| User interrupt | 保留已输出部分 |
Watchdog 守护线程每 10s 检查心跳,双判据触发关流:
- 停滞:距上次事件超过
API_TIMEOUT(连接黑洞) - 超时:整轮耗时超过
API_ROUND_MAX(thinking-only 长响应)
空回复保护
LLM 返回空文本且无 tool_use 时,线性退避重试(3s → 6s → 9s 封顶),最多 10 次后询问用户是否继续。TUI 模式下自动继续。
Recall Integration
当历史记忆命中时,harness 自动在最终回复首尾包裹记忆引用:
[根据我的记忆 (YYYY-MM-DD),结合工具调用结果:]
... LLM 回复 ...
[以上内容基于历史记忆和实时工具调用结果综合生成]
工具调用过程中的中间文本不受 recall 包裹,仅最终答案受控。
When to Use harness
| Good For | Not Ideal For |
|---|---|
| Exploratory tasks | Tasks with hard deadlines |
| Quick edits and fixes | Multi-step verification |
| Fuzzy requirements | Parallel independent tasks |
| Single-goal work | Complex orchestration |
Example: Bug Fix
> The login function in auth.py throws a KeyError when email is missing. Fix it.
harness will:
- Read
auth.pyto find the login function - Identify the missing email check
- Add input validation
- Run tests if available
- Report the fix
Example: Code Generation
> Create a REST API endpoint for user registration with email validation
harness will:
- Examine existing project structure
- Identify framework and patterns
- Generate the endpoint code
- Add validation logic
- Create or update tests
Best Practices
Be Specific
# Good — harness knows exactly what to do
> Add a `delete_user` method to the UserService class in services/user.py
that soft-deletes by setting `is_active=False` and logs the action.
# Vague — harness has to guess
> Fix the user service
Provide Context
# Good — gives harness enough to work with
> The project uses FastAPI + SQLAlchemy. Add pagination to the
GET /users endpoint using limit/offset parameters.
# Missing context — harness needs to discover everything
> Add pagination
Single Goal Per Task
harness works best with one clear objective. For multiple tasks, either:
- Combine them into a single well-described request
- Use
/loopfor structured multi-step work - Send separate messages for separate tasks
harness vs /loop
| Aspect | harness | /loop |
|---|---|---|
| Planning | Model decides internally | Explicit plan + user confirmation |
| Execution | Autonomous flow | Structured rounds with verify |
| Verification | Implicit (model self-checks) | Explicit verify command per task |
| Failure handling | Dead-loop detection stops | 3-strike self-fix per task |
| User control | Cancel only | Confirm/exclude/modify at each step |
| Best for | Fuzzy, exploratory tasks | Decomposable, verifiable tasks |
Use harness when you want the model to figure things out. Use /loop when you want structured execution with checkpoints and verification.