Add files via upload

This commit is contained in:
公明
2026-07-07 14:04:18 +08:00
committed by GitHub
parent 3dfcde7c88
commit 00802a275c
61 changed files with 9460 additions and 24 deletions
+65
View File
@@ -0,0 +1,65 @@
# Eino 多代理改造说明(DeepAgent
本文档记录 **Eino 单代理(ADK****多 AgentCloudWeGo Eino `adk/prebuilt`** 的改造范围、进度与后续事项。原生 ReAct 执行路径已移除。
## 总体结论
- **改造已可用于生产试验**:流式对话、MCP 工具桥接、配置开关、前端模式切换均已落地。
- **入口策略**:**单代理** 走 `/api/eino-agent/stream`;多代理走 `/api/multi-agent/stream`,请求体 **`orchestration`** 指定编排。模式定位按 Eino ADK 最佳实践区分:**Deep** 适合复杂安全测试与 task 子代理协作;**Plan-Execute** 适合目标明确的规划 → 执行 → 重规划闭环;**Supervisor** 适合多个专业子代理动态分派的专家路由场景。机器人默认 `robot_default_agent_mode: eino_single`;批量队列默认 `eino_single`,多代理模式需 `multi_agent.enabled`
## 已完成项
| 项 | 说明 |
|----|------|
| 依赖与代理 | `go.mod` 直接依赖 `github.com/cloudwego/eino``eino-ext/.../openai``go.mod` 注释与 `scripts/bootstrap-go.sh` 指导 **GOPROXY**(如 `https://goproxy.cn,direct`)。 |
| 配置 | `config.yaml``agent.max_iterations` 为全局 ReAct 上限(主/子代理统一);`multi_agent``enabled``robot_use_multi_agent``sub_agents`(含可选 `bind_role`)、`eino_skills``eino_middleware` 等;结构体见 `internal/config/config.go`。 |
| Markdown 子代理 / 主代理 | 在 `agents_dir` 下放 `*.md`。**子代理**:供 Deep `task``supervisor` `transfer`。**主代理(按模式分离)**`orchestrator.md`(或 `kind: orchestrator` 的**单个**其他 .md)→ **Deep**;固定名 `orchestrator-plan-execute.md`**plan_execute**;固定名 `orchestrator-supervisor.md`**supervisor**。正文优先于 YAML`multi_agent.orchestrator_instruction``orchestrator_instruction_plan_execute``orchestrator_instruction_supervisor`plan_execute / supervisor **不会**回退到 Deep 的 `orchestrator_instruction`。皆空时 plan_execute / supervisor 使用代码内置默认提示。管理:**Agents → Agent管理**API`/api/multi-agent/markdown-agents*`。 |
| MCP 桥 | `internal/einomcp``ToolsFromDefinitions` + 会话 ID 持有者,执行走 `Agent.ExecuteMCPToolForConversation`。 |
| 编排 | `internal/multiagent/runner.go``deep.New` + 子 `ChatModelAgent` + `adk.NewRunner``EnableStreaming: true`,可选 `CheckPointStore`),事件映射为现有 SSE `tool_call` / `response_delta` 等。 |
| HTTP | `POST /api/multi-agent`(非流式)、`POST /api/multi-agent/stream`(SSE);路由**常注册**,是否可用由运行时 `multi_agent.enabled` 决定(流式未启用时 SSE 内 `error` + `done`)。 |
| 会话准备 | `internal/handler/multi_agent_prepare.go``prepareMultiAgentSession`(含 **WebShell** `CreateConversationWithWebshell`、工具白名单与单代理一致)。 |
| 单 Agent | `internal/agent` 为 MCP/工具层(`ToolsForRole``ExecuteMCPToolForConversation`);单代理编排走 `RunEinoSingleChatModelAgent``/api/eino-agent*`)。 |
| 前端 | 主聊天 / WebShell**Eino 单代理**`/api/eino-agent/stream`)与 **Deep / Plan-Execute / Supervisor**`/api/multi-agent/stream` + `orchestration`);`multi_agent.enabled` 控制多代理选项是否展示。 |
| 流式兼容 | Eino 单/多代理与 Web UI 共用 `handleStreamEvent``conversation``progress``response_start` / `response_delta``thinking` / `thinking_stream_*``tool_*``response``done` 等。 |
| 批量任务 | 队列 `agentMode``deep` / `plan_execute` / `supervisor` 时子任务带对应 `orchestration` 调用 `RunDeepAgent`;旧值 `multi` 与「`agentMode` 为空且 `batch_use_multi_agent: true`」均按 `deep`。 |
| 配置 API | `GET /api/config` 返回 `multi_agent: { enabled, robot_use_multi_agent, sub_agent_count }``PUT /api/config` 可更新 `enabled``robot_use_multi_agent`(不覆盖 `sub_agents`)。 |
| OpenAPI | 多代理路径说明已更新(流式未启用为 SSE 错误事件)。 |
| 机器人 | `ProcessMessageForRobot``robot_default_agent_mode`(默认 `eino_single`)调用 `RunEinoSingleChatModelAgent``RunDeepAgent`。 |
| 预置编排 | 聊天 / WebShell`POST /api/multi-agent*` 请求体 `orchestration``deep` \| `plan_execute` \| `supervisor`(缺省 `deep`)。`deep` 使用 task 子代理协作;`plan_execute` 不构建 YAML/Markdown 子代理;`plan_execute_loop_max_iterations` 仍来自配置;`supervisor` 至少需一个子代理,只有一个子代理时会提示其专家路由空间有限。 |
| Eino 中间件 | `multi_agent.eino_middleware`(可选):`patchtoolcalls`(默认开)、`toolsearch`(按阈值拆分 MCP 工具列表)、`plantask`(需 `eino_skills`)、`reduction`(大工具输出截断/落盘)、`checkpoint_dir`Runner 断点)、`deep_output_key` / `deep_model_retry_max_retries` / `task_tool_description_prefix`Deep 与 supervisor 主代理共享其中模型重试与 OutputKey)。**`plan_execute`**Executor 使用 Eino 官方允许的自定义 `adk.ChatModelAgent`,保持官方 Plan/UserInput/ExecutedSteps session contract,同时挂载与 Deep/Supervisor 主代理同源的 middlewarepatch → reduction → toolsearch → plantask → filesystem → skill → summarization tail)。Planner/Replanner 仅 summarization tail + prompt 预算截断,不跑 MCP 工具链。当前 Eino 官方 `planexecute.NewExecutor` 尚未暴露 Handlers 字段,因此该自定义 Executor 是保留 middleware 的对齐实现。 |
## 进行中 / 待办( backlog
| 优先级 | 项 | 说明 |
|--------|----|------|
| P3 | **观测与计费** | Eino 事件可进一步打结构化日志 / trace id,便于排障。 |
| P3 | **测试** | 增加 `internal/multiagent` 与 einomcp 的集成测试(mock model 或录屏回放)。 |
## 关键文件索引
- `internal/multiagent/runner.go` — DeepAgent / plan_execute / supervisor 组装与事件循环
- `internal/multiagent/eino_orchestration.go` — PlanExecute 根节点与 Executor 中间件栈(`buildPlanExecuteExecutorHandlers`
- `internal/handler/multi_agent.go` — SSE 与(同步)HTTP
- `internal/handler/multi_agent_prepare.go` — 会话准备(含 WebShell
- `internal/einomcp/` — MCP → Eino Tool
- `config.yaml``multi_agent` 示例块
- `web/static/js/chat.js` — 模式选择与 stream URL
- `web/static/js/webshell.js` — WebShell AI 流式 URL 与主聊天模式对齐
- `web/static/js/settings.js` — 多代理标量保存
## 版本记录
| 日期 | 说明 |
|------|------|
| 2026-03-22 | 首版:Eino DeepAgent + stream + 前端开关 + GOPROXY 脚本。 |
| 2026-03-22 | 补充:进度文档、`prepareMultiAgentSession` 抽取、WebShell 后端对齐、`POST /api/multi-agent`、OpenAPI `/api/multi-agent*` 条目。 |
| 2026-03-22 | 路由常注册、流式未启用 SSE 错误、`robot_use_multi_agent`、设置页持久化、WebShell/机器人多代理、`bind_role` 子代理 Skills/tools。 |
| 2026-03-22 | `tool_result.toolCallId``ReasoningContent`→思考流、`batch_use_multi_agent` 与批量队列 Eino 执行。 |
| 2026-03-22 | 流式工具事件:按稳定签名去重,避免每 chunk 刷屏与「未知工具」;最终回复去重相同段落;内置调度显示为 `task`。 |
| 2026-03-22 | `agents/*.md` 子代理定义、`agents_dir`、合并进 `RunDeepAgent`、前端 Agents 菜单与 CRUD API。 |
| 2026-03-22 | `orchestrator.md` / `kind: orchestrator` 主代理、列表主/子标记、与 `orchestrator_instruction` 优先级。 |
| 2026-04-19 | 主聊天「对话模式」:原生 ReAct 与 Deep / Plan-Execute / Supervisor`POST /api/multi-agent*` 请求体 `orchestration` 与界面一致;`config.yaml` / 设置页不再维护预置编排字段(机器人/批量默认 `deep`)。 |
| 2026-04-21 | 移除角色 `skills``/api/roles/skills/list``bind_role` 仅继承 toolsSkills 仅通过 Eino `skill` 工具按需加载。 |
| 2026-07-06 | **最佳实践对齐**Deep / Plan-Execute / Supervisor 改为中性适用场景描述;Supervisor 标为专家路由特定场景并收紧 transfer/exit 约束;plan_execute Executor 明确为遵循官方 session contract 的自定义 ChatModelAgent,保留 middleware 并补类型保护。 |
| 2026-07-02 | **plan_execute Executor 中间件对齐**`ExecPreMiddlewares` 与 Deep 主代理同源;`buildPlanExecuteExecutorHandlers` + 回归测试;文档更正。 |
| 2026-06-02 | **移除原生 ReAct**:删除 `/api/agent-loop*` 执行入口与 `AgentLoopWithProgress`;统一 Eino ADK(单代理 `/api/eino-agent*`,多代理 `/api/multi-agent*`);任务 cancel/tasks API 保留。 |
+29
View File
@@ -0,0 +1,29 @@
# 中文文档
- [部署指南](deployment.md):部署形态、HTTPS、反向代理、systemd、备份、升级和验收。
- [运维 Runbooks](runbooks.md):生产部署、外部 MCP、知识库、Web 测试、C2 清理和工具排障的操作步骤。
- [配置画像](configuration-profiles.md):本地开发、内网团队、知识库、高审计生产、C2 演练等推荐配置。
- [安全加固指南](security-hardening.md):上线前基线、反向代理、HITL 白名单、文件权限和周期巡检。
- [API Recipes](api-recipes.md):登录、Agent、流式、多代理、上传、漏洞、知识库、MCP 和审计导出示例。
- [贡献规范](contributing-guide.md):新增 API、配置、工具、前端、数据库、高风险能力和文档的 checklist。
- [配置参考](configuration.md)`config.yaml` 字段、热应用边界、参数建议和源码锚点。
- [安全模型](security-model.md):信任边界、HITL、工具执行、C2/WebShell 与数据安全。
- [架构说明](architecture.md):请求路径、模块关系、复杂度热点和设计取舍。
- [API 参考](api-reference.md):认证、OpenAPI、SSE、稳定性分层和常用接口。
- [排错指南](troubleshooting.md):诊断顺序、最小命令、常见误判和故障模板。
- [审计与监控](audit-and-monitoring.md):平台审计、工具监控、HITL 日志和保留策略。
- [知识库](knowledge-base.md):索引链路、检索调参、日志分析和内容写法。
- [C2 使用说明](c2.md):生命周期、任务分级、事件复盘和安全建议。
- [WebShell 管理](webshell.md):操作分层、连接命名、AI 约束和排错。
- [MCP 联邦](mcp-federation.md):内置 MCP、外部 MCP、生命周期和工具命名。
- [Agent 与角色](agent-and-role-guide.md):角色、子代理、Skill、编排模式和工具可见性。
- [Skills 指南](skills-guide.md):Skill 结构、渐进式披露、反模式和本地工具风险。
- [插件开发](plugin-development.md):API 插件、MCP 插件、资源包插件和安全边界。
- [发布流程](release-process.md):发布风险、配置兼容、数据库迁移和验收。
- [测试指南](testing.md):测试分层、回归重点、测试数据和失败用例。
- [图编排使用说明](workflow-graph.md)
- [人机协同最佳实践](hitl-best-practices.md)
- [机器人使用说明](robot.md)
- [视觉分析](VISION.md)
- [前端国际化方案](frontend-i18n.md)
- [Eino 多代理改造说明](MULTI_AGENT_EINO.md)
+45
View File
@@ -0,0 +1,45 @@
# 视觉分析(analyze_image
## 概述
- **工具名**`analyze_image`MCP 内置)
- **行为**:读取本地图片 → `imaging` 缩放/JPEG 压缩 → 调用独立 **Vision** 模型 → 返回**纯文本**给 Agent
- **上下文**:图片字节**不会**写入对话历史;仅路径与文字摘要进入 Agent 上下文
## 配置(`config.yaml` → `vision`
```yaml
vision:
enabled: true
model: qwen-vl-max # 必填
api_key: # 留空 → openai.api_key
base_url: # 留空 → openai.base_url
provider: # 留空 → openai.provider
max_image_bytes: 5242880
max_dimension: 2048
jpeg_quality: 82
max_payload_bytes: 524288
skip_preprocess_below_bytes: 2097152 # 低于 2MB 且长边<=max_dimension 时原图直传;0=始终 JPEG 压缩
detail: low # low | high | auto
timeout_seconds: 60
```
`enabled: false` 时不注册工具。
## Web 设置
**系统设置 → 基本设置 → 视觉分析(analyze_image** 可配置启用开关、视觉模型、API Key/Base URL(留空复用 OpenAI)、预处理参数;**保存并应用** 后写入 `config.yaml` 并重新注册 MCP 工具。
## 路径
`analyze_image` 可读取服务器上任意可读的图片文件路径(绝对路径或相对于进程工作目录的相对路径)。仍校验图片扩展名与常规文件类型。
## Agent 使用
系统提示已说明:遇图片调用 `analyze_image`,勿用 `read_file` 读二进制图。
`multi_agent.eino_middleware.tool_search_always_visible_tools` 建议包含 `analyze_image`
## 合规
启用后图片会发往 Vision API 配置的上游;敏感环境请使用可信网关或保持 `enabled: false`
+197
View File
@@ -0,0 +1,197 @@
# Agent 与角色指南
CyberStrikeAI 的 Agent 行为由三类资源共同决定:角色、子代理和 Skills。角色决定当前任务身份和可用工具;子代理决定多代理分工;Skills 提供可按需加载的专题知识与流程。
## 角色
角色文件位于 `roles/`,格式为 YAML。角色通常包含:
- 名称。
- 描述。
- 系统提示词。
- 可用工具列表。
设计原则:
- 专用角色只绑定必要工具。
- 提示词明确授权边界。
- 对高风险操作要求先说明影响并等待审批。
- 输出格式尽量稳定,便于报告和复盘。
示例方向:
- 信息收集。
- Web 应用扫描。
- API 安全测试。
- 云安全审计。
- 数字取证。
- 二进制分析。
- CTF。
## 单代理
单代理接口:
- `POST /api/eino-agent`
- `POST /api/eino-agent/stream`
适合:
- 快速问答。
- 单目标测试。
- 工具链较短的任务。
- 需要稳定上下文的交互式分析。
## 多代理模式
多代理接口:
- `POST /api/multi-agent`
- `POST /api/multi-agent/stream`
编排模式:
- `deep`:主代理拆解任务,按需调用子代理。
- `plan_execute`:先规划,再执行,必要时重规划。
- `supervisor`:主管代理根据进展转交不同子代理。
适合:
- 多阶段渗透测试。
- 大范围信息收集。
- 需要并行角色分工的分析。
- 长任务和批量任务。
## 子代理 Markdown
子代理位于 `agents/*.md`。Front matter 示例:
```yaml
---
name: Attack Surface Enumeration
id: attack-surface-enumeration
description: 枚举目标暴露面并整理可验证线索
tools:
- subfinder
- nmap
- http-framework-test
bind_role: 信息收集
max_iterations: 300
---
```
正文写系统提示词。建议包含:
- 职责边界。
- 输入期望。
- 使用工具顺序。
- 输出格式。
- 禁止事项。
## 主代理
主代理可用:
- `agents/orchestrator.md`
- `agents/orchestrator-plan-execute.md`
- `agents/orchestrator-supervisor.md`
或在 front matter 中设置 `kind: orchestrator`。每种编排只应有一个主代理定义。
## 工具选择
工具选择顺序建议:
1. 角色绑定最小工具集。
2. 子代理按任务补充专用工具。
3. `tool_search` 动态解锁大量工具。
4. 高风险工具由 HITL 审批。
不要给所有角色默认绑定全部工具,否则上下文成本和误调用风险都会上升。
## 提示词建议
好的角色提示词应说明:
- 只在授权范围内行动。
- 先确认目标和约束。
- 对写入、删除、爆破、持久化、C2、WebShell 等操作请求审批。
- 输出可复核证据。
- 不确定时标注假设,不编造结果。
## 调试
如果 Agent 选错工具:
- 缩小角色工具列表。
- 增强工具 `short_description`
- 开启或调整 `tool_search_always_visible_tools`
- 在角色提示词中明确工具使用顺序。
如果多代理跑偏:
- 检查子代理描述是否过宽。
- 降低 `sub_agent_user_context_max_runes` 或明确任务输入。
- 优化 orchestrator 提示词。
- 查看过程详情和工具执行监控。
## 角色、子代理、Skill 的职责边界
三者经常混用,建议这样分工:
| 资源 | 解决的问题 | 不适合承载 |
| --- | --- | --- |
| Role | 当前对话的身份、语气、工具边界和授权规则 | 大量参考资料 |
| Agent Markdown | 多代理中的专业分工、交接格式和局部策略 | 一次性任务事实 |
| Skill | 可复用方法论、检查清单、模板和长参考资料 | 权限控制 |
如果把授权边界写进 Skill,而角色没有限制工具,Agent 仍可能在未加载 Skill 前选错工具。权限边界应优先放在 Role 和 HITL 中。
## 编排模式选择
| 模式 | 适合 | 不适合 |
| --- | --- | --- |
| `eino_single` | 短任务、交互式分析、需要稳定上下文 | 多阶段大任务 |
| `deep` | 主代理动态拆分任务,子代理按需深入 | 需要严格步骤顺序的流程 |
| `plan_execute` | 有明确阶段、需要执行后复盘和重规划 | 用户频繁打断的即兴对话 |
| `supervisor` | 专家分工明确,需要主管路由 | 子代理定义含糊或过多 |
经验上,普通安全测试先用 `eino_single`;复杂项目用 `plan_execute`;需要多个专业角色时用 `deep``supervisor`
## 工具可见性如何影响行为
多代理里 `tool_search` 会让模型一开始只看见部分常驻工具。结果是:
- 工具页面显示可用,不代表模型当前上下文可见。
- `tool_search_always_visible_tools` 里的工具更容易被模型调用。
- 工具描述越清晰,越容易被搜索命中。
- 子代理自己的 `tools` 限制仍然很重要。
调试“Agent 为什么不用某工具”时,要同时检查角色工具、子代理工具、tool_search 配置和工具描述。
## 好的子代理输出格式
子代理不要只返回“已完成”。建议固定格式:
```markdown
## 结论
## 证据
- 命令/工具:
- 关键输出:
- 置信度:
## 风险
## 建议下一步
```
这样主代理才能继续编排,也方便攻击链和项目事实沉淀。
## 源码锚点
- Markdown Agent 解析:`internal/agents/markdown.go`
- 多代理准备:`internal/handler/multi_agent_prepare.go`
- 编排实现:`internal/multiagent/eino_orchestration.go`
- 工具搜索中间件:`internal/multiagent/eino_middleware.go`
- 子代理上下文:`internal/multiagent/sub_agent_context_test.go`
+153
View File
@@ -0,0 +1,153 @@
# API Recipes
[English](../en-US/api-recipes.md)
本文给出外部脚本或插件常用的 API 调用配方。完整字段以 `/api-docs``/api/openapi/spec` 为准。
## Recipe 1:登录并验证
```bash
curl -k https://127.0.0.1:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"password":"<password>"}'
```
后续请求推荐使用:
```bash
Authorization: Bearer <token>
```
验证:
```bash
curl -k https://127.0.0.1:8080/api/auth/validate \
-H "Authorization: Bearer <token>"
```
## Recipe 2:创建对话并发送消息
最简单方式是不先创建空对话,直接调用 Agent:
```bash
curl -k https://127.0.0.1:8080/api/eino-agent \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"message":"对 127.0.0.1 做授权的基础信息收集,只做只读操作"}'
```
如果需要先创建对话:
```bash
curl -k https://127.0.0.1:8080/api/conversations \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"title":"Web 测试"}'
```
然后把返回的 `conversationId` 放入 Agent 请求。
## Recipe 3:流式调用 Agent
```bash
curl -k -N https://127.0.0.1:8080/api/eino-agent/stream \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"message":"总结当前项目事实并列出下一步,只读"}'
```
注意:
- `-N` 禁用 curl 缓冲。
- 反向代理也要关闭 buffering。
- 收到 `done` 才算本轮结束。
## Recipe 4:调用多代理
```bash
curl -k -N https://127.0.0.1:8080/api/multi-agent/stream \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"message":"对授权目标做分阶段 Web 安全测试,先规划再执行只读步骤",
"orchestration":"plan_execute"
}'
```
可选 `orchestration`
- `deep`
- `plan_execute`
- `supervisor`
## Recipe 5:上传附件
```bash
curl -k https://127.0.0.1:8080/api/chat-uploads \
-H "Authorization: Bearer <token>" \
-F "file=@./request.txt"
```
大文件建议上传后在消息中引用,不要直接塞进 prompt。
## Recipe 6:写入漏洞
```bash
curl -k https://127.0.0.1:8080/api/vulnerabilities \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"title":"示例 SQL 注入",
"severity":"high",
"target":"https://example.com/item?id=1",
"description":"参数 id 存在可验证 SQL 注入",
"evidence":"只读验证输出...",
"remediation":"使用参数化查询"
}'
```
字段以 OpenAPI 为准。
## Recipe 7:查询知识库
```bash
curl -k https://127.0.0.1:8080/api/knowledge/search \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"query":"SQL 注入如何判断字段数",
"riskType":"SQL Injection",
"topK":5,
"threshold":0.4
}'
```
如果结果为空,先调用 categories 看风险类型名称是否匹配。
## Recipe 8:检查外部 MCP 状态
```bash
curl -k https://127.0.0.1:8080/api/external-mcp/stats \
-H "Authorization: Bearer <token>"
```
如果服务 running 但 Agent 找不到工具,检查角色工具限制和 `tool_search`
## Recipe 9:获取工具 schema
```bash
curl -k https://127.0.0.1:8080/api/config/tools/nmap/schema \
-H "Authorization: Bearer <token>"
```
插件或自动化脚本应根据 schema 构造参数,不要猜字段名。
## Recipe 10:导出审计日志
```bash
curl -k "https://127.0.0.1:8080/api/audit/logs/export" \
-H "Authorization: Bearer <token>" \
-o audit.csv
```
导出文件可能包含敏感操作信息,应加密保存。
+239
View File
@@ -0,0 +1,239 @@
# API 参考
CyberStrikeAI 内置 OpenAPI 规格和 API 文档页面。启动服务后访问:
```text
/api-docs
```
OpenAPI JSON
```text
GET /api/openapi/spec
```
`/api/openapi/spec` 需要登录认证,避免未授权用户直接枚举接口结构。
## 认证
登录:
```http
POST /api/auth/login
Content-Type: application/json
{"password":"your-password"}
```
认证成功后,前端通常使用 Cookie 会话。外部客户端也可参考 OpenAPI 中的 Bearer Token 描述,按实际返回字段接入。
常用认证接口:
- `POST /api/auth/login`
- `POST /api/auth/logout`
- `POST /api/auth/change-password`
- `GET /api/auth/validate`
## 对话与 Agent
单代理:
- `POST /api/eino-agent`
- `POST /api/eino-agent/stream`
多代理:
- `POST /api/multi-agent`
- `POST /api/multi-agent/stream`
多代理请求体通过 `orchestration` 指定:
- `deep`
- `plan_execute`
- `supervisor`
对话管理:
- `POST /api/conversations`
- `GET /api/conversations`
- `GET /api/conversations/:id`
- `PUT /api/conversations/:id`
- `DELETE /api/conversations/:id`
- `POST /api/conversations/:id/delete-turn`
- `GET /api/messages/:id/process-details`
## 项目、漏洞、攻击链
项目:
- `GET /api/projects`
- `POST /api/projects`
- `GET /api/projects/:id`
- `PUT /api/projects/:id`
- `DELETE /api/projects/:id`
- `GET /api/projects/:id/facts`
- `POST /api/projects/:id/facts`
- `GET /api/projects/:id/fact-graph`
漏洞:
- `GET /api/vulnerabilities`
- `POST /api/vulnerabilities`
- `GET /api/vulnerabilities/:id`
- `PUT /api/vulnerabilities/:id`
- `DELETE /api/vulnerabilities/:id`
- `GET /api/vulnerabilities/export`
攻击链:
- `GET /api/attack-chain/:conversationId`
- `POST /api/attack-chain/:conversationId/regenerate`
## 工具、MCP、配置
配置:
- `GET /api/config`
- `PUT /api/config`
- `POST /api/config/apply`
- `GET /api/config/tools`
- `GET /api/config/tools/:name/schema`
- `POST /api/config/test-openai`
- `POST /api/config/test-vision`
- `POST /api/config/list-models`
MCP
- `POST /api/mcp`
- `GET /api/external-mcp`
- `PUT /api/external-mcp/:name`
- `POST /api/external-mcp/:name/start`
- `POST /api/external-mcp/:name/stop`
- `DELETE /api/external-mcp/:name`
## 知识库、Skills、角色、Agent
知识库:
- `GET /api/knowledge/categories`
- `GET /api/knowledge/items`
- `POST /api/knowledge/scan`
- `POST /api/knowledge/index`
- `POST /api/knowledge/search`
角色:
- `GET /api/roles`
- `POST /api/roles`
- `GET /api/roles/:name`
- `PUT /api/roles/:name`
- `DELETE /api/roles/:name`
Skills
- `GET /api/skills`
- `POST /api/skills`
- `GET /api/skills/:name`
- `PUT /api/skills/:name`
- `DELETE /api/skills/:name`
- `GET /api/skills/:name/files`
- `GET /api/skills/:name/file`
- `PUT /api/skills/:name/file`
Markdown 子代理:
- `GET /api/multi-agent/markdown-agents`
- `POST /api/multi-agent/markdown-agents`
- `GET /api/multi-agent/markdown-agents/:filename`
- `PUT /api/multi-agent/markdown-agents/:filename`
- `DELETE /api/multi-agent/markdown-agents/:filename`
## 高风险能力
WebShell
- `GET /api/webshell/connections`
- `POST /api/webshell/connections`
- `POST /api/webshell/exec`
- `POST /api/webshell/file`
C2
- `GET /api/c2/listeners`
- `POST /api/c2/listeners`
- `GET /api/c2/sessions`
- `POST /api/c2/tasks`
- `POST /api/c2/payloads/build`
终端:
- `POST /api/terminal/run`
- `POST /api/terminal/run/stream`
- `GET /api/terminal/ws`
这些接口应只开放给可信管理员,并配合 HTTPS、强密码、网络隔离和审计。
## 调用建议
- 优先使用 `/api-docs` 查看完整参数和响应结构。
- 流式接口使用 SSE,反向代理需关闭缓冲。
- 所有修改类接口都应处理 401、403、404、409、500。
- 外部集成建议创建最小权限网络路径,不要把 Web 管理面直接暴露到公网。
## 认证细节
认证中间件会按顺序提取 token
1. `Authorization: Bearer <token>`
2. `Authorization: <token>`
3. 查询参数 `?token=<token>`
4. Cookie `auth_token`
这意味着外部脚本最稳妥的方式是使用 `Authorization: Bearer`。查询参数虽然支持,但容易进入代理日志,不建议生产使用。
## SSE 客户端注意事项
`/api/eino-agent/stream``/api/multi-agent/stream` 是长连接。客户端应处理:
- 网络中断后不要盲目重放破坏性请求。
- 收到 `error` 事件后读取错误正文。
- 收到 `done` 才视为本轮结束。
- 代理层不能缓冲。
- 请求体中的 `conversationId` 决定是否接续已有对话。
## API 稳定性分层
| API 类型 | 稳定性 | 集成建议 |
| --- | --- | --- |
| `/api/auth/*` | 高 | 可直接集成 |
| `/api/eino-agent*` | 高 | 推荐外部对话入口 |
| `/api/openapi/spec` | 高 | 用于生成客户端 |
| `/api/config*` | 中 | 管理工具使用,谨慎自动化 |
| `/api/c2/*``/api/webshell/*` | 中 | 高风险,必须加权限边界 |
| 前端私有调用细节 | 低 | 不建议插件依赖 |
## Curl 示例
登录并提取 token 的返回字段可能随实现调整,建议先看 `/api-docs`。如果已有 token
```bash
curl -k https://127.0.0.1:8080/api/conversations \
-H "Authorization: Bearer <token>"
```
发送非流式单代理请求:
```bash
curl -k https://127.0.0.1:8080/api/eino-agent \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"message":"对 127.0.0.1 做授权的基础信息收集,先不要执行高风险操作"}'
```
## 源码锚点
- 路由:`internal/app/app.go`
- 认证:`internal/security/auth_middleware.go`
- OpenAPI`internal/handler/openapi.go`
- 单代理:`internal/handler/eino_single_agent.go`
- 多代理:`internal/handler/multi_agent.go`
+171
View File
@@ -0,0 +1,171 @@
# 架构说明
CyberStrikeAI 是一个以 Web 管理面为入口、以 Agent 和 MCP 工具为执行核心的安全测试编排平台。
## 总览
```mermaid
flowchart LR
U["Web / Robot / API 用户"] --> R["Gin Router"]
R --> H["Handlers"]
H --> DB["SQLite"]
H --> A["Agent / Multi-Agent"]
A --> M["MCP Server"]
M --> T["内置工具 / YAML 工具 / Skills FS"]
M --> EM["外部 MCP"]
A --> K["知识库检索"]
H --> W["Workflow 图编排"]
H --> C2["内置 C2"]
H --> WS["WebShell"]
H --> AU["Audit / Monitor"]
```
## Web 层
入口在 `cmd/server/`,应用组装在 `internal/app/`。Web 使用 Gin
- `web/templates/index.html`:主页面。
- `web/templates/api-docs.html`API 文档页面。
- `web/static/js/`:各业务模块前端逻辑。
- `web/static/css/`:样式。
路由注册集中在 `internal/app/app.go`
## Handler 层
`internal/handler/` 按业务拆分:
- `agent.go``eino_single_agent.go``multi_agent.go`
- `workflow.go``workflow_run.go`
- `knowledge.go`
- `webshell.go`
- `c2.go`
- `audit.go`
- `monitor.go`
- `project.go`
- `vulnerability.go`
- `config.go`
- `openapi.go`
Handler 负责参数解析、权限中间件后的业务协调和 HTTP 响应。
## Agent 层
单代理和多代理主要在:
- `internal/agent/`
- `internal/multiagent/`
- `internal/agents/`
- `agents/`
Eino ADK 提供单代理、Deep、Plan-Execute、Supervisor 等执行模式。多代理子 Agent 由 Markdown 文件定义。
## MCP 与工具
MCP 相关:
- `internal/mcp/`:Server、外部 MCP、连接恢复。
- `internal/einomcp/`Eino 与 MCP 工具适配。
- `tools/`YAML 命令工具。
- `internal/app/*_tools.go`Go 内置工具注册。
工具调用会进入监控记录,并可受 HITL 审批影响。
## Workflow
图编排在 `internal/workflow/`HTTP 入口在 `internal/handler/workflow*.go`。它支持 start、agent、tool、condition、hitl、output、end 等节点。
详细使用见 [图编排使用说明](workflow-graph.md)。
## 知识库
知识库在 `internal/knowledge/`,包括:
- Markdown/文本内容管理。
- chunk。
- embedding。
- SQLite 向量索引。
- multi-query。
- rerank。
- 检索日志。
启用后会向 Agent 暴露知识检索工具。
## 数据层
`internal/database/` 封装 SQLite 访问,保存:
- 对话、消息、过程详情。
- 分组。
- 工具执行记录。
- HITL 日志。
- 知识库索引和检索日志。
- WebShell、C2、项目、漏洞、批量任务等业务数据。
默认数据库文件:
- `data/conversations.db`
- `data/knowledge.db`
## 安全与审计
`internal/security/` 提供认证、限流、Shell 执行和命令流处理。`internal/audit/``internal/monitor/` 分别负责平台审计和执行监控。
高风险模块包括:
- Terminal。
- WebShell。
- C2。
- 外部 MCP。
- 文件系统和 Shell Skills。
这些模块应结合角色、HITL 和部署隔离使用。
## 一次对话请求的真实路径
`/api/eino-agent/stream` 为例:
1. Gin 路由进入认证中间件。
2. Handler 解析请求体、会话 ID、角色、附件和 WebShell 上下文。
3. Agent 构建模型输入,包括历史消息、角色提示、项目事实、工具列表。
4. Eino Runner 调用模型。
5. 模型需要工具时走 MCP Tool。
6. 工具调用前可能触发 HITL。
7. 工具执行结果写入过程详情和监控。
8. 模型继续推理并生成最终回答。
9. SSE 将进度、工具事件、文本增量推给前端。
10. 会话、消息、过程详情写入 SQLite。
这个路径解释了为什么问题可能出在很多层:认证、会话、模型、工具、HITL、MCP、数据库、SSE 或前端渲染。
## 横向模块依赖
几个模块不是独立页面,而是横向能力:
- Project facts:会被注入 Agent 上下文,影响多轮和跨对话判断。
- HITL:插在工具调用前,影响所有 Agent/MCP 工具。
- Monitor:记录工具执行,影响任务取消、复盘和通知。
- Audit:记录平台管理动作,影响安全运营。
- Tool search:影响模型看见哪些工具,而不仅仅是工具页面显示。
改这些模块时要看全局调用点,不要只测单个页面。
## 复杂度热点
维护时优先警惕:
- `internal/app/app.go`:组装所有服务,容易引入初始化顺序问题。
- `internal/handler/config.go`:热应用配置,影响模型、知识库、C2、机器人和 MCP。
- `internal/multiagent/`:中间件多,流式、重试、摘要和工具调用交错。
- `internal/security/`Shell 和认证是安全边界。
- `internal/database/`:SQLite 结构演进必须兼容旧数据。
## 设计取舍
项目选择单体 Go 服务 + SQLite + 静态前端,是为了降低部署门槛。但代价是:
- 多实例横向扩展不天然成立,尤其 SQLite 写入和内存 session。
- 运行态配置和本地文件强绑定,需要良好备份。
- 高权限工具和 Web 管理面在同一进程内,部署隔离更重要。
这些不是缺陷,而是部署时必须理解的边界。
+148
View File
@@ -0,0 +1,148 @@
# 审计与监控
CyberStrikeAI 有两类常用可观测数据:平台操作审计和工具执行监控。二者用途不同,建议同时开启。
## 平台审计
配置:
```yaml
audit:
enabled: true
retention_days: 15
max_detail_bytes: 8192
auth_failure_cooldown_seconds: 60
```
审计记录覆盖登录、配置、资源管理等平台操作。它不会完整记录对话正文,也不逐条记录所有工具调用正文。
接口:
- `GET /api/audit/meta`
- `GET /api/audit/summary`
- `GET /api/audit/logs`
- `GET /api/audit/logs/:id`
- `GET /api/audit/logs/export`
建议关注:
- 登录失败和异常来源 IP。
- 密码修改。
- 配置修改。
- 外部 MCP 增删改。
- C2/WebShell/知识库等高风险资源操作。
## 工具执行监控
配置:
```yaml
monitor:
retention_days: 90
```
工具执行监控用于查看 MCP 工具调用、命令状态、耗时、取消和结果摘要。
接口:
- `GET /api/monitor`
- `GET /api/monitor/execution/:id`
- `POST /api/monitor/execution/:id/cancel`
- `DELETE /api/monitor/execution/:id`
- `DELETE /api/monitor/executions`
- `GET /api/monitor/stats`
- `GET /api/monitor/calls-timeline`
- `POST /api/monitor/executions/names`
## 通知摘要
接口:
- `GET /api/notifications/summary`
- `POST /api/notifications/read`
通知用于提示待处理事项、未读状态或运行中任务概况。具体展示取决于前端页面。
## HITL 日志
HITL 决策日志独立管理:
- `GET /api/hitl/pending`
- `GET /api/hitl/logs`
- `GET /api/hitl/logs/:id`
- `DELETE /api/hitl/logs`
- `POST /api/hitl/decision`
- `POST /api/hitl/dismiss`
建议将 HITL 日志与平台审计结合,用于复盘 Agent 为什么执行或没有执行某个工具。
## 保留策略
建议:
- 审计日志保留 15 到 90 天,按组织要求调整。
- 工具执行记录保留 30 到 180 天。
- C2、WebShell、上传附件和任务结果按项目周期单独清理。
- 导出日志时注意脱敏和访问权限。
## 运维巡检
每周检查:
- 是否有异常登录失败。
- 是否有未授权配置变更。
- 长时间运行或失败率高的工具。
- 外部 MCP 连接状态。
- 数据库文件大小和磁盘空间。
每次演练结束:
- 导出必要审计证据。
- 删除无用 WebShell/C2 会话和 payload。
- 清理上传附件和临时工作区。
- 归档报告、漏洞和项目事实。
## 审计和监控的边界
两者经常被混用,但语义不同:
- 审计回答“谁在平台上做了什么管理动作”。
- 监控回答“工具调用运行得怎么样”。
- HITL 日志回答“某个工具调用为什么被放行、修改或拒绝”。
- 对话过程详情回答“Agent 当时如何推理和串联步骤”。
一次安全复盘通常要把四类信息合在一起看。只看审计,会漏掉具体工具输出;只看监控,会漏掉谁修改了配置。
## 关键事件解释
建议重点关注这些事件类型:
| 事件 | 为什么重要 |
| --- | --- |
| 登录失败 | 暴力尝试、密码泄露或误配置 |
| 修改密码 | 所有旧 session 会被撤销,可能影响正在使用的人 |
| 更新配置 | 可能改变模型、工具、C2、知识库、审计策略 |
| 外部 MCP 变更 | 新工具可能拥有本机或远端执行能力 |
| C2 listener/task | 直接影响授权目标和网络暴露面 |
| WebShell 连接变更 | 可能引入真实业务系统执行通道 |
| HITL 拒绝 | 说明 Agent 或用户请求触达风险边界 |
## 日志保留不是越久越好
安全工具日志往往包含目标、漏洞、路径、命令输出和组织内部信息。保留时间应平衡复盘价值与泄露风险:
- 短期演练:15-30 天。
- 持续红队平台:90-180 天。
- 合规要求:按组织规范归档,但导出后应加密。
如果没有专门日志平台,不要无限期保留 SQLite 中的所有明细。
## 源码锚点
- 审计服务:`internal/audit/service.go`
- 审计脱敏:`internal/audit/sanitize.go`
- 审计保留:`internal/audit/retention.go`
- 审计接口:`internal/handler/audit.go`
- 监控 reconcile`internal/monitor/reconcile.go`
- 监控接口:`internal/handler/monitor.go`
- HITL 日志:`internal/handler/hitl_logs.go`
+172
View File
@@ -0,0 +1,172 @@
# 内置 C2 使用说明
内置 C2 用于授权环境中的会话管理、任务下发、payload 生成和结果回收。不使用时建议关闭。
```yaml
c2:
enabled: false
```
## 功能组成
主要对象:
- Listener:监听器,负责接收会话。
- Session:上线会话。
- Task:下发给会话的任务。
- Payload:生成的载荷或 one-liner。
- Profile:通信配置模板。
- Event:监听器、会话、任务产生的事件。
- File:给 implant 下载或任务结果回收的文件。
Web API 前缀是 `/api/c2`。关闭 C2 时接口返回 `503 c2_disabled`
## 监听器
常用接口:
- `GET /api/c2/listeners`
- `POST /api/c2/listeners`
- `POST /api/c2/listeners/:id/start`
- `POST /api/c2/listeners/:id/stop`
- `DELETE /api/c2/listeners/:id`
建议给监听器使用清晰命名,标明演练项目、网络区域和授权范围。
## 会话
常用接口:
- `GET /api/c2/sessions`
- `GET /api/c2/sessions/:id`
- `PUT /api/c2/sessions/:id/sleep`
- `DELETE /api/c2/sessions/:id`
`sleep` 用于调整会话轮询间隔。间隔越短,交互越实时,但流量和暴露面更高。
## 任务
常用接口:
- `GET /api/c2/tasks`
- `POST /api/c2/tasks`
- `POST /api/c2/sessions/:id/tasks`
- `POST /api/c2/tasks/:id/cancel`
- `GET /api/c2/tasks/:id/wait`
- `GET /api/c2/tasks/:id/result-file`
任务应和授权目标一致。高风险任务建议走 HITL,并在审计日志中保留操作痕迹。
## Payload
常用接口:
- `POST /api/c2/payloads/oneliner`
- `POST /api/c2/payloads/build`
- `GET /api/c2/payloads/:id/download`
生成前确认:
- 回连地址是否正确。
- 平台和架构是否匹配。
- 是否需要代理、sleep、profile。
- 文件是否只在授权环境分发。
## 文件
常用接口:
- `POST /api/c2/files/upload`
- `GET /api/c2/files`
- `GET /api/c2/tasks/:id/result-file`
上传文件可供 implant 下载。结果文件可能包含敏感信息,应按项目保密级别保存和清理。
## MCP 工具
C2 启用后会注册相关 MCP 工具,供 Agent 管理监听器、会话、任务、payload 等。建议:
- 不把 C2 工具加入全局免审批白名单。
- 在角色提示词中限制项目、目标、任务类型。
- 对执行命令、上传文件、生成 payload 的步骤开启人工审批。
## 安全建议
- 仅在授权环境启用。
- 不在公网暴露管理 Web。
- Listener 暴露端口与 Web 管理端口分离。
- 定期清理会话、任务、payload 和事件。
- 演练结束后关闭监听器并删除无用 payload。
- 保留必要审计证据,但不要长期保存敏感输出。
## 排错
监听器无法启动:
- 端口被占用。
- 权限不足,低端口需要额外权限。
- 防火墙或安全组未放行。
会话不上线:
- payload 回连地址错误。
- 目标无法访问监听器。
- TLS/Profile 不匹配。
- 被安全产品阻断。
任务无结果:
- 会话 sleep 较长。
- 会话已离线。
- 命令在目标端卡住。
- 结果过大,需要通过结果文件下载。
## 生命周期视角
C2 的正确使用不是“创建 listener 然后下命令”,而是一个生命周期:
1. 授权确认:项目、目标、时间窗口、允许动作。
2. Profile 设计:通信方式、sleep、回连地址、文件通道。
3. Listener 启动:确认端口、网络路径和日志。
4. Payload 生成:记录 hash、用途、投递方式。
5. Session 接入:确认目标身份、权限和环境。
6. Task 下发:只执行与授权目标一致的任务。
7. 结果归档:必要输出写入项目事实或报告。
8. 清理:停止 listener、删除 payload、清理 session/task/event。
跳过前两步会导致后续每个操作都不可审计。
## 任务分级
| 等级 | 示例 | 审批建议 |
| --- | --- | --- |
| L1 只读识别 | `whoami`、主机名、当前目录 | 可由审计 Agent 放行 |
| L2 环境枚举 | 网络接口、进程、用户组 | 建议人工或严格审计 |
| L3 文件访问 | 读取配置、下载结果文件 | 人工确认目标和路径 |
| L4 执行变更 | 上传文件、修改 sleep、运行脚本 | 人工审批 |
| L5 持久化/横向/破坏 | 自启、凭证、删除、加密、扩散 | 默认拒绝,除非授权明确 |
把这个分级写进 HITL 提示词,比单纯“危险则拒绝”更可操作。
## 事件复盘
一次 C2 操作复盘至少回答:
- 哪个 listener 接收了哪个 session
- payload 是谁生成的,什么时候生成的?
- session 属于哪个授权目标?
- 下发了哪些 task
- task 输出是否写入报告或项目事实?
- 是否停止 listener 并清理 payload
如果这些问题答不上来,说明 C2 过程管理还不够闭环。
## 源码锚点
- C2 Manager`internal/c2/manager.go`
- Listener`internal/c2/listener.go`
- HTTP Listener`internal/c2/listener_http.go`
- TCP Listener`internal/c2/listener_tcp.go`
- Payload`internal/c2/payload_builder.go`
- Handler`internal/handler/c2.go`
- MCP 工具:`internal/app/c2_tools.go`
+194
View File
@@ -0,0 +1,194 @@
# 配置画像
[English](../en-US/configuration-profiles.md)
本文给出几套常用配置画像。它们不是完整 `config.yaml`,而是部署时最容易影响安全和可用性的关键段落。
## 本地开发画像
目标:方便调试,允许较多本地能力。
常用启动:
```bash
chmod +x run.sh && ./run.sh
```
```yaml
server:
host: 127.0.0.1
port: 8080
tls_enabled: true
tls_auto_self_sign: true
auth:
password: "dev-only-change-me"
audit:
enabled: true
retention_days: 7
c2:
enabled: false
multi_agent:
enabled: true
eino_skills:
filesystem_tools: true
```
适用:
- 本地功能开发。
- 调试前端和 Handler。
- 调试 Skills、本地文件工具。
不适用:
- 多人共享。
- 公网访问。
## 内网团队画像
目标:团队共享,保留审计,限制高风险能力。
```yaml
server:
host: 127.0.0.1
port: 8080
tls_enabled: false
auth:
password: "<long-random-password>"
audit:
enabled: true
retention_days: 30
monitor:
retention_days: 90
c2:
enabled: false
mcp:
enabled: false
hitl:
default_reviewer: human
tool_whitelist: [read_file, glob, grep, tool_search]
```
配合:
- Nginx/Traefik 终止 HTTPS。
- 反向代理 IP 白名单。
- 定期备份 `data/`
## 只启用知识库画像
目标:把 CyberStrikeAI 作为知识增强助手,尽量关闭攻击面。
```yaml
c2:
enabled: false
mcp:
enabled: false
knowledge:
enabled: true
base_path: knowledge_base
retrieval:
top_k: 5
similarity_threshold: 0.4
multi_agent:
eino_skills:
filesystem_tools: false
```
建议:
- 角色只绑定知识库和只读工具。
- 禁用外部 MCP。
- 不保存真实客户敏感材料。
## 高审计生产画像
目标:生产红队或长期安全平台。
```yaml
auth:
password: "<managed-secret>"
session_duration_hours: 8
audit:
enabled: true
retention_days: 90
max_detail_bytes: 8192
monitor:
retention_days: 180
hitl:
default_reviewer: human
retention_days: 180
tool_whitelist: [read_file, glob, grep, tool_search]
c2:
enabled: false
multi_agent:
eino_callbacks:
enabled: true
mode: log_only
sse_trace_to_client: false
```
配合:
- 反向代理认证。
- 独立运行用户。
- 日志采集。
- 备份加密。
- 明确项目结束清理流程。
## C2 演练画像
目标:只在授权演练窗口临时启用 C2。
```yaml
c2:
enabled: true
hitl:
default_reviewer: human
tool_whitelist: [read_file, glob, grep, tool_search]
audit:
enabled: true
monitor:
retention_days: 180
```
操作要求:
- 演练前确认授权范围。
- Listener 端口和 Web 管理端口分离。
- 演练结束执行 C2 清理 Runbook。
- 结束后恢复 `c2.enabled: false`
## 外部 MCP 自动化画像
目标:接入可信的内部工具服务。
```yaml
external_mcp:
servers: {}
multi_agent:
eino_middleware:
tool_search_enable: true
tool_search_min_tools: 20
hitl:
default_reviewer: audit_agent
tool_whitelist: [read_file, glob, grep, tool_search]
```
建议:
- 每个 MCP 工具都写清楚 schema。
- 高风险 MCP 工具不进白名单。
- stdio MCP 用独立工作目录。
- HTTP MCP 必须有认证。
## 画像选择决策
| 需求 | 选择 |
| --- | --- |
| 单人开发 | 本地开发画像 |
| 多人内网使用 | 内网团队画像 |
| 文档/知识问答 | 只启用知识库画像 |
| 长期生产平台 | 高审计生产画像 |
| 授权 C2 演练 | C2 演练画像 |
| 接内部工具平台 | 外部 MCP 自动化画像 |
+275
View File
@@ -0,0 +1,275 @@
# 配置参考
CyberStrikeAI 的主配置文件是 `config.yaml`。大多数配置也可以在 Web 的“系统设置”中修改,保存后再应用。生产环境中,建议把敏感值放在受控配置系统中,并限制 `config.yaml` 的文件权限。
## 基础配置
```yaml
version: "v1.6.51"
server:
host: 0.0.0.0
port: 8080
tls_enabled: true
tls_auto_self_sign: true
auth:
password: "change-me"
session_duration_hours: 12
log:
level: info
output: stdout
```
- `version`:前端展示版本。
- `server.host/port`Web 服务监听地址和端口。
- `server.tls_*`HTTPS 配置。生产环境建议使用 `tls_cert_path``tls_key_path`
- `auth.password`Web 登录密码,必须改为强密码。
- `auth.session_duration_hours`:登录会话有效期。
- `log.output`:可以是 `stdout``stderr` 或文件路径。
## 模型配置
```yaml
openai:
provider: openai
base_url: https://api.openai.com/v1
api_key: sk-...
model: gpt-4.1
max_total_tokens: 120000
reasoning:
mode: on
effort: high
allow_client_reasoning: true
profile: openai_compat
```
- `provider``openai` 表示 OpenAI 兼容接口;`claude` 会桥接到 Anthropic Claude Messages API。
- `base_url/api_key/model`:主模型配置。
- `max_total_tokens`:上下文压缩、攻击链构建、多代理摘要等共用的总预算。
- `reasoning`:控制推理扩展字段。不同网关支持差异较大,异常时先尝试 `mode: off`
## Agent
```yaml
agent:
max_iterations: 12000
tool_timeout_minutes: 60
shell_no_output_timeout_seconds: 1200
workspace_root_dir: ""
system_prompt_path: ""
```
- `max_iterations`:单代理、多代理主执行器和子代理的默认迭代上限。
- `tool_timeout_minutes`:单次工具最长运行时间。
- `shell_no_output_timeout_seconds`Shell 长时间无输出时终止。
- `workspace_root_dir`:会话工作区根目录,建议不要设置到系统 `/tmp`
- `system_prompt_path`:单代理系统提示词覆盖文件。
## HITL
```yaml
hitl:
default_reviewer: audit_agent
retention_days: 90
tool_whitelist: [read_file, list_dir, glob, grep, tool_search]
audit_model:
provider: ""
base_url: ""
api_key: ""
model: ""
```
- `default_reviewer``human``audit_agent`
- `tool_whitelist`:全局免审批工具列表,会与会话白名单合并。
- `audit_model`:审计 Agent 独立模型;留空复用主模型。
- `audit_agent_prompt` / `audit_agent_prompt_review_edit`:可覆盖默认审批策略。
更多策略见 [人机协同最佳实践](hitl-best-practices.md)。
## 多代理
```yaml
multi_agent:
enabled: true
robot_default_agent_mode: eino_single
batch_use_multi_agent: false
eino_skills:
disable: false
filesystem_tools: true
skill_tool_name: skill
```
支持模式:
- `eino_single`Eino 单代理。
- `deep`DeepAgent 风格多代理。
- `plan_execute`:规划、执行、重规划。
- `supervisor`:主管代理转交子代理。
`agents_dir` 指向 Markdown 子代理目录。单个代理可在 front matter 中设置 `tools``bind_role``max_iterations`
## 工具与 MCP
```yaml
security:
tools_dir: tools
tool_description_mode: full
mcp:
enabled: false
host: 0.0.0.0
port: 8081
auth_header: "X-MCP-Token"
auth_header_value: ""
external_mcp:
servers: {}
```
- `security.tools_dir`:内置工具 YAML 目录。
- `tool_description_mode``short` 更省 token`full` 更完整。
- `mcp.enabled`:是否启动独立 HTTP MCP 服务。
- `mcp.auth_header_value`:外部调用 MCP 时的共享密钥,生产环境必须设置。
- `external_mcp.servers`:外部 MCP 联邦配置。
工具 YAML 规则见 `tools/README.md`
## 知识库
```yaml
knowledge:
enabled: false
base_path: knowledge_base
embedding:
provider: openai
model: text-embedding-v4
base_url: ""
api_key: ""
retrieval:
top_k: 5
similarity_threshold: 0.4
indexing:
chunk_size: 512
chunk_overlap: 50
batch_size: 10
```
启用后会注册知识库检索工具,并开放管理接口。详细说明见 [知识库](knowledge-base.md)。
## 数据库
```yaml
database:
path: data/conversations.db
knowledge_db_path: data/knowledge.db
```
默认使用 SQLite。`knowledge_db_path` 为空时可复用会话数据库;独立文件更便于迁移知识库。
## 审计与监控
```yaml
audit:
enabled: true
retention_days: 15
max_detail_bytes: 8192
monitor:
retention_days: 90
```
- `audit` 记录平台操作,不记录对话正文和每次工具调用正文。
- `monitor` 管理工具执行记录保留时间。
## C2、WebShell、项目
```yaml
c2:
enabled: true
project:
enabled: true
fact_index_max_runes: 65000
```
- `c2.enabled`:关闭后不启动 C2 监听器,也不注册 C2 MCP 工具。
- WebShell 连接配置存 SQLite,没有单独的主配置开关。
- `project` 控制跨对话事实黑板注入预算。
## 机器人
`robots` 支持个人微信 iLink、企业微信、钉钉、飞书、Telegram、Slack、Discord、QQ。详细配置步骤见 [机器人使用说明](robot.md)。
## 配置修改建议
- 先在测试环境验证模型、MCP、知识库和高风险工具。
- 改动 `tools_dir``roles_dir``skills_dir``agents_dir` 后,检查 Web 页面是否能列出对应资源。
- 生产环境避免开启不需要的 C2、WebShell、终端和外部 MCP。
- 修改敏感配置后,检查审计页面是否有异常登录或配置变更记录。
## 配置应用机制
配置不是所有字段都同等“热更新”。`/api/config/apply` 会做一组协调动作:更新模型配置、工具描述模式、重新注册部分 MCP 工具、初始化或更新知识库、重启机器人连接、按配置启停 C2。这个逻辑在 `internal/handler/config.go` 中由 `ConfigHandler` 协调。
实务判断:
| 配置段 | 应用后通常立即生效 | 需要额外动作 |
| --- | --- | --- |
| `openai` | 新请求使用新模型配置 | 旧的流式请求不会被强制切换 |
| `agent.max_iterations` | 新 Agent 任务生效 | 已运行任务按启动时状态继续 |
| `security.tool_description_mode` | 工具重新暴露时生效 | 模型已有上下文不会回滚 |
| `hitl.tool_whitelist` | 新工具调用审批判断生效 | 已挂起审批不自动重判 |
| `knowledge.enabled` | 会尝试初始化/更新组件 | 启用后仍需扫描和索引 |
| `knowledge.embedding` | 检索器/索引器配置更新 | 已有向量通常需要重建索引 |
| `robots` | 会触发连接重启 | 平台回调配置仍需在平台侧正确 |
| `c2.enabled` | 会协调 C2 runtime | 已暴露端口和会话要人工确认 |
| `server.port/tls` | 通常需要重启进程 | 监听地址不是普通热更新 |
## 配置优先级和派生关系
几个字段有“留空复用”的关系:
- `vision.api_key/base_url/provider` 留空时复用 `openai`
- `hitl.audit_model` 留空时复用 `openai`
- `knowledge.embedding.base_url/api_key` 留空时复用主模型或 embedding 默认配置。
- `knowledge.retrieval.rerank.base_url/api_key` 留空时复用 embedding/openai。
- `database.knowledge_db_path` 留空时可以复用主会话数据库,但独立文件更利于备份。
这类配置排障时不要只看子配置段,也要看它会回落到哪个上级配置。
## 参数取值建议
| 参数 | 保守值 | 激进值 | 判断依据 |
| --- | --- | --- | --- |
| `agent.tool_timeout_minutes` | 10-30 | 60+ | 扫描工具是否常跑长任务 |
| `shell_no_output_timeout_seconds` | 300-600 | 1200+ | 工具是否长时间静默 |
| `knowledge.indexing.batch_size` | 5-10 | 20+ | embedding 服务批量限制 |
| `knowledge.indexing.rate_limit_delay_ms` | 300-800 | 0-100 | 服务商 RPM 和 429 情况 |
| `retrieval.top_k` | 3-5 | 8-12 | 内容质量和上下文预算 |
| `similarity_threshold` | 0.35-0.45 | 0.5+ | 召回优先还是精度优先 |
| `audit.retention_days` | 15-30 | 90+ | 合规要求和磁盘空间 |
| `monitor.retention_days` | 30-90 | 180+ | 是否需要长周期复盘 |
## 变更前后验证模板
修改配置前记录:
```text
变更目的:
涉及配置段:
预期影响:
回滚方式:
验证接口:
```
修改后验证:
```bash
curl -k https://127.0.0.1:8080/api/auth/validate \
-H "Authorization: Bearer <token>"
```
再按配置类型验证模型、工具、知识库、C2 或机器人。不要只看 Web 保存成功提示。
## 源码锚点
- 配置结构:`internal/config/config.go`
- 环境变量展开:`internal/config/envexpand.go`
- Web 配置接口:`internal/handler/config.go`
- 路由注册:`internal/app/app.go`
- C2 配置协调:`internal/app/c2_lifecycle.go`
+115
View File
@@ -0,0 +1,115 @@
# 贡献规范
[English](../en-US/contributing-guide.md)
本文定义向 CyberStrikeAI 增加功能、接口、工具、前端页面或文档时的基本要求。
## 总原则
- 新功能要有文档入口。
- 新 API 要更新 OpenAPI。
- 新前端文案要补中英文 i18n。
- 新配置要说明是否支持热应用。
- 新高风险工具要说明 HITL 策略。
- 新数据库字段要兼容旧库。
- 新长任务要有状态、取消或恢复策略。
## 新增 API Checklist
- Handler 参数校验明确。
- 错误响应包含稳定 `error` 和可读 `message`
- 接口受认证保护,除非明确是平台回调。
- 修改类接口写审计。
- 长任务写监控或任务状态。
- 更新 `internal/handler/openapi.go`
- 更新 API 文档或 Recipe。
- 增加 Handler 测试。
## 新增配置 Checklist
- `config.Config` 结构体有字段。
- `config.yaml` 示例有注释。
- 省略字段时有安全默认值。
- 旧配置能启动。
- 说明是否热应用。
- Web 设置页不会误删未知字段。
- 如影响高风险能力,更新安全文档。
## 新增工具 Checklist
适用于 YAML 工具和 Go 内置 MCP 工具。
- 工具名稳定、具体、避免重名。
- `short_description` 能被 `tool_search` 搜到。
- 输入 schema 明确,不用裸 `cmd` 包所有行为。
- 输出可读且结构稳定。
- 超时和错误路径可控。
- 高风险操作不进全局白名单。
- 文档说明使用场景和风险。
## 新增前端页面 Checklist
- 复用现有 `apiFetch`、modal、通知和状态样式。
- 所有可见文案补 `zh-CN.json``en-US.json`
- 有 loading、empty、error 状态。
- 删除/高风险操作有确认。
- 长文本和英文按钮不溢出。
- 浏览器控制台无错误。
## 新增数据库变更 Checklist
- 迁移幂等。
- 旧库可升级。
- 字段默认值合理。
- 大表索引谨慎。
- 测试空库和旧库。
- 发布说明提醒备份。
## 新增高风险能力 Checklist
高风险包括:Shell、WebShell、C2、外部 MCP 写入/执行、凭证访问、批量扫描。
必须回答:
- 谁能调用?
- 是否需要 HITL
- 审计记录什么?
- 如何取消?
- 如何清理?
- 如何禁用?
- 默认是否关闭?
## 文档要求
每个重要功能至少补:
- 用途。
- 配置。
- 操作流程。
- 风险边界。
- 排错。
- 源码锚点。
中英文文档要保持文件名一致,分别放在:
```text
docs/zh-CN/
docs/en-US/
```
更新导航:
- `docs/README.md`
- `docs/zh-CN/README.md`
- `docs/en-US/README.md`
## Review 关注点
代码评审优先看:
- 行为回归。
- 安全边界。
- 旧数据兼容。
- 错误处理。
- 测试缺口。
- 文档和 OpenAPI 是否同步。
+249
View File
@@ -0,0 +1,249 @@
# 部署指南
本文说明 CyberStrikeAI 的常见部署方式。生产环境部署前,请先阅读 [安全模型](security-model.md),确认授权范围、认证、HITL、审计和高风险功能开关。
## 部署前准备
基础依赖:
- Go:用于源码运行或构建二进制。
- Python:部分 MCP 服务或工具脚本需要 Python 运行环境。
- SQLite:默认使用文件型数据库,无需单独服务。
- 安全工具:`tools/` 中的 YAML 只是工具定义,实际命令如 `nmap``sqlmap``nuclei` 仍需安装到系统 PATH。
- 模型服务:需要 OpenAI 兼容 API,或配置 `openai.provider: claude` 走 Claude 桥接。
建议目录:
```text
CyberStrikeAI-main/
config.yaml
data/
tools/
roles/
skills/
agents/
knowledge_base/
```
`data/``config.yaml`、自定义 `tools/roles/skills/agents/knowledge_base` 是最重要的持久化内容,升级前应备份。
## 快速启动
仓库提供 `run.sh`,适合本地体验和小规模部署:
```bash
chmod +x run.sh && ./run.sh
```
默认配置中 `server.tls_enabled: true``tls_auto_self_sign: true`,访问地址通常是:
```text
https://127.0.0.1:8080/
```
自签证书会触发浏览器安全提示,这是本地测试的正常现象。生产环境建议配置真实证书。
`run.sh` 是最常用的启动入口,适合:
- 本机体验。
- 开发调试。
- 小团队临时内网使用。
- 升级后快速验证新版是否能启动。
如果需要长期运行、开机自启、日志托管或进程崩溃自动恢复,建议改用 systemd 托管二进制。
## 源码运行
适合开发调试:
```bash
go run ./cmd/server --config config.yaml
```
如果依赖下载较慢,可以先配置 Go 代理:
```bash
go env -w GOPROXY=https://goproxy.cn,direct
```
## 构建二进制
```bash
go build -o cyberstrike-ai ./cmd/server
./cyberstrike-ai --config config.yaml
```
交付二进制时仍需要携带:
- `web/templates/`
- `web/static/`
- `tools/`
- `roles/`
- `skills/`
- `agents/`
- `config.yaml`
## HTTPS
本地测试可以使用自签:
```yaml
server:
tls_enabled: true
tls_auto_self_sign: true
```
生产环境建议使用证书文件:
```yaml
server:
host: 0.0.0.0
port: 8080
tls_enabled: true
tls_cert_path: /etc/letsencrypt/live/example.com/fullchain.pem
tls_key_path: /etc/letsencrypt/live/example.com/privkey.pem
```
启用 TLS 后,同端口 HTTP 请求默认会 308 跳转到 HTTPS。若前面有反向代理负责 TLS,可以关闭应用内 TLS,在代理层处理 HTTPS。
## 反向代理
Nginx 示例:
```nginx
server {
listen 443 ssl http2;
server_name cyberstrike.example.com;
ssl_certificate /etc/letsencrypt/live/cyberstrike.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cyberstrike.example.com/privkey.pem;
client_max_body_size 200m;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
}
}
```
`proxy_buffering off` 对 SSE 流式输出和 WebSocket 终端更友好。
## systemd
示例服务:
```ini
[Unit]
Description=CyberStrikeAI
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/CyberStrikeAI
ExecStart=/opt/CyberStrikeAI/cyberstrike-ai --config /opt/CyberStrikeAI/config.yaml
Restart=on-failure
RestartSec=5
Environment=GIN_MODE=release
[Install]
WantedBy=multi-user.target
```
启用:
```bash
sudo systemctl daemon-reload
sudo systemctl enable --now cyberstrikeai
sudo journalctl -u cyberstrikeai -f
```
## 数据与备份
重点备份:
- `config.yaml`
- `data/conversations.db`
- `data/knowledge.db`
- `data/eino-checkpoints/`
- 自定义 `tools/roles/skills/agents/knowledge_base`
- 上传文件目录 `chat_uploads/`
SQLite 热备份时最好先停止服务,或至少复制 `*.db``*.db-wal``*.db-shm` 三类文件。
## 升级
推荐流程:
1. 停止服务。
2. 备份 `config.yaml``data/` 和自定义目录。
3. 拉取或替换新版代码/二进制。
4. 保留原配置,按新版 `config.yaml` 示例补新增字段。
5. 启动服务,检查登录、模型测试、工具列表、知识库状态。
仓库提供 `upgrade.sh`,适合无兼容性问题的快速升级;生产环境仍建议先备份再运行。
## 回滚
回滚时同时恢复:
- 上一版本二进制或代码。
- 升级前的 `config.yaml`
- 升级前的 `data/`
如果新版已经写入数据库结构变更,单独回滚二进制可能不够,建议整体恢复备份。
## 生产部署决策表
| 场景 | 推荐部署 | 关键配置 | 不建议 |
| --- | --- | --- | --- |
| 单人本机测试 | `./run.sh` + 自签 HTTPS | `tls_auto_self_sign: true` | 暴露公网 |
| 小团队内网 | 二进制 + systemd + 内网 HTTPS | 强密码、审计、备份、限制来源 IP | 所有人共用弱密码 |
| 生产红队平台 | 反向代理 + 独立运行用户 + 日志采集 | 真实证书、反向代理认证、C2 按需启用 | Web 管理面直连公网 |
| 只做知识库/对话 | 关闭 C2,禁用不需要的外部 MCP | `c2.enabled: false` | 默认开启所有高风险模块 |
| 多工具自动化 | 独立工作目录 + HITL + 工具白名单 | `workspace_root_dir``hitl``monitor` | 让 Agent 拥有全局 Shell 权限且免审批 |
## 运行时文件分层
部署时最容易出问题的是“代码、配置、运行数据混在一起”。建议按下面方式理解:
- 可替换:二进制、`web/`、默认 `tools/roles/skills/agents/docs`
- 必须保留:`config.yaml``data/`、自定义工具/角色/技能/子代理、`knowledge_base/``chat_uploads/`
- 可清理但要谨慎:`data/eino-checkpoints/`、临时 workspace、旧 payload、旧工具执行记录。
升级时如果覆盖整个目录,应先把自定义目录和 `data/` 移出或备份。很多“升级后配置丢了”的问题,本质是把运行态文件当成发布包的一部分覆盖掉。
## 启动后验收清单
启动成功不代表可用,至少做下面检查:
1. 打开 `/`,确认 HTTPS/反向代理没有跳转循环。
2. 登录后访问 `/api/auth/validate`,确认会话可用。
3. 系统设置中执行模型测试。
4. 打开工具列表,确认 `tools/` 被加载,核心工具 schema 正常。
5. 若启用知识库,访问知识库页,确认 `index-status` 正常。
6. 若启用外部 MCP,查看外部 MCP 状态和工具是否出现在对话侧。
7. 若启用 C2,只在授权网络启动一个测试 listener,并确认停止/删除正常。
8. 查看审计页面,确认登录和配置读取有记录。
## 反向代理容易踩的坑
- SSE 被缓冲:表现为 Agent 一直不输出,结束时一次性吐出。关闭 `proxy_buffering`
- WebSocket 失败:终端或事件流异常。检查 `Upgrade``Connection` 头。
- HTTPS 混用:应用内 TLS 和 Nginx TLS 同时启用时,`proxy_pass` 协议必须匹配。
- 上传失败:调大 `client_max_body_size`,并检查应用侧上传限制。
- 308 循环:如果应用启用同端口 HTTPS 跳转,而代理又用 HTTP 回源,需要关闭应用 TLS 或改代理回源 HTTPS。
## 源码锚点
- 服务组装和路由:`internal/app/app.go`
- HTTPS 和自签证书:`internal/app/main_server_tls.go`
- HTTP 到 HTTPS 跳转:`internal/app/main_server_http_redirect.go`
- 配置结构和默认值:`internal/config/config.go`
- 配置应用逻辑:`internal/handler/config.go`
+178
View File
@@ -0,0 +1,178 @@
# 开发者指南
本文面向二次开发者,说明项目结构、启动方式、主要扩展点和开发习惯。
## 项目结构
```text
cmd/server/ Web 服务入口
internal/app/ 应用组装、路由注册、MCP 工具注册
internal/handler/ HTTP Handler
internal/database/ SQLite 数据访问
internal/security/ 认证、限流、Shell 执行
internal/mcp/ MCP Server、外部 MCP 管理
internal/multiagent/ Eino 单代理、多代理、中间件
internal/workflow/ 图编排运行时
internal/knowledge/ 知识库索引与检索
internal/c2/ 内置 C2
internal/project/ 项目事实黑板
web/static/ 前端 JS/CSS/资源
web/templates/ HTML 模板
tools/ 命令工具 YAML
roles/ 角色 YAML
agents/ 多代理 Markdown 定义
skills/ Agent Skills
docs/ 项目文档
```
## 启动开发环境
```bash
go run ./cmd/server --config config.yaml
```
前端是静态页面,模板在 `web/templates/`JS/CSS 在 `web/static/`。修改后刷新浏览器即可验证,多数场景不需要单独前端构建。
## 路由
路由集中在 `internal/app/app.go``registerRoutes` 中。新增业务接口通常需要:
1.`internal/handler/` 增加 Handler。
2.`internal/database/` 增加必要的数据访问。
3.`internal/app/app.go` 构造并注册路由。
4. 如需对外文档,更新 `internal/handler/openapi.go`
5. 如需前端调用,更新 `web/static/js/`
## 数据库
默认 SQLite。新增表或字段时:
- 将迁移逻辑放到数据库初始化或对应模块迁移函数。
- 保持向后兼容,避免破坏已有 `data/conversations.db`
- 添加针对迁移和核心查询的单测。
## 新增工具
命令工具优先通过 `tools/*.yaml` 增加,不必改 Go 代码。需要 Go 内置工具时:
- 在合适模块注册 MCP Tool。
- 定义清晰 `InputSchema`
- 处理超时、错误、审计和 HITL 上下文。
- 避免把高风险操作默认免审批。
工具 YAML 规则见 `tools/README.md`
## 新增角色
角色通过 `roles/*.yaml` 管理。常见字段包括名称、描述、系统提示词和工具列表。角色应遵循最小工具集原则,不要把所有工具默认交给专用角色。
## 新增子代理
多代理子 Agent 放在 `agents/*.md`。Front matter 示例:
```yaml
---
name: Vulnerability Triage
id: vulnerability-triage
description: 对漏洞线索进行验证、定级和修复建议整理
tools:
- nmap
- nuclei
bind_role: 综合漏洞扫描
max_iterations: 200
---
```
正文是系统提示词。主代理可使用固定文件名或 `kind: orchestrator`
## 新增 Skill
Skill 放在 `skills/<name>/SKILL.md`。用于提供专题能力、流程说明或附属资料。详见 [Skills 指南](skills-guide.md)。
## 前端开发
前端代码按功能拆分在 `web/static/js/`。新增页面或模块时:
- 复用现有 `apiFetch`、modal、通知、i18n 工具。
- 同步更新 `web/static/i18n/zh-CN.json``en-US.json`
- 避免把敏感 Key 放到前端。
- 高风险按钮要有确认和清晰状态反馈。
i18n 规范见 [前端国际化方案](frontend-i18n.md)。
## OpenAPI
`internal/handler/openapi.go` 维护内置 OpenAPI 输出。新增公开接口后建议同步补:
- path
- method
- summary/description
- requestBody
- responses
- security
这样 `/api-docs` 才能反映最新接口。
## 开发习惯
- 优先保持现有模块边界。
- 大模型、外部 API、文件系统、Shell 相关改动必须考虑超时和错误路径。
- 高风险能力要接入 HITL 或至少有清晰审计。
- 代码变更后运行相关包单测。
## 新增业务模块的完整配方
不要只加一个 Handler。完整模块通常要考虑:
1. 数据模型:是否需要 SQLite 表和迁移。
2. Handler:HTTP 参数、错误码、分页、过滤。
3. Audit:管理动作是否要审计。
4. Monitor:如果会执行长任务,是否要记录执行状态。
5. MCP:是否要暴露给 Agent。
6. HITL:MCP 工具是否有审批边界。
7. OpenAPI:是否更新 `/api/openapi/spec`
8. Frontend:是否需要 i18n、状态、空态、错误提示。
9. Tests:数据库、handler、边界条件。
10. Docs:配置、使用、排错和安全影响。
少做其中一项,后面通常会以“用户看不懂”“Agent 调错”“接口没人会用”的形式返工。
## Handler 错误设计
建议错误响应保持:
```json
{
"error": "machine_readable_code",
"message": "给用户看的说明"
}
```
不要只返回 Go error 字符串。前端需要稳定字段,用户需要可操作建议,日志需要详细错误。
## 长任务设计
扫描、索引、批量任务、C2 等都可能长时间运行。设计时要回答:
- 是否能取消?
- 是否能查询进度?
- 失败后能否重试?
- 结果写在哪里?
- 页面刷新后状态是否还在?
- 是否会阻塞 HTTP 请求?
如果答案是否定的,应考虑接入任务表、事件流或监控模块。
## 测试优先级
最值得补测试的地方:
- 配置热应用。
- HITL 审批分支。
- Shell 超时和无输出。
- 外部 MCP 失败恢复。
- 知识库索引和检索后处理。
- WebShell 编码和系统识别。
- SQLite 迁移兼容。
这些地方比普通 getter/setter 更容易出现真实用户故障。
+335
View File
@@ -0,0 +1,335 @@
## CyberStrikeAI 前端国际化方案
本文档说明 CyberStrikeAI Web 前端(`web/templates/index.html` + `web/static/js/*.js`)的国际化设计与开发规范,确保在不引入打包工具和不改动后端路由的前提下,实现可扩展、低返工的多语言支持。
当前目标:
- **支持中英文切换(zh-CN / en-US**
- 后续可方便扩展更多语言(如 ja-JP、ko-KR 等)
---
## 一、总体设计原则
- **前端主导的客户端国际化**:所有 UI 文案在浏览器端根据当前语言动态渲染,后端 Go 仅负责结构和数据,不参与语言分发。
- **单一 HTML 模板**:继续使用一份 `index.html` 模板,不为不同语言复制模板文件。
- **文案与逻辑分离**:所有可见文本通过「键值表」管理(多语言 JSON),HTML / JS 只写 key,不直接写中文/英文常量。
- **渐进式改造**:先覆盖 header / 登录 / 侧边栏 / 系统设置等关键区域,其他页面按模块逐步迁移,避免一次性大改动。
- **可回退默认语言**:即使目标语言未完全翻译,也能回退到默认中文,不出现原始 key。
---
## 二、技术选型与目录结构
### 2.1 技术选型
- **i18n 引擎**:使用 [i18next](https://www.i18next.com/) 的浏览器 UMD 版本(通过 CDN 引入),无需打包器。
- **资源格式**:每种语言一份 JSON 文件,采用「域 + 语义」的层级 key 方案,例如:
- `common.ok`
- `nav.dashboard`
- `header.apiDocs`
- `settings.robot.wecom.token`
### 2.2 目录结构
- `web/templates/index.html`
- 页面骨架 + 所有静态文案位置,将逐步改为 `data-i18n` 标记。
- `web/static/js/i18n.js`
- 前端 i18n 初始化与 DOM 应用逻辑(本方案新增)。
- `web/static/i18n/`(新增目录)
- `zh-CN.json`:中文文案(默认语言)
- `en-US.json`:英文文案
- 未来可新增:`ja-JP.json``ko-KR.json` 等。
---
## 三、文案组织规范
### 3.1 Key 命名约定
- 采用「**模块.语义**」形式,最多 2–3 级,确保可读性:
- 导航:`nav.dashboard``nav.chat``nav.settings`
- 头部:`header.title``header.apiDocs``header.logout`
- 登录:`login.title``login.subtitle``login.passwordLabel``login.submit`
- 仪表盘:`dashboard.title``dashboard.refresh``dashboard.runningTasks`
- 系统设置:`settings.title``settings.nav.basic``settings.nav.robot``settings.apply`
- 机器人配置:`settings.robot.wecom.enabled``settings.robot.wecom.token` 等。
- 尽量按「界面区域」而不是「文件名」划分域,便于非开发人员理解。
### 3.2 JSON 示例
`web/static/i18n/zh-CN.json` 示例:
```json
{
"common": {
"ok": "确定",
"cancel": "取消"
},
"nav": {
"dashboard": "仪表盘",
"chat": "对话",
"infoCollect": "信息收集",
"tasks": "任务管理",
"vulnerabilities": "漏洞管理",
"settings": "系统设置"
},
"header": {
"title": "CyberStrikeAI",
"apiDocs": "API 文档",
"logout": "退出登录",
"language": "界面语言"
},
"login": {
"title": "登录 CyberStrikeAI",
"subtitle": "请输入配置中的访问密码",
"passwordLabel": "密码",
"passwordPlaceholder": "输入登录密码",
"submit": "登录"
}
}
```
英文文件 `en-US.json` 保持相同 key,不同 value
```json
{
"common": {
"ok": "OK",
"cancel": "Cancel"
},
"nav": {
"dashboard": "Dashboard",
"chat": "Chat",
"infoCollect": "Recon",
"tasks": "Tasks",
"vulnerabilities": "Vulnerabilities",
"settings": "Settings"
},
"header": {
"title": "CyberStrikeAI",
"apiDocs": "API Docs",
"logout": "Sign out",
"language": "Interface language"
},
"login": {
"title": "Sign in to CyberStrikeAI",
"subtitle": "Enter the access password from config",
"passwordLabel": "Password",
"passwordPlaceholder": "Enter password",
"submit": "Sign in"
}
}
```
> 约定:**新增界面时,必须先定义 i18n key,再在 HTML/JS 中使用 key**,禁止直接写死中文/英文。
---
## 四、HTML 标记规范(data-i18n
### 4.1 基本规则
- 使用 `data-i18n` 将元素文本与某个 key 绑定:
```html
<span data-i18n="nav.dashboard">仪表盘</span>
```
- 默认行为:脚本会替换元素的 `textContent`
- 同时翻译属性时,额外使用 `data-i18n-attr`,逗号分隔多个属性名:
```html
<button
class="openapi-doc-btn"
onclick="window.open('/api-docs', '_blank')"
data-i18n="header.apiDocs"
data-i18n-attr="title"
title="API 文档">
<span data-i18n="header.apiDocs">API 文档</span>
</button>
```
### 4.2 默认文本的作用
- HTML 内的中文默认值作为「**无 JS / 初始化前**」的占位内容:
- 页面在 JS 尚未加载完成时不会出现空白或 key。
- JS 初始化后会用当前语言覆盖这些文本。
---
## 五、JavaScript 中的文案规范
### 5.1 全局翻译函数 `t()`
`i18n.js` 暴露以下全局函数:
- `window.t(key: string): string`
- 返回当前语言下的翻译文本,若缺失则回退到默认语言,再不行则返回 key 本身。
- `window.changeLanguage(lang: string): Promise<void>`
- 切换语言并刷新页面文案(不会刷新整页)。
示例(以 `web/static/js/settings.js` 为例):
```js
// 之前
alert('加载配置失败: ' + error.message);
// 之后
alert(t('settings.loadConfigFailed') + ': ' + error.message);
```
> 规范:**JS 内所有面向用户的提示、按钮文字、对话框标题都应通过 `t()` 获取**,不直接写死中文/英文。
### 5.2 渐进迁移建议
- 优先改造:
- 频繁弹出的错误提示 / 成功提示;
- 登录相关、系统设置相关文案。
- 低优先级:
- 仅面向运维人员的调试提示,可以暂时保留英文/中文常量。
---
## 六、i18n 初始化与语言切换实现
### 6.1 语言选择策略
- 默认语言:`zh-CN`
- 优先级(从高到低):
1. `localStorage` 中的用户选择(key`csai_lang`)。
2. 浏览器 `navigator.language``zh` 开头 → `zh-CN`,否则 `en-US`)。
3. 默认 `zh-CN`
### 6.2 初始化流程(`i18n.js`
1. 读取初始语言。
2. 初始化 i18next
- `lng` 为当前语言;
- `fallbackLng``zh-CN`
- 资源先留空,采用按需加载。
3. 通过 `fetch` 拉取 `/static/i18n/{lng}.json``i18next.addResources`
4. 更新:
- `<html lang="...">` 属性;
- 所有带 `data-i18n` / `data-i18n-attr` 的元素。
5. 暴露 `window.t``window.changeLanguage`
### 6.3 DOM 应用逻辑
伪代码:
```js
function applyTranslations(root = document) {
const elements = root.querySelectorAll('[data-i18n]');
elements.forEach(el => {
const key = el.getAttribute('data-i18n');
if (!key) return;
const text = i18next.t(key);
if (text) {
el.textContent = text;
}
const attrList = el.getAttribute('data-i18n-attr');
if (attrList) {
attrList.split(',').map(s => s.trim()).forEach(attr => {
if (!attr) return;
const val = i18next.t(key);
if (val) el.setAttribute(attr, val);
});
}
});
}
```
> 对于由 JS 动态插入的元素,需要在插入后再次调用 `applyTranslations(新容器)`。
---
## 七、语言切换 UI 规范
### 7.1 位置与形态
- 位置:`index.html` header 右侧 `API 文档` 按钮附近(靠近用户头像)。
- 交互形式:
- 一个紧凑的语言切换组件,例如:
- `🌐` 图标 + 当前语言文本(`中文` / `English`)的下拉按钮;
- 下拉内容列出所有可用语言。
### 7.2 示例结构
```html
<div class="lang-switcher">
<button class="btn-secondary lang-switcher-btn" onclick="toggleLangDropdown()" data-i18n="header.language">
<span class="lang-switcher-icon">🌐</span>
<span id="current-lang-label">中文</span>
</button>
<div id="lang-dropdown" class="lang-dropdown" style="display: none;">
<div class="lang-option" data-lang="zh-CN" onclick="onLanguageSelect('zh-CN')">中文</div>
<div class="lang-option" data-lang="en-US" onclick="onLanguageSelect('en-US')">English</div>
</div>
</div>
```
对应 JS(在 `i18n.js` 中):
```js
function onLanguageSelect(lang) {
changeLanguage(lang).then(updateLangLabel).catch(console.error);
closeLangDropdown();
}
function updateLangLabel() {
const labelEl = document.getElementById('current-lang-label');
if (!labelEl) return;
const lang = i18next.language || 'zh-CN';
labelEl.textContent = lang.startsWith('zh') ? '中文' : 'English';
}
```
> 规范:**语言切换只更新文案,不刷新整页,也不修改 URL hash**。
---
## 八、开发流程建议
### 8.1 新增 / 修改界面的流程
1. 设计界面时,先列出所有文案。
2. 在对应语言 JSON 中补充/修改 key 与翻译。
3. 在 HTML 中使用 `data-i18n`,在 JS 中使用 `t('...')`
4. 在浏览器中切换中英文,确认两种语言显示都正确。
### 8.2 渐进式改造顺序(推荐)
1. **阶段 1(已规划)**
- 引入 i18next 与 `i18n.js`
- 新建 `zh-CN.json` / `en-US.json`(先覆盖 header / 登录 / 左侧导航)。
- 实现 header 区域语言切换组件。
2. **阶段 2**(已完成)
- 系统设置页面(包括机器人配置页面)全部文案 i18n 化。
- `settings.js` 中的提示与错误信息改用 `t()`
3. **阶段 3**(进行中)
- 仪表盘、任务管理、漏洞管理、MCP、Skills、Roles 等页面按模块逐步迁移。
4. **阶段 4**
- 清理 JS / HTML 中残留的硬编码中文,统一通过 i18n。
---
## 九、后续扩展新语言
当需要新增语言时:
1.`web/static/i18n/` 中新增 `{lang}.json`,复制现有英文/中文文件结构,补充对应翻译。
2. 在语言切换下拉中添加对应选项,例如:
- `data-lang="ja-JP"` / 文本 `日本語`
3. 无需修改 `i18n.js` 或现有 HTML/JS 逻辑,即可支持新语言。
---
## 十、注意事项与坑点
- **不要复制多份 HTML 模板** 来做多语言,那样维护成本极高,本方案统一由前端 i18n 控制。
- **避免 key 直接用中文/英文句子**,统一采用「模块.语义」短 key,便于 diff 与搜索。
- 避免在 CSS 中写死文本(如 `content: "xxx"`),如确有需要,应通过 JS 设置并走 i18n。
- 对于后端返回的可本地化错误文本(未来可能支持),优先由后端根据 `Accept-Language` 返回对应语言,前端只负责展示。
+122
View File
@@ -0,0 +1,122 @@
# 人机协同(HITL)最佳实践
[English](../en-US/hitl-best-practices.md)
人机协同用于在 Agent 执行工具前做审批拦截。它适合控制高风险操作、保留审计痕迹,并在人工审计压力过大时让审计 Agent 接管常规审批。
## 配置入口
Web 端进入 **系统设置 → 人机协同**,可配置:
- 全局默认审批方:`human``audit_agent`
- 审计 Agent 专用模型:`hitl.audit_model`
- 已决策审计日志保留天数
- 免审批工具白名单:`hitl.tool_whitelist`
- 审批模式与审查编辑模式的审计提示词
对应的 `config.yaml` 示例:
```yaml
hitl:
default_reviewer: human
audit_model:
provider: ""
base_url: ""
api_key: ""
model: "" # 可填小模型;留空复用 openai.model
retention_days: 90
tool_whitelist: [read_file, list_dir, glob, grep, tool_search]
```
`audit_model` 的字段可以只填一部分。空字段会自动继承主 `openai` 配置,因此常见做法是只填 `model`,让审计 Agent 使用更便宜的小模型。
## 推荐审批策略
### 1. 默认人工,逐步放权
刚开始建议:
- `default_reviewer: human`
- 仅把明显只读工具加入 `tool_whitelist`
- 对写文件、执行命令、C2 任务、WebShell 操作保持人工审批
运行一段时间后,观察审计日志,把重复、低风险、误报少的工具加入白名单。
### 2. 人工审不过来时,用小模型接管常规审批
当待审批积压明显时,可以切换为:
```yaml
hitl:
default_reviewer: audit_agent
audit_model:
model: "your-small-reviewer-model"
```
建议让小模型处理:
- 只读查询
- 信息收集
- 端口与服务扫描
- 目录枚举
- 无破坏性的验证命令
仍建议人工处理:
- 删除、覆盖、清空数据
- 修改权限、密码、账号
- 持久化、横向移动、C2 高风险任务
- 对生产目标的写入操作
### 3. 用提示词定义组织策略
审计 Agent 的提示词应该写成策略,而不是泛泛地说“谨慎审批”。建议明确:
- 默认放行哪些低风险操作
- 必须拒绝哪些破坏性操作
- 哪些情况需要人工升级
- 审查编辑模式下允许怎样收窄参数
示例策略片段:
```text
常规信息收集、只读查询、端口扫描默认 approve。
涉及删除文件、清空数据库、修改账号权限、写入持久化后门、停止关键服务时必须 reject。
若目标范围超出用户授权范围,应 reject。
审查编辑模式下,可将路径、目标、命令参数收窄后 approve,但不得扩大攻击面。
```
### 4. 白名单只放稳定低风险工具
白名单工具会跳过审批,因此要保守维护。推荐放:
- `read_file`
- `list_dir`
- `glob`
- `grep`
- `tool_search`
不建议直接全局白名单:
- 任意 shell 执行工具
- 文件写入/删除工具
- C2 任务工具
- WebShell 命令执行工具
## 模式选择
| 模式 | 适用场景 |
|------|----------|
| 关闭 | 本地实验、完全信任工具链 |
| 审批模式 | 只需要通过/拒绝 |
| 审查编辑 | 希望审计 Agent 收窄参数后放行 |
如果你已经配置了小模型审计,推荐从 **审批模式** 开始。只有当你希望 AI 自动收窄路径、目标范围或命令参数时,再开启 **审查编辑**
## 运维建议
- 定期查看 **人机协同 → 审计日志**,调整白名单和提示词。
- 高风险环境下保持 `default_reviewer: human`,只让审计 Agent 辅助给出建议。
- 小模型审批失败时默认保守拒绝,这是预期行为。
- 修改 `hitl.audit_model` 后先在页面点击 **测试审计模型**
- 对生产、客户、真实业务系统操作前,应保留人工最终确认。
+272
View File
@@ -0,0 +1,272 @@
# 知识库
知识库用于把本地安全知识、漏洞手册、测试方法和组织经验转成可检索上下文,供 Agent 在任务中按需引用。
## 启用
```yaml
knowledge:
enabled: true
base_path: knowledge_base
embedding:
provider: openai
model: text-embedding-v4
base_url: ""
api_key: ""
database:
knowledge_db_path: data/knowledge.db
```
`embedding.base_url/api_key` 留空时会复用 `openai` 配置。建议知识库数据库独立保存,便于迁移和复用。
## 内容目录
默认目录是 `knowledge_base/`。项目中已有示例:
```text
knowledge_base/
SQL Injection/
README.md
MySQL Injection.md
Prompt Injection/
README.md
```
推荐用一级目录表示风险类型或知识域,如:
- `SQL Injection`
- `XSS`
- `File Upload`
- `Cloud Security`
- `Incident Response`
## 管理流程
常见流程:
1. 把 Markdown 知识文件放到 `knowledge_base/`
2. 在 Web 知识库页面扫描目录。
3. 重建索引。
4. 用搜索功能验证召回效果。
5. 在角色或任务中要求 Agent 优先查询知识库。
接口入口包括:
- `GET /api/knowledge/categories`
- `GET /api/knowledge/items`
- `POST /api/knowledge/scan`
- `POST /api/knowledge/index`
- `POST /api/knowledge/search`
- `GET /api/knowledge/index-status`
- `GET /api/knowledge/retrieval-logs`
## 索引
索引配置:
```yaml
knowledge:
indexing:
chunk_size: 512
chunk_overlap: 50
max_chunks_per_item: 0
max_rpm: 0
rate_limit_delay_ms: 300
max_retries: 3
retry_delay_ms: 1000
chunk_strategy: markdown_then_recursive
request_timeout_seconds: 120
prefer_source_file: false
batch_size: 10
sub_indexes: []
```
建议:
- 文档结构清晰时用 `markdown_then_recursive`
- 嵌入接口限制严格时降低 `batch_size`,增加 `rate_limit_delay_ms`
- 单篇超长文档可设置 `max_chunks_per_item` 控制成本。
- 需要按业务域隔离时使用 `sub_indexes``sub_index_filter`
## 检索
```yaml
knowledge:
retrieval:
top_k: 5
similarity_threshold: 0.4
multi_query:
max_queries: 4
post_retrieve:
prefetch_top_k: 20
max_context_chars: 0
max_context_tokens: 0
```
检索链路大致为:
1. 用户查询或 Agent 查询。
2. MultiQuery 改写出多个语义变体。
3. 向量检索获取候选块。
4. rerank 精排。
5. 后处理去重、限长。
6. 返回给 Agent 或 API 调用方。
`similarity_threshold` 太高会漏召回,太低会带入噪声。初始建议 0.35 到 0.45。
## Rerank
```yaml
knowledge:
retrieval:
rerank:
provider: ""
model: ""
base_url: ""
api_key: ""
```
留空时会根据 `base_url` 推断。DashScope 常用 `gte-rerank`;其他 OpenAI 兼容端点可能走 `/v1/rerank`。如果服务商不支持 rerank,检索质量可能下降,建议降低 `top_k` 并提高知识条目质量。
## MCP 工具
启用知识库后,会注册类似以下能力:
- 列出风险类型。
- 搜索知识库。
- 获取相关知识片段。
角色提示词中可以写明:
```text
遇到漏洞验证、修复建议或检测方法不确定时,先检索知识库,再给出结论。
```
## 内容编写建议
每篇知识建议包含:
- 适用场景。
- 检测方法。
- 验证步骤。
- 常见误报。
- 修复建议。
- 工具命令示例。
- 参考链接或内部标准。
避免把无关主题堆在同一篇长文中。小而清晰的文档更利于 chunk 和召回。
## 排错
索引失败:
- 检查 embedding API Key、模型名、base_url。
- 降低 `batch_size`
- 增大 `request_timeout_seconds`
- 查看服务日志中的 400/401/429/5xx。
检索为空:
- 检查是否已重建索引。
- 降低 `similarity_threshold`
- 查看 `categories` 是否识别到风险类型。
- 搜索时不要使用过窄的 `riskType`
召回不准:
- 优化标题层级。
- 把混杂内容拆成多篇。
- 增加关键术语和同义词。
- 调整 `top_k``prefetch_top_k` 和 rerank 配置。
## 内部数据流
知识库链路不是“全文搜索”,而是一个多阶段检索系统:
```mermaid
flowchart LR
F["Markdown / Web 知识项"] --> M["Manager"]
M --> C["Chunker"]
C --> E["Embedding"]
E --> V["SQLite Vector Index"]
Q["Agent 查询"] --> MQ["MultiQuery 改写"]
MQ --> V
V --> R["Rerank"]
R --> P["Post-process 去重/限长"]
P --> A["Agent 上下文"]
```
因此检索质量取决于四件事:原文结构、chunk 粒度、embedding 质量、rerank 可用性。单纯调 `top_k` 往往不是最有效的办法。
## 知识项写作反例
不好的知识:
```text
SQL注入很危险,可以用sqlmap扫,修复就是过滤。
```
好的知识:
```markdown
# MySQL UNION 注入验证
## 触发条件
- 参数进入 SELECT 查询并直接拼接。
- 页面返回字段数量错误或类型错误。
## 验证步骤
1. 使用 `' order by 1-- -` 递增列数。
2. 使用 `union select null,...` 校验回显位。
3. 用只读函数确认数据库类型,例如 `database()`
## 误报排除
- WAF 注入拦截页可能模拟 SQL 错误。
- 统一错误页不能直接证明注入。
## 修复
- 参数化查询。
- 最小数据库权限。
- 统一错误处理但不吞掉安全日志。
```
第二种写法能给 chunk 足够的标题、术语和步骤信号,Agent 也能直接执行。
## 调参方法
先固定一组测试问题,例如:
```text
MySQL union 注入怎么判断字段数?
SSRF 如何验证云元数据访问?
文件上传黑名单绕过有哪些误报?
```
然后逐项调:
1. 搜索为空:降低 `similarity_threshold`,确认索引完成。
2. 结果主题错:提高文档标题质量,增加风险类型过滤。
3. 结果片段断裂:增大 `chunk_overlap` 或降低 `chunk_size` 后重建索引。
4. 噪声多:提高 `similarity_threshold`,启用/修复 rerank。
5. 成本高:降低 `multi_query.max_queries``prefetch_top_k``top_k`
每次只改一个参数,并记录查询结果,否则无法判断哪个变量有效。
## 检索日志怎么用
检索日志不只是排错用,还可以反向改进知识库:
- 高频无结果查询:说明缺知识或同义词不足。
- 高频低分查询:说明文档标题和术语不匹配。
- 同一问题召回多个重复文档:说明需要合并或加 category。
- Agent 常忽略知识库结果:说明结果太长、太散或缺明确结论。
## 源码锚点
- 知识管理:`internal/knowledge/manager.go`
- 索引流水线:`internal/knowledge/index_pipeline.go`
- Eino chunk`internal/knowledge/chunk_eino.go`
- 检索器:`internal/knowledge/retriever.go`
- Eino 检索链:`internal/knowledge/eino_retrieve_chain.go`
- rerank`internal/knowledge/rerank_http.go`
- MCP 工具:`internal/knowledge/tool.go`
+189
View File
@@ -0,0 +1,189 @@
# MCP 联邦
CyberStrikeAI 同时支持内置 MCP 工具、独立 HTTP MCP 服务和外部 MCP 联邦。MCP 是 Agent 调用工具的主要协议层。
## 内置 MCP
Web 服务内部会创建 MCP Server,并注册:
- YAML 命令工具。
- 内置安全执行工具。
- 知识库工具。
- 项目事实工具。
- C2 工具。
- WebShell 工具。
- 批量任务工具。
- 视觉分析工具。
前端和 Agent 通常通过应用内部调用,不需要额外配置。
## HTTP MCP 服务
配置:
```yaml
mcp:
enabled: true
host: 0.0.0.0
port: 8081
auth_header: "X-MCP-Token"
auth_header_value: "random-secret"
```
生产环境必须设置 `auth_header_value`,并限制网络访问。
## Web 内 MCP 端点
登录后可通过:
```text
POST /api/mcp
```
该端点复用 Web 认证,适合内部页面或受控集成。
## 外部 MCP
外部 MCP 配置在:
```yaml
external_mcp:
servers: {}
```
也可以通过 Web 的 MCP 管理页面新增、启动、停止和删除。
接口:
- `GET /api/external-mcp`
- `GET /api/external-mcp/stats`
- `GET /api/external-mcp/:name`
- `PUT /api/external-mcp/:name`
- `POST /api/external-mcp/:name/start`
- `POST /api/external-mcp/:name/stop`
- `DELETE /api/external-mcp/:name`
## stdio
stdio MCP 适合本机命令启动的工具服务。
关注点:
- 命令路径必须存在。
- 工作目录正确。
- 环境变量完整。
- 进程退出会导致工具不可用。
- 日志中查看启动失败原因。
## HTTP / SSE
HTTP 或 SSE MCP 适合远端或长期运行服务。
关注点:
- URL 可达。
- 认证头正确。
- TLS 证书可信。
- 代理和防火墙放行。
- 服务端协议版本兼容。
## 工具暴露策略
工具过多会增加上下文成本和误选概率。多代理中可通过:
```yaml
multi_agent:
eino_middleware:
tool_search_enable: true
tool_search_min_tools: 20
tool_search_always_visible: 12
tool_search_always_visible_tools:
- read_file
- glob
- grep
- tool_search
```
让常用工具常驻,其余工具由 `tool_search` 动态解锁。
## 安全建议
- 外部 MCP 只接入可信服务。
- 远端 MCP 必须认证。
- 高风险工具不要常驻上下文。
- 外部 MCP 的文件系统和命令执行能力要单独评估。
- 变更外部 MCP 后查看审计日志。
## 调试
排查顺序:
1. `/api/external-mcp/stats` 查看状态。
2. 检查服务日志。
3. 单独运行 stdio 命令。
4. 用 curl 测试 HTTP/SSE 地址。
5. 检查工具是否被角色或 tool_search 策略隐藏。
## MCP 生命周期
外部 MCP 的生命周期不是简单的“添加 URL”:
1. 注册配置:名称、类型、命令或 URL、环境变量。
2. 启动连接:stdio 拉起进程,HTTP/SSE 建立客户端。
3. 拉取工具列表:工具名、描述、schema 进入平台。
4. 暴露给 Agent:受角色、tool_search、HITL 影响。
5. 执行工具:参数校验、调用、记录监控。
6. 连接恢复:进程退出或网络失败后尝试恢复。
7. 停止/删除:从运行时和配置中移除。
排错时要确认卡在哪一步。
## 工具命名规范
工具名应:
- 稳定。
- 小写或 snake_case。
- 表达动作和对象。
- 避免和内置工具重名。
不建议:
```text
run
execute
scan
tool1
```
建议:
```text
burp_send_to_repeater
asset_lookup_domain
cloud_list_public_buckets
```
好的工具名会提升 tool_search 命中率,也降低误调用。
## 外部 MCP 安全审查清单
接入前问:
- 它能读写本机文件吗?
- 它能执行命令吗?
- 它会访问哪些网络?
- 它是否把请求发给第三方?
- 它的工具描述是否可信?
- 它的输出是否可能包含 prompt injection
- 它是否需要独立运行用户或容器隔离?
只要答案不清楚,就不要放进生产环境常驻工具池。
## 源码锚点
- 外部 MCP Manager`internal/mcp/external_manager.go`
- 连接恢复:`internal/mcp/connection_recovery.go`
- MCP 工具适配:`internal/einomcp/mcp_tools.go`
- 外部 MCP Handler`internal/handler/external_mcp.go`
- 工具调用通知:`internal/einomcp/tool_invoke_notify.go`
+157
View File
@@ -0,0 +1,157 @@
# 插件开发
CyberStrikeAI 当前仓库中的插件主要位于 `plugins/`,示例是 Burp Suite 扩展。插件通常通过 HTTP API、MCP 或本地文件与主应用集成。
## 目录
```text
plugins/
README.md
burp-suite/
cyberstrikeai-burp-extension/
src/main/java/burp/
README.md
README.zh-CN.md
build.gradle
pom.xml
```
## 插件类型
常见集成方式:
- 浏览器或安全工具扩展:调用 CyberStrikeAI API。
- MCP Server:向 CyberStrikeAI 暴露新工具。
- 文件型扩展:提供 tools、roles、skills、agents。
- Webhook/机器人:通过平台回调与 CyberStrikeAI 对话。
## Burp Suite 扩展
Burp 插件目录包含 Java 源码和构建脚本。典型能力:
- 读取 Burp 中的 HTTP 请求/响应。
- 格式化消息。
- 调用 CyberStrikeAI API。
- 在 Burp 标签页展示 AI 分析结果。
构建前确认:
- JDK 可用。
- Gradle 或 Maven 可用。
- CyberStrikeAI 服务地址和认证配置正确。
## API 对接建议
插件调用主应用时:
- 先登录或使用受控认证方式。
- 优先调用 `/api/eino-agent``/api/eino-agent/stream`
- 大文件通过 `/api/chat-uploads` 上传,再在消息中引用。
- 查询结果或漏洞可写入 `/api/vulnerabilities`
- 项目信息可写入 `/api/projects/:id/facts`
完整接口以 `/api-docs` 为准。
## MCP 插件
如果插件的目标是给 Agent 增加工具,优先实现 MCP Server。然后在外部 MCP 管理中接入:
- stdio:本机启动。
- HTTP/SSE:长期服务。
MCP 工具设计建议:
- schema 明确。
- 参数最小化。
- 输出结构稳定。
- 错误信息可读。
- 高风险动作拆成独立工具,方便 HITL 审批。
## 文件型扩展
插件也可以交付:
- `tools/*.yaml`
- `roles/*.yaml`
- `skills/<name>/SKILL.md`
- `agents/*.md`
这种方式简单可靠,适合内部方法论或工具链沉淀。
## 发布检查
发布插件前确认:
- 不包含 API Key、Cookie、目标信息。
- README 有安装、配置、卸载说明。
- 错误提示清晰。
- 与当前 CyberStrikeAI API 版本兼容。
- 高风险能力有明显说明。
## 版本兼容
插件应避免依赖未公开的前端内部实现。优先依赖:
- `/api/openapi/spec`
- 稳定 HTTP API。
- MCP 协议。
- 文件目录规范。
如果必须依赖内部接口,插件 README 中应标注兼容版本。
## 插件设计的三个层次
| 层次 | 例子 | 优点 | 代价 |
| --- | --- | --- | --- |
| API 插件 | Burp 扩展调用 `/api/eino-agent` | 易实现,适合 UI 集成 | 依赖认证和 API 稳定性 |
| MCP 插件 | 提供新工具给 Agent | Agent 可主动调用 | 需要 schema 和安全设计 |
| 资源包插件 | 交付 tools/roles/skills/agents | 最简单,可版本化 | 交互能力弱 |
插件一开始不必做成 MCP。如果只是“把 Burp 请求交给 AI 分析”,API 插件更直接;如果要让 Agent 主动调用 Burp 扫描或查询结果,再做 MCP。
## API 插件请求设计
发送给 Agent 的内容应包含:
- 来源工具和上下文。
- 目标 URL、方法、关键 header。
- 请求体和响应体的截断策略。
- 用户希望 AI 做什么。
- 授权边界。
不要把完整大响应直接塞进消息。大文件应走上传接口或做摘要。
## MCP 插件 schema 设计
坏 schema
```json
{"cmd":{"type":"string"}}
```
好 schema
```json
{
"target_url": {"type":"string","description":"授权目标 URL"},
"scan_profile": {"type":"string","enum":["passive","active-safe"]},
"max_requests": {"type":"integer","description":"最大请求数"}
}
```
schema 越具体,HITL 越容易判断风险,Agent 也越不容易发散。
## 插件安全边界
插件不要绕过平台安全控制:
- 不要直接执行本机高风险命令而不暴露给 HITL。
- 不要在插件内保存明文长期凭证。
- 不要默认把目标数据发给第三方服务。
- 不要依赖浏览器本地状态绕过登录。
## 源码锚点
- Burp 插件 Java 代码:`plugins/burp-suite/cyberstrikeai-burp-extension/src/main/java/burp/`
- OpenAPI`internal/handler/openapi.go`
- 外部 MCP`internal/handler/external_mcp.go`
+169
View File
@@ -0,0 +1,169 @@
# 发布流程
本文用于维护者或部署者发布、升级和回滚 CyberStrikeAI。
## 版本准备
发布前检查:
- `README.md``README_CN.md` 的功能说明是否更新。
- `docs/` 是否补充新功能文档。
- `config.yaml` 示例是否包含新增配置。
- OpenAPI 是否包含新增接口。
- 中英文 i18n 是否同步。
- 高风险功能是否有安全说明。
## 测试
至少运行:
```bash
go test ./internal/...
```
如果修改了入口、构建或命令:
```bash
go test ./cmd/...
go build -o cyberstrike-ai ./cmd/server
```
如果修改前端,手动验证:
- 登录。
- 对话流式输出。
- 设置保存和应用。
- 工具列表。
- 相关页面无控制台错误。
## 构建
```bash
go build -o cyberstrike-ai ./cmd/server
```
发布包应包含:
- `cyberstrike-ai`
- `web/templates/`
- `web/static/`
- `config.yaml` 示例。
- `tools/`
- `roles/`
- `skills/`
- `agents/`
- `docs/`
- `README.md` / `README_CN.md`
- `LICENSE`
不要把本地 `data/`、真实 `config.yaml` 密钥、上传附件和日志打进公开发布包。
## 升级检查清单
升级前:
- 停服务。
- 备份 `config.yaml`
- 备份 `data/`
- 备份自定义 `tools/roles/skills/agents/knowledge_base`
- 记录当前版本和启动方式。
升级后:
- 启动服务。
- 登录。
- 测试模型。
- 检查工具列表。
- 检查知识库状态。
- 检查外部 MCP。
- 检查 C2/WebShell 是否按预期启用或关闭。
- 查看日志和审计。
## 回滚
触发回滚的常见情况:
- 服务无法启动。
- 数据库迁移失败。
- 核心对话功能不可用。
- 高风险功能行为异常。
回滚步骤:
1. 停止新版本。
2. 恢复旧二进制或旧代码。
3. 恢复升级前 `config.yaml`
4. 恢复升级前 `data/`
5. 启动旧版本并验证。
如果新版已修改数据库结构,必须恢复数据库备份,不能只替换二进制。
## Changelog 建议
每个版本记录:
- 新增功能。
- 行为变更。
- 配置变更。
- 数据库变更。
- 安全修复。
- 兼容性说明。
- 升级注意事项。
高风险模块的变更要单独标出,例如 C2、WebShell、终端、外部 MCP、HITL。
## 发布风险分级
| 改动 | 风险 | 必测 |
| --- | --- | --- |
| 文档、图片 | 低 | 链接和渲染 |
| 前端页面 | 中 | 登录、页面状态、API 错误 |
| Handler/API | 中 | OpenAPI、权限、错误码 |
| 配置结构 | 高 | 旧配置兼容、ApplyConfig |
| 数据库结构 | 高 | 旧库迁移、回滚策略 |
| Agent/MCP/HITL | 高 | 工具调用、审批、流式中断 |
| C2/WebShell/Terminal | 极高 | 授权环境、审计、禁用开关 |
发布说明里要按风险级别提示用户,而不是只列功能点。
## 配置兼容策略
新增配置字段要遵循:
- 省略时有安全默认值。
- 旧配置能启动。
- 示例 `config.yaml` 有注释。
- Web 设置页不会把未知字段误删。
- 热应用和重启两种路径都验证。
如果新增字段默认开启高风险功能,应重新考虑默认值。
## 数据库变更策略
SQLite 迁移要考虑:
- 用户可能从很老版本直接升级。
- 迁移中断后再次启动是否幂等。
- 新字段是否允许空值。
- 索引是否会锁表太久。
- 是否需要数据回填。
发布说明必须写清楚“升级前备份 data/”。
## Release 验收脚本思路
最小自动化:
```bash
go test ./internal/...
go test ./cmd/...
go build -o cyberstrike-ai ./cmd/server
```
手动冒烟:
```text
登录 -> 模型测试 -> 新建对话 -> 工具列表 -> HITL -> 知识库 -> 外部 MCP -> 关闭/开启 C2
```
对高风险模块,宁可多做一个授权靶场测试,也不要只靠单测放行。
+491
View File
@@ -0,0 +1,491 @@
# CyberStrikeAI 机器人使用说明
[English](../en-US/robot.md)
本文档说明如何通过**个人微信**、**钉钉**、**飞书**与 **企业微信** 与 CyberStrikeAI 对话(长连接 / 回调模式),在手机端即可使用,无需在服务器上打开网页。按下面步骤操作可避免常见弯路。
---
## 一、在 CyberStrikeAI 里从哪里配置
1. 登录 CyberStrikeAI Web 端
2. 左侧导航进入 **系统设置**
3. 在左侧设置分类中点击 **机器人设置**(位于「基本设置」与「安全设置」之间)
4. 按平台配置:
- **个人微信**:点击「微信 / iLink」→「生成二维码并绑定」,用微信扫码确认(见 [3.4 个人微信](#34-个人微信-wechat--ilink)
- **钉钉**:勾选并填写 Client ID / Client Secret
- **飞书**:勾选并填写 App ID / App Secret
5. 点击 **应用配置** 保存(微信扫码绑定成功后会**自动保存并启用**,一般无需再点)
6. **重启 CyberStrikeAI 应用**(钉钉/飞书:只保存不重启,长连接不会建立;微信绑定成功后会自动重启连接,通常无需手动重启)
配置会写入 `config.yaml``robots` 段,也可在配置文件中直接编辑。**修改钉钉/飞书配置后必须重启,长连接才会生效。** 个人微信绑定成功后程序会自动写入 `robots.wechat` 并重启 iLink 长轮询。
---
## 二、支持的平台(长连接 / 回调)
| 平台 | 说明 |
|----------|------|
| 个人微信 | 使用微信 iLink 协议,Web 端扫码绑定后长轮询收消息,**无需公网回调** |
| 钉钉 | 使用 Stream 长连接,程序主动连接钉钉接收消息 |
| 飞书 | 使用长连接,程序主动连接飞书接收消息 |
| 企业微信 | 使用 HTTP 回调接收消息,被动回包 + 主动调用企业微信发送消息 API |
| Telegram | Bot API 长轮询(getUpdates),**无需公网回调** |
| Slack | Socket Mode(出站 WebSocket),**无需公网回调** |
| Discord | Gateway WebSocket**无需公网回调** |
| QQ 机器人 | QQ 开放平台 WebSocketC2C / 群 @),**无需公网回调** |
下面第三节会按平台写清:在开放平台要做什么、要复制哪些字段、填到 CyberStrikeAI 的哪一栏。
---
## 三、各平台配置项与详细步骤
### 3.1 钉钉
**先搞清楚:两种钉钉机器人不一样**
| 类型 | 从哪里创建 | 能否做「用户发消息→机器人回复」 | 本程序是否支持 |
|------|------------|----------------------------------|----------------|
| **自定义机器人** | 钉钉群里:群设置 → 添加机器人 → 自定义(Webhook) | ❌ 不能,只能你往群里发消息 | ❌ 不支持 |
| **企业内部应用机器人** | [钉钉开放平台](https://open.dingtalk.com) 创建应用并开通机器人 | ✅ 能 | ✅ 支持 |
如果你手里是「自定义机器人」的 Webhook 地址(`oapi.dingtalk.com/robot/send?access_token=xxx`)和加签密钥(`SEC...`),**不能直接填到本程序**,必须按下面步骤在开放平台创建「企业内部应用」并拿到 **Client ID**、**Client Secret**。
---
**钉钉配置完整步骤(按顺序做)**
1. **打开钉钉开放平台**
浏览器访问 [https://open.dingtalk.com](https://open.dingtalk.com),用**企业管理员**账号登录。
2. **进入应用开发**
左侧选 **应用开发****企业内部开发** → 点击 **创建应用**(或选择已有应用)。填写应用名称等基本信息后创建。
3. **拿到 Client ID 和 Client Secret**
- 左侧点 **凭证与基础信息**(在「基础信息」下)。
- 页面上有 **Client ID(原 AppKey****Client Secret(原 AppSecret**
- 点击复制,**不要手打**,注意:数字 **0** 和字母 **o**、数字 **1** 和字母 **l** 容易抄错(例如 `ding9gf9tiozuc504aer` 中间是数字 **504** 不是 5o4)。
4. **开通机器人并选 Stream 模式**
- 左侧 **应用能力****机器人**
- 打开「机器人配置」开关。
- 填写机器人名称、简介等(必填项按提示填)。
- **关键**:消息接收方式要选 **「Stream 模式」**(流式接入)。若只有「HTTP 回调」或未选 Stream,本程序收不到消息。
- 保存。
5. **权限与发布**
- 左侧 **权限管理**:搜索「机器人」「消息」等,勾选**接收消息**、**发送消息**等机器人相关权限,并确认授权。
- 左侧 **版本管理与发布**:若有未发布配置,点击 **发布新版本** / **上线**,否则修改不生效。
6. **填回 CyberStrikeAI**
- 回到 CyberStrikeAI → 系统设置 → 机器人设置 → 钉钉。
- 勾选「启用钉钉机器人」。
- **Client ID (AppKey)** 粘贴第 3 步复制的 Client ID。
- **Client Secret** 粘贴第 3 步复制的 Client Secret。
- 点击 **应用配置**,然后**重启 CyberStrikeAI**。
---
**CyberStrikeAI 钉钉栏位对照**
| CyberStrikeAI 中填写项 | 在钉钉开放平台的来源 |
|------------------------|------------------------|
| 启用钉钉机器人 | 勾选即启用 |
| Client ID (AppKey) | 凭证与基础信息 → **Client ID(原 AppKey** |
| Client Secret | 凭证与基础信息 → **Client Secret(原 AppSecret** |
---
### 3.2 飞书 (Lark)
| 配置项 | 说明 |
|--------|------|
| 启用飞书机器人 | 勾选后启动飞书长连接 |
| App ID | 飞书开放平台应用凭证中的 App ID |
| App Secret | 飞书开放平台应用凭证中的 App Secret |
| Verify Token | 事件订阅用(可选) |
**飞书配置简要步骤**:登录 [飞书开放平台](https://open.feishu.cn) → 创建企业自建应用 → 在「凭证与基础信息」中获取 **App ID**、**App Secret** → 在「应用能力」中开通**机器人**并启用相应权限 → **在「事件订阅」中添加事件**(见下)→ 发布应用 → 将 App ID、App Secret 填到 CyberStrikeAI 机器人设置 → 保存。
**重要:事件订阅**
飞书长连接只有在开放平台订阅了「接收消息」事件后才会收到用户消息。请在该应用的 **事件订阅** 页面点击「添加事件」,在「消息与群组」下勾选 **接收消息(im.message.receive_v1** 或同类事件;若未添加,连接会建立成功但收不到任何消息,表现为发消息后本地无日志、机器人无回复。
**飞书权限配置(必读)**
**权限管理** 中需开通以下权限(与开放平台列表中的名称、标识一致);修改后需在 **版本管理与发布** 中发布新版本才生效。
| 权限名称(开放平台中显示) | 权限标识 | 说明 |
|----------------------------|----------|------|
| 获取与发送单聊、群组消息 | `im:message` | 收发消息的基础权限,**必须开通**。 |
| 接收群聊中@机器人消息事件 | `im:message.group_at_msg:readonly` | 群聊中 @ 机器人时收消息,需开通。 |
| 读取用户发给机器人的单聊消息 | `im:message.p2p_msg:readonly` | 单聊收消息,**必须开通**,否则私聊发消息没反应。 |
| 获取单聊、群组消息 | `im:message:readonly` | 读取消息内容,**必须开通**。 |
**事件订阅**(与权限分开配置):在 **事件订阅** 中添加 **接收消息(im.message.receive_v1**,否则长连接收不到消息推送。
- **单聊**:在飞书里打开与机器人的私聊窗口,直接发「帮助」或任意文字即可,无需 @。
- **群聊**:在群里只有 **@ 机器人** 后发送的内容才会被机器人收到并回复。
---
### 3.3 企业微信 (WeCom)
> 企业微信目前采用「HTTP 回调 + 主动发送消息 API」的方式工作:
> - 用户发消息 → 企业微信以加密 XML **回调到你的服务器**(本程序的 `/api/robot/wecom`);
> - CyberStrikeAI 解密并调用 AI → 使用企业微信的 `message/send` 接口**主动发消息给用户**。
**配置概览:**
- 在企业微信管理后台创建或选择一个**自建应用**。
- 在该应用的「接收消息」处配置回调 URL、Token、EncodingAESKey。
- 在 CyberStrikeAI 的 `config.yaml` 中填入:
- `robots.wecom.corp_id`:企业 IDCorpID
- `robots.wecom.agent_id`:应用的 AgentId
- `robots.wecom.token`:消息回调使用的 Token
- `robots.wecom.encoding_aes_key`:消息回调使用的 EncodingAESKey
- `robots.wecom.secret`:该应用的 Secret(用于调用企业微信主动发送消息接口)
> **重要:IP 白名单(errcode 60020**
> CyberStrikeAI 使用 `https://qyapi.weixin.qq.com/cgi-bin/message/send` 主动发送 AI 回复。
> 若企业微信日志或本程序日志中出现 `errcode 60020 not allow to access from your ip`
>
> - 说明你的服务器出口 IP **没有加入企业微信的 IP 白名单**;
> - 请在企业微信管理后台中找到该自建应用的**「安全设置 / IP 白名单」**(具体入口可能因版本略有不同),将运行 CyberStrikeAI 的服务器公网 IP(如 `110.xxx.xxx.xxx`)加入白名单;
> - 保存后等待生效,再次发送消息测试。
>
> 如果 IP 未加入白名单,企业微信会拒绝主动发送消息,表现为:
> - 回调接口 `/api/robot/wecom` 能正常收到并处理消息;
> - 但手机端**始终收不到 AI 回复**,日志中有 `not allow to access from your ip` 提示。
---
### 3.4 个人微信 (WeChat / iLink)
> 个人微信采用「Web 扫码绑定 + iLink 长轮询」方式工作:
> - 在 CyberStrikeAI Web 端生成二维码 → 用**手机微信**扫码并确认绑定;
> - 绑定成功后自动写入 `config.yaml` 的 `robots.wechat`,并启动 iLink 长轮询(程序主动连接 `ilinkai.weixin.qq.com` 收消息);
> - **无需**在服务器上配置公网回调 URL,也**无需**去微信开放平台注册应用。
**与企业微信的区别**
| 项目 | 个人微信 (iLink) | 企业微信 (WeCom) |
|------|------------------|------------------|
| 使用场景 | 个人微信私聊 | 企业微信自建应用 |
| 配置方式 | Web 端扫码绑定 | 管理后台配置回调 URL + Token |
| 是否需要公网 | 否(长轮询出站即可) | 是(需可被企业微信访问的 HTTPS 回调) |
| 配置段 | `robots.wechat` | `robots.wecom` |
**绑定步骤(按顺序做)**
1. **登录 CyberStrikeAI Web 端**
左侧 **系统设置****机器人设置** → 点击 **微信 / iLink** 卡片。
2. **(可选)勾选「启用微信机器人」**
首次绑定可跳过;绑定成功后会自动勾选并启用。
3. **生成二维码**
点击 **「生成二维码并绑定」**。页面会显示二维码(约 **5 分钟**有效;过期请重新生成)。
4. **微信扫码确认**
- 用手机微信扫描页面二维码;
- 按手机提示完成确认;
- 若手机微信弹出**配对数字**,在 Web 页面对应输入框填写并点击 **提交**(仅部分账号需要)。
5. **等待绑定完成**
页面显示「绑定成功,微信机器人已启用」即完成。`bot_token``ilink_bot_id` 等会自动写入 `config.yaml`,程序会自动重启 iLink 长轮询,**一般无需手动重启服务**。
6. **在手机微信里测试**
打开与 CyberStrikeAI 机器人的**私聊**(绑定后微信内会出现对应会话),发送「帮助」或任意文字测试。
**CyberStrikeAI 微信栏位说明**
| 栏位 | 说明 |
|------|------|
| 启用微信机器人 | 勾选后启动 iLink 长轮询;绑定成功后会自动勾选 |
| 生成二维码并绑定 | 发起扫码绑定流程 |
| **高级设置**(一般保持默认即可) | |
| API Base URL | 默认 `https://ilinkai.weixin.qq.com` |
| Bot Type | 默认 `3` |
| Bot Agent | 默认 `CyberStrikeAI/1.0` |
| iLink Bot ID | 绑定成功后自动填充,只读 |
**使用方式**
- 仅支持在与机器人的**私聊**中对话,直接发送文字即可,**不需要 @**。
- 不支持群聊 @ 机器人(与钉钉/飞书群聊不同)。
- 仅处理**文本消息**;图片、语音等会忽略或提示暂不支持。
**重新绑定**
- 若需更换绑定的微信账号,在机器人设置页点击 **「重新绑定」**,再次扫码即可。
- 若提示「该微信已绑定过,无需重复绑定」,说明该账号此前已完成绑定。
**常见问题**
| 现象 | 处理 |
|------|------|
| 二维码过期 | 重新点击「生成二维码并绑定」(有效期约 5 分钟) |
| 扫码后要求输入数字 | 查看手机微信显示的配对数字,在 Web 页面输入并提交 |
| 绑定成功但发消息无回复 | 看程序日志是否有 `微信 iLink 长轮询已启动``微信收到消息`;确认已勾选「启用微信机器人」 |
| 断网或睡眠后无回复 | 程序会自动重连(约 5~60 秒);仍无回复可重启 CyberStrikeAI |
| 无法生成二维码 | 确认服务器能访问 `https://ilinkai.weixin.qq.com`(出站 HTTPS |
---
### 3.5 Telegram
> Telegram 使用 **Bot API 长轮询**`getUpdates`):程序主动连接 `api.telegram.org` 收消息,**无需公网回调**。
**配置步骤:**
1. 在 Telegram 中找 **@BotFather**,发送 `/newbot` 创建机器人,获得 **Bot Token**
2. CyberStrikeAI → **系统设置****机器人设置****Telegram**
3. 勾选「启用 Telegram 机器人」,粘贴 **Bot Token**
4. (可选)填写 Bot Username(不含 `@`),或留空由程序自动 `getMe`
5. (可选)勾选「允许群聊」— 群聊中仅响应 **@机器人** 的消息。
6. 点击 **应用配置**(会自动重启长轮询连接)。
**使用:** 与机器人私聊直接发消息;群聊需 @ 机器人(且已勾选允许群聊)。
---
### 3.6 Slack
> Slack 使用 **Socket Mode**(出站 WebSocket):需 **Bot Token** 与 **App-Level Token****无需公网回调**。
**配置步骤:**
1. 在 [Slack API](https://api.slack.com/apps) 创建 App → 启用 **Socket Mode**
2. **Basic Information****App-Level Tokens** → 创建 tokenscope: `connections:write`),即 **xapp-** 开头。
3. **OAuth & Permissions** → 添加 Bot Token Scopes`app_mentions:read``chat:write``im:history``im:read` 等 → 安装到工作区,获得 **xoxb-** Bot Token。
4. **Event Subscriptions** → 订阅 `message.im``app_mention` 等(Socket Mode 下在应用内配置)。
5. 在 CyberStrikeAI 填入 Bot Token 与 App-Level Token → **应用配置**
**使用:** 与 Bot 私聊直接发;频道中需 @ 机器人。
---
### 3.7 Discord
> Discord 使用 **Gateway WebSocket**:程序主动连接 Discord Gateway**无需公网回调**。
**配置步骤:**
1. 在 [Discord Developer Portal](https://discord.com/developers/applications) 创建应用 → **Bot** → 复制 **Token**
2. 开启 **Privileged Gateway Intents** 中的 **Message Content Intent**(否则读不到消息正文)。
3. OAuth2 → URL Generator → scopes: `bot` → 权限勾选 **Send Messages**、**Read Message History** 等 → 邀请 Bot 到服务器。
4. CyberStrikeAI → **机器人设置****Discord** → 填入 Token → **应用配置**
5. (可选)勾选「允许服务器频道」— 频道中仅响应 **@机器人**。
**使用:** 与 Bot 私聊直接发;服务器频道需 @ 机器人(且已勾选允许服务器频道)。
---
### 3.8 QQ 机器人
> QQ 机器人使用 **QQ 开放平台 WebSocket**(官方 `botgo` SDK):支持 C2C 私聊与群 @**无需公网回调**(WebSocket 出站连接)。
**配置步骤:**
1. 在 [QQ 机器人开放平台](https://q.qq.com) 创建机器人,获取 **App ID****Client Secret**
2. 在沙箱中添加测试成员(上线前仅沙箱可对话)。
3. 订阅 **C2C 消息**、**群 @ 消息** 等事件(WebSocket 模式)。
4. CyberStrikeAI → **机器人设置****QQ 机器人** → 填入 App ID、Client Secret。
5. 测试阶段勾选 **沙箱环境**;正式上线后取消沙箱并发布。
6. 点击 **应用配置**
**使用:** 与机器人 C2C 私聊直接发;QQ 群中需 @ 机器人。
> 注意:QQ 官方正逐步推广 Webhook 回调;当前实现使用 WebSocket(与钉钉/飞书类似的长连接模式)。若配置变更后连接未刷新,可重启 CyberStrikeAI 进程。
---
## 四、机器人命令
在任一已接入平台(钉钉/飞书/微信/Telegram/Slack/Discord/QQ 等)向机器人发送以下**文本命令**(仅支持文本):
| 命令 | 说明 |
|------|------|
| **帮助** | 显示命令帮助与说明 |
| **列表****对话列表** | 列出所有对话的标题与对话 ID |
| **切换 \<对话ID\>****继续 \<对话ID\>** | 指定对话 ID,后续消息在该对话中继续 |
| **新对话** | 开启一个新对话,后续消息在新对话中 |
| **清空** | 清空当前对话上下文(效果等同「新对话」) |
| **当前** | 显示当前对话 ID 与标题 |
| **停止** | 中断当前正在执行的任务 |
| **角色****角色列表** | 列出所有可用角色(渗透测试、CTF、Web 应用扫描等) |
| **角色 \<角色名\>****切换角色 \<角色名\>** | 切换当前使用的角色 |
| **删除 \<对话ID\>** | 删除指定对话 |
| **版本** | 显示当前 CyberStrikeAI 版本号 |
除以上命令外,**直接输入任意文字**会作为用户消息发给 AI,与 Web 端对话逻辑一致(渗透测试/安全分析等)。
---
## 五、如何使用(要 @ 机器人吗?)
- **个人微信**:在与 CyberStrikeAI 机器人的**私聊**中直接发送即可,**不需要 @**(不支持群聊)。
- **钉钉 / 飞书单聊(推荐)**:**搜索并打开该机器人**,进入**私聊**,直接输入「帮助」或任意文字即可,**不需要 @**。
- **钉钉 / 飞书群聊**:若机器人被添加到群里,在群内只有 **@机器人** 后发送的消息才会被机器人收到并回复;不 @ 的群消息不会触发机器人。
总结:**个人微信、单聊时直接发**;**钉钉/飞书在群里用时需要 @机器人** 再发内容。
---
## 六、推荐使用流程(避免漏步骤)
**个人微信(最简单,无需开放平台)**
1. CyberStrikeAI Web 端 → 系统设置 → 机器人设置 → **微信 / iLink****生成二维码并绑定**
2. 手机微信扫码确认(如需配对数字则在 Web 页填写)。
3. 绑定成功后,在手机微信私聊中发「帮助」测试。
**钉钉 / 飞书**
1. **在开放平台**:按第三节完成应用创建、凭证复制、机器人开通(钉钉务必选 **Stream 模式**)、权限与发布。
2. **在 CyberStrikeAI**:系统设置 → 机器人设置 → 勾选对应平台,粘贴 Client ID/App ID、Client Secret/App Secret → 点击 **应用配置**
3. **重启 CyberStrikeAI 进程**(否则长连接不会建立)。
4. **在手机钉钉/飞书**:找到该机器人(单聊直接发,群聊需 @机器人),发「帮助」或任意内容测试。
若发消息没反应,先看 **第九节排查****第十节常见弯路**
---
## 七、配置文件示例
`config.yaml` 中机器人相关片段示例:
```yaml
robots:
wechat: # 个人微信 iLink(扫码绑定后自动写入,一般无需手填)
enabled: true
bot_token: "your_bot_token@im.bot:..."
ilink_bot_id: "your_bot_id@im.bot"
ilink_user_id: "your_user_id@im.wechat"
base_url: "https://ilinkai.weixin.qq.com"
bot_type: "3"
bot_agent: "CyberStrikeAI/1.0"
dingtalk:
enabled: true
client_id: "your_dingtalk_app_key"
client_secret: "your_dingtalk_app_secret"
lark:
enabled: true
app_id: "your_lark_app_id"
app_secret: "your_lark_app_secret"
verify_token: ""
wecom:
enabled: false
corp_id: ""
agent_id: 0
token: ""
encoding_aes_key: ""
secret: ""
telegram:
enabled: false
bot_token: ""
allow_group_messages: false
slack:
enabled: false
bot_token: ""
app_token: ""
discord:
enabled: false
bot_token: ""
allow_guild_messages: false
qq:
enabled: false
app_id: ""
client_secret: ""
sandbox: true
```
修改钉钉/飞书/企业微信/Telegram/Slack/Discord/QQ 配置后,点击 **应用配置** 会自动重启对应长连接。个人微信扫码绑定成功后会自动写入并重启 iLink 连接。
---
## 八、如何验证是否可用(无需钉钉/飞书客户端)
在未安装钉钉或飞书时,可用**测试接口**验证机器人逻辑是否正常:
1. 先登录 CyberStrikeAI Web 端(保证有登录态)。
2. 使用 curl 调用测试接口(需携带登录后的 Cookie):
```bash
# 将 YOUR_COOKIE 替换为登录后获得的 Cookie(浏览器 F12 → 网络 → 任意请求 → 请求头中的 Cookie)
curl -X POST "http://localhost:8080/api/robot/test" \
-H "Content-Type: application/json" \
-H "Cookie: YOUR_COOKIE" \
-d '{"platform":"dingtalk","user_id":"test_user","text":"帮助"}'
```
若返回 JSON 中含有 `"reply":"【CyberStrikeAI 机器人命令】..."`,说明命令处理正常。可再试 `"text":"列表"``"text":"当前"` 等。
接口说明:`POST /api/robot/test`(需登录),请求体 `{"platform":"可选","user_id":"可选","text":"必填"}`,响应 `{"reply":"回复内容"}`
---
## 九、发消息没反应时排查
### 9.1 个人微信
按顺序检查:
1. **是否已完成扫码绑定**
机器人设置页应显示「已连接」或已绑定 Bot ID;`config.yaml``robots.wechat.bot_token` 不应为空。
2. **是否已启用**
确认「启用微信机器人」已勾选;若刚修改过,可重启 CyberStrikeAI 进程。
3. **看程序日志**
- 启动后应看到:`微信 iLink 长轮询已启动`
- 发消息后应有:`微信收到消息`;若没有,多为未绑定成功或 `bot_token` 失效,可尝试 **重新绑定**
- 若出现 `微信 iLink 长轮询异常,将自动重连`,等待自动重连或重启进程。
4. **网络**
服务器需能访问 `https://ilinkai.weixin.qq.com`(出站 HTTPS)。绑定阶段若无法生成二维码,优先检查此项。
5. **断网或睡眠后**
与钉钉/飞书类似,程序会**自动重连**(约 5~60 秒);仍无回复可重启 CyberStrikeAI。
### 9.2 钉钉
按顺序检查:
0. **笔记本合盖睡眠 / 断网后**
钉钉、飞书均使用长连接收消息,睡眠或断网后连接会断开。程序会**自动重连**(约 5 秒~60 秒内重试)。唤醒或恢复网络后稍等一会儿再发消息;若仍无反应,可重启 CyberStrikeAI 进程。
1. **Client ID / Client Secret 是否与开放平台完全一致**
从「凭证与基础信息」里**复制粘贴**,不要手打。注意数字 **0** 与字母 **o**、数字 **1** 与字母 **l**(例如 `ding9gf9tiozuc504aer` 中间是 **504** 不是 5o4)。
2. **是否在保存配置后重启了应用**
机器人长连接在**应用启动时**建立。在 Web 端点击「应用配置」只写入配置文件,**必须重启 CyberStrikeAI 进程**后钉钉连接才会生效。
3. **看程序日志**
- 启动后应看到:`钉钉 Stream 正在连接…``钉钉 Stream 已启动(无需公网),等待收消息`
- 若出现 `钉钉 Stream 长连接退出` 且带错误信息,多为 **Client ID / Client Secret 错误**或**开放平台未开通流式接入**
- 在钉钉里发一条消息后,若有收到,应有日志:`钉钉收到消息`;若没有,说明钉钉未把消息推到本程序(回头检查开放平台「机器人」是否开通、是否选用 **Stream 模式**)。
4. **开放平台侧**
应用需已**发布**;在「机器人」能力中需开启**流式接入(Stream)** 用于接收消息(仅 HTTP 回调不够);权限管理里需有机器人接收、发送消息等权限。
---
## 十、常见弯路(避免踩坑)
- **个人微信与企业微信混淆**:个人微信走 `robots.wechat` + Web 扫码绑定;企业微信走 `robots.wecom` + 管理后台回调 URL,二者完全不同。
- **个人微信二维码过期**:二维码约 5 分钟有效,过期需重新生成,不要一直扫旧码。
- **用错了机器人类型**:在钉钉**群里**添加的「自定义」机器人(Webhook + 加签)**不能**用来做对话,本程序只支持**开放平台「企业内部应用」**里的机器人。
- **只保存没重启**:钉钉/飞书改完配置后必须**重启应用**,否则长连接不会建立(个人微信扫码绑定会自动重启连接)。
- **Client ID 抄错**:开放平台是 `504` 就填 `504`,不要填成 `5o4`;尽量用复制粘贴。
- **钉钉只开了 HTTP 回调没开 Stream**:本程序通过 **Stream 长连接**收消息,开放平台里机器人的消息接收方式必须选 **Stream 模式**
- **应用没发布**:开放平台里修改了机器人或权限后,要在「版本管理与发布」里**发布新版本**,否则不生效。
---
## 十一、注意事项
- 各平台均**仅处理文本消息**;其他类型(如图片、语音)会提示暂不支持或忽略。
- 个人微信仅支持**私聊**,不支持群聊 @ 机器人。
- 会话与 Web 端共用同一套对话数据:在机器人里创建的对话会在 Web 端「对话」列表中看到,反之亦然。
- 机器人执行与 **Eino 单/多代理** 相同逻辑(`ProcessMessageForRobot`,含进度回调与过程详情入库),仅不向客户端推送 SSE,最后一次性回复个人微信/钉钉/飞书/企业微信。默认 `robot_default_agent_mode: eino_single`
+223
View File
@@ -0,0 +1,223 @@
# 运维 Runbooks
[English](../en-US/runbooks.md)
Runbook 是“遇到一个真实任务时照着做”的步骤清单。本文覆盖 CyberStrikeAI 最常见的运维和安全测试操作。
## Runbook 1:生产实例从 0 到可用
适用:内网团队或生产红队平台首次部署。
如果只是本地或临时验证,优先用仓库自带脚本启动:
```bash
chmod +x run.sh && ./run.sh
```
确认可用后,再决定是否升级为 systemd + 反向代理的长期部署。
### 前置确认
- 运行主机已纳入资产管理。
- 访问路径确定:内网、VPN、堡垒机或反向代理。
- 有模型 API Key 和允许使用的模型。
- 已决定是否启用 C2、WebShell、外部 MCP。
### 步骤
1. 准备目录:
```bash
mkdir -p /opt/CyberStrikeAI
```
2. 放置二进制和资源目录:
```text
cyberstrike-ai
web/
tools/
roles/
skills/
agents/
docs/
config.yaml
```
3. 修改关键配置:
```yaml
auth:
password: "<long-random-password>"
server:
host: 127.0.0.1
port: 8080
tls_enabled: false
audit:
enabled: true
c2:
enabled: false
```
4. 配置反向代理 HTTPS,并限制来源 IP。
5. 使用 systemd 托管进程。
6. 登录 Web,测试模型。
7. 检查工具列表和审计日志。
8. 建立备份策略。
### 验收
- `/api/auth/validate` 登录后返回成功。
- 模型测试成功。
- `tools/` 能正常加载。
- 审计页面能看到登录事件。
- C2 在不需要时访问返回禁用状态。
### 回滚
恢复:
- 上一版二进制。
- 上一版 `config.yaml`
- 升级前 `data/`
## Runbook 2:接入外部 MCP
适用:接入本地工具服务、Burp 辅助服务、资产查询服务等。
### 前置确认
- MCP 服务可信。
- 明确它是否能读文件、写文件、执行命令或访问第三方网络。
- 确定接入方式:stdio、HTTP、SSE。
### 步骤
1. 在外部 MCP 页面新增服务。
2. 如果是 stdio,填写命令、参数、工作目录和环境变量。
3. 如果是 HTTP/SSE,填写 URL 和认证信息。
4. 启动服务。
5. 查看 `/api/external-mcp/stats`
6. 检查工具列表是否出现。
7. 用低风险参数执行一次工具。
8. 把高风险工具排除在全局免审批白名单之外。
### 验收
- MCP 状态为 running。
- 工具 schema 可见。
- Agent 能通过 `tool_search` 找到工具。
- 工具执行记录出现在监控页。
- 配置变更出现在审计页。
### 回滚
- 停止 MCP。
- 删除外部 MCP 配置。
- 从角色/白名单中移除相关工具。
- 检查 Agent 当前任务是否仍持有旧上下文。
## Runbook 3:启用知识库并调优召回
适用:把内部安全知识、漏洞手册或测试方法接入 Agent。
### 步骤
1. 修改配置:
```yaml
knowledge:
enabled: true
base_path: knowledge_base
embedding:
model: text-embedding-v4
retrieval:
top_k: 5
similarity_threshold: 0.4
```
2. 把 Markdown 放入 `knowledge_base/`
3. 在 Web 知识库页面执行扫描。
4. 重建索引。
5. 准备 5 到 10 个固定测试问题。
6. 搜索并记录命中情况。
7. 根据结果调 `threshold``top_k`、chunk 参数和文档标题。
### 验收
- `index-status` 显示索引完成。
- 常见问题能命中正确文档。
- Agent 在不确定时会先查知识库。
- 检索日志能显示查询和命中文档。
### 常见回滚
- 关闭 `knowledge.enabled`
- 恢复旧的 `data/knowledge.db`
- 降低 `batch_size` 后重新索引。
## Runbook 4:一次授权 Web 测试标准流程
适用:对授权目标做 Web 安全测试。
### 步骤
1. 创建项目,记录授权范围。
2. 新建对话,绑定项目。
3. 选择最小角色,例如“信息收集”或“Web 应用扫描”。
4. 明确目标、时间窗口、禁止动作。
5. 先执行只读信息收集。
6. 发现线索后写入项目事实。
7. 对高风险验证请求使用 HITL。
8. 确认漏洞后写入漏洞管理。
9. 生成攻击链或报告材料。
10. 清理上传文件、临时 workspace 和无用执行记录。
### 验收
- 每个漏洞都有证据、影响、复现和修复建议。
- 高风险操作有 HITL 记录。
- 项目事实能复现测试路径。
- 报告不包含无关敏感数据。
## Runbook 5C2 演练结束清理
适用:授权演练中启用了 C2。
### 步骤
1. 停止所有 listener。
2. 列出 sessions,确认没有仍在线的授权会话。
3. 导出必要 task 结果。
4. 删除 payload 或移动到受控归档。
5. 删除无用 task、event、file。
6. 审计 C2 操作记录。
7. 将关键结果写入项目事实或报告。
8.`c2.enabled` 改回 false,除非平台持续需要。
### 验收
- 无运行中 listener。
- 无待处理 task。
- payload 不再公开可下载。
- 审计与报告能解释整个生命周期。
## Runbook 6Agent 不调用工具
排查顺序:
1. 当前角色是否绑定了该工具。
2. 工具是否在 `/api/config/tools` 中出现。
3. `tool_search` 是否隐藏了该工具。
4. 工具描述是否过短或命名不清。
5. HITL 是否挂起。
6. Agent 是否处于总结/结束阶段。
7. 多代理子 Agent 是否有自己的工具限制。
修复方式:
- 把工具加入角色。
- 优化 `short_description`
- 加入 `tool_search_always_visible_tools`
- 在提示词中明确什么时候使用。
- 检查过程详情和监控记录。
+140
View File
@@ -0,0 +1,140 @@
# 安全加固指南
[English](../en-US/security-hardening.md)
本文给出 CyberStrikeAI 上线前和持续运行中的安全加固清单。
## 上线前必做
- 修改 `auth.password` 为长随机密码。
- 使用 HTTPS,或放在可信反向代理之后。
- 限制来源 IP、VPN 或堡垒机访问。
- 开启 `audit.enabled`
- 不需要 C2 时设置 `c2.enabled: false`
- 不暴露独立 HTTP MCP,除非设置强认证和网络隔离。
- 外部 MCP 只接可信服务。
- 备份 `config.yaml``data/`、自定义资源目录。
## 反向代理建议
Nginx 基线:
```nginx
client_max_body_size 200m;
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
```
建议额外加:
```nginx
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy no-referrer;
add_header X-Frame-Options DENY;
```
## HITL 白名单基线
推荐最小白名单:
```yaml
hitl:
tool_whitelist:
- read_file
- glob
- grep
- tool_search
```
不要默认加入:
- `execute`
- WebShell 写入/执行工具
- C2 任务和 payload 工具
- 外部 MCP 高风险工具
- 删除、写入、上传、持久化相关工具
## 文件权限
建议:
```bash
chmod 600 config.yaml
chmod 700 data
```
生产环境使用独立系统用户运行:
```text
cyberstrike-ai:cyberstrike-ai
```
避免 root 运行,除非明确需要绑定低端口或访问特殊资源。
## 外部 MCP 审查
接入前确认:
- 工具是否能执行命令。
- 是否能读写本机文件。
- 是否会把数据发往第三方。
- 是否有自己的认证。
- 是否会返回不可信网页或模型内容。
- 是否需要容器隔离。
接入后:
- 高风险工具不进白名单。
- 定期检查工具列表变化。
- 审计配置变更。
## C2 和 WebShell
C2
- 默认关闭。
- 演练窗口临时开启。
- Listener 端口与管理端口分离。
- 结束后清理 payload、session、task、event。
WebShell
- 只保存授权目标。
- 使用清晰命名。
- 写入/删除/执行必须审批。
- 项目结束删除连接。
## 数据保留
建议:
- 审计:30-90 天。
- 工具监控:90-180 天。
- 上传附件:项目结束清理。
- C2/WebShell 输出:只保留报告需要的证据。
- 知识库:不放真实凭证和客户私密数据。
## 周期巡检
每周:
- 登录失败和异常 IP。
- 配置变更。
- 外部 MCP 增删改。
- 长时间运行工具。
- C2 是否被意外开启。
- WebShell 连接是否过期。
- 磁盘空间和数据库大小。
每个项目结束:
- 清理临时 workspace。
- 删除无用附件。
- 归档必要证据。
- 删除过期 WebShell/C2 资源。
- 导出审计记录。
+180
View File
@@ -0,0 +1,180 @@
# 安全模型
CyberStrikeAI 面向授权安全测试场景,内置命令执行、MCP 工具、WebShell、C2、批量任务和多代理编排等能力。部署者必须把它当作高权限安全工具管理,而不是普通聊天应用。
## 信任边界
主要边界:
- Web 登录用户:可以发起对话、调用工具、修改配置、管理 WebShell/C2/知识库。
- Agent:根据角色、工具列表、HITL 策略调用内置或外部工具。
- MCP 工具:可能访问本机文件、执行命令、调用外部服务或操作目标系统。
- 外部 MCP:由第三方进程或远端服务提供,需单独信任。
- 机器人入口:企业微信、钉钉、飞书等回调入口不走 Web 登录,但有平台验签和速率限制。
如果一个账号可以登录 Web,就应视为拥有该 CyberStrikeAI 实例的操作权限。
## 认证与会话
`auth.password` 是 Web 登录密码。建议:
- 首次部署立即修改默认密码。
- 使用长随机密码,并限制分享范围。
- 将服务放在内网、VPN、堡垒机或反向代理认证后面。
- 生产环境开启 HTTPS,避免明文传输 Cookie。
- 结合反向代理限制来源 IP。
登录态有效期由 `auth.session_duration_hours` 控制。
## 工具执行风险
工具来源包括:
- 内置安全执行工具。
- `tools/` 下的 YAML 命令工具。
- Eino Skills 文件系统工具,如 `read_file``write_file``edit_file``execute`
- 外部 MCP 暴露的工具。
- C2 和 WebShell 相关 MCP 工具。
风险控制建议:
- 只启用当前任务需要的工具。
- 高风险命令工具不要加入全局白名单。
- 给角色绑定最小工具集合。
- 对 destructive、持久化、横向移动、凭证操作保持人工审批。
- 外部 MCP 尽量使用本地可信进程,远端 MCP 必须有认证和网络隔离。
## HITL
HITL 是工具调用前的审批层。常见模式:
- `human`:人工审批。
- `audit_agent`:审计 Agent 自动审批。
- `review_edit`:审计 Agent 可改参后放行。
建议策略:
- 新环境默认人工审批。
- 只把只读、低风险、稳定工具加入白名单。
- 扫描类工具按目标范围配置角色和提示词约束。
- 写入、删除、执行 payload、C2、WebShell、账号改动等操作必须谨慎审批。
详见 [HITL 最佳实践](hitl-best-practices.md)。
## 审计
平台审计由 `audit` 配置控制,记录登录、配置、资源管理等平台操作。它不记录完整对话正文,也不等同于取证日志。
工具执行记录由监控模块维护,保留时间由 `monitor.retention_days` 控制。
建议:
- 开启 `audit.enabled`
- 定期导出审计日志。
- 配置合理保留期。
- 对失败登录、配置变更、C2/WebShell 操作重点复核。
## C2 风险
内置 C2 会启动监听器、生成 payload、接收会话并执行任务。仅在明确授权的靶场、内网演练或红队环境中启用。
建议:
- 不使用时设置 `c2.enabled: false`
- 不在公网暴露 C2 监听端口,除非有明确授权和隔离。
- 对 payload 文件、回连地址、任务输出进行访问控制。
- C2 任务建议走 HITL。
## WebShell 风险
WebShell 管理允许对已登记连接执行命令和文件操作。建议:
- 只添加授权目标。
- 给连接使用清晰名称、标签和备注。
- 不在共享环境保存真实生产 WebShell。
- AI 使用 WebShell 前确认目标和命令。
- 清理失效或不再授权的连接。
## 数据与隐私
本地会保存:
- 对话和消息:`data/conversations.db`
- 知识库索引:`data/knowledge.db`
- WebShell、C2、漏洞、项目、任务等业务数据。
- 上传附件:`chat_uploads/`
建议:
- 限制文件权限。
- 备份加密。
- 不上传无授权的敏感数据。
- 清理不再需要的会话、附件、C2 输出和审计日志。
## 生产基线
最低建议:
- 强密码 + HTTPS + 内网访问。
- `audit.enabled: true`
- `mcp.auth_header_value` 设置随机值。
- 不需要时关闭 `c2.enabled`
- 外部 MCP 最小化启用。
- 高风险工具不进白名单。
- 定期备份和更新。
## 真实威胁模型
| 威胁 | 攻击路径 | 影响 | 防护点 |
| --- | --- | --- | --- |
| Web 密码泄露 | 登录管理面,调用终端/WebShell/C2 | 完整接管平台能力 | 强密码、HTTPS、内网、反向代理认证、审计 |
| Prompt Injection | 目标页面或文档诱导 Agent 调高权限工具 | 越权执行工具或泄露数据 | 角色边界、HITL、工具最小化、知识库来源标注 |
| 外部 MCP 恶意 | MCP 服务返回误导描述或执行副作用 | 本机或目标系统受影响 | 只接入可信 MCP、独立运行用户、网络隔离 |
| 工具 YAML 被篡改 | 改写命令模板或参数 | Agent 调用时执行恶意命令 | 文件权限、代码审查、工具白名单 |
| C2 滥用 | 生成 payload 或下发任务到非授权目标 | 法律和业务风险 | 默认关闭、审批、事件保留、网络隔离 |
| WebShell 误操作 | AI 或用户在生产目标执行破坏命令 | 业务中断或数据损坏 | 连接命名、人工确认、只读优先、删除过期连接 |
| 数据库泄露 | 复制 `data/*.db` 或上传目录 | 对话、目标、漏洞、连接信息泄露 | 文件权限、加密备份、最小保留 |
## 授权边界写法
每个高风险角色都应把授权边界写进提示词,而不是只依赖用户口头说明。示例:
```text
你只能在用户明确给出的目标范围内行动。若需要执行写入、删除、爆破、持久化、凭证访问、C2、WebShell 或横向移动相关操作,必须先说明目的、影响、目标和回滚方式,并等待 HITL 审批。
```
这段话不能代替技术控制,但能降低 Agent 在模糊任务中扩张行为边界的概率。
## HITL 不是万能保险
HITL 的风险在于审批者看到的是“工具名 + 参数 + 上下文摘要”,不是完整现实世界影响。下面几类情况要特别保守:
- 参数看似只读,但工具本身会触发大量请求或写缓存。
- 命令通过 `bash -c`、脚本、base64 包装隐藏真实动作。
- 外部 MCP 工具描述不可信。
- WebShell 目标名称模糊,无法确认是否生产环境。
- C2 payload 生成和分发链路不在平台内。
审计 Agent 适合筛掉普通低风险请求,不适合替代人类批准破坏性动作。
## 数据最小化原则
不要把这些内容长期留在平台里:
- 真实客户凭证。
- 未脱敏报告。
- 生产数据库导出。
- 长期有效 Cookie。
- 无关目标的扫描输出。
- 已结束项目的 WebShell/C2 会话。
建议按项目结束流程清理:附件、WebShell 连接、C2 payload、临时 workspace、长输出工具记录。
## 源码锚点
- 认证会话:`internal/security/auth_manager.go`
- 认证中间件:`internal/security/auth_middleware.go`
- 限流:`internal/security/ratelimit.go`
- Shell 执行:`internal/security/executor.go`
- HITL 执行:`internal/handler/hitl_execution.go`
- 审计服务:`internal/audit/service.go`
+180
View File
@@ -0,0 +1,180 @@
# Skills 指南
Skills 用于给 Agent 提供可按需加载的专题能力、流程说明、模板和参考资料。它适合承载稳定方法论,而不是一次性任务输入。
## 目录结构
默认目录:
```yaml
skills_dir: skills
```
推荐结构:
```text
skills/
api-security-testing/
SKILL.md
ssrf-testing/
SKILL.md
cyberstrike-eino-demo/
SKILL.md
REFERENCE.md
assets/
```
每个 Skill 至少包含 `SKILL.md`
## SKILL.md
`SKILL.md` 使用 YAML front matter
```markdown
---
name: ssrf-testing
description: SSRF 漏洞识别、验证、绕过和修复建议流程
---
# SSRF Testing
当任务涉及服务端请求伪造、URL 回调、云元数据访问或内网探测时使用本技能。
```
`description` 很重要,Agent 会根据它判断何时加载。
## 渐进式披露
Eino Skills 支持按需加载。配置:
```yaml
multi_agent:
eino_skills:
disable: false
filesystem_tools: true
skill_tool_name: skill
```
Agent 初始只看到技能名称和描述,真正需要时再调用 `skill` 读取详情,减少上下文占用。
## 适合写成 Skill 的内容
- 某类漏洞测试流程。
- 安全审计 checklist。
- 报告模板。
- 工具组合方法。
- 内部规范。
- 常见误报判断。
不适合:
- 临时目标信息。
- API Key、密码、Cookie。
- 经常变化的扫描结果。
- 大量无结构原始日志。
## 附属文件
Skill 可以带附属文件,如 `REFERENCE.md`、模板、字典或示例。`SKILL.md` 中应说明何时读取这些文件。
建议:
- 主文件保持短而清晰。
- 参考资料按主题拆分。
- 大文件只在必要时读取。
## 与角色绑定
角色可以提示 Agent 使用某类 Skill;Skill 也可以通过页面管理和角色形成绑定关系。建议:
- 通用技能保持不绑定,按描述自动触发。
- 高风险技能绑定到专用角色。
- 同类技能不要描述过度重叠。
## 开发建议
Skill 内容结构:
1. 触发场景。
2. 目标和边界。
3. 操作步骤。
4. 工具建议。
5. 输出格式。
6. 风险和禁止事项。
7. 参考资料。
写法要让 Agent 能执行,而不是只给人阅读。
## 排错
Skill 没被使用:
- `description` 过窄或过模糊。
- 任务没有触发关键词。
- `multi_agent.eino_skills.disable: true`
- Skill 文件 front matter 格式错误。
Skill 读取太多:
- 拆分附属文件。
-`SKILL.md` 中明确“只有在需要 X 时读取 Y”。
- 删除重复内容。
## Skill 设计深水区
Skill 的核心价值不是“让 Agent 知道一个概念”,而是让 Agent 在正确时机拿到一套可执行的程序。写 Skill 时要特别关注触发条件和退出条件。
推荐结构:
```markdown
## When to use
明确触发场景。
## Preconditions
需要用户提供什么、目标必须满足什么。
## Procedure
按步骤执行,每步说明工具、输入和判断标准。
## Stop conditions
什么情况下停止、升级审批或转人工。
## Output
最终结果格式。
```
## 反模式
| 反模式 | 后果 | 改法 |
| --- | --- | --- |
| 描述过泛:`用于安全测试` | 几乎所有任务都触发 | 写具体漏洞、场景、信号 |
| 内容像百科 | Agent 不知道下一步做什么 | 改成流程和决策树 |
| 把敏感配置写进 Skill | 泄露和误用 | 用运行时配置或用户输入 |
| 一个 Skill 装所有内容 | 读取成本高,召回混乱 | 按漏洞/任务拆分 |
| 没有停止条件 | Agent 可能持续扩大范围 | 写明何时停止和审批 |
## Skill 与知识库的区别
- Skill:指导 Agent 怎么做,强调流程。
- 知识库:提供事实、案例和参考,强调检索。
例如 SSRF
- Skill 写“如何测试 SSRF、如何判定、何时停止”。
- 知识库写“云厂商 metadata 地址、历史绕过、修复方案”。
## 本地文件工具风险
`filesystem_tools: true` 会暴露读写和执行能力。它对开发和自动化很有用,但也是安全边界。生产环境建议:
- 配合 `workspace_root_dir` 限制工作目录。
- 对写入和执行动作使用 HITL。
- 不把 `execute` 加入全局白名单。
- Skill 中明确禁止读写授权范围外文件。
## 源码锚点
- Skill 包校验:`internal/skillpackage/validate.go`
- Skill 服务:`internal/skillpackage/service.go`
- Eino Skills 接入:`internal/multiagent/eino_skills.go`
- Skills Handler`internal/handler/skills.go`
+191
View File
@@ -0,0 +1,191 @@
# 测试指南
CyberStrikeAI 的测试包括 Go 单测、配置验证、API 手测、MCP 工具验证和前端冒烟测试。
## Go 单测
运行全部内部测试:
```bash
go test ./internal/...
```
运行指定包:
```bash
go test ./internal/workflow
go test ./internal/multiagent
go test ./internal/handler
```
常见重点包:
- `internal/security`
- `internal/mcp`
- `internal/multiagent`
- `internal/workflow`
- `internal/knowledge`
- `internal/project`
- `internal/handler`
- `internal/c2`
## 构建测试
```bash
go build -o cyberstrike-ai ./cmd/server
```
构建通过不代表功能正确,但能发现入口、依赖和静态类型问题。
## 配置验证
启动前检查:
- YAML 缩进。
- 模型配置。
- 数据库路径可写。
- `tools_dir``roles_dir``skills_dir``agents_dir` 是否存在。
- HTTPS 证书路径是否正确。
启动后在 Web 设置页测试:
- OpenAI 兼容模型。
- 视觉模型。
- 工具列表。
- 外部 MCP 状态。
## API 手测
访问:
```text
/api-docs
```
重点验证:
- 登录。
- `/api/eino-agent/stream`
- `/api/config`
- `/api/config/tools`
- `/api/knowledge/search`
- `/api/monitor`
流式接口经过反向代理时要验证输出是否实时。
## 工具测试
新增或修改 `tools/*.yaml` 后:
- 在工具列表中确认 schema。
- 用低风险参数执行。
- 检查错误输出是否可读。
- 检查超时是否生效。
- 检查 HITL 是否按预期拦截。
不要用生产目标测试新工具。
## MCP 测试
外部 MCP
- stdio:先在终端独立运行命令。
- HTTP/SSE:用 curl 检查连通性。
- Web 页面启动后检查 `/api/external-mcp/stats`
- 在对话中确认工具是否可被 `tool_search` 找到。
## 知识库测试
步骤:
1. 放入小型 Markdown 文档。
2. 扫描知识库。
3. 重建索引。
4. 搜索文档中的关键词和同义表达。
5. 查看检索日志。
如果使用真实 embedding API,注意配额和速率限制。
## 前端冒烟
修改前端后至少验证:
- 登录和退出。
- 侧边栏对话列表。
- 新建对话和流式回复。
- 设置页面保存。
- 相关业务页面增删改查。
- 中英文切换。
- 浏览器控制台无明显错误。
## 高风险模块测试
C2、WebShell、终端、批量任务只能在授权测试环境验证。测试前确认:
- 目标是本机、靶机或演练环境。
- 命令无破坏性。
- HITL 策略符合预期。
- 测试后清理会话、payload、上传文件和任务结果。
## 测试金字塔
建议测试分层:
| 层级 | 目标 | 示例 |
| --- | --- | --- |
| 单元测试 | 纯逻辑正确 | 表达式、chunk、脱敏、超时格式 |
| Handler 测试 | HTTP 行为 | 参数校验、状态码、权限 |
| 集成测试 | 多模块协作 | 外部 MCP、知识库索引、HITL |
| 冒烟测试 | 用户路径可用 | 登录、对话、工具、设置 |
| 授权靶场测试 | 高风险能力安全 | C2、WebShell、终端 |
不要用端到端手测代替单元测试,也不要用单元测试代替高风险靶场验证。
## 回归测试重点
修改这些模块时必须扩大测试范围:
- `internal/handler/config.go`:测模型、知识库、MCP、C2、机器人配置应用。
- `internal/multiagent/`:测流式、工具调用、摘要、重试、HITL。
- `internal/security/`:测认证、Shell、超时、无输出。
- `internal/database/`:测旧数据兼容。
- `web/static/js/chat.js`:测对话、过程详情、攻击链、分组。
## 测试数据管理
不要用真实客户数据做测试。建议准备:
- 小型 Markdown 知识库样例。
- 本地假 MCP Server。
- 本地可控 HTTP 目标。
- 无害 WebShell 模拟端。
- 临时 SQLite 数据库。
测试完成后删除临时数据库和上传文件,避免污染开发环境。
## 失败用例比成功用例更重要
至少覆盖:
- 模型 API 401/429/500。
- MCP 进程启动失败。
- 工具超时。
- HITL 拒绝。
- 知识库索引中断。
- 数据库不可写。
- WebShell 目标返回非 200。
- C2 关闭时访问接口。
这些才是用户真实会遇到的问题。
## 源码锚点
已有测试集中在:
- `internal/handler/*_test.go`
- `internal/multiagent/*_test.go`
- `internal/workflow/*_test.go`
- `internal/knowledge/*_test.go`
- `internal/security/*_test.go`
- `internal/mcp/*_test.go`
- `internal/c2/*_test.go`
+224
View File
@@ -0,0 +1,224 @@
# 排错指南
本文按现象列出常见问题。优先查看服务日志、浏览器控制台和 `/api-docs` 中的接口响应。
## 无法访问页面
检查:
- 服务是否启动。
- 端口是否被占用。
- 配置中是否启用 HTTPS。
- 访问协议是否正确。
默认配置常见地址:
```text
https://127.0.0.1:8080/
```
如果使用自签证书,浏览器会提示不受信任,需要手动继续访问。
## 登录失败
检查:
- `config.yaml` 中的 `auth.password`
- 是否修改后未重启或未应用配置。
- 浏览器 Cookie 是否异常,可尝试无痕窗口。
- 审计日志中是否有登录失败节流。
生产环境忘记密码时,需要在服务器上修改 `config.yaml` 并重启服务。
## 模型无响应
检查:
- `openai.base_url` 是否包含正确路径,如 `/v1`
- `openai.api_key` 是否有效。
- `openai.model` 是否存在。
- 服务商是否支持当前 `reasoning` 字段。
可在系统设置中使用模型测试。若网关报 400,先尝试:
```yaml
openai:
reasoning:
mode: off
```
## 流式输出中断
常见原因:
- 反向代理缓冲 SSE。
- 模型网关超时。
- 浏览器网络断开。
- 上下文过大。
Nginx 需要:
```nginx
proxy_buffering off;
proxy_http_version 1.1;
```
## 工具执行失败
检查:
- 工具命令是否已安装到 PATH。
- `tools/*.yaml` 参数 schema 是否正确。
- 是否被 HITL 拒绝。
- 是否超过 `agent.tool_timeout_minutes`
- Shell 长时间无输出是否触发 `shell_no_output_timeout_seconds`
工具配置可参考 `tools/README.md`
## MCP 连不上
内置 MCP
- 检查 `mcp.enabled`
- 检查 `mcp.port`
- 检查 `auth_header``auth_header_value`
外部 MCP
- stdio:检查命令路径、工作目录、环境变量。
- HTTP/SSE:检查 URL、认证、网络连通性。
- 查看 `/api/external-mcp/stats`
## 知识库不可用
检查:
- `knowledge.enabled: true`
- embedding 配置是否正确。
- 是否已经扫描并重建索引。
- `data/knowledge.db` 是否可写。
- 嵌入服务是否 429 或超时。
如果索引大量失败,降低:
```yaml
knowledge:
indexing:
batch_size: 5
rate_limit_delay_ms: 600
```
## 机器人没有回复
检查:
- 对应平台 `robots.<platform>.enabled`
- 平台回调 URL 是否指向 `/api/robot/...`
- Token、secret、verify_token 是否一致。
- 服务器是否可被平台访问。
- 群聊是否需要 @ 机器人。
详细步骤见 [机器人使用说明](robot.md)。
## C2 监听器启动失败
检查:
- `c2.enabled`
- 端口是否被占用。
- 防火墙或安全组。
- 是否需要管理员权限绑定低端口。
关闭 C2 后 `/api/c2/*` 返回 503 是预期行为。
## WebShell 命令乱码
处理:
- 确认目标系统编码。
- 尝试更短命令。
- 使用 base64 包装输出。
- Windows 目标检查代码页。
## 数据库锁或写入失败
检查:
- `data/` 是否可写。
- 是否多个实例共用同一个 SQLite 文件。
- 磁盘是否满。
- 是否异常复制了 WAL/SHM 文件。
生产环境不要让多个进程同时写同一份 SQLite 数据库。
## 前端页面异常
检查:
- 浏览器控制台错误。
- 静态资源是否加载成功。
- 修改前端后是否刷新缓存。
- i18n key 是否缺失。
接口异常时打开 `/api-docs` 对照请求体。
## 诊断顺序
遇到问题时不要直接改配置,先定位层级:
1. 进程:服务是否还在,日志是否有 panic。
2. 网络:端口、HTTPS、反向代理、浏览器控制台。
3. 认证:`/api/auth/validate` 是否 200。
4. 配置:`/api/config` 是否能读,应用后是否报错。
5. 模型:模型测试是否通过。
6. 工具:工具列表和单个 schema 是否正常。
7. 数据库:`data/` 是否可写,有无锁。
8. 业务模块:知识库、MCP、C2、WebShell 分别测最小动作。
先定位层级,再改参数。否则容易把一个代理问题误判成模型问题。
## 最小诊断命令
```bash
# 进程和端口
lsof -i :8080
# 本机 HTTPS 是否通
curl -k -I https://127.0.0.1:8080/
# 静态资源是否通
curl -k -I https://127.0.0.1:8080/static/logo.png
# 查看数据库文件
ls -lh data/
```
如果经过 Nginx,再分别测代理地址和回源地址,确认问题在哪一层。
## 常见误判
- “模型坏了”:实际是 HITL 挂起等待审批。
- “工具没加载”:实际是 tool_search 隐藏了大部分工具。
- “知识库没效果”:实际是索引没重建或 risk_type 过滤过窄。
- “C2 接口坏了”:实际是 `c2.enabled: false`,返回 503 是正常保护。
- “配置保存了但没生效”:实际是监听端口/TLS 需要重启。
- “机器人不回复”:实际是平台侧没有正确配置回调 URL 或验签参数。
## 故障报告模板
提交问题时建议附:
```text
版本/提交:
启动方式:
访问方式:http/https/反向代理:
相关配置段:
复现步骤:
预期结果:
实际结果:
服务端日志:
浏览器控制台:
相关接口响应:
```
有了这些信息,定位速度通常会快很多。
+176
View File
@@ -0,0 +1,176 @@
# WebShell 管理
WebShell 管理用于保存授权目标的 WebShell 连接,并通过 Web 页面或 Agent 工具执行命令、文件操作和上下文分析。
## 基本流程
1. 在 WebShell 页面新增连接。
2. 填写名称、URL、密码或请求参数。
3. 测试连接。
4. 执行命令或文件操作。
5. 在对话中选择 WebShell 连接,让 AI 基于该连接辅助排查。
连接数据保存在 SQLite 中。
## 接口
主要 API
- `GET /api/webshell/connections`
- `POST /api/webshell/connections`
- `PUT /api/webshell/connections/:id`
- `DELETE /api/webshell/connections/:id`
- `GET /api/webshell/connections/:id/state`
- `PUT /api/webshell/connections/:id/state`
- `POST /api/webshell/exec`
- `POST /api/webshell/file`
- `GET /api/webshell/connections/:id/ai-history`
- `GET /api/webshell/connections/:id/ai-conversations`
## MCP 工具
系统会注册 WebShell MCP 工具,例如:
- `webshell_exec`:在连接上执行命令。
- `webshell_file_list`:列目录。
- `webshell_file_read`:读取文件。
- `webshell_file_write`:写文件。
- WebShell 连接管理工具。
Agent 使用这些工具时需要 `connection_id`。前端通常会把当前选中的连接注入上下文。
## 命令执行
执行命令前确认:
- 当前连接属于授权目标。
- 命令不会破坏业务。
- 输出中可能包含敏感信息。
- 长命令和交互式命令不适合 WebShell 通道。
建议先执行只读命令确认环境:
```bash
whoami
pwd
uname -a
id
```
Windows 目标可用:
```cmd
whoami
cd
ver
ipconfig
```
## 文件操作
文件操作包括列目录、读取、写入。建议:
- 写入前先备份原文件。
- 不在生产目标写入未经确认的脚本或二进制。
- 大文件优先通过专用下载/上传通道处理。
- 注意目标编码和换行符。
## AI 辅助
AI 可以帮助:
- 识别操作系统和当前权限。
- 规划只读枚举步骤。
- 分析命令输出。
- 汇总风险和修复建议。
不建议让 AI 自动执行:
- 删除文件。
- 修改业务配置。
- 持久化。
- 凭证抓取。
- 大范围扫描内网。
这些操作应由人工确认,并配合 HITL。
## 安全建议
- 仅保存授权目标连接。
- 给连接命名时包含项目、环境、目标。
- 演练结束后删除连接。
- 不把 WebShell 写入工具加入全局免审批白名单。
- 重要输出及时纳入项目事实或报告,随后清理敏感原始数据。
## 排错
连接失败:
- URL 不可达。
- 参数名或密码错误。
- 目标 WAF 拦截。
- 代理或 TLS 配置异常。
命令乱码:
- 检查目标系统编码。
- 尝试切换命令输出编码或使用 base64 包装。
AI 找不到连接:
- 确认前端已选中 WebShell 连接。
- 确认连接未被删除。
- 检查 `connection_id` 是否正确。
## 操作分层
WebShell 操作建议分成四层,不同层级使用不同审批策略:
| 层级 | 操作 | 风险 | 建议 |
| --- | --- | --- | --- |
| 识别 | `whoami``pwd`、系统版本 | 低 | 可自动 |
| 枚举 | 目录、进程、环境变量 | 中 | 限定路径和命令 |
| 读取 | 配置、日志、源码 | 中高 | 人工确认敏感性 |
| 写入/执行 | 写文件、运行脚本、删除 | 高 | 人工审批,说明回滚 |
不要把“WebShell 已经拿到了”理解成“后续操作都低风险”。WebShell 通常位于业务系统内部,误操作成本很高。
## 连接命名规范
建议命名:
```text
<项目>-<环境>-<目标>-<权限>-<日期>
```
示例:
```text
acme-staging-web01-www-20260707
```
糟糕命名:
```text
test
shell1
客户机器
```
AI 和人类审批都依赖上下文,连接名称含糊会直接放大误操作概率。
## AI 使用约束模板
给 WebShell 相关角色加一段约束:
```text
使用 WebShell 前先确认 connection_id、目标名称、当前目录和权限。默认只执行只读命令。任何写入、删除、上传、权限修改、持久化、凭证读取、内网探测都必须先给出目的、影响和回滚方式,并等待审批。
```
## 源码锚点
- Handler`internal/handler/webshell.go`
- 连接上下文:`internal/handler/webshell_context.go`
- 探测逻辑:`internal/handler/webshell_probe.go`
- OS/编码处理测试:`internal/handler/webshell_os_test.go``internal/handler/webshell_encoding_test.go`
- MCP 工具注册:`internal/app/app.go``registerWebshellTools`
+553
View File
@@ -0,0 +1,553 @@
# CyberStrikeAI 图编排使用说明
[English](../en-US/workflow-graph.md)
本文档说明 **图编排(Graph Orchestration** 的完整使用方式:如何在画布上搭建流程、配置各类型节点、在节点之间传递数据,以及如何将流程绑定到角色并自动运行。
---
## 一、在哪里使用图编排
1. 登录 CyberStrikeAI Web 端
2. 左侧导航进入 **图编排**
3. 在左侧列表选择已有流程,或新建流程
4. 在中央画布拖拽、连线、配置节点
5. 填写流程 **ID**、**名称**、**描述** 后点击 **保存**
保存后的流程可在 **角色管理** 中绑定到某个角色。绑定后,用户与该角色对话时会按流程图自动执行(`workflow_policy: auto`)。
---
## 二、画布基本操作
| 操作 | 说明 |
|------|------|
| 添加节点 | 点击画布上方节点类型按钮(开始、工具、Agent、条件、审批、输出、结束) |
| 连线 | 点击 **连线**,依次点击源节点和目标节点;再次点击 **连线** 退出连线模式 |
| 选中元素 | 单击节点或连线,右侧显示 **节点属性** |
| 删除选中 | 点击 **删除选中** 删除当前节点或连线 |
| 自动布局 | 点击 **自动布局** 整理节点位置 |
| 试运行 | 点击 **试运行** 使用安全 dry-run 验证数据流;工具、Agent、审批不会真实执行 |
| 删除流程 | 点击 **删除** 删除整个流程定义 |
**硬性规则:** 每个流程至少包含 **1 个开始节点****1 个输出节点**;开始节点不能有入边,输出 / 结束节点不能有出边。保存时前端和后端都会执行严格校验。
---
## 三、执行模型(先理解再配置)
图编排按 **有向图** 执行,引擎从 **开始** 节点出发,沿连线依次运行下游节点。
每次运行会维护一份内部状态,模板变量 `{{...}}` 从这里取值:
| 内部状态 | 模板前缀 | 含义 |
|----------|----------|------|
| `inputs` | `{{inputs.xxx}}` | 流程启动时的输入(用户消息、会话 ID 等) |
| `lastOutput` | `{{previous.xxx}}` | **上一个刚执行完** 的节点的输出 |
| `outputs` | `{{outputs.xxx}}` | 全局 **命名变量池**(由节点的「输出变量名」写入) |
| `nodeOutputs` | `{{节点ID.xxx}}` | 指定节点 ID 的完整输出对象 |
| `metrics` | 运行详情中查看 | 节点耗时、工具调用数、可收集到的 token / cost 等指标 |
### 3.1 `previous` 是什么?
`{{previous.output}}` 表示 **紧邻的上一个执行节点**`output` 字段。
- 每执行完一个节点,引擎都会更新 `lastOutput`
- **不是**「画布上画线的上游」,而是 **实际执行顺序上的上一步**
示例:
```text
开始 → Agent A → Agent B
```
Agent B 的 `{{previous.output}}` = Agent A 的输出。
但若中间有条件节点:
```text
开始 → Agent A → 条件 → Agent B
```
Agent B 的 `{{previous.output}}` = **条件节点** 的输出(`true` / `false`),**不是** Agent A 的结果。
如果一个节点有 **多个上游节点** 同时连入,`previous` 会先按该节点的 **汇聚策略** 生成:
| 汇聚策略 | 含义 | 适合场景 |
|----------|------|----------|
| `all_merge` | 合并所有上游输出,`previous.output` 为数组 | 默认推荐,综合多路结果 |
| `last_by_canvas` | 按画布顺序取最后一个上游输出 | 明确只采用一路结果 |
| `first_non_empty` | 取第一个非空输出 | 多路兜底 |
| `fail_fast` | 任一上游失败则中止当前节点 | 关键链路、审批前置、安全检查 |
### 3.2 `outputs` 是什么?
`outputs` 是引擎在运行过程中维护的 **命名变量注册表**
当 Agent、工具、输出 等节点配置了 **输出变量名**(字段 `output_key`)后,节点执行成功会把结果写入:
```text
outputs["你填的变量名"] = 节点输出内容
```
之后 **任意下游节点** 都可以通过 `{{outputs.变量名}}` 引用,不要求两个节点直接相连。
示例:
- Agent A 的 **输出变量名**`agent_result1`
- Agent B 的 **输入来源**`{{outputs.agent_result1}}`
即使 A 和 B 之间隔着条件节点,B 仍能拿到 A 的输出。
### 3.3 什么时候用 `previous`,什么时候用 `outputs`
| 场景 | 推荐写法 |
|------|----------|
| 两个节点 **直连**,只取上一步结果 | `{{previous.output}}` |
| 中间有其他节点(条件、工具、审批等) | `{{outputs.变量名}}` |
| 需要引用 **更早** 的某个节点结果 | `{{outputs.变量名}}``{{节点ID.output}}` |
| 条件判断要基于某 Agent 的输出 | `{{outputs.变量名}} != ""` |
| 读取用户最初输入 | `{{inputs.message}}` |
**记忆口诀:**
- `previous` = 上一步(链式、紧邻)
- `outputs` = 按名字取(跨节点、可回溯)
---
## 四、模板语法
### 4.1 基本格式
```text
{{变量路径}}
```
支持字母、数字、下划线、点、连字符,例如:
```text
{{previous.output}}
{{outputs.agent_result1}}
{{inputs.message}}
{{inputs.conversationId}}
{{previous.matched}}
{{node-abc123.output}}
```
### 4.2 可用路径一览
| 路径 | 说明 |
|------|------|
| `{{inputs.message}}` | 用户消息(开始节点输入) |
| `{{inputs.conversationId}}` | 会话 ID |
| `{{inputs.projectId}}` | 项目 ID |
| `{{previous.output}}` | 上一节点主输出 |
| `{{previous.matched}}` | 上一条件节点的匹配结果(`true` / `false` |
| `{{outputs.变量名}}` | 某节点注册过的命名输出 |
| `{{节点ID.output}}` | 指定节点 ID 的 `output` 字段 |
| `{{previous.kind}}` | 上一节点输出类型,如 `agent` / `tool` / `condition` |
| `{{previous.status}}` | 上一节点状态,如 `completed` / `failed` / `simulated` |
节点输出会保留兼容字段(如 `output``matched`),同时带有结构化字段:
```json
{
"kind": "agent",
"node_id": "node-2",
"node_type": "agent",
"status": "completed",
"output": "..."
}
```
### 4.3 条件表达式
条件节点和连线条件支持比较、文本匹配、正则、逻辑组合与安全 JSONPath/JQ 路径读取:
```text
{{outputs.agent_result1}} != ""
{{previous.output}} == "ok"
{{outputs.count}} >= 100
{{previous.output}} contains "success"
{{previous.output}} matches "^ok"
{{outputs.risk_score}} >= 8 && {{previous.output}} != ""
jsonpath({{previous.output}}, "$.status") == "ok"
jq({{outputs.scan}}, ".severity") == "high"
```
规则:
- 支持 `==``!=``>``>=``<``<=`
- 支持 `contains` 子串匹配与 `matches` 正则匹配
- 支持简单 `&&` / `||`
- 支持 `jsonpath(value, "$.path")``jq(value, ".path")` 的**安全路径子集**,仅做字段读取,不执行任意脚本
- 比较两侧会自动去掉首尾空格和引号
- 无比较符时,非空且不为 `false` / `0` / `null` 视为真
- 保存时会静态校验表达式格式、JSONPath/JQ 路径和正则语法
### 4.4 嵌套字段绑定
节点的字段绑定除 `output``message` 等普通字段外,也支持 JSONPath/JQ 风格路径:
| 绑定配置 | 含义 |
|----------|------|
| `from=previous, field=$.status` | 从上一节点输出对象读取 `status` |
| `from=outputs, field=$.scan.severity` | 从命名输出中读取嵌套字段 |
| `from=node-1, field=.output.items[0]` | 从指定节点输出读取数组元素 |
---
## 五、节点类型与配置
### 5.1 开始(start
流程入口,将用户输入注入 `inputs`
| 字段 | 说明 | 默认值 |
|------|------|--------|
| 输入变量 | 逗号分隔的输入键名 | `message, conversationId, projectId` |
开始节点输出包含:`output``message``conversationId``projectId`
### 5.2 Agentagent
调用大模型 Agent 处理任务,支持多种运行模式。
| 字段 | 说明 | 默认值 |
|------|------|--------|
| Agent 模式 | `eino_single` / `deep` / `plan_execute` / `supervisor` | `eino_single` |
| 输入来源 | 上游数据的模板表达式 | `{{previous.output}}` |
| 节点指令 | 本节点要完成的任务描述 | 空 |
| 输出变量名 | 写入 `outputs` 的键名 | `agent_result` |
| 汇聚策略 | 多上游进入本节点时如何生成 `previous` | `all_merge` |
**消息拼装规则:**
- 仅填 **节点指令**:直接把指令发给 Agent
- 仅填 **输入来源**:生成「请基于上游节点输出继续处理:…」
- 两者都填:合并为「上游输入 + 节点指令」
Agent 节点执行后:
- `previous.output` 更新为本节点响应文本
- 若配置了 **输出变量名**,同时写入 `outputs[输出变量名]`
- Agent 子图在 Eino 中拆为 `prepare → execute → finalize`,便于 trace 与后续局部 checkpoint
### 5.3 工具(tool
调用已启用的 MCP 工具。
| 字段 | 说明 | 默认值 |
|------|------|--------|
| MCP 工具 | 工具名称(必填) | — |
| 参数模板 | JSON,支持 `{{...}}` 模板 | `{}` |
| 超时秒数 | 可选 | 空 |
| 汇聚策略 | 多上游进入本节点时如何生成 `previous` | `all_merge` |
示例参数模板:
```json
{"target": "{{inputs.message}}", "port": "443"}
```
若配置了 **输出变量名**,工具返回结果会写入 `outputs`
### 5.4 条件(condition
根据表达式计算分支,输出 `matched``true` / `false`)。
| 字段 | 说明 | 默认值 |
|------|------|--------|
| 条件表达式 | 支持 `{{...}}``==` / `!=` | `{{previous.output}} != ""` |
| 汇聚策略 | 多上游进入本节点时如何生成 `previous` | `all_merge` |
**分支规则:**
- 从条件节点连出的 **第一条线** 默认为 **「是」** 分支(`matched == true`
- **第二条线** 默认为 **「否」** 分支(`matched == false`
- 连线标签可写 `是` / `否`(或 `yes` / `no``true` / `false`)辅助识别
- 第三条及以后的出边需在 **连线条件** 中自定义表达式
连线条件示例(选中连线后在右侧配置):
```text
{{previous.matched}} == "true"
{{previous.matched}} == "false"
```
### 5.5 审批(hitl
人工确认检查点。流程运行到该节点前会通过 Eino interrupt/checkpoint 暂停,等待 API 或监控面板审批后恢复。
| 字段 | 说明 | 默认值 |
|------|------|--------|
| 审批提示 | 支持模板 | `请审批该步骤是否继续执行` |
| 提示字段绑定 | 留空审批提示时,从绑定字段读取说明 | `previous.output` |
| 审批方 | `human` / `audit_agent` | `human` |
| 汇聚策略 | 多上游进入本节点时如何生成 `previous` | `all_merge` |
HITL 等待信息会记录:
- `checkpointId`
- interrupt `beforeNodes`
- resume target / address / path
- resume payload schema`approved``comment`
### 5.6 输出(output
将流程最终结果写入 `outputs`,供结束摘要和对话展示使用。
| 字段 | 说明 | 默认值 |
|------|------|--------|
| 输出变量名 | 必填,最终结果的键名 | `result` |
| 变量来源 | 模板表达式,决定写入的值 | `{{previous.output}}` |
| 固定输出值 | 可选,填写后覆盖变量来源 | 空 |
| 汇聚策略 | 多上游进入本节点时如何生成 `previous` | `all_merge` |
**注意:** 输出节点是流程的「出口」,不应再有出边。
### 5.7 结束(end
可选节点,用于生成结束摘要模板(角色绑定流程中较少单独使用)。
| 字段 | 说明 | 默认值 |
|------|------|--------|
| 结束摘要模板 | 支持 `{{outputs.xxx}}` | `{{outputs.result}}` |
| 汇聚策略 | 多上游进入本节点时如何生成 `previous` | `all_merge` |
---
## 六、连线配置
选中 **连线** 后,右侧可配置 **连线条件**
| 场景 | 示例 |
|------|------|
| 普通节点后的过滤 | `{{previous.output}} == "ok"` |
| 条件节点「是」分支 | `{{previous.matched}} == "true"` |
| 条件节点「否」分支 | `{{previous.matched}} == "false"` |
若不填连线条件:
- 非条件节点:连线始终放行
- 条件节点:按出边顺序自动分配是/否分支
---
## 七、完整示例:跨条件节点传递 Agent 输出
### 7.1 流程结构
```text
开始 → Agent(生成初始值)→ 条件 → Agent(加工)→ 输出
↘ 否 → 输出
```
### 7.2 节点配置
**Agent 1(第一个 Agent**
| 字段 | 值 |
|------|-----|
| 节点指令 | 只输出 `123333333` |
| 输出变量名 | `agent_result1` |
**条件**
| 字段 | 值 |
|------|-----|
| 条件表达式 | `{{outputs.agent_result1}} != ""` |
**Agent 2(第二个 Agent**
| 字段 | 值 |
|------|-----|
| 输入来源 | `{{outputs.agent_result1}}` |
| 节点指令 | 在输入基础上加 100,然后输出 |
| 输出变量名 | `agent_result` |
**输出**
| 字段 | 值 |
|------|-----|
| 输出变量名 | `result` |
| 变量来源 | `{{outputs.agent_result}}` |
### 7.3 常见错误
| 错误配置 | 原因 |
|----------|------|
| Agent 2 输入来源写 `{{previous.output}}` | `previous` 指向条件节点,得到的是 `true`/`false`,不是 Agent 1 的文本 |
| 未给 Agent 1 填输出变量名 | `outputs.agent_result1` 不存在,下游取到空值 |
| 条件表达式写 `{{previous.output}}` | 判断的是开始节点或上一节点的输出,而非 Agent 1 的命名变量 |
---
## 八、绑定角色并运行
### 8.1 在角色管理中绑定
1. 进入 **角色管理**,编辑或新建角色
2. 选择 **工作流 / 图编排** 绑定的流程 ID
3. 策略设为 `auto`(默认:有 `workflow_id` 时自动执行)
4. 保存角色
也可在角色 YAML 中直接配置:
```yaml
name: 工作流测试
workflow_id: "1233"
workflow_version: latest
workflow_policy: auto
```
### 8.2 运行效果
用户选择该角色并发送消息后:
1. 引擎加载对应 `graph_json` 并按图执行
2. 对话页可看到 `workflow_start``workflow_node_start`、Agent 推理等进度事件
3. 流程结束后返回摘要,列出 `outputs` 中所有命名输出
若未配置输出节点或条件未命中,`outputs` 可能为空,摘要会提示检查输出节点与分支。
---
## 九、调试、试运行与复盘
### 9.1 安全试运行(dry-run
画布工具栏点击 **试运行**,输入一条测试消息即可模拟执行流程。
dry-run 的安全边界:
- `start` / `condition` / `output` / `end` 会按真实逻辑计算
- `tool` 不会真实调用 MCP,只返回 `[dry-run] tool call skipped`
- `agent` 不会真实调用模型,只返回 `[dry-run] agent execution skipped`
- `hitl` 不会暂停,只模拟通过
相关 API
```http
POST /api/workflows/dry-run
```
请求体:
```json
{
"graph": { "nodes": [], "edges": [], "config": {} },
"inputs": { "message": "ping" }
}
```
响应包含:
- `outputs`
- `nodeOutputs`
- `trace`
- `metrics`
- `replayScript`
### 9.2 运行详情与 replay
运行后可查询完整节点执行轨迹:
```http
GET /api/workflows/runs/{runId}
```
返回 `run``nodeRuns`,每个节点记录包含:
- input 快照
- output 快照
- status / error
- started_at / finished_at
- `duration_ms`
复盘接口:
```http
GET /api/workflows/runs/{runId}/replay
```
该接口只根据已保存的 `nodeRuns` 生成步骤,不会重新执行工具或 Agent。
### 9.3 指标(metrics
工作流会尽量累计:
- `node_count`
- `duration_ms`
- `tool_call_count`
- Agent progress 中可收集到的 `prompt_tokens` / `completion_tokens` / `total_tokens` / `cost`
token 与成本是否存在取决于底层模型/Agent 事件是否上报 usage。
---
## 十、保存前校验规则
保存时系统会自动检查:
| 规则 | 说明 |
|------|------|
| 必须有开始节点 | 至少 1 个 `start` |
| 必须有输出节点 | 至少 1 个 `output`,且填写输出变量名 |
| 连线合法 | 源/目标节点存在,不能自环 |
| 开始节点无入边 | 开始节点不能被指向 |
| 输出 / 结束节点无出边 | 输出 / 结束节点后不应再连线 |
| 非开始节点必须有入边 | 避免孤岛节点 |
| 非输出 / 结束节点必须有出边 | 避免执行到死路 |
| 无环路 | Workflow 编排必须是 DAG |
| 可达性 | 所有节点必须能从开始节点到达,并能最终到达 output/end |
| 工具节点 | 必须选择 MCP 工具;参数 JSON 必须合法;超时必须为正整数 |
| Agent 节点 | 必须填写节点指令或输入绑定;必须填写输出变量名 |
| 条件节点 | 必须填写表达式;需要 1~2 条出边;分支必须标记是/否且不能重复 |
| 连线条件 | 表达式、正则、JSONPath/JQ 路径必须通过静态校验 |
| 汇聚策略 | 必须是 `all_merge` / `last_by_canvas` / `first_non_empty` / `fail_fast` |
---
## 十一、排错指南
| 现象 | 可能原因 | 处理建议 |
|------|----------|----------|
| 下游拿到空值 | 上游未配置输出变量名 | 给上游 Agent/工具填 **输出变量名**,下游用 `{{outputs.xxx}}` |
| 下游拿到 `true`/`false` | 误用 `{{previous.output}}`,上一步是条件节点 | 改用 `{{outputs.xxx}}` |
| 条件总走「否」 | 表达式与真实输出格式不一致 | 检查 Agent 输出是否带引号、换行;用 `!= ""` 先验证 |
| 流程无最终输出 | 未命中输出节点所在分支 | 检查条件分支连线;确保至少一条路径到达 **输出** 节点 |
| 角色对话未跑流程 | 角色未绑定或未启用 | 确认 `workflow_id``workflow_policy: auto`、流程 `enabled: true` |
| 工具节点失败 | 参数 JSON 不合法或工具未启用 | 检查参数模板;在 MCP 中启用对应工具 |
| 保存失败提示分支非法 | 条件节点出边未标记是/否或重复 | 选中连线,设置条件分支为 `true``false` |
| 多上游结果不符合预期 | 汇聚策略不合适 | 根据场景改为 `all_merge` / `first_non_empty` / `last_by_canvas` / `fail_fast` |
| 嵌套字段取不到 | JSONPath/JQ 路径不符合安全子集 | 使用 `$.a.b[0]``.a.b[0]`,不要用通配符/递归/表达式 |
---
## 十二、最佳实践
1. **命名规范**:为每个需要被引用的节点设置有意义的输出变量名,如 `scan_result``parsed_targets`,避免都叫 `agent_result`
2. **跨节点传参优先用 `outputs`**:只要中间可能插入条件、工具、审批节点,就应用命名变量。
3. **`previous` 仅用于直连**:A → B 且无中间节点时,`{{previous.output}}` 最简洁。
4. **条件判断引用源数据**:判断 Agent 输出时用 `{{outputs.xxx}}`,不要用 `{{previous.output}}`(除非条件紧跟在目标 Agent 之后)。
5. **每条路径都要有出口**:确保「是」「否」分支最终都能到达 **输出** 节点(或你期望的终点)。
6. **多上游节点显式选择汇聚策略**:综合结果用 `all_merge`,兜底用 `first_non_empty`,关键链路用 `fail_fast`
7. **嵌套 JSON 用 JSONPath/JQ 安全路径**:例如 `jsonpath({{previous.output}}, "$.status") == "ok"`
8. **保存前先 dry-run**:用简单消息验证数据传递和分支,再绑定角色真实执行。
---
## 十三、相关代码位置(开发者参考)
| 模块 | 路径 |
|------|------|
| 执行引擎 | `internal/workflow/runner.go` |
| Eino 编译 / checkpoint / HITL | `internal/workflow/eino_compile.go` |
| 图校验 | `internal/workflow/validation.go` |
| 表达式 / JSONPath / 汇聚 | `internal/workflow/expression.go``jsonpath.go``join.go` |
| dry-run / replay 数据 | `internal/workflow/dry_run.go``internal/handler/workflow_run.go` |
| 画布前端 | `web/static/js/workflows.js` |
| 流程 API | `internal/handler/workflow.go` |
| 角色绑定 | `internal/config/config.go``workflow_id` 字段) |