前言
完整代码已开源,欢迎 Star 和交流。
https://github.com/SkyChenSky/Sky.DingTalk.AI
业务群里,同事与 QA、产品围绕问题几轮沟通后结论清晰:或是 Bug 需排期,或是新需求待评估。然而讨论结束后,最痛苦的环节随之而来:有人需消化聊天记录,手动在云效(或 Oncs)中立项、提炼标题描述并指派负责人。讨论越充分,搬运越痛苦。
团队日常沟通在钉钉,项目管理在云效,中间隔着「手工搬运」的机械重复。于是目标很朴素:讨论定论后,在群里 @机器人 说一句话,它便自动建好工作项并返回地址。结合刚 GA 的Microsoft Agent Framework与 .NET 10,这个 Demo 应运而生。
打通「口语转结构化工作项」不仅是省事的建单工具,更是整条 AI 研发流水线的第一个闸口。工作项作为研发过程的结构化锚点,可挂载一系列 Agent:
- Bug 建完只是开始
:Agent 根据项目拉取代码仓库,AI 扫描相关模块,将「疑似出错文件、最近变更记录」回填至工作项,让开发在打开 IDE 前即可获取排查线索; - 需求立项即预估
:结合历史相似需求进行影响面分析,给出改动范围和涉及模块,辅助排期决策; - 订单(数据)查找
:根据提供的订单号,通过 MCP 由 AI 进行整理。
本文旨在打通第一环,后续 Agent 均挂在「工作项」这一锚点上:
当信息在钉钉、云效、代码库间自动流动,人便从「搬运工」回归「决策者」。本文将详解从前期准备、钉钉机器人接入、AI Agent 集成到云效 API 封装的全流程。
最终效果如下,在钉钉群 @机器人:

@云效助手 下单页在 iOS 上白屏了,项目是商城,严重的话帮我建个缺陷,给陈珙
机器人回复:
创建成功,工作项地址:https://devops.aliyun.com/projex/project/xxx/bug/xxxx
下面正式开工。
目的与作用
核心目标明确:把群里口语化的反馈,自动落地成云效里结构化的工作项。
具体实现三大功能:
- 听懂人话
:AI 从口语消息中提取结构化信息——项目名、类型(Bug/需求/任务)、标题、负责人及描述。 - 会干活
:通过 Function Calling 直接操作云效 API,执行查项目、查成员、建工作项等任务。 - 有上下文
:支持多轮会话。若信息缺失(如未指定项目),AI 会追问;用户补充后,能结合语境继续完成任务。
整体架构如下:
技术选型三件套:
- Jusoft.DingtalkStream
:钉钉官方 Stream 模式的 .NET 社区封装,免去自建 WebSocket 和暴露公网回调地址。 - Microsoft.Agents.AI
:微软新出的 Agent 框架, ChatClientAgent+ 工具注册,快速构建能调工具的 Agent。 - Sikiro.YunXiao
:自封装的云效 OpenAPI 客户端类库(独立项目,可复用)。
前期准备:AI、钉钉、云效的配置获取
需提前获取三方平台的凭证配置。
2.1 AI 接口(DeepSeek 为例)
Agent 需依赖支持工具调用(Function Calling)的 OpenAI 兼容 Chat Completions 接口。
以 DeepSeek 为例:
-
注册并充值,创建 API Key( sk-开头); -
记录 ApiKey、Endpoint(https://api.deepseek.com)及Model(如deepseek-chat)。
智谱、通义、Kimi 等国产模型均提供 OpenAI 兼容接口,更换模型仅需修改配置。
2.2 钉钉应用(Stream 模式机器人)
采用 Stream 模式通过 WebSocket 长连接反向连接钉钉服务端,便于本地调试。
-
在钉钉开放平台创建企业内部应用; -
添加「机器人」应用能力; -
消息接收模式选择Stream 模式; -
获取 ClientId和ClientSecret; -
发布应用并添加至群聊。
2.3 云效(阿里云 Yunxiao)
云效 Projex OpenAPI 提供两种认证方式:
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
|
|
|
|
x-yunxiao-token
|
推荐PAT 方案:在云效「个人设置 → 个人访问令牌」生成,无需阿里云主账号 AK,且支持 oapi/v1 新接口(工作项类型、字段定义等)。
另需记录OrganizationId(组织 ID):位于云效页面 URL 的organizations/{ID}/段落中。
2.4 配置外置
将所有凭证存入appsettings.json,避免硬编码。
钉钉机器人与 AI 的集成
建议实施顺序:先跑通消息链路,再赋予 Agent 能力。
3.1 消息处理器:模板方法模式
采用模板方法模式固定处理骨架:过滤 → 提取 → 生成回答 → 回复。基类定义流程,子类专注「如何生成回答」。
细节上,GetTextContent需按消息类型分派:文字为text,富文本(转发、引用、Markdown)为richText。
具体处理器逻辑简洁:
3.2 Agent:ChatClientAgent + 工具注册
利用Microsoft.Agents.AI的ChatClientAgent打包大模型、提示词与工具集:
IChatClient来自Microsoft.Extensions.AI.OpenAI,兼容任意 OpenAI 模型:
services.AddSingleton<IChatClient>(_ => new OpenAIClient(new ApiKeyCredential(ai.ApiKey), new OpenAIClientOptions { Endpoint = new Uri(ai.Endpoint), }).GetChatClient(ai.Model).AsIChatClient());
提示词策略:能默认则默认,仅在项目名不明时追问,避免繁琐交互。
你是钉钉群里的「云效项目助手」,帮助团队成员把口语化的反馈落地成云效工作项。 处理用户消息的规则:1. 从消息中提取:项目名、工作项类型(Bug 缺陷 / Req 需求 / Task 任务)、标题、负责人、描述。2. 信息不全时优先用合理默认值,不要向用户二次确认: - 类型未提及 → 默认 Bug; - 描述未提及 → 把用户的原话整理成描述; - 负责人未提及 → 默认用消息标注的「发起人」(@机器人的用户)。3. 只有当「项目名」完全无法确定时,才回复用户请他补充是哪个项目; 用户补充后必须结合上下文继续处理,不要重复追问。4. 不确定项目名是否真实存在时,先调用 ListProjects 核对(宁可多查一次,不要猜)。5. 创建成功后,回复一句话结果并附上工作项地址(URL)。
3.3 多轮会话
使用ConcurrentDictionary<群 ID, AgentSession>按群保存会话。需注意协议差异:
|
|
|
|
|---|---|---|
|
|
|
conversation_id,历史存服务端
|
|
|
|
|
DeepSeek 属无状态协议,需在应用侧自行管理历史(SetInMemoryChatHistory),每轮发送全量历史。
每个群保留最近 40 条消息(滑动窗口),截断时需避开「工具调用/结果」对,确保上下文完整。
云效 API 的封装
将云效 OpenAPI 封装为独立类库Sikiro.YunXiao,供 AI 调用。
4.1 双认证方案:一个客户端兼容两套网关
YunxiaoClient构造时二选一,自动路由:
- 方案一(AK)
:基于阿里云 V2.0 通用 SDK,自动完成 ACS V3 签名; - 方案二(PAT)
:裸 HttpClient+x-yunxiao-token请求头直连,无需签名。
4.2 极简创建:QuickCreateWorkItemAsync
封装极简版本,调用方仅需传大类、标题、项目名,其余参数自动推断,降低 AI 调用难度。
返回工作项 URL,实现体验闭环。设计原则:减少参数、返回人话。
4.3 把客户端变成 Agent 工具
利用AIFunctionFactory.Create将普通方法转为 Agent 工具,[Description]特性作为模型说明书。
工具返回值统一为中文文本,失败时直接返回错误描述,便于模型转述。同时支持类型参数别名兼容。
三者的集成:组装起飞
通过依赖注入串联三者,Program.cs保持简洁:
注册顺序体现依赖:云效客户端 → Agent → 消息处理器。
消息完整旅程如下:
我有话想说
当前能力边界及后续计划:
- 群聊总结建单
:结合钉钉 AI 小钉先做对话总结,再交由本 Agent 落单; - 图片上传
:完善富文本图片下载与云效附件上传链路; - 上下文外置
:将会话历史迁移至 Redis/数据库,确保持久化; - 代码初判
:AI 扫描代码仓库,将疑似模块线索回填至工作项。
最后分享一点感触。
边界不是墙,是插座。「拿不到群聊历史」看似短板,实则是与其他 Agent 协作的接入点。Agent 时代的架构精髓在于编排这些边界——单体能力有限,组合想象无限。
自动化的终点绝非替代人。妄言用 AI 代替人是狂妄的——机器人建单、AI 给线索,但最终拍板、定责、取舍的依然是人。工具越强,人的决策越值钱。让信息自动流动,让人专注于判断,这便是初衷。
让 AI 代替人,本是不负责任的狂妄——重复给流程,繁琐给 AI,决策与创造留给人。
与诸君共勉。

