agentchat-task-agent 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agentchat_task_agent-0.1.0/LICENSE +21 -0
- agentchat_task_agent-0.1.0/PKG-INFO +251 -0
- agentchat_task_agent-0.1.0/README.md +214 -0
- agentchat_task_agent-0.1.0/pyproject.toml +53 -0
- agentchat_task_agent-0.1.0/setup.cfg +4 -0
- agentchat_task_agent-0.1.0/src/agentchat_task_agent.egg-info/PKG-INFO +251 -0
- agentchat_task_agent-0.1.0/src/agentchat_task_agent.egg-info/SOURCES.txt +31 -0
- agentchat_task_agent-0.1.0/src/agentchat_task_agent.egg-info/dependency_links.txt +1 -0
- agentchat_task_agent-0.1.0/src/agentchat_task_agent.egg-info/entry_points.txt +3 -0
- agentchat_task_agent-0.1.0/src/agentchat_task_agent.egg-info/requires.txt +16 -0
- agentchat_task_agent-0.1.0/src/agentchat_task_agent.egg-info/top_level.txt +1 -0
- agentchat_task_agent-0.1.0/src/task_agent/__init__.py +44 -0
- agentchat_task_agent-0.1.0/src/task_agent/cli.py +98 -0
- agentchat_task_agent-0.1.0/src/task_agent/config.py +32 -0
- agentchat_task_agent-0.1.0/src/task_agent/demo.py +132 -0
- agentchat_task_agent-0.1.0/src/task_agent/executor.py +42 -0
- agentchat_task_agent-0.1.0/src/task_agent/graph.py +314 -0
- agentchat_task_agent-0.1.0/src/task_agent/judge.py +48 -0
- agentchat_task_agent-0.1.0/src/task_agent/llm.py +19 -0
- agentchat_task_agent-0.1.0/src/task_agent/memory.py +45 -0
- agentchat_task_agent-0.1.0/src/task_agent/nodes.py +394 -0
- agentchat_task_agent-0.1.0/src/task_agent/prompts.py +120 -0
- agentchat_task_agent-0.1.0/src/task_agent/py.typed +1 -0
- agentchat_task_agent-0.1.0/src/task_agent/state.py +36 -0
- agentchat_task_agent-0.1.0/src/task_agent/telemetry.py +45 -0
- agentchat_task_agent-0.1.0/src/task_agent/tools.py +155 -0
- agentchat_task_agent-0.1.0/tests/test_cli.py +39 -0
- agentchat_task_agent-0.1.0/tests/test_judge.py +66 -0
- agentchat_task_agent-0.1.0/tests/test_memory.py +78 -0
- agentchat_task_agent-0.1.0/tests/test_resilience.py +226 -0
- agentchat_task_agent-0.1.0/tests/test_task_agent.py +466 -0
- agentchat_task_agent-0.1.0/tests/test_telemetry.py +15 -0
- agentchat_task_agent-0.1.0/tests/test_tools.py +81 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Zhuliqx
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agentchat-task-agent
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: 自主任务 Agent:面向模糊长目标的多步自主执行引擎(LangGraph),零业务依赖
|
|
5
|
+
Author: Zhuliqx
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Zhuliqx/task-agent
|
|
8
|
+
Project-URL: Repository, https://github.com/Zhuliqx/task-agent
|
|
9
|
+
Project-URL: Issues, https://github.com/Zhuliqx/task-agent/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/Zhuliqx/task-agent/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: llm,agent,langgraph,rag,autonomous-agent
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: langgraph>=1.0
|
|
25
|
+
Provides-Extra: openai
|
|
26
|
+
Requires-Dist: openai>=1.0; extra == "openai"
|
|
27
|
+
Provides-Extra: observability
|
|
28
|
+
Requires-Dist: langfuse>=3.0; extra == "observability"
|
|
29
|
+
Provides-Extra: all
|
|
30
|
+
Requires-Dist: openai>=1.0; extra == "all"
|
|
31
|
+
Requires-Dist: langfuse>=3.0; extra == "all"
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
34
|
+
Requires-Dist: ruff>=0.4; extra == "dev"
|
|
35
|
+
Requires-Dist: pyright>=1.1; extra == "dev"
|
|
36
|
+
Dynamic: license-file
|
|
37
|
+
|
|
38
|
+
# 自主任务 Agent(task-agent)
|
|
39
|
+
|
|
40
|
+
> 最后校验:2026-08-30(独立包;宿主集成见 Agentchat 主仓库)
|
|
41
|
+
|
|
42
|
+
> 独立的**长任务自主执行器**:接收模糊复杂目标 → LLM 分解 / 每步重规划 → 循环执行(注入 Executor)→ 结构化交付。
|
|
43
|
+
> 零业务依赖的独立 Python 包;宿主应用通过适配器注入 LLM / Checkpointer / 每步执行器。
|
|
44
|
+
|
|
45
|
+
## 一句话
|
|
46
|
+
|
|
47
|
+
面向"**模糊长目标**"的 Agentic 编排:把 LangGraph 的**交互式 HITL / 容错 / 时间旅行 / 状态管理**组合成一套可用的自主任务引擎。
|
|
48
|
+
|
|
49
|
+
## 核心能力
|
|
50
|
+
|
|
51
|
+
| 能力 | 说明 |
|
|
52
|
+
|------|------|
|
|
53
|
+
| 每步动态重规划 | `replan`(默认);也可 `mode="fixed"` 一次计划 |
|
|
54
|
+
| 独立完成度判断 | `check` 判是否达成 + `max_steps` 防循环 |
|
|
55
|
+
| 信息源感知 | replan 标注 `expected_source`(kb/db/web/code),宿主按源收紧开关 |
|
|
56
|
+
| 节点级 HITL | `interrupt` / resume,proceed/edit/skip;无 checkpointer 自动降级全自主 |
|
|
57
|
+
| verify 自检重试 | 子任务失败 → LLM 判是否重试(不计步数,`max_retries` 上限) |
|
|
58
|
+
| 节点级容错 | `retry_policy` + `timeout` + `error_handler`(返回 `Command`) |
|
|
59
|
+
| Time Travel | `list_task_history` + `checkpoint_id` 分叉 / 重放 |
|
|
60
|
+
| 状态治理 | `findings` reducer 增量合并 |
|
|
61
|
+
| 工具调用执行器 | `ToolCallingExecutor` + 内置 calculator/time/random(零依赖) |
|
|
62
|
+
| 跨任务记忆 | 任务结论沉淀与召回(`InMemoryMemory` 或宿主实现 `TaskMemory`) |
|
|
63
|
+
|
|
64
|
+
## 安装
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pip install agentchat-task-agent # 从 PyPI 安装(发行名)
|
|
68
|
+
pip install 'agentchat-task-agent[all]' # openai + observability(Langfuse)
|
|
69
|
+
# 仓库内开发:
|
|
70
|
+
pip install -e . # 或 pip install -e <仓库路径>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## 快速体验(离线 demo,无需 API key)
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
python -m task_agent.demo
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
输出 replan 全流程的 findings 与 final_answer。设置 `TASK_AGENT_OPENAI_API_KEY`(可选 `TASK_AGENT_OPENAI_BASE_URL` / `TASK_AGENT_OPENAI_MODEL`)后自动切换真实 OpenAI 兼容端点。
|
|
80
|
+
|
|
81
|
+
## 编程接口
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
from task_agent import TaskAgentConfig, build_agent
|
|
85
|
+
from task_agent.executor import ExecuteRequest, StepResult
|
|
86
|
+
|
|
87
|
+
async def my_executor(request: ExecuteRequest) -> StepResult:
|
|
88
|
+
# 宿主在此提供真实工具能力(检索/数据库/搜索/代码…)
|
|
89
|
+
return StepResult(answer=f"执行了 {request.action}")
|
|
90
|
+
|
|
91
|
+
agent = build_agent(
|
|
92
|
+
config=TaskAgentConfig(mode="replan", hitl=True),
|
|
93
|
+
llm_factory=llm_factory, # Callable[[], LLM]
|
|
94
|
+
checkpointer_provider=checkpointer_provider, # Callable[[], Any | None]
|
|
95
|
+
executor=my_executor, # 缺省为纯 LLM 直答
|
|
96
|
+
on_event=on_event, # 可选: (kind, data) 事件回调
|
|
97
|
+
)
|
|
98
|
+
result = await agent.ainvoke({"goal": "..."}) # -> {findings, final_answer, ...}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
接口缝(详见 `src/task_agent/`):
|
|
102
|
+
- `TaskAgentConfig`:mode / hitl / max_retries / max_steps / llm_timeout / llm_max_retries /
|
|
103
|
+
findings_budget(findings 保留上限,超限自动压缩历史);
|
|
104
|
+
- `LLM` / `LLMFactory`:仅需 `async ainvoke(prompt)`;
|
|
105
|
+
- `CheckpointerProvider`:返回 LangGraph checkpointer 或 None(无状态降级);
|
|
106
|
+
- `Executor` / `ExecuteRequest(action, source)` / `StepResult(answer)`:每步执行端口;
|
|
107
|
+
- `memory`:可选跨任务记忆(`build_agent(..., memory=...)`)。
|
|
108
|
+
|
|
109
|
+
## 工具调用执行器(开箱即用)
|
|
110
|
+
|
|
111
|
+
不依赖宿主也能"自己干活":`ToolCallingExecutor` 让 LLM 决定调工具或直答,内置纯计算工具
|
|
112
|
+
(calculator / current_time / random_number,全部零依赖、AST 白名单求值):
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
from task_agent import TaskAgentConfig, build_agent
|
|
116
|
+
from task_agent.tools import ToolCallingExecutor, builtin_tools
|
|
117
|
+
|
|
118
|
+
agent = build_agent(
|
|
119
|
+
config=TaskAgentConfig(mode="replan", hitl=False),
|
|
120
|
+
llm_factory=llm_factory,
|
|
121
|
+
executor=ToolCallingExecutor(llm_factory, builtin_tools),
|
|
122
|
+
)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
宿主也可实现自己的 `Executor` 注入(接口缝不变)。工具声明用零依赖的 `Tool` dataclass
|
|
126
|
+
(name / description / parameters / func),支持同步与异步函数。
|
|
127
|
+
|
|
128
|
+
## CLI
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
task-agent run "介绍一下公司并计算质数和" --llm openai --tools --event --json
|
|
132
|
+
task-agent run "目标" --mode fixed --findings-budget 5
|
|
133
|
+
task-agent demo
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
`--llm fake`(默认)离线脚本化;`--tools` 启用内置工具;`--memory` 启用跨任务记忆;
|
|
137
|
+
`--event` 打印执行过程。
|
|
138
|
+
|
|
139
|
+
## 跨任务记忆
|
|
140
|
+
|
|
141
|
+
`build_agent(..., memory=...)` 传入实现 `TaskMemory` 的对象:
|
|
142
|
+
任务开始时按目标召回历史结论(注入 replan/plan 上下文),结束后把 `final_answer` 沉淀回记忆。
|
|
143
|
+
内置 `InMemoryMemory`(关键词召回,进程内);宿主可对接自己的 Store 实现。
|
|
144
|
+
|
|
145
|
+
## 可观测
|
|
146
|
+
|
|
147
|
+
`on_event` 是唯一接入点,可接任意可观测后端:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
from task_agent.telemetry import langfuse_event_sink
|
|
151
|
+
|
|
152
|
+
agent = build_agent(..., on_event=langfuse_event_sink()) # 需 task-agent[observability]
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
未安装 Langfuse 时自动降级为控制台输出,不抛错。
|
|
156
|
+
|
|
157
|
+
## 发布到 PyPI
|
|
158
|
+
|
|
159
|
+
变更记录见 [CHANGELOG](https://github.com/Zhuliqx/task-agent/blob/main/CHANGELOG.md)。
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
python -m build
|
|
163
|
+
python -m twine upload --repository testpypi dist/* # 先发 TestPyPI 验证
|
|
164
|
+
python -m twine upload dist/* # 正式 PyPI(项目级令牌)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
发行名 `agentchat-task-agent`(import 名 `task_agent`,CLI 命令 `task-agent`)。
|
|
168
|
+
打 `v*` 标签可触发 CI 自动发布(需在仓库 Secrets 配置 `PYPI_API_TOKEN`,见
|
|
169
|
+
`.github/workflows/publish.yml`)。
|
|
170
|
+
|
|
171
|
+
## 事件回调(过程可见)
|
|
172
|
+
|
|
173
|
+
`build_agent(on_event=...)` 会收到生命周期事件:`plan / replan / execute / check / verify / hitl / final`,
|
|
174
|
+
数据形如 `{"action": ..., "source": ..., "ok": ...}`。宿主可接 SSE 或日志:
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
def on_event(kind: str, data: dict) -> None:
|
|
178
|
+
print(f"[{kind}] {data}")
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## 长任务记忆治理(findings 压缩)
|
|
182
|
+
|
|
183
|
+
长任务 `findings` 会持续累积。设 `TaskAgentConfig(findings_budget=N)` 后,超过 N 条时把历史
|
|
184
|
+
交给 LLM 压缩进 `findings_summary`,仅保留最新一条——控制后续 replan/check/final 的上下文
|
|
185
|
+
与 token 成本(LLM 失败自动退化为截断拼接,不中断执行)。
|
|
186
|
+
|
|
187
|
+
## 基准与容错
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
cd task-agent
|
|
191
|
+
python benchmarks/bench_task_agent.py # fixed vs replan 结构指标对比(离线)
|
|
192
|
+
python benchmarks/bench_task_agent.py --judge # 追加质量评估(离线=规则代理)
|
|
193
|
+
python benchmarks/bench_task_agent.py --llm openai --judge --out results/bench.json # 真实 LLM 指标 + LLM-judge 打分
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
离线模式统计完成率 / 答案命中 / 平均执行步数 / 平均重试 / 平均耗时;真实质量指标用
|
|
197
|
+
`--llm openai`(配 `TASK_AGENT_OPENAI_API_KEY`);`--judge` 开启 LLM-judge 质量评估
|
|
198
|
+
(目标达成度 / 信息完整性 / 幻觉,0-1,见 `src/task_agent/judge.py`)。容错通过混沌测试验证
|
|
199
|
+
(`tests/test_resilience.py`:执行器随机失败 / 永久失败 / LLM 永久失败均能收敛交付)。
|
|
200
|
+
宿主侧评估(真实 LLM + judge)位于 Agentchat 主仓库的 `backend/scripts/eval_task_agent.py`,
|
|
201
|
+
本仓库用 `python benchmarks/bench_task_agent.py --llm openai --judge` 做等价质量评估。
|
|
202
|
+
|
|
203
|
+
### 实测快照(真实 LLM:DeepSeek-chat,3 自包含任务 × 2 轮,2026-08-29)
|
|
204
|
+
|
|
205
|
+
| 模式 | 完成率 | 目标达成 | 信息完整 | 幻觉 | 平均步数 | 平均耗时 |
|
|
206
|
+
|------|--------|----------|----------|------|----------|----------|
|
|
207
|
+
| replan | 1.000 | 1.000 | 1.000 | 0.000 | **1.0** | **6.0s** |
|
|
208
|
+
| fixed | 1.000 | 1.000 | 1.000 | 0.000 | 3.0 | 12.0s |
|
|
209
|
+
|
|
210
|
+
**关键发现**:简单自包含任务上,replan 一步收敛(LLM 直答 → check 判完成),fixed 因
|
|
211
|
+
"先拆计划"多出 2 个执行步、耗时翻倍;而离线脚本化基准中 fixed 反而更快(脚本化计划恰好 2 步)。
|
|
212
|
+
结论:**脚本化基准只能测结构,真实 LLM 才能暴露行为差异**——两者都要跑,别只用离线数字下结论。
|
|
213
|
+
|
|
214
|
+
## 目录
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
task-agent/
|
|
218
|
+
├── pyproject.toml
|
|
219
|
+
├── benchmarks/bench_task_agent.py # fixed vs replan 基准
|
|
220
|
+
├── src/task_agent/
|
|
221
|
+
│ ├── config.py # TaskAgentConfig(运行配置)
|
|
222
|
+
│ ├── llm.py # LLM 协议 + 文本抽取
|
|
223
|
+
│ ├── executor.py # ExecuteRequest / StepResult / Executor / DefaultExecutor
|
|
224
|
+
│ ├── state.py # TaskState(findings reducer)
|
|
225
|
+
│ ├── prompts.py # PLAN/FINAL/REPLAN/CHECK/VERIFY/COMPRESS 提示词
|
|
226
|
+
│ ├── judge.py # 任务级质量评估(LLM-judge,0-1 三指标)
|
|
227
|
+
│ ├── tools.py # ToolCallingExecutor + 内置工具(零依赖)
|
|
228
|
+
│ ├── memory.py # TaskMemory / InMemoryMemory(跨任务记忆)
|
|
229
|
+
│ ├── telemetry.py # 控制台 / Langfuse 事件接入
|
|
230
|
+
│ ├── cli.py # task-agent 命令行入口
|
|
231
|
+
│ ├── nodes.py # 节点(闭包注入 Runtime)
|
|
232
|
+
│ ├── graph.py # build_agent / list_task_history / 路由 / error_handler
|
|
233
|
+
│ └── demo.py # 离线 demo(脚本化 FakeLLM)
|
|
234
|
+
└── tests/
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## 测试
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
cd task-agent && pytest -q
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
覆盖:解析 / 路由 / HITL(含无 checkpointer 降级)/ verify / error_handler / 执行节点 /
|
|
244
|
+
默认执行器 / Time Travel / fixed 全流程 / demo 离线全流程 / 容错混沌注入 / findings 压缩 / 事件流。
|
|
245
|
+
|
|
246
|
+
## 宿主集成(Agentchat 主仓库)
|
|
247
|
+
|
|
248
|
+
本包零业务依赖、可独立使用;作为 Agentchat 平台的"项目 2",宿主通过适配器注入
|
|
249
|
+
LLM / Checkpointer / 执行器,并提供 `/api/agent-tasks/run`、`/api/agent-tasks/run/stream`(SSE)、
|
|
250
|
+
`/api/agent-tasks/history`、`/api/agent-tasks/confirm` 等 API。宿主仓库地址:
|
|
251
|
+
`https://github.com/Zhuliqx/Agentchat`。
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# 自主任务 Agent(task-agent)
|
|
2
|
+
|
|
3
|
+
> 最后校验:2026-08-30(独立包;宿主集成见 Agentchat 主仓库)
|
|
4
|
+
|
|
5
|
+
> 独立的**长任务自主执行器**:接收模糊复杂目标 → LLM 分解 / 每步重规划 → 循环执行(注入 Executor)→ 结构化交付。
|
|
6
|
+
> 零业务依赖的独立 Python 包;宿主应用通过适配器注入 LLM / Checkpointer / 每步执行器。
|
|
7
|
+
|
|
8
|
+
## 一句话
|
|
9
|
+
|
|
10
|
+
面向"**模糊长目标**"的 Agentic 编排:把 LangGraph 的**交互式 HITL / 容错 / 时间旅行 / 状态管理**组合成一套可用的自主任务引擎。
|
|
11
|
+
|
|
12
|
+
## 核心能力
|
|
13
|
+
|
|
14
|
+
| 能力 | 说明 |
|
|
15
|
+
|------|------|
|
|
16
|
+
| 每步动态重规划 | `replan`(默认);也可 `mode="fixed"` 一次计划 |
|
|
17
|
+
| 独立完成度判断 | `check` 判是否达成 + `max_steps` 防循环 |
|
|
18
|
+
| 信息源感知 | replan 标注 `expected_source`(kb/db/web/code),宿主按源收紧开关 |
|
|
19
|
+
| 节点级 HITL | `interrupt` / resume,proceed/edit/skip;无 checkpointer 自动降级全自主 |
|
|
20
|
+
| verify 自检重试 | 子任务失败 → LLM 判是否重试(不计步数,`max_retries` 上限) |
|
|
21
|
+
| 节点级容错 | `retry_policy` + `timeout` + `error_handler`(返回 `Command`) |
|
|
22
|
+
| Time Travel | `list_task_history` + `checkpoint_id` 分叉 / 重放 |
|
|
23
|
+
| 状态治理 | `findings` reducer 增量合并 |
|
|
24
|
+
| 工具调用执行器 | `ToolCallingExecutor` + 内置 calculator/time/random(零依赖) |
|
|
25
|
+
| 跨任务记忆 | 任务结论沉淀与召回(`InMemoryMemory` 或宿主实现 `TaskMemory`) |
|
|
26
|
+
|
|
27
|
+
## 安装
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install agentchat-task-agent # 从 PyPI 安装(发行名)
|
|
31
|
+
pip install 'agentchat-task-agent[all]' # openai + observability(Langfuse)
|
|
32
|
+
# 仓库内开发:
|
|
33
|
+
pip install -e . # 或 pip install -e <仓库路径>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 快速体验(离线 demo,无需 API key)
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
python -m task_agent.demo
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
输出 replan 全流程的 findings 与 final_answer。设置 `TASK_AGENT_OPENAI_API_KEY`(可选 `TASK_AGENT_OPENAI_BASE_URL` / `TASK_AGENT_OPENAI_MODEL`)后自动切换真实 OpenAI 兼容端点。
|
|
43
|
+
|
|
44
|
+
## 编程接口
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from task_agent import TaskAgentConfig, build_agent
|
|
48
|
+
from task_agent.executor import ExecuteRequest, StepResult
|
|
49
|
+
|
|
50
|
+
async def my_executor(request: ExecuteRequest) -> StepResult:
|
|
51
|
+
# 宿主在此提供真实工具能力(检索/数据库/搜索/代码…)
|
|
52
|
+
return StepResult(answer=f"执行了 {request.action}")
|
|
53
|
+
|
|
54
|
+
agent = build_agent(
|
|
55
|
+
config=TaskAgentConfig(mode="replan", hitl=True),
|
|
56
|
+
llm_factory=llm_factory, # Callable[[], LLM]
|
|
57
|
+
checkpointer_provider=checkpointer_provider, # Callable[[], Any | None]
|
|
58
|
+
executor=my_executor, # 缺省为纯 LLM 直答
|
|
59
|
+
on_event=on_event, # 可选: (kind, data) 事件回调
|
|
60
|
+
)
|
|
61
|
+
result = await agent.ainvoke({"goal": "..."}) # -> {findings, final_answer, ...}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
接口缝(详见 `src/task_agent/`):
|
|
65
|
+
- `TaskAgentConfig`:mode / hitl / max_retries / max_steps / llm_timeout / llm_max_retries /
|
|
66
|
+
findings_budget(findings 保留上限,超限自动压缩历史);
|
|
67
|
+
- `LLM` / `LLMFactory`:仅需 `async ainvoke(prompt)`;
|
|
68
|
+
- `CheckpointerProvider`:返回 LangGraph checkpointer 或 None(无状态降级);
|
|
69
|
+
- `Executor` / `ExecuteRequest(action, source)` / `StepResult(answer)`:每步执行端口;
|
|
70
|
+
- `memory`:可选跨任务记忆(`build_agent(..., memory=...)`)。
|
|
71
|
+
|
|
72
|
+
## 工具调用执行器(开箱即用)
|
|
73
|
+
|
|
74
|
+
不依赖宿主也能"自己干活":`ToolCallingExecutor` 让 LLM 决定调工具或直答,内置纯计算工具
|
|
75
|
+
(calculator / current_time / random_number,全部零依赖、AST 白名单求值):
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
from task_agent import TaskAgentConfig, build_agent
|
|
79
|
+
from task_agent.tools import ToolCallingExecutor, builtin_tools
|
|
80
|
+
|
|
81
|
+
agent = build_agent(
|
|
82
|
+
config=TaskAgentConfig(mode="replan", hitl=False),
|
|
83
|
+
llm_factory=llm_factory,
|
|
84
|
+
executor=ToolCallingExecutor(llm_factory, builtin_tools),
|
|
85
|
+
)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
宿主也可实现自己的 `Executor` 注入(接口缝不变)。工具声明用零依赖的 `Tool` dataclass
|
|
89
|
+
(name / description / parameters / func),支持同步与异步函数。
|
|
90
|
+
|
|
91
|
+
## CLI
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
task-agent run "介绍一下公司并计算质数和" --llm openai --tools --event --json
|
|
95
|
+
task-agent run "目标" --mode fixed --findings-budget 5
|
|
96
|
+
task-agent demo
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
`--llm fake`(默认)离线脚本化;`--tools` 启用内置工具;`--memory` 启用跨任务记忆;
|
|
100
|
+
`--event` 打印执行过程。
|
|
101
|
+
|
|
102
|
+
## 跨任务记忆
|
|
103
|
+
|
|
104
|
+
`build_agent(..., memory=...)` 传入实现 `TaskMemory` 的对象:
|
|
105
|
+
任务开始时按目标召回历史结论(注入 replan/plan 上下文),结束后把 `final_answer` 沉淀回记忆。
|
|
106
|
+
内置 `InMemoryMemory`(关键词召回,进程内);宿主可对接自己的 Store 实现。
|
|
107
|
+
|
|
108
|
+
## 可观测
|
|
109
|
+
|
|
110
|
+
`on_event` 是唯一接入点,可接任意可观测后端:
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
from task_agent.telemetry import langfuse_event_sink
|
|
114
|
+
|
|
115
|
+
agent = build_agent(..., on_event=langfuse_event_sink()) # 需 task-agent[observability]
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
未安装 Langfuse 时自动降级为控制台输出,不抛错。
|
|
119
|
+
|
|
120
|
+
## 发布到 PyPI
|
|
121
|
+
|
|
122
|
+
变更记录见 [CHANGELOG](https://github.com/Zhuliqx/task-agent/blob/main/CHANGELOG.md)。
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
python -m build
|
|
126
|
+
python -m twine upload --repository testpypi dist/* # 先发 TestPyPI 验证
|
|
127
|
+
python -m twine upload dist/* # 正式 PyPI(项目级令牌)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
发行名 `agentchat-task-agent`(import 名 `task_agent`,CLI 命令 `task-agent`)。
|
|
131
|
+
打 `v*` 标签可触发 CI 自动发布(需在仓库 Secrets 配置 `PYPI_API_TOKEN`,见
|
|
132
|
+
`.github/workflows/publish.yml`)。
|
|
133
|
+
|
|
134
|
+
## 事件回调(过程可见)
|
|
135
|
+
|
|
136
|
+
`build_agent(on_event=...)` 会收到生命周期事件:`plan / replan / execute / check / verify / hitl / final`,
|
|
137
|
+
数据形如 `{"action": ..., "source": ..., "ok": ...}`。宿主可接 SSE 或日志:
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
def on_event(kind: str, data: dict) -> None:
|
|
141
|
+
print(f"[{kind}] {data}")
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## 长任务记忆治理(findings 压缩)
|
|
145
|
+
|
|
146
|
+
长任务 `findings` 会持续累积。设 `TaskAgentConfig(findings_budget=N)` 后,超过 N 条时把历史
|
|
147
|
+
交给 LLM 压缩进 `findings_summary`,仅保留最新一条——控制后续 replan/check/final 的上下文
|
|
148
|
+
与 token 成本(LLM 失败自动退化为截断拼接,不中断执行)。
|
|
149
|
+
|
|
150
|
+
## 基准与容错
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
cd task-agent
|
|
154
|
+
python benchmarks/bench_task_agent.py # fixed vs replan 结构指标对比(离线)
|
|
155
|
+
python benchmarks/bench_task_agent.py --judge # 追加质量评估(离线=规则代理)
|
|
156
|
+
python benchmarks/bench_task_agent.py --llm openai --judge --out results/bench.json # 真实 LLM 指标 + LLM-judge 打分
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
离线模式统计完成率 / 答案命中 / 平均执行步数 / 平均重试 / 平均耗时;真实质量指标用
|
|
160
|
+
`--llm openai`(配 `TASK_AGENT_OPENAI_API_KEY`);`--judge` 开启 LLM-judge 质量评估
|
|
161
|
+
(目标达成度 / 信息完整性 / 幻觉,0-1,见 `src/task_agent/judge.py`)。容错通过混沌测试验证
|
|
162
|
+
(`tests/test_resilience.py`:执行器随机失败 / 永久失败 / LLM 永久失败均能收敛交付)。
|
|
163
|
+
宿主侧评估(真实 LLM + judge)位于 Agentchat 主仓库的 `backend/scripts/eval_task_agent.py`,
|
|
164
|
+
本仓库用 `python benchmarks/bench_task_agent.py --llm openai --judge` 做等价质量评估。
|
|
165
|
+
|
|
166
|
+
### 实测快照(真实 LLM:DeepSeek-chat,3 自包含任务 × 2 轮,2026-08-29)
|
|
167
|
+
|
|
168
|
+
| 模式 | 完成率 | 目标达成 | 信息完整 | 幻觉 | 平均步数 | 平均耗时 |
|
|
169
|
+
|------|--------|----------|----------|------|----------|----------|
|
|
170
|
+
| replan | 1.000 | 1.000 | 1.000 | 0.000 | **1.0** | **6.0s** |
|
|
171
|
+
| fixed | 1.000 | 1.000 | 1.000 | 0.000 | 3.0 | 12.0s |
|
|
172
|
+
|
|
173
|
+
**关键发现**:简单自包含任务上,replan 一步收敛(LLM 直答 → check 判完成),fixed 因
|
|
174
|
+
"先拆计划"多出 2 个执行步、耗时翻倍;而离线脚本化基准中 fixed 反而更快(脚本化计划恰好 2 步)。
|
|
175
|
+
结论:**脚本化基准只能测结构,真实 LLM 才能暴露行为差异**——两者都要跑,别只用离线数字下结论。
|
|
176
|
+
|
|
177
|
+
## 目录
|
|
178
|
+
|
|
179
|
+
```
|
|
180
|
+
task-agent/
|
|
181
|
+
├── pyproject.toml
|
|
182
|
+
├── benchmarks/bench_task_agent.py # fixed vs replan 基准
|
|
183
|
+
├── src/task_agent/
|
|
184
|
+
│ ├── config.py # TaskAgentConfig(运行配置)
|
|
185
|
+
│ ├── llm.py # LLM 协议 + 文本抽取
|
|
186
|
+
│ ├── executor.py # ExecuteRequest / StepResult / Executor / DefaultExecutor
|
|
187
|
+
│ ├── state.py # TaskState(findings reducer)
|
|
188
|
+
│ ├── prompts.py # PLAN/FINAL/REPLAN/CHECK/VERIFY/COMPRESS 提示词
|
|
189
|
+
│ ├── judge.py # 任务级质量评估(LLM-judge,0-1 三指标)
|
|
190
|
+
│ ├── tools.py # ToolCallingExecutor + 内置工具(零依赖)
|
|
191
|
+
│ ├── memory.py # TaskMemory / InMemoryMemory(跨任务记忆)
|
|
192
|
+
│ ├── telemetry.py # 控制台 / Langfuse 事件接入
|
|
193
|
+
│ ├── cli.py # task-agent 命令行入口
|
|
194
|
+
│ ├── nodes.py # 节点(闭包注入 Runtime)
|
|
195
|
+
│ ├── graph.py # build_agent / list_task_history / 路由 / error_handler
|
|
196
|
+
│ └── demo.py # 离线 demo(脚本化 FakeLLM)
|
|
197
|
+
└── tests/
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## 测试
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
cd task-agent && pytest -q
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
覆盖:解析 / 路由 / HITL(含无 checkpointer 降级)/ verify / error_handler / 执行节点 /
|
|
207
|
+
默认执行器 / Time Travel / fixed 全流程 / demo 离线全流程 / 容错混沌注入 / findings 压缩 / 事件流。
|
|
208
|
+
|
|
209
|
+
## 宿主集成(Agentchat 主仓库)
|
|
210
|
+
|
|
211
|
+
本包零业务依赖、可独立使用;作为 Agentchat 平台的"项目 2",宿主通过适配器注入
|
|
212
|
+
LLM / Checkpointer / 执行器,并提供 `/api/agent-tasks/run`、`/api/agent-tasks/run/stream`(SSE)、
|
|
213
|
+
`/api/agent-tasks/history`、`/api/agent-tasks/confirm` 等 API。宿主仓库地址:
|
|
214
|
+
`https://github.com/Zhuliqx/Agentchat`。
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "agentchat-task-agent"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "自主任务 Agent:面向模糊长目标的多步自主执行引擎(LangGraph),零业务依赖"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
authors = [{ name = "Zhuliqx" }]
|
|
13
|
+
keywords = ["llm", "agent", "langgraph", "rag", "autonomous-agent"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Programming Language :: Python :: 3.13",
|
|
22
|
+
"Topic :: Software Development :: Libraries :: Application Frameworks",
|
|
23
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
24
|
+
]
|
|
25
|
+
requires-python = ">=3.11"
|
|
26
|
+
dependencies = [
|
|
27
|
+
"langgraph>=1.0",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.urls]
|
|
31
|
+
Homepage = "https://github.com/Zhuliqx/task-agent"
|
|
32
|
+
Repository = "https://github.com/Zhuliqx/task-agent"
|
|
33
|
+
Issues = "https://github.com/Zhuliqx/task-agent/issues"
|
|
34
|
+
Changelog = "https://github.com/Zhuliqx/task-agent/blob/main/CHANGELOG.md"
|
|
35
|
+
|
|
36
|
+
[project.optional-dependencies]
|
|
37
|
+
openai = ["openai>=1.0"]
|
|
38
|
+
observability = ["langfuse>=3.0"]
|
|
39
|
+
all = ["openai>=1.0", "langfuse>=3.0"]
|
|
40
|
+
dev = ["pytest>=8", "ruff>=0.4", "pyright>=1.1"]
|
|
41
|
+
|
|
42
|
+
[project.scripts]
|
|
43
|
+
task-agent = "task_agent.cli:main"
|
|
44
|
+
task-agent-demo = "task_agent.demo:main"
|
|
45
|
+
|
|
46
|
+
[tool.setuptools.packages.find]
|
|
47
|
+
where = ["src"]
|
|
48
|
+
|
|
49
|
+
[tool.setuptools.package-data]
|
|
50
|
+
task_agent = ["py.typed"]
|
|
51
|
+
|
|
52
|
+
[tool.pytest.ini_options]
|
|
53
|
+
testpaths = ["tests"]
|