# deepseek-agent
**Repository Path**: panhu01/deepseek-agent
## Basic Information
- **Project Name**: deepseek-agent
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2025-08-27
- **Last Updated**: 2025-08-27
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
DeepSeek-Agent
## 项目概述
本仓库是一个关于 **Agent(智能体)** 的实验性 DEMO 项目,主要展示如何利用大语言模型(LLM)在计算机上执行“**全自动的代码编写、编译、测试、调试、文档生成全套流水线**”、“**文件系统自由探索**”等操作。项目基于 DeepSeek R1 系列模型做了一些初步探索,希望借此分享经验与心得,也为更多对 Agent 感兴趣的开发者提供参考。
## 目录结构
```
├── chains
│ └── factory.py ------------------ LLM 链式调用工厂,用于统一加载并管理提示模板
├── core
│ ├── pipeline.py ----------------- 核心流水线,实现 Python 代码到 C 语言的转换与测试
│ ├── piplinebase.py -------------- 流水线基础类,提供 LLM 调用、结果保存、代码清洗等通用功能
│ └── romingbot.py ---------------- 文件系统探索机器人,支持目录漫游、笔记生成及简单命令执行
├── prompts
│ ├── c_code_gen.txt -------------- Python 转 C 的代码生成提示模板
│ ├── history_builder_chain.txt ---- 代码开发与测试历史记录的生成模板
│ ├── result_report_gen.txt -------- 系统状态和结果报告的生成提示模板
│ └── sa_chain.txt ----------------- 静态分析报告的生成提示模板
├── utils
│ ├── openai_client.py ------------- OpenAI 客户端封装类,简化与 OpenAI API 的交互
│ ├── compiler.py ------------------- C 代码编译和测试工具,支持自动化编译和执行
│ ├── logger.py --------------------- 分级调试日志系统,支持多级别日志输出与存储
│ ├── output.py --------------------- 输出目录管理器,自动备份旧目录并生成新输出路径
│ └── parser.py --------------------- JSON 报告解析工具,支持多种容错和正则匹配解析
├── config.py ------------------------- 配置文件,包含 OpenAI API、模型与运行参数
├── input.py -------------------------- 示例 Python 脚本(矩阵乘法实现),作为待转换代码
├── main.py --------------------------- 主程序入口,整合 Python->C 转换与自动化执行功能
├── requirements.txt ------------------ 依赖库说明,包括 LangChain、OpenAI 与 Pygments 等
```
## 快速上手
1. 安装依赖:
```bash
pip install -r requirements.txt
```
2. **配置参数:**
在 `config.py` 中填写你的 OpenAI API Key 及相关模型配置。
3. 运行主程序:
```bash
python main.py # Python -> C 的转换器需要在 linux 环境下,安装 gcc 工具链
```
# 技术报告:当 DeepSeek 接管操作系统:智能体(Agent)真能让程序员提前退休?
> 公众号:PikaPython 物联网脚本框架 | 撰稿:李昂 | Thanks to: DeepSeek & OpenAI
“DeepSeek R1” 刚上线时,就在全球范围内刮起了一股新的智能对话风潮。它看起来“好像什么都知道”,但在使用中,人们也会碰到重复 Debug、测试琐碎、对话失控等常见问题。想象一下,如果 DeepSeek 不仅会回答问题,还能像一位开发者那样主动编写代码、编译测试、排查故障,并给出最终的总结报告——那将是多么理想的场景。
正因如此,我对“Agent 智能体”的概念产生了兴趣,开始加入相关的探索和研究。在社区里,“Agent”早已是一个热门话题,简单来说,Agent 的目标就是让大模型从“聊天式交互”进化到“帮助执行实际开发和操作”的高级阶段。
## 一、为什么要打造 Agent?
在我的 DEMO 项目中,我尝试给 DeepSeek 一个更“真实”的工作环境,让它能直接用到电脑上的一些资源(比如文件系统、编译器、Shell 命令等),从而充分发挥大模型的潜力。可这样一来,新的问题也随之出现,包括但不限于:
- **安全风险**:当 Agent 有了较高的权限,就有可能在无意或恶意的情况下执行危险操作。因此,访问控制和审计成为首要课题。
- **误读与幻觉(Hallucination)**:如果上下文信息过于复杂,或模型没理解清楚,就有可能读错指令,甚至“编故事”,在关键任务中会带来严重后果。
- **远程 API 不稳定**:如果推理过程依赖外部服务,一旦网络波动或服务故障,Agent 的核心功能就可能瘫痪,需要额外的重试和容错方案。
- **Prompt 编写困难**:软指导(Prompt)是让 Agent 发挥创造力的关键,但写得不好就会导致输出混乱,甚至陷入无限循环。
- **格式约束与结果校验**:如果 Agent 的输出格式不符合要求,就会影响后续流程。针对每一步结果进行自动校验也并非易事。
- **扩展性与工程维护**:要让 Agent 支持更多的领域和场景,就得有更健壮的模型和更完善的状态管理,这对代码架构提出了相当的要求。
### 关于这些新问题的几点思考与应对思路
其实,“为什么要打造 Agent”从来不是为了让人类开发者“退出舞台”,而是希望以自动化的方式分担那些琐碎、重复、低产出的工作,让人类可以更专注于创造性的部分。与此同时,这些新问题也提醒我们,Agent 并非“唤醒就能自由工作”的魔法师,它更像是一个有超强“潜力”的实习生,需要配套的工作规范与安全限制,才能在实际开发和运维中放心使用。
- **权限与监控**:通过权限沙盒、审计日志等机制,将 Agent 的权限精细化管控,不放大安全风险。
- **Prompt 策略**:为 Agent 设计好提示语的结构与流程,辅以简明、稳定的状态管理,让对话在可控边界内展开,避免死循环或产生危险命令。
- **模型与上下文管理**:根据任务重要性选择模型规模与上下文策略,既不过度依赖外部服务,也避免一次丢给 Agent 大量不必要的信息,从而降低“编故事”的概率。
- **持续迭代与落地**:对于工程级别的 Agent,需要在架构、测试、监控、上线等环节持续投入,并围绕扩展性和可维护性做专门设计。
只有在充分重视这些问题的情况下,Agent 才能真正释放大模型的潜能,帮助开发者摆脱机械繁琐的任务,向更高层次的创造性工作进阶。
## 二、我在测试不同模型时的实践与心得
1. **Agent 就像个小程序员,但也会“偷懒”和“犯错”**
- 不管模型大小如何,大模型在功能上确实像个非常聪明的开发者,可以帮你写代码、调试、测试——可有时也会忽视提示,或者在同一个问题上反复纠缠。
- 这时候就需要我们在“软提示”(Prompt)和“硬编码流程”之间找到平衡。Prompt 提供灵活度和创造力,而状态机或其它逻辑约束则帮助避免死循环或危险行为。
2. **本地 GPU 部署:2080Ti + 32B 模型**
- 我尝试在一块 2080Ti (22G 魔改版)显卡上本地部署了一个 32B(320 亿参数)的模型,比如 `deepseek-r1:32b-q4-8k` 或类似版本(`iq4-10k` 等)。
- 为了让大模型能在有限显存上跑起来,需要用到低比特量化(Q4、Q6、INT4 等),牺牲一定精度来换取显存与算力的平衡。
- 本地部署的好处是可以离线跑,不担心网络延迟和第三方服务故障;但受限于显存和硬件算力,推理速度、上下文长度都需要在效率和效果之间做权衡。
3. **远程调用:多种 API、多种模型参数与上下文配置**
- 我也在配置文件里尝试了各种远程模型,包括:
- `deepseek-ai/DeepSeek-R1`、`deepseek-ai/DeepSeek-R1-Distill-Qwen-32B`、`deepseek-ai/DeepSeek-R1-Distill-Llama-70B-free` 等。
- Qwen 系列模型,如 `Qwen2.5-7B-Instruct`、`Qwen2.5-72B-Instruct-128K`。
- 量化版本如 `qwen2.5-32b-iq4-10k:latest` 或 `phi-4:q6-24k`。
- 以及类似 `gpt-4o` 这样的 API 接口版本。
- 这些模型的参数规模从 7B(70 亿)到 70B(700 亿)不等,所能支持的上下文长度也从 2K、8K、32K 到 128K 各有差异。
- 远程服务虽然部署了更强的硬件和更大参数量模型,但一旦网络波动或服务本身不稳定,就可能导致 Agent 推理卡顿或超时,需要在代码中增加重试和断路保护。
2. **上下文不是越多越好**
- 尽管大模型往往宣传“上下文窗口很大”,但是如果给出的背景或指令太复杂,模型出现误读或“编故事”的几率也会上升。
- 我测试过 32k、8k、128k 等不同上下文模型,都发现上下文过多时,出现失误或反常输出的概率也会上升。
3. **大框架未必是最佳实践**
- 我最初尝试了 langchain,但因其不支持流式输出,又重写了一套支持流式输出的 LLM 请求机制。
- 同时,我采用状态机逻辑来管理 Agent 的流程,每次请求都相对独立,结果是几乎没用到 langchain 其他功能。
- 由此也开始思考:或许直接基于 OpenAI API 或类似的低层接口,从零搭建“简易框架”就够用了。很多“通用大框架”虽然概念丰富,但实际工程里未必完全适配。
## 三、为什么说 LLM 不需要大而全的“万能框架”?
其实,LLM 的应用往往面向细分场景,在不同业务部门或技术领域都存在大量个性化需求。一个“大而全”的通用框架看似可以“一次性打包所有功能”,但往往在实际落地时会出现过度耦合、配置复杂度高、模块臃肿等问题,不见得能满足所有场景,反而拖慢开发效率。
因此,“细颗粒度、灵活组合”的思路才更能激发大模型的潜力:让它专注在当前场景需要的功能上,然后用最小可行架构将其封装到业务流中。最简单的方式,就是在 LLM 之上构建一个带决策机制的**状态机**或**流程编排**:为每一个可预期的步骤和异常处理定义好状态转移逻辑,再通过 Prompt 或 API 调用触发对应环节。这种结构清晰、维护简单、可随时扩展,正是许多实际项目快速迭代的实践经验。而且对于团队而言,不同阶段或场景所需的“插件”也能更灵活地接入,不必被一个庞大的框架牵着走。
## 四、初步 DEMO 展示
经过一周左右的探索,我基于 DeepSeek 做了两个 DEMO,用来展示如何解决或部分缓解上述问题。这些 DEMO 仅作为学习和讨论用,离实用工具还有相当距离。
### 1. Python -> C 自动转换 DEMO
Python 代码编写简单、灵活,但性能不足。如果能“一键”把 Python 代码转成对等功能的 C 程序,并自动完成编译和测试,最后在 Python 里通过接口调用这个 C 库,将显著提升开发效率和部署速度。
在这个 DEMO 中,我尝试了如下流程:
1. 解析指定的 Python 脚本;
2. 调用 DeepSeek 生成对应的 C 代码;
3. 自动编译生成的 C 代码;
4. 运行测试并输出性能或结果报告;
5. 将 C 库再次封装给 Python 使用。
目前只实现了简单的函数级转换。如果遇到第三方库或更复杂的逻辑,还需要更深入的兼容适配。但它为自动化移植与测试提供了一个雏形,一旦与日常开发结合,可减少大量繁琐重复的工作。
具体流程如下:

```
flowchart LR
A[开始:INIT]
C[状态:CODE_GEN\n调用LLM生成C代码\n写入C文件]
E[状态:TEST_GEN\n调用LLM生成测试脚本\n写入测试文件]
F[状态:COMPILE_TEST\n保存输入代码\n编译并测试C代码]
G[状态:FINAL_REPORT\n调用LLM生成最终报告\n解析报告]
H{报告 correctness == True?}
I[状态:COMPLETED\n构造返回结果]
J[状态:RETRY\n增加重试次数\n构造历史记录\n准备重试]
A --> C
C --> E
E --> F
F --> G
G --> H
H -- 是 --> I
H -- 否 --> J
J --> C
```
1. **初始化阶段(INIT)**
流程从初始状态开始,系统准备好必要的环境和文件,进入代码生成阶段。
2. **代码生成(CODE_GEN)**
在该阶段,流水线调用 LLM(大语言模型)生成对应的 C 代码,并将生成的 C 代码写入到文件中。此步骤决定了后续操作的基础,因此生成的代码质量至关重要。
3. **测试脚本生成(TEST_GEN)**
随后,系统利用 LLM 生成测试脚本,该脚本用于对生成的 C 代码进行功能验证。测试脚本同样经过清洗和格式化,确保测试环境能正确加载并执行。
4. **编译与测试(COMPILE_TEST)**
系统保存原始 Python 输入代码后,调用编译器对生成的 C 代码进行编译,并执行测试。此阶段的输出为验证代码正确性的关键依据。
5. **最终报告生成(FINAL_REPORT)**
根据编译和测试的结果,流水线再次调用 LLM 生成最终评估报告。解析报告后,系统会检查报告中 “correctness” 字段是否为 `True`,从而决定是否进入完成状态或进行重试。
6. **重试机制(RETRY)**
如果最终报告表明转换结果不符合预期,系统将增加重试次数,记录之前的尝试信息(包括 C 代码、测试脚本、编译测试输出和评估报告),并回到代码生成阶段重新执行转换。这个机制确保了在出现错误时可以多次修正,争取达到正确转换的效果。
7. **完成(COMPLETED)**
当生成的 C 代码通过所有测试和评估,且最终报告确认正确性后,系统构造最终返回结果,流程进入完成状态,整个转换过程结束。
### 2. 文件漫游(File System Explorer) DEMO
在这个场景下,Agent 拥有一定的文件系统访问权限(如执行 `ls`、`pwd`、`cat` 等指令)。它可以自动定位并浏览文件,自发记录笔记、总结内容,并尽量避免对同一个文件进行重复操作或重复总结。
如果工作流程中常要检索海量文件并做周期性的分析或汇总,这样的 Agent 能帮忙显著降低人工操作量,提高效率。它展示了 Agent 的“主动决策”和“资源利用”能力,具备一定的自我迭代和记录机制。
Agent 首先会从初始状态(**BotState.INIT**)开始,获取当前工作目录,并执行一系列基础命令,以探索项目文件结构并查看部分文件内容。这个过程中,Agent 的操作步骤和决策逻辑大致如下:
1. **初始阶段(BotState.INIT):**
Agent 获取工作目录以及项目的初始状态。此时,系统会输出相关日志,记录当前工作目录和文件结构信息,为后续操作提供上下文数据。
2. **决策下一步(BotState.DECIDE_NEXT):**
在决策阶段,Agent 根据当前操作结果和日志输出,决定下一步是继续执行命令、重新生成笔记,还是直接结束整个流程。决策结果同样会记录日志,帮助理解 Agent 的思考过程。
3. **执行基础命令(BotState.EXEC_COMMAND):**
接下来,Agent 会执行如 `ls`、`cat`、`cd` 等命令,以获取目录列表和文件内容。这些操作会生成对应的日志输出,直观展示 Agent 如何探索项目文件结构以及查看关键文件内容。
4. **笔记写入(BotState.WRITE_NOTE):**
根据用户输入或执行结果,Agent 可能需要生成和保存笔记,以记录操作过程中获得的重要信息。如果笔记写入成功,则会进入决策阶段;如果写入过程中出现错误且重试次数未达上限,Agent 会进行重试。
5. **流程结束(BotState.COMPLETED):**
当所有操作完成,且决策结果为“complete”时,Agent 进入结束状态,整个流程随之结束。

```
flowchart LR
A[BotState.INIT]
C[BotState.WRITE_NOTE
(笔记写入)]
D[BotState.EXEC_COMMAND
(执行命令)]
F[BotState.DECIDE_NEXT
(决策下一步)]
I[BotState.COMPLETED
流程结束]
J[BotState.WRITE_NOTE
重试笔记写入]
A --> F
C -- 正常 --> F
C -- 写入失败且重试次数未达上限 --> J
J --> C
D --> F
F -- "complete" --> I
F -- "write_note" --> C
F -- "execute" --> D
```
## 五、DEMO 运行示例及结果
以下是一些运行的过程,以便更直观地展示两个 DEMO 的实际运行过程和输出。
### 1. Python -> C 自动转换 DEMO 运行过程
本次 DEMO 展示了从 Python 代码自动转换为 C 代码的完整流水线,整个过程由多个状态依次推进,并在必要时进行重试以确保转换效果。本次测试使用的模型是 `DeepSeek-V3` ,推理服务器是硅基流动,通过这个链接你也可以免费领取到 20 万 token。
**https://cloud.siliconflow.cn/i/O52HTvI9**
本地测试使用过相对较好的的模型是 `qwen2.5:32b-iq4`,`10k` 上下文,这里我发现使用 32b-q4 的 DeepSeek R1 效果并不好,经常会出现输出错别字,在修改代码时还会出现“知错不改”的现象,就是明明知道哪里该改,但是就是只在要改地方写注释(我要改了,我真的要改了!)但是还是不改(= =)。
因为涉及到错误修复的流程,所以上下文长度很重要,ollama 默认的 2k 上下文是很难成功的(虽然有一次跑了40多分钟重试了 70多次硬是试出来了)。我一开始使用的是 `qwen2.5:32b-q4`,后来为了增加上下文使用了更小的 `iq4` 量化,综合效果看,`iq4-10k` 是明显优于 `q4-2k` 的。
#### 1.1. **输入的 Python 代码**
输入的测试 py 代码是一个手动实现的矩阵乘法,我测试了多个模型都不能一次性做对,主要是下表索引和 c 的动态内存申请的过程有一定的复杂度,测试脚本也有一定难度,但是多次重试之后是能够成功生成的。
``` python
def mat_mult(a, b): # 手动实现矩阵乘法
if len(a[0]) != len(b):
return "矩阵维度不匹配"
res = [[0 for _ in range(len(b[0]))] for _ in range(len(a))]
for i in range(len(a)):
for j in range(len(b[0])):
for k in range(len(b)):
res[i][j] += a[i][k] * b[k][j]
return res
```
#### 1.2. **Agent 执行过程日志**
DeepSeek-V3 总共重试了 3 次,最后解决了存在的 bug。
另外可以看到因为 API 服务器的负载过大,多次请求没有响应,但是进行重试之后最后还是稳定地运行完了。
这里值得注意的是,Agent 会存在偷跑行为,也就是给测试代码放水,比如检测的时候如果 py 和 c 输出的都是空内容也判对,针对这些问题有针对性地用这些 prompt 进行了围堵。
```
4. 必须捕获c和py的打印输出并判断输出一致性
5. 不得假设C代码的正确性,只能通过调用C库来验证
6. 必须调用功能验证函数
7. 功能验证必须判断输出值是否为空
```
执行过程的日志,为了避免过于繁琐,把输出的代码隐去了,最后会单独放出修改过的代码。实际运行中是可以流式输出推理过程和代码的这一点原生 LangChain 是做不到的,我在代码里重新写了 LLM 调用的实现。
````bash
[DEBUG1] 16:04:10 发现已存在目录,已备份至: backup/output_bck_20250208_160410
[DEBUG1] 16:04:10 输出目录已创建: output
[DEBUG2] 16:04:10 正在加载提示模板...
[DEBUG2] 16:04:11 已初始化7个处理链
[DEBUG2] 16:04:11 已加载的链: test_script_gen, result_report_gen, c_code_gen, next_action_decision, history_builder_chain, note_generation, sa_chain
[DEBUG2] 16:04:11 开始处理Python代码
[DEBUG2] 16:04:11 def mat_mult(a, b): # 手动实现矩阵乘法
[DEBUG2] 16:04:11 if len(a[0]) != len(b):
[DEBUG2] 16:04:11 return "矩阵维度不匹配"
[DEBUG2] 16:04:11 res = [[0 for _ in range(len(b[0]))] for _ in range(len(a))]
[DEBUG2] 16:04:11 for i in range(len(a)):
[DEBUG2] 16:04:11 for j in range(len(b[0])):
[DEBUG2] 16:04:11 for k in range(len(b)):
[DEBUG2] 16:04:11 res[i][j] += a[i][k] * b[k][j]
[DEBUG2] 16:04:11 return res
[DEBUG2] 16:04:11
[DEBUG1] 16:04:11 初始化
[DEBUG1] 16:04:11 开始C代码生成...
[DEBUG2] 16:04:40 结果已保存至: output/c_code.json
[DEBUG2] 16:04:40 清洗后C代码长度: 491 chars
[DEBUG2] 16:04:40 写入C文件到: output/temp_py2c.c
[DEBUG1] 16:04:40 开始测试脚本生成...
[DEBUG2] 16:09:50 结果已保存至: output/test_script.json
[DEBUG2] 16:09:50 清洗后测试脚本长度: 2905 chars
[DEBUG2] 16:09:50 代码已保存至: output/input.py
[DEBUG1] 16:09:50 开始编译测试流程
[DEBUG2] 16:09:50 待编译代码长度: 491 chars
[DEBUG2] 16:09:50 执行编译命令: gcc -O3 -shared -fPIC output/temp_py2c.c -o output/libpy2c.so
[DEBUG1] 16:09:50 编译完成 [0.3s]
[DEBUG2] 16:09:50 编译器退出码: 0
[DEBUG1] 16:09:50 开始执行测试脚本: output/temp_test.py
[DEBUG1] 16:09:50 测试完成 [0.0s]
[DEBUG2] 16:09:50 测试退出码: 1
[DEBUG2] 16:09:50 测试输出摘要:
[DEBUG2] 16:09:50
[DEBUG1] 16:09:50 生成最终评估报告...
result_report_gen 输出流: ```json
{
"speedup": 0.0,
"correctness": false,
"keylog": "IndexError: list index out of range",
"info": "测试失败,原因是矩阵a的维度不正确,导致在访问a[0]时出现索引越界错误。可能的原因是输入的矩阵a为空或未正确初始化。建议检查输入矩阵的初始化过程,确保矩阵a和b的维度符合矩阵乘法的要求。"
}
```
[DEBUG2] 16:11:01 结果已保存至: output/final_report.json
[DEBUG1] 16:11:01 测试未通过,重试次数: 1
[DEBUG1] 16:11:01 开始C代码生成...
流式请求发生错误: Error code: 504 - {'code': 50501, 'message': 'Model service timeout. Please try again later.', 'data': None}
[DEBUG1] 16:14:03 链执行失败: Error code: 504 - {'code': 50501, 'message': 'Model service timeout. Please try again later.', 'data': None} (第 1 次重试,共 10 次)
[DEBUG2] 16:14:40 结果已保存至: output/c_code.json
[DEBUG2] 16:14:40 清洗后C代码长度: 591 chars
[DEBUG2] 16:14:40 写入C文件到: output/temp_py2c.c
[DEBUG1] 16:14:40 开始测试脚本生成...
[DEBUG2] 16:19:13 结果已保存至: output/test_script.json
[DEBUG2] 16:19:13 清洗后测试脚本长度: 2884 chars
[DEBUG2] 16:19:13 代码已保存至: output/input.py
[DEBUG1] 16:19:13 开始编译测试流程
[DEBUG2] 16:19:13 待编译代码长度: 591 chars
[DEBUG2] 16:19:13 执行编译命令: gcc -O3 -shared -fPIC output/temp_py2c.c -o output/libpy2c.so
[DEBUG1] 16:19:13 编译完成 [0.1s]
[DEBUG2] 16:19:13 编译器退出码: 0
[DEBUG1] 16:19:13 开始执行测试脚本: output/temp_test.py
[DEBUG1] 16:19:13 测试完成 [0.0s]
[DEBUG2] 16:19:13 测试退出码: 1
[DEBUG2] 16:19:13 测试输出摘要:
[DEBUG2] 16:19:13
[DEBUG1] 16:19:13 生成最终评估报告...
result_report_gen 输出流: ```json
{
"speedup": 0.0,
"correctness": false,
"keylog": "TypeError: incompatible types, LP_c_int_Array_1 instance instead of LP_c_int instance",
"info": "测试失败,原因是类型不匹配错误。在将Python数组转换为C语言二维数组时,出现了类型不兼容的问题。可能的原因是C语言数组的指针类型与Python的ctypes库不匹配。建议检查to_c_matrix函数中的数组创建逻辑,确保类型转换正确。"
}
```
[DEBUG2] 16:20:02 结果已保存至: output/final_report.json
[DEBUG1] 16:20:02 测试未通过,重试次数: 2
[DEBUG1] 16:20:02 开始C代码生成...
[DEBUG2] 16:21:05 结果已保存至: output/c_code.json
[DEBUG2] 16:21:05 清洗后C代码长度: 591 chars
[DEBUG2] 16:21:05 写入C文件到: output/temp_py2c.c
[DEBUG1] 16:21:05 开始测试脚本生成...
[DEBUG2] 16:26:56 结果已保存至: output/test_script.json
[DEBUG2] 16:26:56 清洗后测试脚本长度: 2929 chars
[DEBUG2] 16:26:56 代码已保存至: output/input.py
[DEBUG1] 16:26:56 开始编译测试流程
[DEBUG2] 16:26:56 待编译代码长度: 591 chars
[DEBUG2] 16:26:56 执行编译命令: gcc -O3 -shared -fPIC output/temp_py2c.c -o output/libpy2c.so
[DEBUG1] 16:26:56 编译完成 [0.1s]
[DEBUG2] 16:26:56 编译器退出码: 0
[DEBUG1] 16:26:56 开始执行测试脚本: output/temp_test.py
[DEBUG1] 16:26:56 测试完成 [0.0s]
[DEBUG2] 16:26:56 测试退出码: 1
[DEBUG2] 16:26:56 测试输出摘要:
[DEBUG2] 16:26:56
[DEBUG1] 16:26:56 生成最终评估报告...
result_report_gen 输出流:
流式请求发生错误: Error code: 504 - {'code': 50501, 'message': 'Model service timeout. Please try again later.', 'data': None}
[DEBUG1] 16:29:58 链执行失败: Error code: 504 - {'code': 50501, 'message': 'Model service timeout. Please try again later.', 'data': None} (第 1 次重试,共 10 次)
result_report_gen 输出流:
流式请求发生错误: Request timed out.
[DEBUG1] 16:32:10 链执行失败: Request timed out. (第 2 次重试,共 10 次)
result_report_gen 输出流:
流式请求发生错误: Request timed out.
[DEBUG1] 16:32:29 链执行失败: Request timed out. (第 3 次重试,共 10 次)
result_report_gen 输出流:
流式请求发生错误: Error code: 504 - {'code': 50501, 'message': 'Model service timeout. Please try again later.', 'data': None}
[DEBUG1] 16:33:48 链执行失败: Error code: 504 - {'code': 50501, 'message': 'Model service timeout. Please try again later.', 'data': None} (第 4 次重试,共 10 次)
result_report_gen 输出流: ```json
{
"speedup": 0.0,
"correctness": false,
"keylog": "IndexError: list index out of range",
"info": "测试失败,原因是矩阵a的维度不正确,导致在访问a[0]时出现索引越界错误。可能的原因是输入矩阵a为空或未正确初始化。建议检查输入矩阵的初始化过程,确保矩阵a和b的维度符合乘法要求。"
}
```
[DEBUG2] 16:35:30 结果已保存至: output/final_report.json
[DEBUG1] 16:35:30 测试未通过,重试次数: 3
[DEBUG1] 16:35:30 开始C代码生成...
[DEBUG2] 16:37:12 结果已保存至: output/c_code.json
[DEBUG2] 16:37:12 清洗后C代码长度: 591 chars
[DEBUG2] 16:37:12 写入C文件到: output/temp_py2c.c
[DEBUG1] 16:37:12 开始测试脚本生成...
test_script_gen 输出流:
流式请求发生错误: Error code: 504 - {'code': 50501, 'message': 'Model service timeout. Please try again later.', 'data': None}
[DEBUG1] 16:40:14 链执行失败: Error code: 504 - {'code': 50501, 'message': 'Model service timeout. Please try again later.', 'data': None} (第 1 次重试,共 10 次)
test_script_gen 输出流:
流式请求发生错误: Error code: 504 - {'code': 50501, 'message': 'Model service timeout. Please try again later.', 'data': None}
[DEBUG1] 16:43:19 链执行失败: Error code: 504 - {'code': 50501, 'message': 'Model service timeout. Please try again later.', 'data': None} (第 2 次重试,共 10 次)
[DEBUG2] 16:46:52 结果已保存至: output/test_script.json
[DEBUG2] 16:46:52 清洗后测试脚本长度: 2908 chars
[DEBUG2] 16:46:52 代码已保存至: output/input.py
[DEBUG1] 16:46:52 开始编译测试流程
[DEBUG2] 16:46:52 待编译代码长度: 591 chars
[DEBUG2] 16:46:52 执行编译命令: gcc -O3 -shared -fPIC output/temp_py2c.c -o output/libpy2c.so
[DEBUG1] 16:46:52 编译完成 [0.1s]
[DEBUG2] 16:46:52 编译器退出码: 0
[DEBUG1] 16:46:52 开始执行测试脚本: output/temp_test.py
[DEBUG1] 16:46:52 测试完成 [0.0s]
[DEBUG2] 16:46:52 测试退出码: 0
[DEBUG2] 16:46:52 测试输出摘要:
[DEBUG2] 16:46:52 python time: 0.03890491
[DEBUG2] 16:46:52 c time: 0.00087452
[DEBUG2] 16:46:52 speedup: 44.48718648
[DEBUG2] 16:46:52
[DEBUG1] 16:46:52 生成最终评估报告...
result_report_gen 输出流: ```json
{
"speedup": 44.5,
"correctness": true,
"keylog": "python time: 0.03890491\nc time: 0.00087452\nspeedup: 44.48718648\n",
"info": "测试通过,C代码的执行速度比Python快44.5倍,矩阵乘法实现正确,没有发现错误。"
}
```
[DEBUG2] 16:47:28 结果已保存至: output/final_report.json
测试结果:
状态: passed
重试次数: 3
总耗时: 0 时43 分17 秒
加速比信息: 44.5
关键日志: python time: 0.03890491
c time: 0.00087452
speedup: 44.48718648
测试报告: 测试通过,C代码的执行速度比Python快44.5倍,矩阵乘法实现正确,没有发现错误。
````
#### 1.3. **自动转换出的 C 代码**
``` c
#include
#include
int32_t mat_mult(int32_t** a, size_t a_rows, size_t a_cols, int32_t** b, size_t b_rows, size_t b_cols, int32_t** res) {
if (a_rows == 0 || a_cols == 0 || b_rows == 0 || b_cols == 0) {
return -1; // 空矩阵
}
if (a_cols != b_rows) {
return -1; // 矩阵维度不匹配
}
for (size_t i = 0; i < a_rows; i++) {
for (size_t j = 0; j < b_cols; j++) {
res[i][j] = 0;
for (size_t k = 0; k < a_cols; k++) {
res[i][j] += a[i][k] * b[k][j];
}
}
}
return 0; // 成功
}
```
#### 1.4. **测试脚本**
``` py
import ctypes, time
from input import *
# Load C library
lib = ctypes.CDLL('./output/libpy2c.so')
# Define argument types for the C function
lib.mat_mult.argtypes = [
ctypes.POINTER(ctypes.POINTER(ctypes.c_int32)), ctypes.c_size_t, ctypes.c_size_t,
ctypes.POINTER(ctypes.POINTER(ctypes.c_int32)), ctypes.c_size_t, ctypes.c_size_t,
ctypes.POINTER(ctypes.POINTER(ctypes.c_int32))
]
lib.mat_mult.restype = ctypes.c_int32
def create_2d_array(rows, cols):
array = (ctypes.POINTER(ctypes.c_int32) * rows)()
for i in range(rows):
array[i] = (ctypes.c_int32 * cols)()
return array
def to_c_matrix(matrix):
rows = len(matrix)
cols = len(matrix[0]) if rows > 0 else 0
c_matrix = create_2d_array(rows, cols)
for i in range(rows):
for j in range(cols):
c_matrix[i][j] = matrix[i][j]
return c_matrix
def from_c_matrix(c_matrix, rows, cols):
matrix = [[0 for _ in range(cols)] for _ in range(rows)]
for i in range(rows):
for j in range(cols):
matrix[i][j] = c_matrix[i][j]
return matrix
def test_mat_mult(a, b):
a_rows, a_cols = len(a), len(a[0]) if len(a) > 0 else 0
b_rows, b_cols = len(b), len(b[0]) if len(b) > 0 else 0
res_rows, res_cols = a_rows, b_cols
# Python implementation
py_res = mat_mult(a, b)
# C implementation
c_a = to_c_matrix(a)
c_b = to_c_matrix(b)
c_res = create_2d_array(res_rows, res_cols)
c_ret = lib.mat_mult(c_a, a_rows, a_cols, c_b, b_rows, b_cols, c_res)
c_res_matrix = from_c_matrix(c_res, res_rows, res_cols)
# Check if the output is empty
assert py_res is not None, "Python output is empty"
assert c_ret != -1, "C output is empty"
# Check consistency
assert py_res == c_res_matrix, f"Output mismatch: Python {py_res}, C {c_res_matrix}"
# Test cases
test_cases = [
([[1]], [[1]]), # n=1
([[1, 2], [3, 4]], [[5, 6], [7, 8]]), # n=2
([[1, 2, 3], [4, 5, 6]], [[7, 8], [9, 10], [11, 12]]), # n=3
([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25]],
[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25]]) # n=5
]
for a, b in test_cases:
test_mat_mult(a, b)
# Performance comparison
a = [[i + j for j in range(10)] for i in range(10)]
b = [[i + j for j in range(10)] for i in range(10)]
# Python performance
start = time.time()
for _ in range(1000):
mat_mult(a, b)
py_time_total = time.time() - start
# C performance
c_a = to_c_matrix(a)
c_b = to_c_matrix(b)
c_res = create_2d_array(10, 10)
start = time.time()
for _ in range(1000):
lib.mat_mult(c_a, 10, 10, c_b, 10, 10, c_res)
c_time_total = time.time() - start
# Output performance results
print('python time: %.8f' % py_time_total)
print('c time: %.8f' % c_time_total)
print('speedup: %.8f' % (py_time_total / c_time_total))
```
#### 1.5. **测试报告输出**
``` bash
测试结果:
状态: passed
重试次数: 3
总耗时: 0 时43 分17 秒
加速比信息: 44.5
关键日志: python time: 0.03890491
c time: 0.00087452
speedup: 44.48718648
测试报告: 测试通过,C代码的执行速度比Python快44.5倍,矩阵乘法实现正确,没有发现错误。
```
### 2. 文件漫游(File System Explorer) DEMO 运行过程
在本次演示中,Agent 首先会获取工作目录并执行一系列基础命令,以探索项目文件结构并查看部分文件内容。为了更直观地了解整个过程,我们不仅罗列操作步骤,还配合展示部分对应的日志输出,以体现 Agent 的思路和决策方式。
本次测试用的模型是 DeepSeek-R1-70b 蒸馏版本的网络 API,感谢 `knox.chat` 提供的免费 70b 模型的 Token。
实际上用 32b-q4 的 qwen 效果也不错,反而 32b-q4 的DeepSeek-R1 效果不如qianwen,32b 容易陷入无限 think 循环和输出错别字(比如多一个下划线或者多个空格),目前还不清楚原因。
我也用 DeepSeek-R1 满血版做过测试,但是服务器响应太慢,实际体验反而不如 DeepSeek-R1-70b。
#### 2.1 列出当前目录内容
- **操作目的**: 获取根目录下的文件和子目录,确定后续要浏览的文件或需要进入的子目录。
- **执行命令**: `ls`
**相关日志示例**:
```
plaintext复制编辑[DEBUG2] 18:31:20 执行命令: ls
[DEBUG1] 18:31:20 system_state: {... 'last_command': 'ls'}
```
从日志可以看到,Agent 发出了 `ls` 命令后,系统状态随之更新,记录了最新一次执行的命令。通过输出结果,Agent 便能知道项目根目录下有哪些文件与目录,为下一步浏览做准备。
#### 2.2 查看主文件 `main.py`
- **操作目的**: 读取主程序逻辑,了解其中定义的函数(如 `python2C()`、`romingbot()`)及其功能,为后续处理与分析做参考。
- **执行命令**: `cat main.py`
**相关日志示例**:
```
bash复制编辑[DEBUG2] 18:31:29 执行命令: cat main.py
[DEBUG1] 18:31:29 system_state: {... 'last_command': 'cat main.py'}
next_action_decision 输出流:
好的... 因为 main.py 可能是主入口文件,所以先 cat main.py。
```
可以看出,Agent 首先根据 `ls` 的结果发现有 `main.py`,并将其视为主入口文件。随后执行 `cat main.py` 命令查看文件内容,并在内部进行“思考”(`` 区域),确认这是它想要获取的关键信息。
#### 2.3 进入子目录 `core`
- **操作目的**: 进一步探索项目核心逻辑所在的位置,查看子目录下的相关文件。
- 执行命令 :
- `cd core`
- `ls`
**相关日志示例**:
```
python复制编辑[DEBUG2] 18:32:28 执行命令: cd core
[DEBUG2] 18:32:36 执行命令: ls
```
当 Agent 发现目录 `core` 可能存放更核心的实现文件后,便执行了 `cd core` 进入该目录,并再次使用 `ls` 命令查看此处的所有文件列表。
#### 2.4 查看并分析核心文件
在 `core` 目录下,Agent 针对关键文件执行了“查看内容—生成笔记—更新总结”的三步流程。下面以 `pipelinebase.py` 与 `pipeline.py` 为例,展示其中的操作和对应日志。
1. **查看 `pipelinebase.py`**
- **操作目的**: 了解基础流水线相关代码,掌握通用工具方法和基类实现细节。
- **执行命令**: `cat pipelinebase.py`
**日志示例**:
```
plaintext复制编辑[DEBUG2] 18:34:16 执行命令: cat pipelinebase.py
[DEBUG1] 18:34:24 开始笔记生成
note_generation 输出流:
正在撰写结构化的笔记...
[DEBUG2] 18:35:59 结果已保存至: output/new_note.json
...
```
这里可以看到,当 Agent 成功读取 `pipelinebase.py` 后,进入了“笔记生成”阶段,把文件要点记录为结构化信息,并保存到指定位置。
2. **查看 `pipeline.py`**
- **操作目的**: 了解 Python 到 C 代码转换的核心流水线,实现细节包括状态机流程、代码生成与编译测试等。
- **执行命令**: `cat pipeline.py`
**日志示例**:
```
plaintext复制编辑[DEBUG2] 18:35:21 执行命令: cat pipeline.py
summary_generation 输出流:
生成摘要并合并至 summaries...
...
```
与前一个文件类似,Agent 也会在确认提取了新信息后,执行自动化的内容总结与合并摘要操作。
#### 2.5 DeepSeek 决策和思考的流程(部分)
````python
[DEBUG2] 18:31:20 正在加载提示模板...
[DEBUG2] 18:31:20 已初始化7个处理链
[DEBUG2] 18:31:20 已加载的链: test_script_gen, result_report_gen, c_code_gen, next_action_decision, history_builder_chain, note_generation, sa_chain
[DEBUG1] 18:31:20 工作目录已初始化: /home/ubuntu/agent_demo
[DEBUG1] 18:31:20 初始化探索机器人
[DEBUG2] 18:31:20 执行命令: ls
[DEBUG1] 18:31:20 system_state: {'current_path': '/home/ubuntu/agent_demo', 'note_count': 0, 'note_word_count': 0, 'start_time': '2025-02-08T18:31:20.363208', 'executed_commands': deque(['ls'], maxlen=10), 'summaries': '', 'last_command': 'ls'}
next_action_decision 输出流:
好的,我现在需要根据系统状态和决策规则来决定下一步的行动。首先,系统当前的路径是‘/home/ubuntu/agent_demo’,最近执行的命令是‘ls’,并且输出显示了当前目录的文件和子目录。
根据决策规则,首先检查最近命令是否失败。这里‘ls’成功了,所以不需要尝试其他命令。接下来,规则3指出只能使用cd、ls、cat,所以我要在这三个命令中选择。
规则5提到要优先查看文件,而不是子目录。当前目录有几个文件:input.py、main.py、requirements.txt、config.py。这些都是代码文件,适合用cat查看。子目录有core、utils、prompts、workspace、chains,可能在后面再处理。
规则6说如果子目录可能有重要信息,建议cd进去,但规则5优先级更高,所以先处理文件。现在,我应该选择一个文件来cat。通常,main.py是项目的主文件,可能包含主要逻辑,所以先看main.py。
因此,下一步行动应该是执行cat main.py,并进行总结。这样可以获取更多信息,帮助后续决策。
```json
{
"reasoning": "最近命令ls成功,显示了当前目录的文件和子目录。根据规则5,优先查看文件。当前目录有input.py、main.py、requirements.txt、config.py等文件,这些都是代码文件,适合用cat查看。选择main.py,因为它通常是项目的主文件,可能包含重要信息。",
"action": "execute",
"next_command": "cat main.py"
}
```
[DEBUG2] 18:31:29 结果已保存至: output/next_action_decision.json
[DEBUG2] 18:31:29 执行命令: cat main.py
[DEBUG1] 18:31:29 system_state: {'current_path': '/home/ubuntu/agent_demo', 'note_count': 0, 'note_word_count': 0, 'start_time': '2025-02-08T18:31:20.363208', 'executed_commands': deque(['ls', 'cat main.py'], maxlen=10), 'summaries': '', 'last_command': 'cat main.py'}
next_action_decision 输出流:
好的,我现在需要根据系统状态和决策规则来决定下一步行动。首先,系统当前路径是‘/home/ubuntu/agent_demo’,最近执行的命令是‘cat main.py’,并且输出成功。根据规则4,如果最近命令是cat且成功,且内容与summaries不重复,应该进行总结。summaries当前为空,所以需要总结main.py的内容。
main.py文件中定义了两个函数:python2C()和romingbot()。python2C()函数使用Python2CPipeline处理输入代码,执行编译并输出结果。romingbot()函数则使用ExplorationBotPipeline执行‘ls’命令。主程序中调用了python2C()函数,而romingbot()被注释了。
因此,总结时应简要描述这两个函数的作用及其调用情况。接下来,根据规则8,优先查看文件,当前目录下可能还有其他文件需要查看,比如input.py或其他代码文件。因此,下一步可以考虑cat input.py,但需要先确认该文件是否存在。
总结完成后,action应为“write_note”,并填写相应的总结内容。同时,下一步的命令可以是‘cat input.py’,但根据输出要求,next_command在action为execute时才填写,否则为空。因此,这里action为“write_note”,next_command为空。
```json
{
"reasoning": "最近命令是cat main.py,成功执行。根据规则4,应进行总结。main.py文件包含两个函数:python2C()和romingbot()。python2C()用于将Python代码转换为C代码并执行,romingbot()用于执行ls命令。主程序调用了python2C()函数。",
"action": "write_note",
"next_command": ""
}
```
[DEBUG2] 18:31:40 结果已保存至: output/next_action_decision.json
[DEBUG1] 18:31:40 开始笔记生成
[DEBUG1] 18:31:40 system_state: {'current_path': '/home/ubuntu/agent_demo', 'note_count': 0, 'note_word_count': 0, 'start_time': '2025-02-08T18:31:20.363208', 'executed_commands': deque(['ls', 'cat main.py', 'write_note'], maxlen=10), 'summaries': '', 'last_command': 'write_note', 'last_reasoning': '最近命令是cat main.py,成功执行。根据规则4,应进行总结。main.py文件包含两个函数:python2C()和romingbot()。python2C()用于将Python代码转换为C代码并执行,romingbot()用于执行ls命令。主程序调用了python2C()函数。'}
note_generation 输出流:
好,我现在需要根据用户提供的代码和系统状态生成一个结构化的笔记。首先,我要理解用户的代码内容。代码中有两个函数,python2C()和romingbot(),以及主程序部分调用了python2C()。
python2C()函数看起来是用来将Python代码转换为C代码并执行的。它使用了Python2CPipeline类,读取input.py文件,执行pipeline,然后输出结果,包括编译状态、重试次数、总耗时、加速比信息、关键日志和测试报告。这个函数的主要目的是测试Python到C的转换过程,并提供详细的执行结果。
romingbot()函数则使用了ExplorationBotPipeline类,传入了一个路径'../agent_demo',并执行了'ls'命令。这可能是一个用于文件系统探索的机器人,执行基本的文件操作。
主程序部分调用了python2C()函数,说明当前的执行重点是Python到C的转换测试,而romingbot()函数被注释掉了,可能暂时不使用。
接下来,系统状态显示了当前路径、笔记数量、已执行的命令等信息。其中,已执行的命令包括'ls'、'cat main.py'和'write_note',最近一次命令是'write_note',用于生成笔记。系统摘要中提到,main.py文件包含两个函数,主程序调用了python2C()。
根据生成要求,我需要使用Markdown格式,内容不少于1000字,不输出系统状态,必须用中文,summaries要避免重复,不能直接输出原文,必须概括总结,禁止输出文件路径,二级标题不与一级标题重复,跳过许可证和版权信息,代码用代码块包裹。
首先,标题应该简短,不包含文件名,比如“Python到C代码转换与探索机器人功能实现”。
内容部分需要分为几个部分。首先是概述,简要介绍整个脚本的功能和结构。然后是详细功能说明,分为Python到C转换功能和探索机器人功能。接着是实现细节,包括代码结构和关键实现步骤。最后是测试与结果展示,说明如何测试这两个功能模块。
在写作过程中,要避免重复summaries中的内容,进行概括总结。例如,summaries中提到main.py包含两个函数,主程序调用了python2C(),在笔记中可以进一步扩展,说明每个函数的具体功能和实现细节。
需要注意的是,不能直接输出文件路径,所以在描述代码时,要避免提及具体的路径,如'../agent_demo'。代码块需要用```包裹,并说明代码的作用。
最后,确保内容达到1000字以上,结构清晰,逻辑连贯。使用适当的二级标题,使内容易于阅读和理解。
现在,根据以上思考,我可以开始撰写结构化的笔记了。
```json
{
"title": "Python到C代码转换与探索机器人功能实现",
"content": "本文档概述了一个用于将Python代码转换为C代码并执行的脚本,以及一个用于文件系统探索的机器人功能的实现。脚本通过两个主要函数实现其核心功能:python2C()和romingbot()。主程序执行python2C()函数以进行代码转换和测试。\n\n### Python到C代码转换功能\n\n该功能通过Python2CPipeline类实现,主要步骤包括读取输入Python代码、执行转换流程、编译并运行生成的C代码。转换过程中会记录编译状态、重试次数、总耗时等信息,并生成详细的测试报告,包括加速比和关键日志。\n\n### 探索机器人功能\n\nromingbot()函数使用ExplorationBotPipeline类,用于执行基本的文件系统操作,如目录列表查询。该功能可扩展为更复杂的文件操作,目前示例中执行'ls'命令以展示目录内容。\n\n### 实现细节\n\n代码结构清晰,主函数调用python2C()执行转换测试。转换过程中,读取输入文件,执行pipeline,处理结果并格式化输出。romingbot()函数初始化pipeline并执行指定命令。\n\n### 测试与结果展示\n\n测试结果包括编译状态、重试次数、总耗时、加速比、关键日志和测试报告。这些信息帮助评估转换的效率和效果。探索机器人部分可通过执行不同命令扩展功能。",
"tags": ["代码转换", "机器人", "测试报告"]
}
```
[DEBUG2] 18:32:09 结果已保存至: output/new_note.json
summary_generation 输出流:
好的,我现在需要根据用户提供的笔记内容生成一个摘要,并将其与之前的摘要合并,确保总长度不超过200字。首先,我要仔细阅读用户提供的笔记内容,理解其中的主要信息。
笔记内容主要分为三个部分:概述、Python到C代码转换功能、探索机器人功能,以及实现细节和测试结果展示。概述部分提到了两个主要功能:代码转换和文件系统探索。转换功能通过python2C()函数实现,使用Python2CPipeline类,处理输入代码,记录状态和生成报告。探索机器人功能由romingbot()函数实现,使用ExplorationBotPipeline类,执行基本文件操作,如'ls'命令。
接下来,我需要将这些内容浓缩成一个简洁的摘要,确保涵盖关键点:代码转换、测试报告、探索机器人功能及其扩展性。同时,要与之前的摘要合并,但用户没有提供之前的摘要内容,所以我可能需要假设之前的摘要已经涵盖了部分内容,或者直接生成一个全新的摘要。
根据生成要求,摘要需要高度概括,避免使用代码或特殊字符,并且控制在200字以内。因此,我需要用简洁的语言概括已记录的内容,确保不重复,并突出主要功能和测试结果。
现在,我会组织语言,确保每个主要部分都有所涵盖,同时保持流畅和简洁。例如,提到代码转换脚本、转换流程、测试报告,探索机器人功能及其扩展性,以及测试结果的展示。
最后,检查字数,确保不超过限制,并且格式正确,输出为JSON格式的summary字段。
```json
{
"summary": "已经记录了Python代码转换为C代码的脚本实现,包括转换流程、测试报告生成和探索机器人功能的基础实现。转换功能通过python2C()函数实现,记录编译状态、耗时等信息并生成报告。探索机器人功能可执行文件系统操作,如目录查询,并具备扩展潜力。测试结果展示了转换效率和效果,机器人功能可通过命令扩展。"
}
```
[DEBUG2] 18:32:21 结果已保存至: output/summary_generation.json
[DEBUG1] 18:32:21 system_state: {'current_path': '/home/ubuntu/agent_demo', 'note_count': 1, 'note_word_count': 1, 'start_time': '2025-02-08T18:31:20.363208', 'executed_commands': deque(['ls', 'cat main.py', 'write_note'], maxlen=10), 'summaries': '已经记录了Python代码转换为C代码的脚本实现,包括转换流程、测试报告生成和探索机器人功能的基础实现。转换功能通过python2C()函数实现,记录编译状态、耗时等信息并生成报告。探索机器人功能可执行文件系统操作,如目录查询,并具备扩展潜力。测试结果展示了转换效率和效果,机器人功能可通过命令扩展。', 'last_command': 'write_note'}
next_action_decision 输出流:
好的,我现在需要根据系统状态和决策规则来决定下一步的行动。首先,最近执行的命令是write_note,输出显示笔记已经保存到notes.md,并列出了当前目录的文件和子目录。系统状态中的summaries已经包含了对代码转换和机器人功能的描述,所以根据规则4,不需要再次总结。
接下来,查看决策规则。规则6指出,如果子目录可能有重要信息,建议cd进去查看。当前目录下有core、utils、prompts、workspace和chains五个子目录,这些看起来都可能包含重要的代码或配置文件,特别是core和utils可能包含转换脚本的核心实现。
规则8提到要优先查看文件,但当前目录的文件如input.py、config.py可能已经被处理过,或者可能不如子目录的内容重要。因此,应该优先探索子目录,特别是core,因为它可能包含主要的功能实现。
所以,下一步应该是执行cd core,进入core子目录查看里面的内容,以便进一步了解代码结构和实现细节。
```json
{
"reasoning": "最近命令write_note成功,summaries已经包含了相关信息。当前目录有多个子目录,特别是core和utils可能包含重要代码。根据规则6,建议cd进入子目录查看。",
"action": "execute",
"next_command": "cd core"
}
```
[DEBUG2] 18:32:28 结果已保存至: output/next_action_decision.json
[DEBUG2] 18:32:28 执行命令: cd core
[DEBUG1] 18:32:28 system_state: {'current_path': '/home/ubuntu/agent_demo/core', 'note_count': 1, 'note_word_count': 1, 'start_time': '2025-02-08T18:31:20.363208', 'executed_commands': deque(['ls', 'cat main.py', 'write_note', 'cd core'], maxlen=10), 'summaries': '已经记录了Python代码转换为C代码的脚本实现,包括转换流程、测试报告生成和探索机器人功能的基础实现。转换功能通过python2C()函数实现,记录编译状态、耗时等信息并生成报告。探索机器人功能可执行文件系统操作,如目录查询,并具备扩展潜力。测试结果展示了转换效率和效果,机器人功能可通过命令扩展。', 'last_command': 'cd core'}
next_action_decision 输出流:
流式请求发生错误: Connection error.
[DEBUG1] 18:32:45 链执行失败: Connection error. (第 1 次重试,共 10 次)
next_action_decision 输出流:
流式请求发生错误: Request timed out.
[DEBUG1] 18:33:04 链执行失败: Request timed out. (第 2 次重试,共 10 次)
next_action_decision 输出流:
流式请求发生错误: Request timed out.
[DEBUG1] 18:33:23 链执行失败: Request timed out. (第 3 次重试,共 10 次)
next_action_decision 输出流:
好的,我现在需要根据系统状态和决策规则来决定下一步行动。首先,系统当前路径是‘/home/ubuntu/agent_demo/core’,最近执行的命令是‘cd core’,输出显示目录切换成功,当前目录有三个文件:piplinebase.py、pipeline.py和romingbot.py。
根据决策规则,首先检查最近命令是否成功。这里‘cd core’成功了,所以不需要考虑规则1。接下来,规则3指出只能执行cd、ls、cat命令,而我打算执行ls来查看目录详细信息,这符合规则3。
规则6提到如果子目录可能有重要信息,建议cd进入查看,但这里当前目录有三个文件,没有子目录,所以暂时不需要cd。规则7说如果目录为空则cd..,但这里有文件,所以也不适用。规则8建议优先查看文件,所以我应该先查看这些文件。
接下来,我应该先执行ls命令,以获取更多关于这些文件的信息,比如大小、修改时间等,这有助于决定下一步是否需要cat查看文件内容。因此,下一步行动应该是执行ls命令。
```json
{
"reasoning": "最近命令'cd core'成功,当前目录有三个Python文件。根据规则8,优先查看文件。执行ls命令以获取文件详细信息,帮助决定下一步是否查看文件内容。",
"action": "execute",
"next_command": "ls"
}
```
...
````
## 六. 文件漫游 Agent 对自己的源码的漫游笔记(部分)
[点击此处查看全部](./doc/note_self.md)
>
> ## 4. factory.py - LLM链式调用与工厂实现
> > Time: `2025-02-08 13:48`
> >
> > Path: `D:\work\agent_demo\chains\factory.py`
> >
> > Tags: `LLM` `流式处理` `链式调用`
>
> 该代码实现了一个支持流式输出的LLM链式调用框架,主要包含两个核心类:VerboseChain和ChainFactory。VerboseChain类用于通过OpenAI API调用模型,支持流式响应处理和日志记录。ChainFactory类则负责加载和管理多个处理链,提供便捷的方式初始化和获取链式调用实例。
>
> ### VerboseChain类
>
> #### 概述
> VerboseChain类是框架的核心,负责实际的模型调用和响应处理。它支持从文件或字符串创建提示模板,并提供了流式输出的处理逻辑。
>
> #### 初始化
> 该类通过构造函数初始化,接受prompt、output_key和name参数。构造函数中初始化OpenAI客户端,加载模板,并设置模型参数如max_tokens和temperature。
>
> #### 方法
> 1. from_prompt_file:从文件路径加载提示模板,返回VerboseChain实例。
> 2. from_prompt_string:从字符串加载提示模板,返回VerboseChain实例。
> 3. invoke:执行模型调用,处理流式响应,返回处理后的结果。
>
> #### 流式处理
> invoke方法通过启用stream参数,接收分块响应,并实时打印和存储内容。处理完所有块后,清理响应内容中的思考标签,返回最终结果。
>
> ### ChainFactory类
>
> #### 概述
> ChainFactory类作为LLM链的工厂,负责加载和管理多个处理链。它自动扫描指定目录下的提示模板文件,初始化并存储各个链式调用实例。
>
> #### 初始化
> 构造函数接受prompts_dir参数,扫描该目录下的所有.txt文件,加载并初始化每个文件对应的VerboseChain实例,存储在chains字典中。
>
> #### 方法
> 1. get_chains:返回所有初始化好的链式调用实例。
>
> ### 实现细节
> 1. 日志记录:通过debug_log函数记录关键步骤的日志,方便调试和监控。
> 2. 正则处理:在invoke方法中使用正则表达式清理响应内容中的<思考>标签。
> 3. 错误处理:在流式处理中捕获异常并打印错误信息。
> 4. 扩展参数:支持通过extra_body传递额外的模型参数,如return_reasoning。
>
> ### 示例
> ```python
> # 创建工厂并加载所有提示模板
> factory = ChainFactory(prompts_dir="prompts")
>
> # 获取所有链
> chains = factory.get_chains()
>
> # 使用特定链进行调用
> response = chains["my_chain"].invoke(inputs)
> ```
>
> ### 总结
> 该框架通过模块化设计,支持灵活的提示管理和流式响应处理,适用于需要详细日志记录和多链式调用场景。通过ChainFactory简化了链的管理和加载过程,而VerboseChain则提供了强大的模型调用和响应处理能力。
>
> ## 5. pipeline.py - Python到C代码转换流水线实现
>
> Time: `2025-02-08 13:49`
>
> Path: `D:\work\agent_demo\core\pipeline.py`
>
> Tags: `代码转换` `流水线` `自动化`
> 该代码实现了一个将Python代码转换为C代码的完整流水线,涵盖了从代码生成到测试和编译的多个阶段。流水线通过状态机的方式管理各个阶段,确保每个步骤按顺序执行,并在必要时进行重试。
>
> ### 结构与组件
>
> 流水线由多个关键组件构成,包括代码生成器、测试生成器、编译器和报告解析器。这些组件协同工作,以确保转换过程的准确性和可靠性。
>
> ### 执行流程
>
> 流水线的执行分为几个关键阶段:
>
> 1. **初始化**:设置初始状态并准备输出目录。
>
> 2. **C代码生成**:利用LLM生成C代码,并对生成的代码进行清洗和保存。
>
> 3. **测试脚本生成**:生成用于测试的Python脚本,并保存以备后用。
>
> 4. **编译与测试**:编译生成的C代码并执行测试,记录测试结果。
>
> 5. **最终报告**:根据测试结果生成评估报告,判断转换的正确性。如果报告指出存在问题,流水线会进入重试状态,重新执行转换过程。
>
> ### 错误处理与重试机制
>
> 流水线在每个关键步骤后进行检查,确保生成的文件和测试结果符合预期。如果在任何阶段检测到错误,流水线会记录错误信息,并在必要时触发重试机制,以确保最终输出的正确性和可靠性。
>
> ## 6. piplinebase.py - 流水线基础类
> > Time: `2025-02-08 13:49`
> >
> > Path: `D:\work\agent_demo\core\piplinebase.py`
> >
> > Tags: `流水线` `LLM` `代码清洗` `结果保存`
>
> 该文件定义了一个基础流水线类PipelineBase,提供了执行LLM链、保存输出、解码中文Unicode和清洗代码等功能。
>
> ### 类概述
>
> PipelineBase类作为基础流水线类,主要用于提供常用的工具方法,包括LLM链的执行、结果保存、中文字符解码和代码清洗等功能。该类在初始化时设置了重试次数、历史记录和开始时间等属性。
>
> ### 方法说明
>
> #### 1. LLM_invoke方法
>
> - 功能:执行单个LLM链并保存结果
> - 参数:prompt_template(VerboseChain类型)、inputs(字典)、output_file(文件名,选项)
> - 返回值:结果字典
> - 特点:支持最多10次重试,每次失败后等待3秒
> - 备注:结果保存为JSON格式,文件名默认为链的名称
>
> #### 2. _save_output方法
>
> - 功能:保存输出到文件
> - 参数:content(字符串内容)、filename(文件名)
> - 特点:仅解码中文字符的Unicode转义,使用utf-8编码保存
> - 备注:文件路径由OutputManager管理
>
> #### 3. _save_code方法
>
> - 功能:保存代码文件
> - 参数:code(代码字符串)、filename(文件名)
> - 备注:直接将代码写入文件
>
> #### 4. _decode_chinese_unicode方法
>
> - 功能:解码中文字符的Unicode转义
> - 参数:content(字符串)
> - 返回值:解码后的字符串
> - 特点:仅处理中文字符的Unicode转义,保留其他转义符
>
> #### 5. _clean_code方法
>
> - 功能:清洗代码块
> - 参数:code(代码字符串)、lang(语言标识)
> - 返回值:清洗后的代码字符串
> - 特点:支持多种代码块格式,包括标准三反引号块和无标记块
> - 备注:处理语言标识、去除反引号、清理空白
>
> #### 6. _post_process方法
>
> - 功能:统一的后续处理
> - 参数:code(代码字符串)
> - 返回值:处理后的代码字符串
> - 处理内容:清理每行末尾空白,保留换行结构
>
> ### 代码示例
>
> ```python
> # 示例:执行LLM链并保存结果
> result = pipeline.LLM_invoke(prompt_template, inputs)
> ```
>
> ```python
> # 示例:保存代码文件
> pipeline._save_code(code, 'example.py')
> ```
>
> ### 总结
>
> PipelineBase类提供了基础的流水线功能,涵盖了LLM链的执行、结果保存、中文字符处理和代码清洗等方面。通过这些方法,可以方便地管理和处理LLM链的输出,确保结果的正确性和可读性。
>
> ## 7. romingbot.py - 文件系统探索机器人功能概述
> > Time: `2025-02-08 13:50`
> >
> > Path: `D:\work\agent_demo\core\romingbot.py`
> >
> > Tags: `文件系统` `探索` `笔记生成` `命令执行`
>
> 文件系统探索机器人旨在通过执行基本的文件系统命令(如cd、ls、cat、pwd)来探索和记录指定目录下的文件和文件夹。该机器人能够记录执行的命令、生成笔记并进行总结,提供结构化的输出结果。以下是对该机器人功能的详细说明。
>
> ### 核心功能
>
> 1. **文件系统命令执行**
> - 支持cd命令:切换目录
> - 支持ls命令:列出目录内容
> - 支持cat命令:查看文件内容
> - 支持pwd命令:显示当前工作目录
>
> 2. **状态管理**
> - 记录当前路径
> - 统计笔记数量和字数
> - 记录开始时间
> - 记录最近执行的命令(最多10条)
> - 生成总结
>
> 3. **笔记生成**
> - 自动生成Markdown格式的笔记
> - 支持多级标题
> - 自动生成内容摘要
> - 支持代码块格式
>
> 4. **扩展性**
> - 通过ChainFactory和PromptFactory实现功能扩展
> - 支持多种状态切换(初始化、空闲、执行命令、写笔记、决定下一步、完成)
>
> ### 实现细节
>
> 1. **初始化流程**
> - 创建必要的目录结构
> - 初始化状态字典
> - 准备笔记目录
> - 重命名现有的notes.md文件以避免覆盖
>
> 2. **命令处理流程**
> - 根据用户输入切换状态
> - 执行相应的命令处理逻辑
> - 记录命令执行结果
> - 更新状态字典
>
> 3. **笔记写入流程**
> - 根据用户输入和系统状态生成笔记内容
> - 使用LLM(大语言模型)进行内容生成
> - 格式化输出为Markdown
>
> 4. **状态管理**
> - 使用枚举定义机器人状态
> - 通过状态字典记录系统的运行状态
> - 提供灵活的状态切换机制
>
> ### 状态管理
>
> 机器人在运行过程中会经历以下几个状态:
>
> 1. **初始化状态(INIT)**
> - 系统初始化
> - 创建必要的目录和文件
> - 准备开始执行任务
>
> 2. **空闲状态(IDLE)**
> - 等待用户输入
> - 可以接受新的命令
>
> 3. **执行命令状态(EXEC_COMMAND)**
> - 处理用户输入的命令
> - 执行相应的操作
> - 记录命令执行结果
>
> 4. **写笔记状态(WRITE_NOTE)**
> - 根据执行结果生成笔记
> - 格式化笔记内容
> - 保存笔记到指定目录
>
> 5. **决定下一步状态(DECIDE_NEXT)**
> - 根据当前状态和执行结果决定下一步操作
> - 切换到新的状态
>
> 6. **完成状态(COMPLETED)**
> - 任务完成
> - 返回最终的状态字典
>
> ### 命令处理
>
> 1. **cd命令**
> - 切换当前工作目录
> - 更新current_dir属性
> - 记录执行的cd命令
>
> 2. **ls命令**
> - 列出当前目录下的文件和文件夹
> - 支持带参数的ls命令(如ls *.txt)
> - 格式化输出结果
>
> 3. **cat命令**
> - 查看指定文件的内容
> - 支持逐行显示文件内容
> - 处理文件不存在或权限不足的情况
>
> 4. **pwd命令**
> - 显示当前工作目录
> - 使用shell命令执行pwd
> - 获取并返回当前路径
>
> ### 笔记生成
>
> 1. **笔记格式**
> - 使用Markdown格式
> - 包含标题、内容和标签
> - 支持多级标题
> - 支持代码块
>
> 2. **内容生成**
> - 根据执行结果生成内容
> - 使用LLM进行内容摘要和总结
> - 避免重复内容
> - 跳过许可证和版权信息
>
> 3. **保存笔记**
> - 将笔记保存到指定目录
> - 自动生成文件名(包含时间戳)
> - 确保文件不被覆盖
>
> ### 扩展性与维护性
>
> 1. **功能扩展**
> - 通过ChainFactory和PromptFactory实现功能扩展
> - 支持添加新的命令处理逻辑
> - 支持添加新的笔记生成模板
>
> 2. **状态扩展**
> - 支持添加新的机器人状态
> - 支持添加新的状态切换逻辑
>
> 3. **日志记录**
> - 使用debug_log记录运行日志
> - 支持不同级别的日志输出
> - 方便调试和维护
>
> ### 未来改进
>
> 1. **增加命令支持**
> - 支持更多的文件系统命令(如mkdir、rm、cp等)
> - 增强命令处理的灵活性
>
> 2. **优化笔记生成**
> - 提高笔记内容的质量和准确性
> - 支持多种笔记生成模板
> - 增强LLM的使用效果
>
> 3. **增强错误处理**
> - 提供更详细的错误信息
> - 支持错误_recovery机制
> - 提高系统的健壮性
>
> 4. **用户界面优化**
> - 提供更友好的用户界面
> - 支持交互式操作
> - 提高用户体验
>
> ### 总结
>
> 文件系统探索机器人是一个功能强大且灵活的工具,能够帮助用户高效地探索和记录文件系统中的内容。通过支持多种文件系统命令、生成结构化笔记、管理系统状态等功能,该机器人在文件系统探索和文档生成方面具有广阔的应用前景。未来可以通过扩展命令支持、优化笔记生成、增强错误处理和优化用户界面等方式进一步提升其功能和用户体验。
## 七、后续展望
这两个 DEMO 还在非常初级的阶段,很多功能都很粗糙。比如:
- Python -> C 转换只实现了单函数层面,若要支持第三方库、类、异常处理等情况,得再做大量适配。
- 文件漫游 Agent 还不支持多个智能体并行协作,也没深入探索文件层级结构的全局摘要或与 RAG(Retrieval-Augmented Generation)的结合。
- 真正实现多人协作、多进程或多线程并行,甚至跨文件夹的语义搜索和“总结记忆”,才可能打造出一个多维度的智能助理。
- 目前文件漫游 Agent 还不能读取过长的文件。
总之,Agent 这个概念想做的事儿很多,但当前只是“把想法跑起来”的第一步。离真正落地还有不少距离:安全、扩展、可靠性、可维护性等都需要更深入的研究和实践。希望这些初步的经验分享,能给大家带来一些启发,也欢迎一起讨论如何让 Agent 在日常开发中更好地发挥作用。