## Structure
```
./examples/blog_sut
├── blog_expert.py
├── configs
│   ├── sut
│   │   └── openapi.json
│   └── tasks
│       └── task_description.json
└── run_task.py
./src/llmops
├── __init__.py
├── agents
│   ├── __init__.py
│   ├── agent.py
│   ├── operation_selector.py
│   └── request_generator.py
├── base.py
├── business
│   ├── __init__.py
│   └── business_expert.py
├── config.py
├── environment
│   ├── __init__.py
│   ├── environment.py
│   ├── execution_analyzer.py
│   ├── executor.py
│   └── target_matcher.py
├── preprocessor.py
├── prompts
│   ├── execution_analyzer.md
│   ├── is_target_ready.md
│   ├── preprocessor.md (TODO: 目前只针对 HTTP，没针对 CLI)
│   ├── request_generator.md (TODO: 目前只针对 HTTP，没针对 CLI)
│   └── select_operation.md
├── storage
│   ├── __init__.py
│   └── transition_store.py (除了 store，别的方法都没用暂时)
├── subtask_orchestrator.py
├── task_orchestrator.py
└── utils
    ├── __init__.py
    ├── json_utils.py
    └── llm_client.py
```

## TODO

update tag 的操作用了 null 没用 [] 导致 200 但是一直不能有效清掉 tag，这个其实是 request_generator 的问题，但是现在没有很好地解决


每一个 LLM 的 system prompt 都要给一个 business related 信息，如果为空就不加，不为空就加。分为 sys 和 user 两类，都需要给默认没有的状态

- [x] system prompt
- [ ] user prompt

需要为 CLI 增加一个类似 OpenAPI Spec 的文件

preprocessor 约等于 operation selector + request generator

operation selector:
- [ ] 当前状态下哪些 Ops 可用 (Subset 1)
- [x] Subset 1 中哪个能最快地让当前状态向目标状态推进

request generator:
- 关注到目标信息中对当前 operation 有用的属性，比如从 2C4G 到 8C16G，应该关注前者还是后者
- Expect 的 CEL 如何写，特别是状态

response analyzer:
- 4xx: 是 op 的错还是 req 的错，如果都有错，就首先是 op 的错
- 5xx: 重试?
- 2xx/3xx:
  - 有进步: 成功
  - 无进步: 是 op 的错还是 req 的错，如果都有错，就首先是 op 的错
  
target matcher:

executor:
  compound 的输入应该是 step，不是拆出来的 http 相关的
