- Renamed `check_environment` to `check_api_key_configured` for clarity, simplifying the API key validation logic. - Removed the blocking behavior of the API key check during application startup, allowing the app to run while providing a prompt for configuration. - Updated `LocalAgentApp` to accept an `api_configured` parameter, enabling conditional messaging for API key setup. - Enhanced the `SandboxRunner` to support backup management and improved execution result handling with detailed metrics. - Integrated data governance strategies into the `HistoryManager`, ensuring compliance and improved data management. - Added privacy settings and metrics tracking across various components to enhance user experience and application safety.
294 lines
7.6 KiB
Markdown
294 lines
7.6 KiB
Markdown
====================
|
||
【产品目标】
|
||
====================
|
||
- 面向 Windows 小白用户:一句话输入
|
||
- 自动判断任务类型:
|
||
- chat:普通对话(如“今天天气怎么样”)
|
||
- execution:本地执行任务(文件处理)
|
||
- chat:
|
||
- 直接调用 LLM 返回文本
|
||
- execution:
|
||
- 生成执行计划
|
||
- 生成 Python 代码
|
||
- 安全校验
|
||
- 用户确认
|
||
- 一次性子进程执行
|
||
- 强制工作区副本目录:
|
||
workspace/input
|
||
workspace/output
|
||
workspace/logs
|
||
- MVP 明确不做:
|
||
- 联网任务(搜索 / 爬取)
|
||
- 鼠标 / 键盘自动化
|
||
- 后台常驻
|
||
- 多任务并行
|
||
- 核心安全原则:
|
||
- LLM 可以联网“思考”
|
||
- Executor(执行器)禁止联网“动手”
|
||
|
||
====================
|
||
【项目结构(必须严格按此生成)】
|
||
====================
|
||
LocalAgent/
|
||
main.py
|
||
requirements.txt
|
||
.env.example
|
||
ui/
|
||
chat_view.py
|
||
task_guide_view.py
|
||
llm/
|
||
client.py
|
||
prompts.py
|
||
intent/
|
||
classifier.py
|
||
labels.py
|
||
safety/
|
||
rule_checker.py
|
||
llm_reviewer.py
|
||
executor/
|
||
sandbox_runner.py
|
||
workspace/
|
||
input/
|
||
output/
|
||
logs/
|
||
|
||
====================
|
||
【统一 LLM 调用规则(非常重要)】
|
||
====================
|
||
- 所有模型(包括 qwen2.5:7b-instruct)都通过同一个 API:
|
||
https://api.siliconflow.cn/v1/chat/completions
|
||
- 不区分“本地 / 云端”客户端
|
||
- 区分只体现在:
|
||
- model name
|
||
- prompt
|
||
- temperature / max_tokens
|
||
|
||
.env.example 中必须包含:
|
||
|
||
LLM_API_URL=https://api.siliconflow.cn/v1/chat/completions
|
||
LLM_API_KEY=your_api_key_here
|
||
|
||
# 用于意图识别的小模型
|
||
INTENT_MODEL_NAME=qwen2.5:7b-instruct
|
||
|
||
# 用于对话 / 计划 / 代码生成的模型(可先用同一个)
|
||
GENERATION_MODEL_NAME=Pro/zai-org/GLM-4.7
|
||
|
||
====================
|
||
【llm/client.py 要求】
|
||
====================
|
||
实现统一的 LLMClient:
|
||
|
||
- 使用 requests.post
|
||
- URL / API KEY 从 .env 读取
|
||
- 提供方法:
|
||
chat(
|
||
messages: list[dict],
|
||
model: str,
|
||
temperature: float,
|
||
max_tokens: int
|
||
) -> str
|
||
|
||
- payload 结构参考:
|
||
{
|
||
"model": model,
|
||
"messages": messages,
|
||
"stream": false,
|
||
"temperature": temperature,
|
||
"max_tokens": max_tokens
|
||
}
|
||
|
||
- headers:
|
||
Authorization: Bearer <API_KEY>
|
||
- 对网络异常 / 非 200 状态码做明确异常抛出
|
||
- 不要在 client 中写任何业务逻辑
|
||
|
||
====================
|
||
【意图识别(核心修改点)】
|
||
====================
|
||
实现 intent/classifier.py:
|
||
|
||
- 使用“小参数 LLM”(INTENT_MODEL_NAME,例如 qwen2.5:7b-instruct)
|
||
- 目标:二分类
|
||
- chat
|
||
- execution
|
||
- 要求输出结构化结果:
|
||
{
|
||
"label": "chat" | "execution",
|
||
"confidence": 0.0 ~ 1.0,
|
||
"reason": "中文解释,说明为什么这是执行任务/对话任务"
|
||
}
|
||
|
||
- Prompt 必须极短、强约束、可解析
|
||
- Prompt 模板放在 llm/prompts.py
|
||
- 对 LLM 输出:
|
||
- 尝试解析 JSON
|
||
- 若解析失败 / 字段缺失 → 走兜底逻辑(判为 chat)
|
||
|
||
intent/labels.py:
|
||
- 定义常量:
|
||
CHAT
|
||
EXECUTION
|
||
- 定义阈值:
|
||
EXECUTION_CONFIDENCE_THRESHOLD = 0.6
|
||
- 低于阈值一律判定为 chat(宁可少执行,不可误执行)
|
||
|
||
====================
|
||
【Chat Task 流程】
|
||
====================
|
||
- 使用 GENERATION_MODEL_NAME
|
||
- messages = 用户原始输入
|
||
- 返回文本直接展示
|
||
- 不触碰本地、不产出文件
|
||
|
||
====================
|
||
【Execution Task 流程】
|
||
====================
|
||
1) 生成执行计划
|
||
- 可用 GENERATION_MODEL_NAME
|
||
- 输出中文、可读
|
||
- 明确:
|
||
- 会做什么
|
||
- 不会动原文件
|
||
- 输入 / 输出目录
|
||
- 可能失败的情况
|
||
|
||
2) 生成 Python 执行代码
|
||
- MVP 先内置“安全示例代码”:
|
||
- 遍历 workspace/input
|
||
- 复制文件到 workspace/output
|
||
- 不依赖第三方库
|
||
- 不修改原文件
|
||
- 保存为 workspace/task_<id>.py
|
||
|
||
3) safety/rule_checker.py(硬规则)
|
||
- 静态扫描执行代码:
|
||
- 禁止 requests / socket / urllib
|
||
- 禁止访问非 workspace 路径
|
||
- 禁止危险操作(os.remove, shutil.rmtree, subprocess 等)
|
||
- 若违反,直接 fail
|
||
|
||
4) safety/llm_reviewer.py(软规则)
|
||
- 使用 GENERATION_MODEL_NAME
|
||
- 输入:用户需求 + 执行计划 + 代码
|
||
- 输出:pass / fail + 中文原因
|
||
|
||
5) UI(小白引导式,方案 C)
|
||
- 显示:
|
||
- 判定原因 reason
|
||
- 三步引导:
|
||
1) 把文件复制到 input
|
||
2) 我来处理
|
||
3) 去 output 取
|
||
- 执行计划
|
||
- 风险提示
|
||
- 【开始执行】按钮
|
||
|
||
6) executor/sandbox_runner.py
|
||
- 使用 subprocess 启动一次性 Python 子进程
|
||
- 工作目录限定为 workspace
|
||
- 捕获 stdout / stderr
|
||
- 写入 workspace/logs/task_<id>.log
|
||
- 执行完即退出
|
||
- 执行器层不允许任何联网能力(由 rule_checker 保证)
|
||
|
||
====================
|
||
【UI(Tkinter)最小可跑要求】
|
||
====================
|
||
- main.py 启动 Tkinter 窗口
|
||
- 顶部:输入框 + 发送按钮
|
||
- 中部:输出区
|
||
- 当识别为 execution:
|
||
- 切换或弹出 task_guide_view
|
||
- 执行完成后展示:
|
||
- success / partial / failed
|
||
- 成功 / 失败数量
|
||
- 日志路径
|
||
|
||
====================
|
||
【requirements.txt(最小集)】
|
||
====================
|
||
- python-dotenv
|
||
- requests
|
||
|
||
====================
|
||
【最小可跑验收标准】
|
||
====================
|
||
- 未配置 LLM_KEY 时给出明确错误提示
|
||
- 输入“今天天气怎么样” → chat
|
||
- 输入“把这个文件夹里的图片复制一份” → execution
|
||
- execution 能生成 task_<id>.py 并真正执行
|
||
- output / logs 中有真实文件
|
||
|
||
====================
|
||
【Plan 模式输出要求】
|
||
====================
|
||
1) 先输出整体实现计划(步骤、模块职责)
|
||
2) 列出所有文件及其责任说明
|
||
3) 再按文件路径逐个输出代码内容
|
||
4) 确保 main.py 可直接运行
|
||
5) main.py 顶部注释说明:
|
||
- 如何配置 .env
|
||
- 如何运行
|
||
- 如何测试(往 input 放文件)
|
||
|
||
====================
|
||
【安全边界策略(P0 级)】
|
||
====================
|
||
|
||
### 1. 静态硬阻断(safety/rule_checker.py)
|
||
|
||
硬性禁止(直接拒绝执行):
|
||
- 网络模块:socket, requests, urllib, http, ftplib, smtplib, aiohttp 等
|
||
- 执行命令:subprocess, os.system, os.popen, eval, exec, compile
|
||
- 危险调用:__import__, ctypes, cffi
|
||
- 绝对路径:C:\, D:\, /home, /usr, /etc 等非 workspace 路径
|
||
|
||
检查方式:
|
||
- AST 语法树分析(主要)
|
||
- 正则表达式匹配(兜底)
|
||
- 路径解析验证
|
||
|
||
违规处理:
|
||
- 立即终止流程
|
||
- 记录安全事件
|
||
- 向用户展示违规详情
|
||
|
||
### 2. 运行时硬隔离(executor/path_guard.py)
|
||
|
||
注入机制:
|
||
- 在用户代码执行前,自动注入守卫代码
|
||
- 替换内置函数:open, __import__
|
||
- 拦截所有文件和模块操作
|
||
|
||
拦截逻辑:
|
||
- 文件访问:检查路径是否在 workspace 内(通过 Path.resolve() + relative_to())
|
||
- 模块导入:检查是否为禁止的网络模块
|
||
- 违规抛出 PermissionError / ImportError
|
||
|
||
隔离特性:
|
||
- 工作目录限定为 workspace
|
||
- 移除环境变量中的网络代理
|
||
- subprocess 独立进程执行
|
||
- 超时自动终止
|
||
|
||
### 3. 安全度量(safety/security_metrics.py)
|
||
|
||
收集指标:
|
||
- 静态阻断次数、警告次数
|
||
- 运行时路径拦截、网络拦截
|
||
- 分类统计:网络违规、路径违规、危险调用
|
||
|
||
度量输出:
|
||
- 拦截率 = (静态阻断 + 运行时拦截) / 总检查次数
|
||
- 误放行率 = 0%(双重防护理论值)
|
||
- 事件日志:时间戳、类型、详情、任务 ID
|
||
|
||
使用方式:
|
||
```python
|
||
from safety.security_metrics import get_metrics
|
||
|
||
metrics = get_metrics()
|
||
metrics.print_summary()
|
||
metrics.save_to_file('workspace/logs/security_metrics.json')
|
||
``` |