pipeline-service/README.md

133 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# pipeline_service
产线执行引擎 —— 任务调度、步骤执行、人工任务交互、LLM 桥接。
## 功能
- **任务执行**DAG 步骤调度与状态机
- **人工任务**:审批/输入等待与交互
- **LLM 桥接**:统一 LLM 调用接口
- **Agent Loop**AI Agent 多轮任务执行
- **意图分类**:自然语言意图识别
- **产物管理**:步骤输入输出存储
## 数据表
| 表 | 说明 |
|---|------|
| pipeline_tasks | 任务实例 |
| pipeline_task_steps | 步骤执行记录 |
| pipeline_artifacts | 步骤产物 |
| pipeline_human_tasks | 人工任务 |
| pipeline_step_types | 步骤类型注册 |
| pipeline_session_settings | 会话设置(多 tab 项目上下文) |
| pipeline_conversations | 平台会话消息回放缓存2026-09-10 归籍本模块——唯一写入方 agent_loop_v2._save_turn此前是无 models 定义的孤儿表) |
| pipeline_agent_instances | 角色 agent 实例注册(项目×角色→稳定实例 id唯一写入方 agent_instance.pym0002 建表未进 models2026-09-10 归籍) |
| pipeline_agent_settings | 用户 agent 偏好(每用户一行 uk_user默认模型/当前项目指针;写入方 agent_loop_v2、set_agent_model.dspy、workspace.py2026-09-10 归籍) |
| pipeline_project_agents | 项目角色 agent 配置(驾驶舱 v1 start_agent 链路v2 已走 pipeline_agent_instances保留至 v1 链路删除决议2026-09-10 归籍) |
## 安装
```bash
cd pkgs/pipeline-service && pip install .
```
## 核心模块
| 文件 | 职责 |
|------|------|
| `executor.py` | 任务/步骤调度引擎 |
| `storage.py` | 数据库读写 |
| `llm_bridge.py` | LLM API 调用 |
| `agent_loop.py` | AI Agent 多轮执行 |
| `human.py` | 人工任务处理 |
| `intent_classifier.py` | 意图识别 |
| `state.py` | 状态机 |
| `step_registry.py` | 步骤类型注册表 |
| `agent_loop_v2.py` | Agent Executor v2会话 agent 执行引擎) |
| `workspace.py` | 项目/通用会话工作空间目录管理 |
| `sdlc_ability.py` | SDLC 产线能力包(工具定义 + handler |
| `skill_live.py` | 技能实时发布/管理publish_skill_live + manage_skill_live 多租户隔离) |
| `bg_jobs.py` | run_command 后台任务(状态文件化 .bg/,跨 worker 可见) |
| `subagents.py` | 后台并行子 agent 委派(.sub/spawn/steer/stop/result |
| `diagram_gate.py` | 文档配图形态硬门禁2026-09-15交付文档/标书章节中的图必须 invoke_model t2i/i2i 真图,确定性检测 mermaid/plantuml/ASCII 伪图deliver 双路径拦截 + pipeline-bidding write/review_chapter 复用;豁免=文中如实标注「配图缺失:平台无可用文生图模型」 |
## 通用会话产线隔离2026-09-057 层纵深防御)
规范通用会话generic=Trueagent_chat_generic.dspy= 纯通用 agent
不挂任何产线工具/技能/角色/记忆,不得看到或操作任何产线的项目。
隔离层(缺一层即泄漏,详见技能 cockpit-agent-patterns
1. **工具注册表**ToolRegistry 每 executor 独立实例(禁全局单例,防跨会话残留)
2. **默认产线回退**generic 会话 pipeline_id 空不回退 DEFAULT_ABILITY_ID
3. **产线能力包**_execute_ability_tool 对 generic 直接拒绝
4. **工具 schema**load_agent_configpipeline-coregeneric 时剔除 project/shell 类工具
5. **执行层兜底**_dispatch_sdlc_tool 对 generic 拒绝项目管理工具(别名归一后拦截)
6. **工作空间**generic 会话文件根 = `_general/{user_id}` 专属目录generic_workspace_dir
_resolve_ws_path 越界保护圈死run_command 剔除shell 无法圈禁);
resolve_upload_dirpipeline-coregeneric=True 上传落同一专属目录
7. **历史回放**_load_history / _t_session_search 对 generic 只读写
`pipeline_id='' OR IS NULL` 的自身历史(与存库端 store_pl='' 对称),
禁止按 created_by 全量回放(会带出用户各产线对话中的项目信息)
## Hermes 能力对齐:写入侧 + 运行时侧2026-09-10
四个 handler 在 `agent_loop_v2.py`,工具定义在 pipeline-core `agent_config.py`
GENERAL_TOOLS。全部经测试机服务端直调 31/31 + HTTP 端到端 5/5 实测通过。
### 1. memory 工具(持久记忆写入,`_t_memory`
- 写入门禁代码强制多机构多用户scope 白名单 user/project/pipeline
global/org 种子域禁写org_id/user_id 强制注入会话真实身份(忽略 LLM 传值);
无 user_id无人值守拒写remove 只能删本人条目org+user 双过滤)。
- 记忆注入改可见性版(`_build_system_prompt` 传 org_id/user_id → store.visible_to
过滤),修了旧「按域叠加」会带出他机构归属记忆的隐患。
### 2. manage_skill 工具(技能增改删,`skill_live.manage_skill_live`
- 五动作 create/patch/write_file/remove_file/delete隔离全在 skill_live
只落本租户 orgs/{org}org≠0或 users/{uid}org 0 降级/个人);
- **fork-on-write**:改 global 原版先整目录继承拷贝到本租户再改(同名覆盖仅本租户
生效);**校验通过才 fork**(旧「先 fork 后校验」失败会留副本遮蔽原版,已修);
- org+user 双副本同步改user 遮蔽 org防改了被遮蔽那份产线/角色/项目层拒改;
delete 只删本租户副本global 删不到,删后重新可见);子文件限四目录 + realpath 双检。
### 3. run_command background + process 工具(`bg_jobs.py``_t_run_command`/`_t_process`
- 状态文件化 workspace/.bg/{job_id}/meta.json+output.log跨 worker/进程可见;
- 沙箱档位与前台一致generic 强制 strict bwrap无 bwrap 拒绝,绝不降级裸 shell
- start_new_session 独立进程组 + 超时 SIGTERM 整组(不留孤儿);心跳 stale 判活。
### 4. delegate_subtask background + subagent 工具(`subagents.py``_t_delegate_subtask`/`_t_subagent`
- 后台并行(同 workspace 上限 3状态文件化 .sub/{sid}/;深度限制 1子禁再委派
- 子会话 session_isolation='none':不读父历史、不写 pipeline_conversations防污染回放
- steer/stop 走文件传递,子 agent 每轮 tool-loop 边界 `subagents.heartbeat` 消费;
result.txt 流式落盘stop/崩溃即部分结果(绝不空手)。
## 第二批 Hermes 能力对齐:五级工具作用域 + patch_file + 原生视觉2026-09-10
### 五级作用域工具解析接线(`_resolve_tool_scopes`,解析逻辑在 core `tool_sources.py`
- `_init_components` 第 8 步:调 core 五级解析global/org/pipeline/role/project
registry 重建为解析后工具集capability 工具(技能 frontmatter 声明)合成
ToolDefinition 注册,执行路由 `capability_tools.exec_capability_tool`
- **执行层门禁**`_execute_tool` 第 0 步):`_allowed_tools` 非 None 时,作用域外
工具名(幻觉/越权)直接拒绝并回可行动提示(列出本会话可用工具)。解析失败
降级 `_allowed_tools=None` 不拦截(回退旧行为,不阻断会话)。
- 隔离走查修复capability 两层语义global 层 all/ 概念技能的 capability 声明
**不作为注入依据**(只当映射手册),否则 generic 会话拿到 ~70 个产线工具击穿
七层隔离;注入只认 org/pipeline/role/project/user 层技能的声明。
### patch_file 工具(`_t_patch_file`
old_string 唯一性校验0/多次拒绝replace_all 放行)+ 原子写 + `_resolve_ws_path`
越界防护 + UTF-8 校验(二进制拒绝)。
### 原生视觉(多模态消息链)
- `run(user_input, image_parts)`image_parts 非空时首条用户消息构造 OpenAI 多模态
content 数组text + image_url data URLllm_bridge→llm_v1 端点→inference 原样透传。
- `_call_llm` 降级兜底:含图调用失败 → `_degrade_images_if_needed` 剥离图片就地改写
消息(文本 + 系统说明「如实告知用户当前模型看不了图,建议切视觉模型或 invoke_model
i2t」重试一次——绝不假装看过图。只降级一次。
- `_estimate_tokens`/`_summarize` 兼容 list content`_content_as_text` 归一,图片按
1000 token 估)。
- `gateway.run_message(image_paths)`build_image_parts 构造 + 超限 notes 注入 content。
- 实测中性文件名红蓝两图agent 正确答「第一张红色、第二张蓝色」degrade 0 次。