一个OCR进度汇报,让我看透了AI编程助手的底层能力
作者:技术从业16年,踩过坑、做过技术负责人、带过团队
这篇博文起源于一次真实的开发场景。后台有 4 个 Python OCR 进程在跑 1000 张图片的批量识别,我需要每 20 分钟汇报一次进度。当时 TRAE Agent 给出了一份精准的中文表格汇报。本文以这次汇报为切入点,剖析 Agent 内部的运作原理,并总结如何"完美"地利用这些能力。
一、那次汇报是怎么产生的
1.1 用户请求
检查后台4个Python OCR进程进度并汇报。执行:
1) Get-Process python | Select Id,StartTime,CPU
2) python -c "import json; [print(f'shard{i}:', json.load(open(f'.../ocr_shard_{i}.json'))['count'], '/250') for i in range(4)]"
3) Get-ChildItem '...\ocr_shard_*.json' | Select Name,LastWriteTime
汇报内容:各分片进度、总进度X/1000、进程数、最近保存时间、是否停滞
所有PS命令前加 $OutputEncoding=[System.Text.Encoding]::UTF8; [Console]::OutputEncoding=[System.Text.Encoding]::UTF8
1.2 Agent 实际做了什么
Agent 在单条消息中并行发出了 3 个 RunCommand 调用(互不依赖),等 3 个命令都返回后,再把结果汇总成中文表格。
关键点:
- 并行执行:3 个命令同时跑,而不是先 A 后 B 后 C,节省了 2 段等待时间。
- 结果聚合:Agent 把 3 份原始输出(进程列表、计数、文件时间戳)合并成"进度 / 是否停滞"的判断。
- 遵循项目规则:每条命令都注入了 UTF-8 编码设置,符合项目规则
ER-001/ER-002,避免中文乱码。 - 单次性:这只是即时的一次执行,对话关闭就没了,不是定时任务。
二、Agent 的核心能力地图
TRAE Agent 不是"只会写代码的聊天机器人",而是一个带工具集的自治体(Autonomous Agent)。核心能力可以分成 6 大类:
| 能力 | 工具 | 典型用途 |
|---|---|---|
| 命令执行 | RunCommand / CheckCommandStatus / StopCommand |
跑脚本、装依赖、起服务 |
| 文件操作 | Read / Edit / Write / Glob / Grep / DeleteFile |
读写改删、按名/内容搜索 |
| 代码检索 | SearchCodebase(语义检索) |
“哪里调用了 encrypt 方法” |
| 子代理 | Task(search / general_purpose_task) |
并行探索、保护主上下文 |
| 定时调度 | Schedule |
cron 周期任务 |
| MCP 工具 | run_mcp(如 Chrome DevTools) |
浏览器自动化、外部连接器 |
| 记忆 | 文件系统中的 memory 文件 | 跨会话保持上下文 |
| 技能 | Skill(web-dev / frontend-design 等) |
加载领域专用工作流 |
| 交互 | AskUserQuestion / NotifyUser |
决策点征求用户 |
| 任务管理 | TodoWrite |
多步骤任务追踪 |
三、原理剖析:为什么能"自动汇报"
3.1 ReAct 模式(Reason + Act)
Agent 不是直接调命令,而是按 思考 → 行动 → 观察 → 思考 的循环工作:
- Reason(思考):用户要"汇报进度",我需要哪些信息?进程、文件计数、文件时间。
- Act(行动):并行调用 3 个
RunCommand。 - Observe(观察):读取每个命令的
command_run_logs。 - Reason(再思考):进程数为 0 + 所有 shard 都是 250/250 → OCR 已完成,不是停滞。
- Respond(响应):生成表格 + 结论 + 下一步建议。
3.2 并行工具调用(Parallel Tool Calls)
这是 TRAE Agent 区别于传统"按顺序调用工具"的关键能力。
适用条件:
- 工具调用之间没有数据依赖(A 不需要 B 的输出作为输入)。
- 调用次数 ≤ 5(除非用户明确要求更多)。
本次场景:3 个命令互相独立 → 并行 → 1 轮往返代替 3 轮。
反面例子(不能并行):
Step 1: git status
Step 2: git add 文件(依赖 Step 1 的结果)
Step 3: git commit(依赖 Step 2 完成)
这种链式依赖必须串行。
3.3 状态判定:完成 vs 停滞
Agent 做的不只是"读数字",而是做了逻辑判断:
完成判定:进程数 == 0 AND 所有 shard.count == 250
停滞判定:进程数 > 0 AND LastWriteTime 距今 > 30 分钟
这种"条件 + 阈值"的判断写在 message 字段里,让 Agent 按规则推断,而不是只报裸数据。
3.4 工具的"约束-安全"设计
每个工具都有边界保护:
RunCommand:危险操作(push --force/reset --hard/rm -rf)需要用户明确授权。Edit:必须先Read文件再编辑,避免盲改。Write:会强制要求先 Read,覆盖前提醒。- 文件操作:项目规则
FR-001/FR-002强制限制在{PROJECT_ROOT}内,禁止../逃逸。
四、定时任务(Schedule):把"一次"变成"周期"
4.1 Schedule 工具的本质
Schedule 创建的是 cron 表达式驱动的周期任务。每次到点,TRAE 会派发一个全新会话,把 message 字段的内容作为该会话的输入。
注意:是新会话,不是当前对话续写。所以
message必须是自包含的——包含所有路径、规则、输出格式要求。
4.2 cron 表达式速查
字段: 分 时 日 月 周
范围: 0-59 0-23 1-31 1-12 0-6(0=周日)
常用模式:
*/20 * * * * 每 20 分钟
0 9 * * 1-5 工作日每天 9:00
0 0 * * * 每天 0:00
0 */2 * * * 每 2 小时
约束:
- 最小粒度:10 分钟(不允许每分钟跑)。
- 仅支持 5 字段 cron,不支持"每月第三个周五"这种复合规则。
- 时区用 IANA 标识符:
Asia/Shanghai/America/Los_Angeles。
4.3 message 字段写法(决定任务质量)
差的 message:
检查 OCR 进度。
好的 message:
检查后台 4 个 Python OCR 进程进度并汇报。
执行命令(所有命令前加 $OutputEncoding=[System.Text.Encoding]::UTF8; [Console]::OutputEncoding=[System.Text.Encoding]::UTF8):
1) Get-Process python -ErrorAction SilentlyContinue | Select Id,StartTime,CPU | Format-Table -Auto
2) python -c "import json; [print(f'shard{i}:', json.load(open(f'f:/AI开发区域/GL-开发隔离/C/scripts/image-toolkit/ocr_shard_{i}.json','r',encoding='utf-8'))['count'], '/250') for i in range(4)]"
3) Get-ChildItem 'f:\AI开发区域\GL-开发隔离\C\scripts\image-toolkit\ocr_shard_*.json' | Select Name,LastWriteTime | Format-Table -Auto
判定规则:
- 进程数为 0 且 4 个 shard 都 250/250 → 报告 OCR 完成,建议合并验证 + 暂停本任务
- 进程数 > 0 且任一文件 >30 分钟未更新 → 报告停滞,列出疑似卡住的分片
- 否则 → 正常汇报进度
汇报格式:中文表格,包含 进程数 / 各分片进度 / 总进度 X/1000 / 最近保存时间 / 状态判定
输出目标:直接在对话中汇报(不写文件)
静默规则:仅在停滞或完成时才提示,进度正常时简短一行即可
4.4 创建 / 管理
| 操作 | 调用 |
|---|---|
| 创建 | Schedule(action: "create", cron_expression, message, name, timezone) |
| 列出 | Schedule(action: "list") |
| 查看历史 | Schedule(action: "get", scheduled_task_id) |
| 立即触发一次 | Schedule(action: "trigger", scheduled_task_id) |
| 暂停 / 恢复 | action: "pause" / "resume" |
| 修改 | action: "update"(只传要改的字段) |
| 删除 | action: "delete" |
4.5 何时该用 / 不该用 Schedule
✅ 该用:
- “每天早上检查一下构建状态”
- “每 20 分钟监控长跑任务进度”
- “工作日 18:00 拉取日报数据”
❌ 不该用:
- 一次性任务(“5 分钟后跑一下测试” → 不支持相对延迟)
- 代码生成(“每天写个新组件” → 不是 Schedule 的职责)
- 不可拆解的长任务(cron 任务最好 5-10 分钟内能跑完)
五、子代理(Task):并行 + 隔离
5.1 为什么需要子代理
主 Agent 的上下文窗口是有限的。如果把一份 5000 行的日志全文读进主对话,会污染后续所有决策。子代理可以:
- 隔离:子代理的中间输出不进主对话,只返回最终摘要。
- 并行:同时启动多个子代理跑独立任务。
- 专用:
search类型专做代码检索,general_purpose_task专做复杂编码。
5.2 典型用法
"重构 OCR 模块,同时调研 PaddleOCR 新版本的 API 变化"
主 Agent 可以:
- 启动
search子代理 → 调研 PaddleOCR API - 启动
general_purpose_task子代理 → 实际重构代码 - 主 Agent 自己 → 写测试
三个并行,最后主 Agent 汇总结果。
5.3 注意事项
- 子代理看不到当前对话历史,必须在 query 里传完整上下文。
- 不要做"子代理能做但我自己也能做"的重复劳动。
- 子代理返回的是单条消息,适合需要大量探索但只需最终结论的场景。
六、记忆系统:跨会话保持一致性
6.1 三层结构
~/.trae-cn/memory/
├── user_profile.md # 用户级(跨项目):偏好、技术栈
└── projects/
└── {项目hash}/
├── project_memory.md # 项目级:规则、约定、踩过的坑
└── 20260715/
├── topics.md # 当日话题摘要
└── session_memory_{id}.jsonl # 单次会话细节
6.2 触发记忆检索的信号
| 场景 | 是否检索 |
|---|---|
| 用户问"之前怎么决定的" | ✅ 必须 |
| 任务涉及项目文件、模块 | ✅ 应该 |
| 模糊需求、可能依赖历史选择 | ✅ 应该 |
| 当前时间、简单翻译、单行命令 | ❌ 跳过 |
6.3 用户说"记住我的 xxx"
- 用户级(跨项目通用):写
user_profile.md。例如"我喜欢用 pnpm 而不是 npm"。 - 项目级(仅当前项目):写
project_memory.md。例如"本项目数据库表前缀用 dat_"。
七、技能(Skill):加载领域专家知识
7.1 Skill 是什么
Skill 是一段预置的专家工作流。当用户的请求匹配某个 Skill 的触发条件时,Agent 会先 Skill 工具加载该技能的详细指令,再开始干活。
7.2 常用技能举例
| 技能 | 触发场景 |
|---|---|
frontend-design |
“帮我做一个高设计感的着陆页” |
web-dev |
“从零搭建一个新网站” |
vercel-react-best-practices |
“审查这个 React 组件的性能” |
chart-visualization |
“把这组数据画成图表” |
screenshot |
“截一下当前桌面” |
skill-creator |
“我想创建一个新技能” |
wx-spring-boot / wx-vue |
项目专用框架开发 |
7.3 完美利用 Skill 的姿势
- 不要直接说"用 XX 技能",而是描述任务,让 Agent 自动匹配。
- 描述越具体,匹配越准。例如 “做一个带交互动效的产品发布页” 比 “做个网页” 更容易命中
frontend-design。 - 如果一个任务涉及多个领域(如"设计 + 写代码"),Agent 会按需串联多个 Skill。
八、MCP:连接外部世界
8.1 MCP 是什么
Model Context Protocol —— 一个让 Agent 调用外部工具/数据源的协议。当前项目已配置 mcp_Chrome_DevTools_MCP,意味着 Agent 可以:
| 工具 | 能力 |
|---|---|
navigate_page / new_page |
打开网页 |
take_screenshot |
截图 |
click / fill / hover |
模拟用户操作 |
evaluate_script |
注入 JS |
list_network_requests |
抓接口 |
list_console_messages |
抓 console 日志 |
lighthouse_audit |
性能审计 |
8.2 典型场景
- 前端调试:“打开 localhost:8080,点登录,看是不是接口 401”
- 回归测试:“走一遍关键流程,截图对比”
- 性能分析:“跑一次 Lighthouse,把分数和优化点列出来”
8.3 注意
调用 MCP 工具前必须先 LS + Read 工具的 JSON 描述文件,确认参数 schema。直接调容易传错参数。
九、实战模式:如何"完美"地组合这些能力
9.1 模式 A:长跑任务监控(Schedule + RunCommand + 判定逻辑)
用户:"每 20 分钟检查 OCR 进度,完成了就告诉我,停滞了也告诉我"
Agent 流程:
1. Schedule create → cron "*/20 * * * *"
2. message 写满:命令 + 判定规则 + 输出格式 + 静默规则
3. 每次 cron 触发 → 新会话 → 并行跑命令 → 判定 → 仅异常时打扰用户
9.2 模式 B:大型重构(Task 子代理 + TodoWrite + Memory)
用户:"把 OCR 模块从同步改成异步队列"
Agent 流程:
1. TodoWrite 拆任务:设计 / 改 Service / 改 Controller / 加测试 / 改前端
2. 并行 Task:
- search 子代理:摸清现有调用链
- general_purpose_task 子代理:写新的异步处理器
3. 主 Agent:串改 Controller + 写测试
4. 写 project_memory.md:"OCR 改造为异步,队列名 ocr_queue"
5. NotifyUser:通知用户审查
9.3 模式 C:前端开发闭环(Skill + MCP + Read/Edit)
用户:"做一个数据看板"
Agent 流程:
1. Skill: frontend-design 加载设计准则
2. Skill: vercel-react-best-practices 加载性能规范
3. Write 生成组件代码
4. RunCommand 起 dev server
5. MCP navigate_page 打开预览
6. MCP take_screenshot 截图
7. 对照截图迭代
8. OpenPreview 推给用户
9.4 模式 D:探索陌生代码库(SearchCodebase + Task search)
用户:"这个项目里加密逻辑在哪?怎么调用的?"
Agent 流程:
1. SearchCodebase "敏感字段加密存储" (语义检索)
2. Grep "encrypt|decrypt" (精确文本)
3. Task search 子代理深挖调用链
4. 主 Agent 汇总:文件位置 + 调用图 + 关键代码引用
十、避坑清单(实战经验)
10.1 命令执行
- ✅ PowerShell 命令前必加 UTF-8 三件套(避免中文乱码)
- ✅ 不要用
&&/||连接 PowerShell 命令,用; - ✅ 长跑命令设
blocking: false,用CheckCommandStatus轮询 - ❌ 不要用
find/grep/cat/sed,用专用工具(Glob / Grep / Read / Edit)
10.2 文件操作
- ✅ 改文件前必须先 Read
- ✅ 大文件用
offset+limit分段读 - ❌ 禁止全文件覆盖写入已有文件(用 Edit 的 SearchReplace)
- ❌ 禁止
../越权访问项目目录外
10.3 定时任务
- ✅ message 必须自包含(路径、规则、格式)
- ✅ 一次任务 5-10 分钟内跑完
- ❌ 不要为一次性任务创建 Schedule
- ❌ 不要在 cron 里塞"自己改自己逻辑"的递归指令
10.4 子代理
- ✅ 独立任务才并行
- ✅ query 里传完整上下文
- ❌ 不要让子代理和主 Agent 做同样的事
- ❌ 不要为 1-2 步的简单任务起子代理
10.5 Skill
- ✅ 描述任务而非描述技能
- ✅ 一次任务可串联多个 Skill
- ❌ 不要显式要求"用 XX 技能",让 Agent 自动匹配
十一、回到最初的例子:一个完美的监控任务
如果要把那次 OCR 进度汇报做成真正的定时任务,理想配置是:
Schedule:
cron: "*/20 * * * *" # 每 20 分钟
timezone: "Asia/Shanghai"
name: "OCR 进度监控"
message: |
检查后台 4 个 Python OCR 进程进度并汇报。
命令(所有命令前加 $OutputEncoding=[System.Text.Encoding]::UTF8;
[Console]::OutputEncoding=[System.Text.Encoding]::UTF8):
1) Get-Process python -ErrorAction SilentlyContinue | Select Id,StartTime,CPU | Format-Table -Auto
2) python -c "import json; [print(f'shard{i}:', json.load(open(f'f:/AI开发区域/GL-开发隔离/C/scripts/image-toolkit/ocr_shard_{i}.json','r',encoding='utf-8'))['count'], '/250') for i in range(4)]"
3) Get-ChildItem 'f:\AI开发区域\GL-开发隔离\C\scripts\image-toolkit\ocr_shard_*.json' | Select Name,LastWriteTime | Format-Table -Auto
判定规则:
- 进程数 == 0 且 4 个 shard 都 250/250 → 报告完成 + 建议合并验证 + 暂停本任务
- 进程数 > 0 且任一文件 >30 分钟未更新 → 报告停滞 + 列出疑似卡住的分片
- 否则 → 一行简报(如 "29% (290/1000),正常运行")
汇报格式:中文表格
静默规则:进度正常时简短一行,仅异常时详细
这个配置的关键点:
- 自包含:路径、命令、规则都在 message 里
- 判定逻辑显式化:明确什么算"完成"、什么算"停滞"
- 静默策略:正常时不打扰用户
- 自动收尾:完成时建议暂停任务
- 编码规范:每个命令都带 UTF-8 设置
- 错误兜底:
-ErrorAction SilentlyContinue防止进程不存在时报错
十二、总结:让 Agent 替你"省心"的三原则
- 自包含原则:把任务描述写得让一个新人无需追问就能执行。路径、规则、格式、判定标准都要写全。
- 职责分离原则:调度(Schedule)、执行(RunCommand/Task)、记忆(Memory)、呈现(响应格式)各司其职,不要让一个工具干所有事。
- 静默优先原则:周期任务默认不打扰用户,只在异常或完成时才详细汇报。这能让你"挂着跑"而不被打断。
附录:能力速查卡
┌─ 命令 ───────────────────────────────────────┐
│ RunCommand 执行 shell 命令 │
│ CheckCommandStatus 查看异步命令状态 │
│ StopCommand 停止命令 │
├─ 文件 ───────────────────────────────────────┤
│ Read / Edit / Write 读写改 │
│ Glob / Grep 按名/内容搜索 │
│ DeleteFile 删除 │
├─ 代码 ───────────────────────────────────────┤
│ SearchCodebase 语义检索(按意图找代码) │
├─ 代理 ───────────────────────────────────────┤
│ Task(search) 并行代码探索 │
│ Task(general_purpose) 复杂编码子任务 │
├─ 调度 ───────────────────────────────────────┤
│ Schedule cron 周期任务 │
├─ MCP ────────────────────────────────────────┤
│ run_mcp 调用外部连接器 │
├─ 记忆 ───────────────────────────────────────┤
│ user_profile.md 用户偏好 │
│ project_memory.md 项目规则 │
│ topics.md 话题摘要 │
├─ 技能 ───────────────────────────────────────┤
│ Skill 加载领域专家工作流 │
├─ 交互 ───────────────────────────────────────┤
│ AskUserQuestion 决策点征求意见 │
│ NotifyUser 通知审查 / 批准 │
│ TodoWrite 多步任务追踪 │
└──────────────────────────────────────────────┘
人到中年,最大的变化是学会了"不急"。带团队也好,找第二曲线也好,都不必非要在某个节点交出满分答卷。每天做一点新的尝试,被年轻人带飞几次,被自己蠢哭几回,这一天就没白过。不油腻的秘诀?保持被打脸的机会,然后笑嘻嘻地爬起来。
关注我,咱们一起晒太阳、赶路。
更多推荐




所有评论(0)