2025-03-30 09:13:46 +08:00
|
|
|
|
#### 1. AI agent
|
|
|
|
|
|
|
|
|
|
Agent模块负责处理request工作流,生成prompt与LLM交互。
|
2025-03-30 11:15:38 +08:00
|
|
|
|
|
|
|
|
|
> Agent代码:
|
|
|
|
|
> <http://ishangsf.com:8100/ken/agent>
|
|
|
|
|
>
|
|
|
|
|
> websocket接口地址:
|
2025-04-04 16:29:24 +08:00
|
|
|
|
> <ws://47.117.75.243:8080/ws>
|
2025-03-30 11:15:38 +08:00
|
|
|
|
>
|
|
|
|
|
> 接口文档:
|
|
|
|
|
> <http://ishangsf.com:8100/ken/agent/src/branch/main/README.md>
|
|
|
|
|
>
|
|
|
|
|
> 前端接口测试案例代码:
|
|
|
|
|
> <http://ishangsf.com:8100/ken/agent/src/branch/main/examples>
|
|
|
|
|
>
|
|
|
|
|
> 测试api_key: “***simpletest2025***_xxxx” xxxx为任意字符串
|
|
|
|
|
|
2025-03-30 09:13:46 +08:00
|
|
|
|
Agent 有三模式运行,由plugin在request的model参数决定,运行模式在交互过程对agent是透明的。
|
|
|
|
|
|
|
|
|
|
> 1. agent local model:就是agent调用本地部署的LLM模型
|
2025-04-04 16:30:50 +08:00
|
|
|
|
> 2. agent remote api:就是agent调用openai或deepseek等外部服务的api (改下llm就看实现)
|
|
|
|
|
> 3. plugin remote api:由plugin调用openai或deepseek等外部服务的api (未实现,要改ideservice)
|
2025-03-30 09:13:46 +08:00
|
|
|
|
|
2025-04-04 15:51:56 +08:00
|
|
|
|
##### 1.1 安装与运行
|
2025-03-30 09:13:46 +08:00
|
|
|
|
|
2025-04-04 15:51:56 +08:00
|
|
|
|
```shell
|
|
|
|
|
# linux
|
|
|
|
|
make
|
|
|
|
|
./build/bin/agent run
|
|
|
|
|
|
|
|
|
|
# windows
|
|
|
|
|
go build -o ../build/bin/agent.exe src/main.go
|
|
|
|
|
./build/bin/agent.exe run
|
|
|
|
|
```
|
|
|
|
|
|
2025-04-04 16:30:50 +08:00
|
|
|
|
##### 1.2系统框架
|
2025-03-30 09:13:46 +08:00
|
|
|
|
|
|
|
|
|
<img src="assets/架构.png" alt="drawing" style="width:700px;"/>
|
|
|
|
|
|
|
|
|
|
ideservice 是须要plugin提供给agent的一些获取IDE信息的基础功能,为穿透NAT需要websocket连接。
|
|
|
|
|
|
2025-04-04 16:30:50 +08:00
|
|
|
|
##### 1.3 workflow
|
2025-03-30 09:13:46 +08:00
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
sequenceDiagram
|
|
|
|
|
plugin->>agent: request
|
|
|
|
|
agent-->>ideservice: more info
|
|
|
|
|
ideservice-->>agent: file, symbol
|
|
|
|
|
agent->>plugin: result
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
agent有可能会多次向ideservice询问更多的信息,这对于plugin是透明的。
|
|
|
|
|
|
|
|
|
|
|
2025-04-04 16:30:50 +08:00
|
|
|
|
##### 1.4 Task Pool
|
2025-03-30 09:13:46 +08:00
|
|
|
|
|
|
|
|
|
章节2中所有带cmd参数带前缀“exec”的request都是涉及LLM模型调用的。
|
|
|
|
|
Agent用一个FIFO队列缓存所有用户的未处理任务,当队列长度过大时agent会拒绝新来的任务。
|
|
|
|
|
同一APIkey同时能建立5个链接,一个连接只能有一个任务在队列,同时提交两个task, 前一个会被取消。
|
|
|
|
|
|
|
|
|
|
#### 2. Agent协议
|
|
|
|
|
|
|
|
|
|
plugin通过websocket连接agent。如果使用https, 需要设置client接受agent的https认证证书。
|
|
|
|
|
|
|
|
|
|
##### 2.1 身份认证
|
|
|
|
|
|
|
|
|
|
建立连接时带header "X-Api-Key" : api_key,如果api_key不对agent主动断开连接
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
let client = new ws.WebSocket('wss://host:8080/ws', {headers: {
|
|
|
|
|
["X-Api-Key"]: "simpletest2025_001",
|
|
|
|
|
}})
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
##### 2.2 获取Agent支持的模型 (list_model)
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
request:
|
|
|
|
|
{
|
|
|
|
|
"request_id": 123, // 随机生成 (必填)
|
|
|
|
|
"cmd" : "list_model"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
response:
|
|
|
|
|
{
|
|
|
|
|
"request_id": 123, // 同request
|
|
|
|
|
"models" : ["local deepseek-R1:32b", "deepseek-R1:32b"] // (必填)
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
##### 2.3 生成代码解释 (exec_explain)
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
request:
|
|
|
|
|
{
|
|
|
|
|
"cmd" : "exec_explain",
|
|
|
|
|
"request_id" : 123, // 随机生成 (必填)
|
|
|
|
|
"language" : "en", // 语言, en-英文, zh-中文,默认为 en (可选)
|
|
|
|
|
"selected_text": text_context, // 选取的代码片段 (必填)
|
|
|
|
|
"visible_text" : text_context, // ide窗口可见的代码片段 (必填)
|
|
|
|
|
"model" : "local deepseek-r1:32b", //(必填)
|
|
|
|
|
"stream" : false // stream方式返回(可选)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
text_context:
|
|
|
|
|
{
|
|
|
|
|
"filepath": "example\\\\game.py", // 文件路径
|
|
|
|
|
"range": {
|
|
|
|
|
"start": { "line": 33, "character": 0}, // 从33行0字符开始
|
|
|
|
|
"end" : { "line": 45, "character": 41} // 到45行41字符结束
|
|
|
|
|
},
|
|
|
|
|
"text": "..." // 源码片段
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
成功返回:
|
|
|
|
|
{
|
|
|
|
|
"request_id" : 123, // 同request(必填)
|
|
|
|
|
"msg" : "", // 返回内容
|
|
|
|
|
"stream_seq_id": 0, // stream=true时才有, 从0开始(可选)
|
|
|
|
|
"stream_finsh" : false, // stream=true时才有, true-stream结束(可选)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
失败返回:
|
|
|
|
|
{
|
|
|
|
|
"request_id": 123, // 同request(必填)
|
|
|
|
|
"error" : "cancelled" // 出错信息,没有就是调用成功(必填)
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
##### 2.4 生成代码文档 (exec_docstring)
|
|
|
|
|
|
|
|
|
|
目前只支持python
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
request:
|
|
|
|
|
{
|
|
|
|
|
"cmd" : "exec_docstring",
|
|
|
|
|
"request_id" : 123, // 随机生成 (必填)
|
|
|
|
|
"language" : "en", // 语言, en-英文, zh-中文,默认为 en (可选)
|
|
|
|
|
"selected_text": text_context, // 选取的代码片段 (必填)
|
|
|
|
|
"model" : "local deepseek-r1:32b", //(必填)
|
|
|
|
|
"stream" : false // stream方式返回 (可选)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
返回json格式同 2.3
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
##### 2.5 代码优化 (exec_optimize)
|
|
|
|
|
|
|
|
|
|
//TODO 未测试效果, prompt该如何描述优化?
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
request:
|
|
|
|
|
{
|
|
|
|
|
"cmd" : "exec_optimize",
|
|
|
|
|
"request_id" : 123, // 随机生成 (必填)
|
|
|
|
|
"language" : "en", // 语言, en-英文, zh-中文,默认为 en (可选)
|
|
|
|
|
"selected_text": "", // 选取的代码片段 (必填)
|
|
|
|
|
"model" : "local deepseek-r1:32b", //(必填)
|
|
|
|
|
"stream" : false // stream方式返回 (可选)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
返回json格式同 2.3
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
##### 2.6 生成单元测试代码 (exec_fix)
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
request:
|
|
|
|
|
{
|
|
|
|
|
"cmd" : "exec_fix",
|
|
|
|
|
"request_id" : 123, // 随机生成 (必填)
|
|
|
|
|
"language" : "en", // 语言, en-英文, zh-中文,默认为 en (可选)
|
|
|
|
|
"selected_text": "", // 选取的代码片段 (必填)
|
|
|
|
|
"model" : "local deepseek-r1:32b",//(必填)
|
|
|
|
|
"stream" : false // stream方式返回 (可选)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
返回json格式同 2.3
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
##### 2.7 生成单元测试代码 (exec_unittest)
|
|
|
|
|
|
|
|
|
|
// TODO 与ideservice交互
|
|
|
|
|
|
|
|
|
|
目前仅支持英文回复, 流程对devchat做了简化
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
sequenceDiagram
|
|
|
|
|
plugin->>agent: exec_unittest_recommend 请求测试建议
|
|
|
|
|
agent->>plugin: 测试建议
|
|
|
|
|
plugin->>agent: exec_unittest_code 请求测试代码
|
|
|
|
|
plugin->>agent: 测试代码
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
请求测试建议:
|
|
|
|
|
{
|
|
|
|
|
"cmd" : "exec_unittest_recommend",
|
|
|
|
|
"request_id": 123, // 随机生成 (必填)
|
|
|
|
|
"language" : "en", // 语言, en-英文, zh-中文,默认为 en (可选)
|
|
|
|
|
|
|
|
|
|
"user_prompt" : "", // 用户定制化描述 (可选)
|
|
|
|
|
"file_content" : "..." // 整个文件内容(必填)
|
|
|
|
|
"filepath" : "\\example\\game.py", // 文件路径(必填)
|
|
|
|
|
"func_name" : "next_turn", // 函数名 (必填)
|
|
|
|
|
"func_location": { // 函数位置(必填)
|
|
|
|
|
"start": { "line": 33, "character": 0},
|
|
|
|
|
"end" : { "line": 45, "character": 41},
|
|
|
|
|
},
|
|
|
|
|
"func_symbols": [ // function 内的所以变量名和函数名 (必填)
|
|
|
|
|
{
|
|
|
|
|
"name": "next_turn",
|
|
|
|
|
"kind": "Function",
|
|
|
|
|
"range": { // 位置
|
|
|
|
|
"start": { "line": 33, "character": 0},
|
|
|
|
|
"end" : { "line": 45, "character": 41}
|
|
|
|
|
},
|
|
|
|
|
"children": [
|
|
|
|
|
{
|
|
|
|
|
"name": "WIDTH",
|
|
|
|
|
"kind": "Constant",
|
|
|
|
|
"range": { // 位置
|
|
|
|
|
"start": { "line": 33, "character": 0},
|
|
|
|
|
"end" : { "line": 45, "character": 41}
|
|
|
|
|
},
|
|
|
|
|
"children": [
|
|
|
|
|
...
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
...
|
|
|
|
|
],
|
|
|
|
|
"model" : "local deepseek-r1:32b", //(必填)
|
|
|
|
|
"stream" : false // stream方式返回 (可选)
|
|
|
|
|
}
|
|
|
|
|
返回json格式同 2.3
|
|
|
|
|
|
|
|
|
|
请求测试代码:
|
|
|
|
|
{
|
|
|
|
|
"cmd" : "exec_unittest_code",
|
|
|
|
|
"request_id" : 123, // 随机生成 (必填)
|
|
|
|
|
"language" : "en", // 语言, en-英文, zh-中文,默认为 en (可选)
|
|
|
|
|
"test_cases_str": "", // exec_unittest_recommend 提供的 (必填)
|
|
|
|
|
|
|
|
|
|
// 如果task_id为空须填写:
|
|
|
|
|
"function_name" : "" // 函数名 (可选)
|
|
|
|
|
"user_prompt" : "" // 定制化描述 (可选)
|
|
|
|
|
"file_path" : "./src/test.py" // 文件在项目里的相对路径 (可选)
|
|
|
|
|
"relevant_content" : "" // the relevant source code of the function (可选)
|
|
|
|
|
"reference_content": "" // the relevant source code of the function (可选)
|
|
|
|
|
|
|
|
|
|
"stream": false // stream方式返回(可选)
|
|
|
|
|
}
|
|
|
|
|
返回json格式同 2.3
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
##### 2.8 和大模型对话 (exec_chat)
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
request:
|
|
|
|
|
{
|
|
|
|
|
"cmd" : "exec_chat",
|
|
|
|
|
"request_id": 123, // 随机生成 (必填)
|
|
|
|
|
"msg" : "", // 内容 (必填)
|
|
|
|
|
"model" : "local deepseek-r1:32b", //(必填)
|
|
|
|
|
"stream" : false // stream方式返回(可选)
|
|
|
|
|
}
|
|
|
|
|
返回json格式同 2.3
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 3. ide_service协议
|
|
|
|
|
|
|
|
|
|
开发优先级低,解决2.7“与ideservice交互”问题前未用到
|
|
|
|
|
|
|
|
|
|
是由 agent 向 ide_service 请求,参考
|
|
|
|
|
<https://github.com/devchat-ai/devchat-vscode/blob/main/src/ide_services/services.ts>
|
|
|
|
|
|
|
|
|
|
只保留以下服务,
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
"/get_document_symbols": {
|
|
|
|
|
keys: ["abspath"],
|
|
|
|
|
handler: getDocumentSymbols,
|
|
|
|
|
},
|
|
|
|
|
"/find_def_locations": {
|
|
|
|
|
keys: ["abspath", "line", "character"],
|
|
|
|
|
handler: findDefinitionLocations,
|
|
|
|
|
},
|
|
|
|
|
"/find_type_def_locations": {
|
|
|
|
|
keys: ["abspath", "line", "character"],
|
|
|
|
|
handler: findTypeDefinitionLocations,
|
|
|
|
|
},
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 3. 功能覆盖
|
|
|
|
|
|
|
|
|
|
<img src="assets/功能覆盖.png"/>
|
|
|
|
|
|