DeepSeek Harness + cc-connect + 飞书:从"只有最终结果"到"实时流式输出"
2026-08-17 | 作者:borong | 分类:AI 编程
一、为什么会有这篇文章
之前我们已经把 DeepSeek Harness 接入飞书:
text
飞书
-> cc-connect
-> DeepSeek Harness ACP
-> DeepSeek 模型
手机发消息、本地 Agent 执行、结果回到飞书,这条路已经能跑通。但实际使用时有一个很明显的问题:
飞书里只能看到最终回复,看不到它在想什么、正在执行什么工具、执行到哪一步。
长时间没有反馈时,体验很像"机器人卡住了"。这篇文章记录我怎么解决这个问题,以及最后把它做成一个社区插件发布出去。
二、问题根因
第一版使用的是 Harness 自带 ACP 服务。ACP 是 Agent Client Protocol,本质是 JSON-RPC over stdio,非常适合 cc-connect 这类桥接层。
但 Harness 的 ACP 实现有明确设计:
text
只发送 committed assistant message
不发送未提交的 token 增量
不发送思考过程
不发送工具过程
所以 cc-connect 虽然支持流式,却没有上游增量可以转发。
三、新架构
我选择不把流式能力塞进 Harness 自带 ACP,而是单独做一个桥接组件:
text
飞书
-> cc-connect(type = "acp")
-> dsh-streaming-mcp-bridge
-> Harness SDK JSON-RPC
-> DeepSeek 模型 + Harness 工具能力
关键变化:
- 不再依赖 Harness ACP 的 committed message。
- 改用 Harness SDK JSON-RPC 的实时事件流。
- 实时事件包括:
session.statusassistant/chunktool/calltool/resultturn/startturn/end
- 桥接组件同时提供:
- ACP 模式,供 cc-connect / 飞书使用
- MCP Streamable HTTP,供其他 MCP 客户端使用
四、实时事件如何转发给飞书
1. Harness SDK JSON-RPC
Harness SDK 会实时推送 session 事件:
json
{
"method": "session.event",
"params": {
"sessionId": "session-xxx",
"event": {
"type": "assistant/chunk",
"data": {
"chunk": {
"type": "text-delta",
"text": "正在..."
}
}
}
}
}
2. ACP 增量
桥接组件把这些事件转成 ACP agent_message_chunk:
json
{
"sessionId": "acp-session-xxx",
"update": {
"sessionUpdate": "agent_message_chunk",
"content": {
"type": "text",
"text": "[工具] bash {...}\n"
}
}
}
cc-connect 收到后转成 EventText,飞书就能实时更新。
3. MCP 进度
除了飞书链路,桥接组件也对外提供 MCP Streamable HTTP:
text
http://127.0.0.1:3477/mcp
调用 dsh_run_stream 时,会发送:
text
notifications/progress
适合接入 Claude、Codex 或其他支持 MCP 的客户端。
五、飞书展示格式
最开始我把所有过程放进一个大代码块,但使用中发现问题:后面的进度被折叠,必须点开才能看到。
最终改成:
text
[已接收] Harness 已开始执行,以下是实时进度。
[状态] running
[开始执行]
[思考中]
[工具] bash {...}
最终回答
[结束] completed
[状态] idle
每条状态、思考、工具调用/结果使用独立代码块,最终回答放在代码块外。
六、cc-connect 配置
toml
[[projects]]
name = "dsh"
admin_from = "*"
[projects.agent]
type = "acp"
[projects.agent.options]
work_dir = "/home/boronglee/dsh-workspace"
cmd = "/path/to/node"
args = [
"/path/to/dsh-streaming-mcp/bin/acp.js",
"--workspace",
"/home/boronglee/dsh-workspace"
]
display_name = "DeepSeek Harness Streaming"
[projects.agent.options.env]
DEEPSEEK_API_KEY = "your-api-key"
DSH_PERMISSION_MODE = "workspace-write"
DSH_MODEL = "deepseek-v4-flash"
七、验证结果
ACP smoke
text
STOP_REASON end_turn
UPDATE_COUNT 8
SMOKE_ACP_OK
输出顺序:
text
[状态] running
[开始执行]
[思考中]
[工具] bash {...}
最终回答
[结束] completed
MCP SSE
调用 dsh_run_stream 后:
text
notifications/progress
[已接收] Harness 已开始执行
[状态] running
[开始执行]
[思考中]
最终返回:
json
{
"sessionId": "session-xxx",
"finalResponse": "最终回答",
"eventCount": 243
}
飞书实机
通过 cc-connect 临时任务验证:
text
session spawned
turn complete
飞书会话中能看到完整过程,不再只有最后一条结果。
八、作为社区插件发布
这个桥接已经发布为 DeepSeek Harness 社区插件:
text
包名:dsh-streaming-mcp-bridge
GitHub:https://github.com/yabolee-kkk/dsh-streaming-mcp-bridge
npm:https://www.npmjs.com/package/dsh-streaming-mcp-bridge
安装:
bash
dsh plugin --profile web add dsh-streaming-mcp-bridge
九、总结
这次解决问题的核心不是"把 ACP 日志打出来",而是换掉事件来源:
text
committed message
->
SDK JSON-RPC 实时 session event
再用一个独立桥接层同时服务 MCP 和 ACP。这样:
- 飞书能看到实时过程。
- MCP 客户端也能拿到进度。
- Harness 自带的 ACP 不需要被强行改造。
- 社区可以直接安装发布好的插件。
Agent 的入口不一定要被绑在电脑前。手机、飞书、MCP 都可以成为调用本地 Agent 的入口。