374 lines
17 KiB
Markdown
374 lines
17 KiB
Markdown
# opagent
|
||
|
||
## PAM Deploy Agent
|
||
|
||
本仓库正在把原有 `PAM_AUTO_DEPLY_SKILL.md` + `deploy.sh` / `deploy.ps1` 的组合,重构为一个 LangGraph-style 的 PAM 智能部署 Agent。
|
||
|
||
当前已加入 `pam_deploy_graph` Python 包,用于先落地 Agent Runtime 的核心骨架:
|
||
|
||
- PAM_HOME action 固定通过 `deploy.sh` / `deploy.ps1` 调用。
|
||
- PAM_NODE action 可通过 MCP runner 调用。
|
||
- 默认执行策略为 `hybrid_node_mcp`,即 HOME 脚本 action + NODE MCP。
|
||
- 离线策略为 `script_only`,全部 action 走脚本 action。
|
||
- `langgraph` 已作为正式依赖引入;核心 Agent、runner、router 和 parser 也可独立测试。
|
||
|
||
## 当前代码骨架
|
||
|
||
```text
|
||
pam_deploy_graph/
|
||
agent.py # Agent runtime,参数归一化、预演、fake 全局流程
|
||
action_router.py # 按 action 路由到脚本、MCP 或 fake runner
|
||
script_runner.py # deploy.sh / deploy.ps1 action 调用封装
|
||
mcp_runner.py # PAM_NODE MCP runner 协议与 action -> tool 映射
|
||
fake_runner.py # 测试用 runner,不访问真实环境
|
||
output_parser.py # 解析 key=value、MCP JSON、待确认回滚标记
|
||
skill_policy.py # 从 PAM_AUTO_DEPLY_SKILL.md 加载 Skill 策略
|
||
config_writer.py # 生成脚本 action 所需 config 文件
|
||
checkpoint_store.py # 业务 checkpoint JSON 读写
|
||
params_loader.py # 读取 JSON 或 config.txt 风格参数文件
|
||
llm/ # LLM structured output 接口、真实 HTTP client、提示词、规则 fallback 和 guardrails
|
||
graph.py # LangGraph StateGraph 集成入口
|
||
langgraph_runtime.py # action 级 LangGraph 运行器
|
||
mcp_client.py # MCP stdio/HTTP/SSE client、鉴权 token 和配置读取
|
||
interactive.py # 常驻式 CLI 对话框,会话命令、确认和续跑
|
||
cli.py # CLI 入口
|
||
|
||
tests/
|
||
test_action_router.py
|
||
test_output_parser.py
|
||
test_params_loader.py
|
||
test_script_runner.py
|
||
test_skill_policy.py
|
||
test_interactive_cli.py
|
||
|
||
docs/
|
||
current_logic_flow.md # 当前整体逻辑结构流程图
|
||
todo.md # chat 优化和 LLM action 后分析待办
|
||
|
||
packaging/
|
||
build_linux_self_contained.sh # Linux 解压即用包构建脚本
|
||
README_linux_package.md # Linux 打包说明和包大小评估
|
||
mcp_client.example.json # MCP server URL + 鉴权配置示例
|
||
```
|
||
|
||
## 当前进度
|
||
|
||
已完成:
|
||
|
||
- 建立 Python 工程骨架和 `pyproject.toml`。
|
||
- 实现 `hybrid_node_mcp` 路由规则:PAM_HOME 走脚本 action,PAM_NODE 走 MCP。
|
||
- 实现 `script_only` 路由规则:所有 action 走脚本 action。
|
||
- 实现脚本 action 命令构造,避免调用脚本主流程。
|
||
- 实现 MCP runner 抽象和 PAM_NODE action 到 MCP tool 的默认映射。
|
||
- 实现脚本/MCP/fake action 结果统一为 `ActionResult`。
|
||
- 实现 `config.txt.example` 风格和 JSON 风格参数读取。
|
||
- 实现 fake 全局流程和完整部署流程,便于不触碰真实环境地验证 Agent 路由。
|
||
- 实现逐 IP 处理骨架:升级、轮询、启动、校验、日志下载。
|
||
- 实现 action 失败或审核阻断后暂停并保留当前 action,修复后 `resume` 会从当前 action 重试。
|
||
- 回滚已从主 workflow 中拆出,改为 chat/CLI 的显式 `rollback` 命令;旧 `confirm` 入口仅作为兼容保留。
|
||
- 实现 checkpoint 自动保存和 `resume` 续跑:全局步骤、成功 IP、单 IP 已完成 action 会跳过。
|
||
- 实现 LLM structured output 骨架:意图识别、参数抽取、部署计划生成。
|
||
- 实现 OpenAI-compatible 真实 LLM client,支持 `base_url` / `model` 配置,`api_key` 可为空。
|
||
- 固化真实 LLM 提示词:意图识别、参数抽取、部署计划生成均要求 JSON structured output。
|
||
- 增加规则 fallback `RuleBasedLlmClient`,用于本地开发和测试。
|
||
- 增加 LLM 输出 guardrails,禁止计划中出现可执行脚本命令和非法 action。
|
||
- 引入 `langgraph` 依赖,CLI/chat 执行流程统一通过 action 级 LangGraph runtime 调度。
|
||
- CLI/chat 执行流程统一通过 action 级 LangGraph runtime 调度;失败暂停状态写入业务 checkpoint,`resume` 会重新进入图并从断点继续。
|
||
- 引入 MCP client adapter,可包装 SDK session、普通 callable、stdio server、HTTP/SSE server,并提供 JSON client 配置读取。
|
||
- CLI/chat 支持 `--mcp-config` 直接加载 MCP server URL、鉴权和可选 tool 覆盖配置。
|
||
- 本地已安装 `langgraph` 和 `mcp`,并完成 LangGraph fake 全局流程 smoke。
|
||
- CLI `analyze` 输出已做敏感字段脱敏。
|
||
- 增加 `chat` 常驻式 CLI 对话框,支持自然语言分析、参数设置、执行确认、显式回滚、状态查看、事件查看、checkpoint 选择和续跑。
|
||
- chat 在开发环境和默认发布包中都会优先启用 `rich` / `prompt_toolkit`;如果增强输入初始化失败,会自动降级到普通 `input()`。
|
||
- chat 执行前会归一化参数并展示实际写入脚本配置的值;`script_only` / `hybrid_node_mcp` 会提前检查 `ZIP_FILE_PATH` 是否存在。
|
||
- chat 执行中会播报每个 action 的开始、完成或失败;action 执行失败会停在当前 checkpoint,不再误报 LangGraph 不可用。
|
||
- 每个 action 完成后都会进入一次 LLM/规则审核;只有审核通过才会把 action 记为 completed,如果审核建议停止,流程会暂停并等待用户 `resume` 重试当前 action。
|
||
- `--analyze-actions` 和 `llm action-analysis on` 改为只控制是否把详细审核结果写入 `events`,不再控制审核是否执行。
|
||
- chat 会播报 action 审核开始、审核完成和审核失败,避免黑盒执行。
|
||
- chat 支持执行中按 `Ctrl+C` 中断,保存 checkpoint 后再 `resume`。
|
||
- chat 支持 `set KEY=VALUE` 和 `load params <路径>` 热更新当前运行参数,并同步回写运行中的 `config.txt` 与 checkpoint。
|
||
- 支持通过 `--llm-action-analysis-prompt-file`、`PAM_LLM_ACTION_ANALYSIS_PROMPT_FILE` 或 chat 内 `llm config action_analysis_prompt_file=...` 自定义 action 审核提示词。
|
||
- 增加统一运行日志,默认写入 `logs/pam_deploy_agent.log`,覆盖 CLI/chat、LLM 调用、action 路由、脚本/MCP 调用、LangGraph、checkpoint 等关键流程。
|
||
- chat 支持 `llm test [文本]`,可用当前 LLM client 做一次轻量调用,确认真实 LLM 或规则 fallback 是否正常加载。
|
||
- 添加基础测试,当前本地结果为 `62 passed, 2 skipped`。
|
||
|
||
未完成:
|
||
|
||
- 尚未执行真实 PAM_NODE MCP 调用;当前已把 MCP HTTP/SSE/stdio client、鉴权和 tools 自动发现准备好。
|
||
- 尚未执行真实脚本 action 或真实 PAM_NODE MCP 调用。
|
||
|
||
## LLM 配置
|
||
|
||
默认不配置 LLM 时,`analyze` 使用本地规则 fallback。配置真实 LLM 后,会走 OpenAI-compatible `/chat/completions`。
|
||
|
||
`base_url` 和 `model` 必填;`api_key` 可为空。如果模型服务不需要鉴权,不配置 `PAM_LLM_API_KEY` 或不传 `--llm-api-key` 即可,Agent 不会发送 `Authorization` 请求头。
|
||
|
||
```powershell
|
||
$env:PAM_LLM_BASE_URL="https://your-llm.example.com/v1"
|
||
$env:PAM_LLM_MODEL="your-model-name"
|
||
|
||
python -m pam_deploy_graph.cli analyze --config doc_scripts/config.txt.example --text "请用 MCP 预演部署 HET PAM Node 版本 2.0.5,不要动环境"
|
||
```
|
||
|
||
也可以直接用 CLI 参数覆盖环境变量:
|
||
|
||
```bash
|
||
python -m pam_deploy_graph.cli analyze \
|
||
--config doc_scripts/config.txt.example \
|
||
--text "请用 MCP 预演部署 HET PAM Node 版本 2.0.5,不要动环境" \
|
||
--llm-base-url https://your-llm.example.com/v1 \
|
||
--llm-model your-model-name
|
||
```
|
||
|
||
如需自定义 action 审核提示词,可再补充:
|
||
|
||
```bash
|
||
python -m pam_deploy_graph.cli analyze \
|
||
--config doc_scripts/config.txt.example \
|
||
--text "请分析这次部署" \
|
||
--llm-base-url https://your-llm.example.com/v1 \
|
||
--llm-model your-model-name \
|
||
--llm-action-analysis-prompt-file prompts/action_review.txt
|
||
```
|
||
|
||
仓库内已提供 [prompts/action_review.txt](/e:/AIcoding/agent_deply/prompts/action_review.txt) 作为“当前默认 action 审核提示词”的落地副本,后续自定义时可以先复制它再改,便于和内置默认行为对照。
|
||
|
||
真实 LLM 调用位置在 `pam_deploy_graph/llm/openai_compatible.py`,提示词在 `pam_deploy_graph/llm/prompts.py`。发送给 LLM 的 `base_params` 会脱敏,`CLIENT_SECRET` 不会进入 prompt;本地生成计划后仍会执行 guardrails 校验。
|
||
|
||
chat 内可以用当前 client 做一次轻量测试,确认真实 LLM 或规则 fallback 是否正常加载:
|
||
|
||
```text
|
||
PAM> llm test 请返回一次连通性测试结果
|
||
```
|
||
|
||
如果服务需要鉴权,再补充:
|
||
|
||
```bash
|
||
export PAM_LLM_API_KEY="your-api-key"
|
||
```
|
||
|
||
## MCP Client 配置
|
||
|
||
CLI/chat 已支持通过 `--mcp-config` 直接加载 MCP 配置。常用场景只需要配置 MCP `server_url` 和独立鉴权信息;Agent 会连接 MCP server,调用 `list_tools` 自动发现 server 暴露的 tools,再按 action 名自动匹配。
|
||
|
||
MCP 鉴权 token 获取方式与 HOME 一致,默认按 `client_credentials` POST 到 `/oauth/token` 风格接口;但 MCP 使用独立的 `token_url`、`client_id`、`client_secret`,不会复用 HOME 的账号密码。
|
||
|
||
CLI 示例:
|
||
|
||
```bash
|
||
python -m pam_deploy_graph.cli chat \
|
||
--config doc_scripts/config.txt.example \
|
||
--strategy hybrid_node_mcp \
|
||
--mcp-config mcp_client.json \
|
||
--checkpoint runtime/checkpoints/demo.json
|
||
```
|
||
|
||
代码内嵌方式:
|
||
|
||
```python
|
||
from pam_deploy_graph.agent import PamDeployAgent
|
||
from pam_deploy_graph.mcp_factory import build_mcp_runner_from_config
|
||
|
||
runner = build_mcp_runner_from_config("mcp_client.json")
|
||
agent = PamDeployAgent(mcp_runner=runner)
|
||
```
|
||
|
||
`mcp_client.json` 示例:
|
||
|
||
```json
|
||
{
|
||
"server_name": "pam-node-prod",
|
||
"transport": "streamable_http",
|
||
"server_url": "https://pam-node-mcp.example.com/mcp",
|
||
"auth": {
|
||
"token_url": "https://pam-node-auth.example.com/oauth/token",
|
||
"client_id": "mcp_client_id",
|
||
"client_secret": "mcp_client_secret",
|
||
"grant_type": "client_credentials"
|
||
},
|
||
"timeout_seconds": 60,
|
||
"sse_read_timeout_seconds": 300,
|
||
"headers": {}
|
||
}
|
||
```
|
||
|
||
字段说明:
|
||
|
||
- `transport`:支持 `streamable_http`、`sse`、`stdio`。一般远端 MCP server 用 `streamable_http` 或 `sse`。
|
||
- `server_url`:MCP server 地址,例如 `/mcp` 或 `/sse` endpoint。
|
||
- `auth.token_url`:MCP 鉴权 token 地址,和 HOME 获取 token 的表单方式一致,但地址和账号密码独立。
|
||
- `auth.client_id` / `auth.client_secret`:MCP 独立账号密码。
|
||
- `headers`:除鉴权外需要额外带给 MCP server 的静态请求头。
|
||
- `action_tools`:通常不用配置。只有 server 暴露的 tool 名称不符合 `get-online-ips`、`get_online_ips`、`pam_get_online_ips` 这类约定时,才用它覆盖 action -> tool,例如 `{ "get-online-ips": "custom_list_ips" }`。
|
||
|
||
如果是本地 stdio MCP server,也仍然支持:
|
||
|
||
```json
|
||
{
|
||
"transport": "stdio",
|
||
"command": "/opt/pam-node-mcp/server",
|
||
"args": ["--stdio"],
|
||
"cwd": "/opt/pam-node-mcp",
|
||
"env": {
|
||
"PAM_NODE_ENV": "prod"
|
||
}
|
||
}
|
||
```
|
||
|
||
## 使用方式
|
||
|
||
开发项目迁移到新环境后,推荐先安装完整开发依赖:
|
||
|
||
```bash
|
||
python -m venv .venv
|
||
source .venv/bin/activate
|
||
python -m pip install --upgrade pip setuptools wheel
|
||
python -m pip install -e ".[mcp,chat,test]"
|
||
pytest -q
|
||
```
|
||
|
||
Windows PowerShell 激活虚拟环境使用:
|
||
|
||
```powershell
|
||
.\.venv\Scripts\Activate.ps1
|
||
```
|
||
|
||
基础要求:Python 3.11+。如果要执行 Linux 脚本 action,运行环境还需要 `bash` 和 `curl`;如果要构建 Linux 解压即用包,请在 Linux x86_64 构建机上执行打包脚本。
|
||
|
||
整体逻辑结构流程图:
|
||
|
||
```text
|
||
docs/current_logic_flow.md
|
||
```
|
||
|
||
Linux 解压即用打包:
|
||
|
||
```bash
|
||
bash packaging/build_linux_self_contained.sh
|
||
```
|
||
|
||
构建产物会输出到:
|
||
|
||
```text
|
||
dist/linux_self_contained/pam-deploy-agent-linux-x86_64/
|
||
dist/linux_self_contained/pam-deploy-agent-linux-x86_64.tar.gz
|
||
```
|
||
|
||
发布包内的 `doc_scripts` 只包含运行必需文件:`deploy.sh`、`config.txt.example`、`PAM_AUTO_DEPLY_SKILL.md`。发布包内的 `README.md` 使用 `packaging/README_packaged_agent.md`,只介绍打包后 Agent 的使用方式;同时会带上 `mcp_client.example.json` 作为 MCP 配置示例。
|
||
|
||
目标机器解压后运行:
|
||
|
||
```bash
|
||
tar -xzf pam-deploy-agent-linux-x86_64.tar.gz
|
||
cd pam-deploy-agent-linux-x86_64
|
||
./run.sh --help
|
||
./run.sh chat --config doc_scripts/config.txt.example --strategy fake --checkpoint runtime/checkpoints/demo.json
|
||
```
|
||
|
||
包大小以构建脚本末尾打印的 `du` 结果为准。按当前依赖估算:默认包含 MCP 依赖时压缩包约 60-110 MB、解压后约 160-300 MB;使用 `PACKAGE_EXTRAS=` 构建最小包时压缩包约 45-75 MB、解压后约 120-200 MB。
|
||
|
||
交互式对话框:
|
||
|
||
```bash
|
||
python -m pam_deploy_graph.cli chat --config doc_scripts/config.txt.example --strategy fake --checkpoint runtime/checkpoints/chat-demo.json
|
||
```
|
||
|
||
启动后可输入自然语言需求或会话命令:
|
||
|
||
```text
|
||
PAM> 请用 MCP 预演部署 HET PAM Node 版本 2.0.5,不要动环境
|
||
PAM> preview
|
||
PAM> set VERSION_NUMBER=2.0.6
|
||
PAM> load params runtime/override.txt
|
||
PAM> run
|
||
即将执行真实 action;确认执行请输入 yes: yes
|
||
开始执行 action: get-token [backend=fake]
|
||
开始分析 action 结果: get-token [backend=fake]
|
||
完成 action: get-token [backend=fake]
|
||
PAM> status
|
||
PAM> params
|
||
PAM> events 5
|
||
PAM> llm test
|
||
PAM> llm action-analysis on
|
||
PAM> llm config action_analysis_prompt_file=prompts/action_review.txt
|
||
PAM> mcp config mcp_client.example.json
|
||
PAM> list checkpoints
|
||
PAM> load checkpoint runtime/checkpoints/chat-demo.json
|
||
PAM> rollback
|
||
PAM> resume
|
||
PAM> exit
|
||
```
|
||
|
||
`chat` 默认仍要求在会话内显式输入 `run`,并确认参数、目标 IP 范围和最终执行后才会执行 action。输入 `你好`、`hello` 这类问候不会触发 LLM/结构化分析;需要分析部署需求时可直接描述部署任务,或显式使用 `analyze <需求>`。每个 action 完成后都会自动进入一次 LLM/规则审核,并播报审核开始/结束;只有审核通过才会把 action 记为 completed;如果审核建议停止或审核本身失败,流程会暂停并输出建议,等待用户决定是否 `resume` 重试当前 action。逐 IP action 失败时也会暂停,修复外部环境后输入 `resume` 会从当前 action 重试;如果确实需要回滚,使用 `rollback [IP]` 显式执行。`llm test [文本]` 可测试当前 LLM client 是否可用。`--analyze-actions` 仅控制详细审核结果是否写入 `events`。执行中可按 `Ctrl+C` 中断,chat 会保存当前 checkpoint 并把流程标记为 `user_interrupted`。`set KEY=VALUE` 和 `load params <路径>` 会把更新同步到当前运行 state、`config.txt` 和 checkpoint。`chat` 也支持 `--llm-base-url` / `--llm-api-key` / `--llm-model` / `--llm-action-analysis-prompt-file`、`--mcp-config` 和 `--analyze-actions`。
|
||
|
||
## 日志
|
||
|
||
Agent 默认写入运行日志到 `logs/pam_deploy_agent.log`。日志覆盖 CLI/chat 输入、LLM 请求和响应摘要、action 路由、脚本/MCP 调用、LangGraph 节点、checkpoint 保存、暂停/续跑等关键流程。日志会递归脱敏 `CLIENT_SECRET`、`MCP_CLIENT_SECRET`、token、Authorization、api_key、password 等字段,并截断长文本。
|
||
|
||
可通过环境变量调整日志位置和级别:
|
||
|
||
```bash
|
||
export PAM_AGENT_LOG_FILE=logs/pam_deploy_agent.log
|
||
export PAM_AGENT_LOG_LEVEL=INFO
|
||
```
|
||
|
||
调试 LLM 或 MCP 调用时可临时设为 `DEBUG`,但仍建议把日志目录放在受控位置。
|
||
|
||
预演:
|
||
|
||
```bash
|
||
python -m pam_deploy_graph.cli preview --config doc_scripts/config.txt.example --strategy fake
|
||
```
|
||
|
||
fake 全局流程验证:
|
||
|
||
```bash
|
||
python -m pam_deploy_graph.cli run-global --config doc_scripts/config.txt.example --strategy fake --confirm
|
||
```
|
||
|
||
fake 完整部署流程验证:
|
||
|
||
```bash
|
||
python -m pam_deploy_graph.cli run-deploy --config doc_scripts/config.txt.example --strategy fake --checkpoint runtime/checkpoints/demo.json --confirm
|
||
```
|
||
|
||
如果 action 失败或审核阻断,流程会保存 checkpoint 并暂停;修复外部环境后可直接续跑,Agent 会从当前 action 重试:
|
||
|
||
```bash
|
||
python -m pam_deploy_graph.cli resume --checkpoint runtime/checkpoints/demo.json --confirm
|
||
```
|
||
|
||
如果需要回滚失败 IP,请显式执行 rollback。未传 `--ip` 时会使用当前失败 IP;执行完成后再用 `resume` 继续主流程。
|
||
|
||
```bash
|
||
python -m pam_deploy_graph.cli rollback --checkpoint runtime/checkpoints/demo.json --confirm
|
||
python -m pam_deploy_graph.cli resume --checkpoint runtime/checkpoints/demo.json --confirm
|
||
```
|
||
|
||
也可以指定 IP 和停机策略:
|
||
|
||
```bash
|
||
python -m pam_deploy_graph.cli rollback --checkpoint runtime/checkpoints/demo.json --ip 192.168.1.10 --stop-first --note "人工决定回滚该 IP" --confirm
|
||
```
|
||
|
||
checkpoint 用于断点续跑,会保存完整运行状态和参数。为了支持真实续跑,Agent 写入 checkpoint 时不会脱敏参数;请把 checkpoint 放在受控目录中。如果不传 `--checkpoint`,流程仍可运行,但不能跨进程 `resume`。
|
||
|
||
结构化理解和计划生成:
|
||
|
||
```bash
|
||
python -m pam_deploy_graph.cli analyze --config doc_scripts/config.txt.example --text "请用 MCP 预演部署 HET PAM Node 版本 2.0.5,不要动环境"
|
||
```
|
||
|
||
测试:
|
||
|
||
```bash
|
||
pytest -q
|
||
```
|
||
|
||
## 下一步建议
|
||
|
||
1. 接入真实 PAM_NODE MCP session,并用 `SessionMcpToolClient` 包装。
|
||
2. 在测试环境中做 smoke:HOME 脚本 `get-token/get-node-url` + NODE MCP `get-online-ips`。
|
||
3. 在测试环境验证真实脚本 action 的失败重试、显式回滚和续跑链路。
|
||
4. 继续细化参数确认、IP 范围确认的交互式 UI 或上层编排。
|