Files
aiagent/docs/创建工单总结.md
renjianbo eabf90c496 feat: add AI学习助手 agent (KG+RAG ideal) and renshenguo feishu bot
- Add AI学习助手 agent creation script with all 39 tools, 3-layer KG+RAG memory
- Add renshenguo (人参果) feishu bot integration (app_service + ws_handler)
- Register renshenguo WS client in main.py startup
- Add RENSHENGUO_APP_ID / RENSHENGUO_APP_SECRET / RENSHENGUO_AGENT_ID config
- Reorganize docs from root into docs/ subdirectories
- Move startup scripts to scripts/startup/
- Various backend optimizations and tool improvements

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-06 01:37:13 +08:00

4.8 KiB
Raw Blame History

创建工单总结

整体流程

测试页面 → 阅读源码 → 后端API验证 → 前端代码审查 → 定位Bug → 写入Gitea平台

1. 测试目标

浏览器访问 http://localhost:3001/agent-chat,测试其中的 Agent 助手对话功能。

2. 源码阅读

读取出错的关键文件:

文件 作用
src/views/AgentChat.vue Agent 对话页面主组件
src/components/AgentChatPreview.vue Agent 预览对话组件
src/api/index.ts 前端 API 封装 (axios)
src/stores/agent.ts Agent 状态管理 (Pinia)
src/router/index.ts 路由配置
backend/app/api/agent_chat.py 后端对话 API

3. 后端 API 验证

用 curl 逐一测试 7 个 API 端点:

# 登录获取 token(后端使用 form-encoded,非 JSON)
curl -s -X POST http://localhost:8037/api/v1/auth/login \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d 'username=admin&password=123456'

# 测试 bare 对话
curl -s -X POST http://localhost:8037/api/v1/agent-chat/bare \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"message":"hello"}'

# 测试带 Agent ID 的对话
curl -s -X POST "http://localhost:8037/api/v1/agent-chat/{agent_id}" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"message":"hello"}'

# 测试 SSE 流式
curl -s -X POST http://localhost:8037/api/v1/agent-chat/bare/stream \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"message":"hello"}'

# 测试多 Agent 编排
curl -s -X POST http://localhost:8037/api/v1/agent-chat/orchestrate \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"message":"hello","mode":"debate","agents":[...]}'

结果:后端 7 个端点全部正常,问题在前端代码。

4. 前端代码审查(定位Bug)

逐行审查 AgentChat.vue 中 sendMessage() 函数的 SSE 流式 + fallback 逻辑:

第 432 行 → push 占位消息(content: '')
第 440-504 行 → SSE 流读取事件
第 506 行 → catch { usedStreaming = false }  ← 流失败
第 513-527 行 → if (!usedStreaming) push fallback 结果 ← 重复!

定位到 5 个 Bug:

# 问题 位置
1 SSE 流失败后占位消息未删除,fallback POST 又 push 一条,导致重复 :424-527
2 流正常结束后 streamTimeout 未清除 :411
3 final 事件与 finally 之间 loading 状态闪烁 :496-537
4 前端 SSE 事件类型硬编码,可能与后端 runtime 不一致 :467-501
5 retryMessage 在流式失败场景下占位消息残留 :571-609

5. 创建 Gitea 工单

获取 Token

curl -s -X POST "http://101.43.95.130:3001/api/v1/users/admin/tokens" \
  -u "admin:123456" \
  -H "Content-Type: application/json" \
  -d '{"name":"claude-code-api","scopes":["write:issue","write:repository","read:repository","read:user"]}'

返回 token:fbc9ee7f96635793f4844187eac5c0e573480721

查找仓库

curl -s "http://101.43.95.130:3001/api/v1/repos/admin/aiagent" \
  -H "Authorization: token $TOKEN"

确认仓库为 admin/aiagent。

批量创建工单

JSON 模板:

{
  "title": "[Bug] 问题标题",
  "body": "## 问题描述\n\n...\n\n## 涉及文件\n\n...\n\n## 严重程度\n\n...",
  "assignee": "admin"
}

创建命令:

curl -s -X POST "http://101.43.95.130:3001/api/v1/repos/admin/aiagent/issues" \
  -H "Authorization: token $TOKEN" \
  -H "Content-Type: application/json" \
  --data-binary @/tmp/issue.json

踩坑记录

  • 中文编码问题:curl -d 参数直接写中文 JSON 会编码异常(json: slice unexpected end of JSON input),改用 --data-binary @文件路径 方式解决
  • labels 参数:Gitea 的 labels 必须传数字 ID 而非字符串名,第一批次去掉 labels 规避
  • Gitea 版本:使用 GET /api/v1/version 确认版本为 1.25.2,API 兼容 GitHub 风格

6. 验证与关闭

# 查看工单列表
curl -s "http://101.43.95.130:3001/api/v1/repos/admin/aiagent/issues?state=open" \
  -H "Authorization: token $TOKEN"

# 关闭工单
curl -s -X PATCH "http://101.43.95.130:3001/api/v1/repos/admin/aiagent/issues/1" \
  -H "Authorization: token $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"state":"closed"}'

总结

步骤 耗时 工具
测试页面 + 读源码 主要时间 Read, Grep
后端 API 验证 快速 curl
前端代码审查定位 Bug 主要时间 Read (逐行审查)
创建工单 快速 curl + Gitea API
关闭工单 快速 curl + Gitea API

核心思路:先验证后端排除服务端问题,再集中审查前端业务逻辑找到根因。