IDE 编排模式
/ide 打开全屏 Python 代码编辑器。编写编排脚本,将 LLM 调用串联为可控的、可重复的工作流,具备完整的工具使用能力(文件读写、bash 执行)。脚本使用标准 Python 语法——无需自定义 DSL。
核心能力:
- 编写 Python 脚本调用 LLM 函数(
llm_call、llm_confirm、llm_judge) - 完整工具使用:LLM 可读写文件、执行 bash 命令、搜索代码库
- 循环处理:遍历文件、数据或动态列表
- 条件工作流:基于 LLM 判断分支执行逻辑
- 隔离执行:IDE 对话不污染主对话
- 运行前预览:F5 静态分析,无需实际执行
什么是 IDE 模式?
IDE 模式不是传统代码编辑器。它是一个工作流创作环境,你编写 Python 脚本,调用注入的异步函数(llm_call、llm_confirm、llm_judge)来编排 LLM 任务。编辑器将脚本编译为 LLM 工具调用,具备完整的工具使用能力(文件读写、bash 执行)。
/ide → 打开草稿列表弹框,选择草稿后进入编辑器
/ide new <名称> → 创建新草稿并打开空白编辑器
/ide rename <旧> <新> → 重命名草稿
Ctrl+I → TUI 快捷键打开草稿列表
工作模式
| 模式 | 操作 | 执行流程 |
|---|---|---|
| 预览 | F5 |
自动格式化(black)→ AST 静态分析 → 在执行面板中展示展开步骤 |
| 运行 | F6 |
校验 → 保存草稿 → 退出编辑器 → 在 TUI 中执行脚本 |
| 保存草稿 | Ctrl+S(第1次) |
保存草稿 + 自动格式化 |
| 退出并携带代码 | Ctrl+S(第2次) |
保存草稿 + 退出编辑器,代码传递给 TUI 执行 |
| 退出不保存 | Esc |
退出编辑器,不保存内容 |
注入函数
IDE 模式在作用域中注入三个异步函数,均可使用 await 调用:
llm_call
向 LLM 发送提示并获取响应。每次调用复用独立对话历史(通过 LLMBridge),IDE 中的对话不会污染主对话。
result = await llm_call("将 UserService 类重构为使用依赖注入")
print(result)
LLM 具备完整的工具使用能力——可以读取文件、执行 bash 命令、写入文件。工具在 IDE 中自动执行,无需权限确认(IDE 是自动化执行环境)。
HYBRID 执行模式:从 TUI 运行时(F6),llm_call 通过消息队列路由到工作线程,流式 token 直达 TUI 输出;独立运行时(F5 预览、CLI)直接调用 LLM API。
工具执行:LLM 可自动使用以下工具:
read_file/write_file/edit_file— 文件操作glob_files/grep_content— 搜索操作execute_bash— Bash 命令(默认 30 秒超时)
IDE 模式下所有工具调用无需权限确认。
llm_confirm
显示确认提示。当前实现始终返回 True(自动批准,不弹确认对话框)。
approved = await llm_confirm("是否继续执行数据库迁移?")
if approved:
result = await llm_call("执行迁移")
llm_judge
让 LLM 基于最近的对话上下文评估一个自然语言条件。返回布尔值。上下文自动从 IDE 对话的最近 4 条消息(2 轮)构建,每条截断至 500 字符。
is_valid = await llm_judge("生成的 SQL 是否遵循 PostgreSQL 最佳实践?")
if is_valid:
print("已批准")
else:
print("需要修改")
Judge 使用同步 LLM 调用,temperature=0 保证确定性输出。如果 LLM 调用失败或返回无法解析的响应,会降级返回 True(安全回退,交由人工确认)。
快捷键
编辑器快捷键
| 按键 | 操作 |
|---|---|
F5 |
预览 — 自动格式化(black)+ AST 静态分析 + 在执行面板中展示展开步骤 |
F6 |
运行 — 校验 + 保存草稿 + 退出编辑器,交由 TUI 执行 |
F9 |
手动校验(检查语法 + 安全性,不展开预览) |
Ctrl+S |
第1次:保存草稿 + 自动格式化;第2次:保存 + 退出并携带代码 |
Esc |
退出编辑器,不保存 |
Ctrl+Z |
撤销 |
Ctrl+R |
重做 |
Tab |
缩进(4 空格);有选区时:缩进所有选中行 |
Shift+Tab |
反缩进;有选区时:反缩进所有选中行 |
Ctrl+Space |
手动触发代码补全菜单 |
Enter |
补全菜单激活时:接受选中项;否则:换行并自动缩进 |
Backspace / Delete |
有选区时:剪切选区;否则:删除字符 |
Ctrl+H |
同 Backspace(部分终端将 Backspace 映射为 Ctrl+H) |
剪贴板操作
| 按键 | 操作 |
|---|---|
Ctrl+C |
复制选中文本到系统剪贴板 |
Ctrl+V |
从系统剪贴板粘贴 |
执行面板(F5 后显示)
| 按键 | 操作 |
|---|---|
Ctrl+P |
复制执行面板全部输出到剪贴板 |
Esc |
从面板返回编辑器焦点 |
Up / Down |
面板滚动 1 行(面板获焦时) |
PageUp / PageDown |
面板滚动一屏(面板获焦时) |
Ctrl+Y / Ctrl+U |
面板向上 / 向下滚动 10 行(无论焦点在何处) |
Ctrl+Home / Ctrl+End |
滚动到面板顶部 / 底部(无论焦点在何处) |
Ctrl+= / Ctrl+- |
面板高度调整 3 行 |
Ctrl+Up / Ctrl+Down |
面板高度按屏幕比例调整 10% |
| 双击 | 面板全屏 / 恢复切换 |
Ctrl+Tab |
在编辑器和执行面板之间切换焦点 |
安全沙箱
IDE 模式在受限环境中运行。
禁止导入的模块
以下模块被禁止导入。检测使用 AST 级分析——在解析时检查每个 import 和 from ... import 语句,包括子模块导入(如 os.path 会被 os 规则拦截):
os, subprocess, shutil, socket, ctypes, sys, io
尝试导入禁止模块会抛出 SecurityError,并精确报告行号。安全检查定义在 py_runner.py 中,validator.py 共享同一份源。
允许的操作
- LLM 调用(
llm_call、llm_confirm、llm_judge) - 文件操作(通过 LLM 工具调用:
read_file、write_file、edit_file、glob_files、grep_content) - Bash 命令执行(通过 LLM 工具调用
execute_bash,默认 30 秒超时) - 字符串处理和数据处理
- 标准库模块(math、json、datetime、re 等)
执行架构
预览(F5)— AST 静态分析
按 F5 查看脚本编译结果。dry-run 引擎(dry_run.py)的工作流程:
- 使用
ast.parse()解析代码 - 递归遍历 AST 树,穿过
For/While/If/Try/With代码块 - 提取
llm_call("prompt")调用及其行号 - 检测循环结构,静态可确定时计算迭代次数(
range(N)、列表字面量) - 展示每一步的行号、prompt 文本和迭代标记
脚本分析:
L12 await llm_call("列出所有表...") [X 1]
L18 await llm_call("生成 ALTER TABLE...") [X 1]
L25 await llm_judge("这段 SQL 是否遵循...") [X 1]
L30 [条件分支] if is_valid: print 已批准
调用统计:2 个 llm_call,1 个 llm_judge
预估轮数:~3
迭代标记说明:
X N— 静态range(N)循环,确切次数已知X N?— 动态循环(如.split()),分析时无法确定次数
F-string 在预览中转换为模板(如 f"处理 {file}" 显示为 处理 {file})。
自动格式化:预览前编辑器自动使用 black(如已安装)格式化代码。若格式化改变了代码,会同步到编辑器缓冲区。
运行(F6)— 脚本执行
按 F6 运行脚本。执行流水线:
- 校验 —
PythonValidator检查语法(ast.parse)和安全(AST 遍历禁止导入检测) - 保存草稿 — 脚本保存至
~/.niuma/projects/{project}/ide/{name}.py - 退出编辑器 — 代码以
[["__f6_code__", code]]格式传递给 TUI - 执行 —
IDEExecutor.execute()在守护线程中通过py_runner.run_script()运行
执行环境:
- 用户代码被包装为
async def __user_script__():通过exec()+await执行 llm_call使用LLMBridge(独立对话历史)。TUI 模式下通过MessageQueue(HYBRID)路由到工作线程,流式输出llm_confirm始终返回True(自动批准)llm_judge使用ConditionJudge(同步 LLM 调用,temperature=0,确定性输出)- LLM 工具(文件读写编辑、grep、glob、bash)自动执行——无权限确认
- HTTP 客户端超时:connect=10s、read=30s、write=30s、pool=10s
执行结果
脚本完成后显示摘要:
- LLM 调用次数和 token 总量
- 耗时
- 模型名称和 effort 级别
- 成功/失败状态,失败时显示错误详情(含行号)
错误处理
- 语法错误:在执行面板(F5)中显示行号,或作为错误消息(F6)
- 安全违规:禁止导入抛出
SecurityError,精确报告行号 - 运行时错误:捕获并显示错误类型和消息
- LLM 失败:优雅降级(如
llm_judge失败时返回True)
编辑器特性
视觉主题
编辑器使用清爽的浅色主题,通过 Pygments(Python lexer)进行语法高亮:
| 元素 | 样式 |
|---|---|
| 编辑器背景 | 白色(#ffffff) |
| 状态栏(上下) | 蓝色(#2a5f8f)白色粗体文字 |
| 行号 | 灰色(#999999),当前行深色粗体(#333333) |
| 关键字 | 紫色(#6f42c1)粗体 |
| 字符串 | 红色(#d73a49) |
| 注释 | 灰色斜体(#6a737d) |
| 函数/变量名 | 蓝色(#005cc5) |
| 执行面板背景 | 深蓝(#1a1a2e) |
代码补全
编辑器提供基于 Jedi 的智能代码补全:
- 自动触发:输入 2 个以上字符后自动激活补全
- Jedi 类型桩:
llm_call、llm_confirm、llm_judge通过注入类型桩让 Jedi 正确识别上下文 - 降级策略:当 Jedi 返回结果少于 3 个时,叠加 Python 关键字模板(
for、if、while、def、class、return、await、import、with、try) - Tab = 缩进专用:Tab 键专用于缩进(4 空格),不触发补全。使用
Ctrl+Space手动触发补全菜单
自动格式化
F5 预览和 Ctrl+S 保存时使用 black 格式化代码。未安装 black 时静默跳过。
状态栏
- 上方状态栏:显示可用快捷键(i18n 感知,跟随
/lang设置) - 下方状态栏:显示实时统计——行数、字符数、错误数、警告数。临时消息会覆盖显示(如"草稿已保存"、"已格式化"、"已复制 N 个字符")
执行面板
执行面板在按 F5 后显示于编辑器下方,展示:
- dry-run 分析结果(行号 + prompt 文本)
- 语法/安全错误(含行号)
- LLM 执行输出(运行脚本时)
- token 用量统计
面板控制:
Ctrl+P— 复制面板全部输出到剪贴板Ctrl+Tab— 在编辑器和面板之间切换焦点- 双击 — 面板全屏/恢复切换
Ctrl+=/Ctrl+-— 面板高度调整 3 行Ctrl+Up/Ctrl+Down— 面板高度按屏幕比例调整 10%
草稿管理
脚本自动保存为命名草稿:
- 存储位置:
~/.niuma/projects/{project}/ide/{name}.py - 草稿列表:输入
/ide打开草稿列表弹框(TUI Float 浮层),选择草稿进入编辑器 - 创建草稿:
/ide new <名称>创建新草稿(名称必填) - 重命名:
/ide rename <旧名称> <新名称> - 删除草稿:在草稿列表弹框中按
d删除选中草稿 - 自动保存:F5 预览和第1次
Ctrl+S时触发 - 名称清洗:特殊字符(
/ \ : * ? " < > |和空格)自动替换为下划线
草稿列表控制
| 按键 | 操作 |
|---|---|
Up / Down |
上下浏览草稿列表 |
Enter |
打开选中草稿进入编辑器 |
d |
删除选中草稿 |
Esc / q |
关闭草稿列表 |
草稿模板
使用 /ide new <名称> 创建新草稿时,编辑器打开并预填默认模板:
# IDE 编排脚本
# F5 预览,F6 运行
await llm_call("生成一个简单的 hello world Python 函数")
模板展示了基本的 llm_call 语法并包含注释说明工作流。
示例:迁移脚本
# IDE 编排脚本 — 数据库迁移
# F5 预览,F6 运行
# 步骤 1:分析当前 schema
schema = await llm_call("列出 models/schema.py 中所有表和字段")
print("当前 schema:\n", schema)
# 步骤 2:生成迁移 SQL
migration = await llm_call(
f"生成添加 'created_at' 字段的 ALTER TABLE SQL:\n{schema}"
)
print("迁移 SQL:\n", migration)
# 步骤 3:验证
is_valid = await llm_judge(
"这段 SQL 是否遵循 PostgreSQL 最佳实践?"
)
if is_valid:
print("迁移已批准 — 可以执行")
else:
print("迁移需要修改 — 请审查 SQL")
示例:多文件重构
# 编排:将 auth 逻辑提取到独立模块
# 步骤 1:识别 auth 相关代码
auth_files = await llm_call(
"找出所有包含认证逻辑(login, logout, token)的文件"
)
print("Auth 文件:\n", auth_files)
# 步骤 2:获取确认
approved = await llm_confirm("是否继续提取 auth 模块?")
if approved:
# 步骤 3:执行
result = await llm_call(f"将 auth 逻辑重构到 auth/ 包:\n{auth_files}")
print("结果:\n", result)
示例:循环处理
# 编排:循环处理多个文件
# 定义待处理文件列表
files = ["config.json", "data.csv", "README.md"]
for file in files:
# 分析每个文件
analysis = await llm_call(f"分析 {file} 的结构")
print(f"\n{file} 分析结果:\n", analysis)
# 判断文件是否需要重构
needs_refactor = await llm_judge(f"{file} 是否需要重构?")
if needs_refactor:
await llm_call(f"重构 {file} 以提高可读性")
示例:条件工作流
# 编排:基于 LLM 判断的条件逻辑
# 初始分析
code_review = await llm_call("审查认证模块的安全问题")
# 判断严重程度
is_critical = await llm_judge("是否存在严重安全漏洞?")
if is_critical:
# 严重:立即修复
fix = await llm_call(f"修复严重安全问题:\n{code_review}")
print("已应用严重修复:\n", fix)
else:
# 非严重:记录待处理
print("发现非严重问题,稍后审查。")
print(f"问题:\n{code_review}")
何时使用 IDE 模式
| 适合 | 不太适合 |
|---|---|
| 可重复的工作流 | 一次性快速编辑 |
| 多步骤流水线 | 简单文件更改 |
| 审计追踪(执行统计) | 探索性工作 |
| 复杂条件逻辑 | 需要人工实时参与的任务 |
| 需要工具使用的脚本(文件操作、bash) | 单次 LLM 调用 |
| 循环处理多个条目 | 线性一次性任务 |