# 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

Model LangChain
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 使用。 目前只实现了简单的函数级转换。如果遇到第三方库或更复杂的逻辑,还需要更深入的兼容适配。但它为自动化移植与测试提供了一个雏形,一旦与日常开发结合,可减少大量繁琐重复的工作。 具体流程如下: ![1](assets/1-1739023720835-1-1739023767308-5.png) ``` 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 进入结束状态,整个流程随之结束。 ![2](assets/2-1739023720836-2-1739023767308-6.png) ``` 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 在日常开发中更好地发挥作用。