Skip to content
XpercentPublic

About

本地双 Agent 轻量级 HTTP 通信工具:Codex控制Workbuddy,Codex控制Qoder

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AgentChat

在同一台机器上的两个 Agent 之间,通过 HTTP 传递任务和结果。

  • Agent1 提交任务,等待或补取结果。
  • Agent2 接收任务、完成工作,再交回结果。
  • serve 是常驻中继,只保存和转发文本,不执行任务。
  • watch 是一次性后台等待进程:先输出信息,再退出,由宿主的后台任务完成通知唤醒 Agent2。

AgentChat 不包含模型,也不会自动执行任务、调用 reply 或重启 watch。这些动作由 Agent2 按输出指引完成。

运行前提

在包含 run.py 的项目目录下执行以下命令。需要 Python,以及项目列出的依赖:

python -m pip install -r agentchat/requirements.txt

通信地址固定为 http://127.0.0.1:18765,不提供自定义地址、端口或 Token 参数。只适用于本机通信,不要将中继暴露到不可信网络。

Agent2 的宿主必须支持:启动后台任务,并在任务结束后恢复 Agent 会话、提供该任务的输出。 仅仅把进程放到操作系统后台,并不等于宿主能唤醒 Agent。若宿主不支持这项能力,不能依靠 watch 实现自动唤醒。

宿主应让 serve 长期运行,并允许每次后台 watch 完整运行 9 分钟,不要让任务工具较短的默认时限提前杀死它。宿主任务工具的时限与 AgentChat 命令行参数是两回事。

给 Agent 使用的具体操作规程见项目根目录 SKILL.md。安装技能时,将其放入宿主支持的技能目录;命令仍应在本项目目录中执行,不是在技能安装目录中执行。

一轮完整交互

1. Agent2 启动接收端

通过宿主的后台任务工具,分别启动以下两个进程;不要把它们串成一个前台命令:

python run.py serve

确认中继启动成功并仍在运行后,再启动另一个后台任务:

python run.py watch

确认 watch 已作为后台任务运行,再结束 Agent2 当前会话,交还控制权给宿主。不要在前台等它退出,也不要为了等通知持续轮询后台状态。

serve 只需启动一次;每次 watch 结束后,需要由 Agent2 重新启动新的 watch。

2. Agent1 发任务

python run.py send --text "请处理这个任务"

该命令默认等待结果,成功时标准输出就是 Agent2 交回的结果。

3. Agent2 被任务唤醒

watch 输出“收到任务 #N”、任务正文和后续指引,然后以退出码 0 退出。Agent2 读取输出,完成任务,再交回结果。下面的 1 必须替换为本次输出中的实际任务 ID:

python run.py reply --id 1 --text "实际处理结果"

长结果可以先写入 .tmp/结果.md,再发送文件内容:

python run.py reply --id 1 --file .tmp/结果.md

确认回复成功后,通过宿主工具重新启动一个后台任务:

python run.py watch

然后结束当前会话,等待下一次通知。不要每轮重启 serve。

九分钟保活:不是新任务

当前使用场景中,后台等待超过 10 分钟后再结束,宿主可能无法恢复 Agent2。为提前产生一次完成通知,watch 每次启动后最多等待 9 分钟。

没有任务时的流程:

  1. 本次 watch 启动,从零计时。
  2. 满 9 分钟后,输出“保活唤醒”“这不是任务”和重新启动 watch 的指引。
  3. 刷新输出,以退出码 0 退出。
  4. 宿主恢复 Agent2;Agent2 不执行任务、不调用 reply,只重新后台启动 python run.py watch。
  5. 新进程从零开始下一轮 9 分钟计时,Agent2 再结束会话。

保活和收到任务的退出码都是 0,必须阅读输出区分,不能只判断退出码。

watch 不会自行创建下一个进程。进程内部的临时通信失败重试,也不会重置本进程的计时。9 分钟是后台接单阶段的保活周期,不是任务执行时限;处理任务期间,已经退出的 watch 不会继续计时或产生通知。

保活依赖宿主实际发出完成通知;若宿主提前终止进程或不能恢复会话,本工具不能保证 Agent2 在线。

当前命令与参数

以下是全部 6 个子命令。所有子命令均支持 --help;没有列出的业务参数不应使用。

命令 业务参数 行为
serve 无 启动常驻中继
watch 无 收到任务或满 9 分钟后,先输出指引再退出
send --text、--file、--detach 提交任务;默认等待结果
reply --id(必填)、--text、--file 为指定任务交回结果
wait --id(必填)、--timeout 等待或补取指定任务的结果
stop 无 停止中继;只在明确需要结束服务时使用

文本与文件

send 和 reply 都可以通过 --text "内容" 或 --file 路径 提供文本,建议每次只选择一种。若同时指定,当前实现优先读取文件。

--file 只读取文件内容,不会创建或删除该文件;--file - 表示读取标准输入。两种参数都未指定时,也可以从管道输入文本。文件优先按 UTF-8 读取,兼容 UTF-8 BOM,解码失败时按 GBK 读取。程序输出固定为 UTF-8。

临时任务文件、结果文件放在 .tmp/,需要时先通过宿主文件工具创建目录。

先提交,再取结果

如果调用方不能让一个命令持续运行约 20 分钟,使用:

python run.py send --text "请处理这个任务" --detach

命令立即返回,任务 ID 写在标准错误中的“已提交 #N”提示里;不要把这条提示误当作提交失败。随后使用实际 ID:

python run.py wait --id 1

send 的默认结果等待上限是 20 分钟,不提供命令行配置。wait 默认也等待 20 分钟,固定每 2 秒查询一次;只有 wait 保留等待时长参数,单位为秒:

python run.py wait --id 1 --timeout 60

wait 只查询已有任务,不会再次提交。超时不取消任务;中继未重启时,迟到的 reply 仍可被后续 wait 取回。没有明确证据表明提交失败时,不要直接重发同一任务。

帮助与停止

python run.py --help
python run.py --version
python run.py send --help
python run.py stop

stop 会终止中继,不应在每次回复或保活时执行。

退出和恢复

场景 退出码 下一步
watch 收到任务 0 完成任务 → reply 成功 → 后台启动新 watch → 结束会话
watch 九分钟保活 0 不调用 reply;后台启动新 watch → 结束会话
watch 启动时无法连接中继 5 检查原 serve 的后台状态与输出;恢复中继后重挂 watch
watch 运行中连续通信失败 3 次 4 检查连接与中继状态;修复后重挂,不当作正常保活
send 或 wait 等结果超时 3 保存任务 ID,用 wait --id N 补取,不直接重发
send 或 wait 的通信等请求错误 4 阅读错误详情;不能据此断定任务未提交
reply 被中继拒绝或通信失败 1 查看具体错误;未确认成功前不声称已交回
命令或参数不合法 2 按当前命令表修正,不是“没有任务”

watch 运行中若通信失败,在剩余生命周期内重试:首次失败后等待最多 2 秒,第二次失败后等待最多 4 秒,连续第三次失败就报错退出。达到九分钟期限时转为保活退出,不额外延长等待。程序不自动重启 serve。

reply 的错误中,404 表示当前中继没有这个任务 ID;409 表示已经回复过,不能重复提交。中继仍运行时先查看其输出,不要盲目启动第二个 serve,更不要为排障随意停止现有中继。

日志与状态限制

  • serve 将任务写入其当前工作目录的 data/i{id}.md,将结果写入 data/o{id}.md。
  • send 在自己的当前工作目录记录已知任务 ID 对应的输入;阻塞等待成功时也记录结果。分离提交和超时返回时只有输入,wait 目前不会补写发送端的结果文件。
  • 路径固定为各进程当前工作目录下的 data/,没有目录配置或禁用记录选项。希望共用一份记录时,所有命令从同一项目目录执行。
  • data/ 只是日志,不是传话渠道。接任务看 watch 输出,取结果用 send 或 wait,不要扫描日志当作消息队列。
  • 任务队列和可查询结果保存在中继内存中。重启 serve 会丢失这些状态;已有日志不会恢复任务。编号会根据现有日志文件名接着分配,这不代表旧任务仍能查询。
  • 日志可能包含完整任务与结果,不要将敏感内容写入不可信目录。

参数变化说明

九分钟保活没有新增命令行参数:直接运行 python run.py watch,不需要传入时长或重启选项。

代码内部的 client.next_task() 增加了可选的 timeout 入参,用于限制本次网络请求的等待时间;这是 Python 内部接口,不是 watch 的命令行参数。

About

本地双 Agent 轻量级 HTTP 通信工具:Codex控制Workbuddy,Codex控制Qoder

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages