用 HelloAgents 组件搭建类 Claude Code 的本地 Code Agent CLI:多轮对话、按需代码探索与安全补丁落盘实战
2026/9/11 23:51:12 网站建设 项目流程

用 HelloAgents 组件搭建类 Claude Code 的本地 Code Agent CLI:多轮对话、按需代码探索与安全补丁落盘实战

【免费下载链接】hello-agents📚 《从零开始构建智能体》——从零开始的智能体原理与实践教程项目地址: https://gitcode.com/GitHub_Trending/he/hello-agents

本文以开源仓库Co-creation-projects/YYHDBL-HelloCodeAgentCli中的code_agent/README.md为核心,深入拆解一个基于 HelloAgents 组件(HelloAgentsLLM/ContextBuilder/ReActAgent/TerminalTool/NoteTool/MemoryTool)实现的简易 Code Agent CLI。它面向本地代码仓库提供类似 Claude Code / Codex 的交互体验:支持多轮对话、按需探索代码库、生成补丁并在用户确认后安全落盘。读完本文,你将掌握该 CLI 的安装启动方式、ReActAgent多轮对话与规划机制、GSSC 上下文工程与按需探索(lazy_fetch)模式、终端工具的沙箱与危险命令确认策略,以及 Codex 风格补丁从模型输出到原子落盘的完整链路。

项目定位与整体设计

HelloAgents Code Agent CLI(代码目录Co-creation-projects/YYHDBL-HelloCodeAgentCli/)是一个面向本地代码仓库的命令行智能体。与通用对话机器人不同,它被设计为"在仓库内工作的 CLI 编程助手":工作区固定为仓库根目录,所有路径都必须经过 repo_root 前缀校验,写盘唯一通道是补丁 + apply_patch,禁止cat >/tee/ Here-Doc / 重定向等终端写法。

从源码结构看,系统采用分层设计:

  • CLI 层code_agent/hello_code_cli.py负责参数解析、环境初始化、交互循环、补丁提取与确认;
  • 智能体层agents/react_agent.py提供 ReAct(推理 + 工具调用)主循环,配合agents/simple_agent.pyagents/plan_solve_agent.pyagents/reflection_agent.py等范式;
  • 核心层core/llm.pyHelloAgentsLLM统一 LLM 接口)、core/message.pycore/config.pycore/exceptions.py
  • 上下文层context/builder.py实现 GSSC 流水线;
  • 工具层tools/builtin/下的terminal_tool.pycontext_fetch_tool.pynote_tool.pytodo_tool.pyplan_tool.pymemory_tool.py等;
  • 执行器层code_agent/executors/apply_patch_executor.py负责安全补丁应用与文件操作。

其中 Code Agent 的主逻辑封装在code_agent/agentic/code_agent.pyCodeAgent类中,CLI 入口main()只负责拼装组件与交互循环(hello_code_cli.py)。

快速开始:从依赖到启动 CLI

1. 准备依赖与环境变量

依赖定义在项目根目录的requirement.txt

openai>=1.0.0 pydantic>=2.0.0 python-dotenv>=1.0.0 tiktoken>=0.5.0 hello-agents[all]=0.2.7

建议先安装根目录的requirements-mvp.txt(见code_agent/README.md),再在仓库根目录创建.env(参考.env.example,不要提交到版本库),至少包含:

DEEPSEEK_API_KEY=sk-xxxxxxxxxxxx

可选配置(OpenAI 兼容 provider 均可):

LLM_MODEL_ID=deepseek-chat LLM_BASE_URL=https://api.deepseek.com

CLI 启动时会执行load_dotenv(dotenv_path=repo_root / ".env", override=False)加载环境变量,并通过HelloAgentsLLM()自动从环境探测 provider(hello_code_cli.py)。启动时还会做一次 LLM 预检(ping请求,max_tokens=1),若认证失败会给出明确提示并返回退出码 2。

2. 启动 CLI

# 工作区默认为当前目录 python3 -m code_agent.hello_code_cli --repo . # 指定其他代码库 python3 -m code_agent.hello_code_cli --repo /path/to/your/project

支持的启动参数:

参数说明默认值
--repo代码库根目录(工作区).
--project项目名称(默认取 repo 目录名),用于笔记标签等目录名

启动后进入交互循环,命令:

  • :quit(或:q/quit/exit):退出;
  • :plan <目标>:强制生成计划(平时由模型按需调用plan[...]工具);
  • 直接输入自然语言即触发一轮 ReAct 对话(hello_code_cli.py)。

多轮对话与智能体范式:ReAct 主循环 + 可选规划

Code Agent 的核心循环使用ReActAgent:每次回复必须包含ThoughtAction两部分,Action二选一——调用工具(tool_name[tool_input])或以Finish[最终回答]结束;Finish中可携带*** Begin Patch ... *** End Patch补丁(react.md)。

CodeAgent.__init__中,工具注册表包含六个工具:terminalnoteplantodocontext_fetch,以及通过MemoryTool启用的情景记忆;ReAct 最大步数设置为 20,并注入observation_summarizer:当工具输出超过 8000 字符时先截断,再交给 LLM 以summarize_observation.md模板压缩为不超过 400 token 的摘要,避免把巨大原始输出直接塞进 Prompt(code_agent.py)。

run_turn每轮流程为:

  1. 空输入提示、闲聊(hi/hello/你好/在吗等)直接自然回复,避免无谓工具调用;
  2. 元请求("刚才说了什么 / recap")直接总结最近对话历史,不调用 memory/note;
  3. 检测到"分步/步骤/计划/改造/完成后"等多步骤词汇时,向系统提示追加轻量 hint,引导模型先用 todo 记录;
  4. ContextBuilder.build_base构建保底上下文(系统指令 + 对话历史 + 最近工具摘要);
  5. 运行 ReAct 循环,收集last_trace中的工具证据摘要存入recent_tool_packets(缓冲区上限 8 个);
  6. 追加用户/助手消息到历史(保留最近 50 条)并持久化会话到sessions/下的 JSON 文件;
  7. 若模型使用了 todo 但未在结尾todo list汇总,自动补一张 Todo board 快照(code_agent.py)。

规划能力作为可选工具plan[...]暴露给模型,模型按需调用;计划模板要求输出## Plan(5~12 条可运行步骤)、## Risks## Validation三节(plan.md)。多步骤任务的进度追踪由todo[...]完成,状态为pending / in_progress(仅 1 个)/ completed

上下文工程:GSSC 流水线与按需探索(lazy_fetch)

上下文构建由context/builder.pyContextBuilder实现 GSSC 流水线:Gather(从历史、记忆、RAG、工具结果多源收集)→Select(基于优先级、相关性、多样性筛选,支持 MMR)→Structure(组织成结构化模板)→Compress(在 token 预算内压缩)。

Code Agent 的关键设计是ContextConfig(lazy_fetch=True)默认不做全仓扫描、不主动查询 memory/rag,只构建"保底上下文"(系统提示 + 最近 10 轮对话历史 + 上次工具摘要),扩展上下文改由模型通过context_fetch工具按需获取(code_agent.py)。

ContextConfig的核心参数(builder.py):

参数默认值说明
max_tokens8000上下文总预算
reserve_ratio0.15生成余量(可用预算 = max_tokens × (1 − reserve_ratio))
min_relevance0.3扩展上下文最小相关性阈值
max_history_turns10最大保留对话轮数
enable_mmr/mmr_lambdaTrue / 0.7最大边际相关性(0=纯多样性,1=纯相关性)
enable_compressionTrue启用压缩
lazy_fetchTrue按需探索模式:不主动查 memory/rag

context_fetch是聚合搜索工具,一次调用可搜索多个源(files/notes/memory/tests),自动控制 token 预算(默认每源约 800 token,单次 5 行上下文),比反复单独调用 note/memory search 更省步数;使用策略是"先用保底上下文推理,证据不足再调用"(tools.md)。

安全终端工具:白名单、shell 语义与危险命令确认

TerminalTool是 Code Agent 查看/检索代码库的主要通道,实现于tools/builtin/terminal_tool.py,具有多层安全机制:

  1. 命令白名单ALLOWED_COMMANDS仅包含只读与文本处理命令——ls/dir/treecat/head/tail/less/morefind/grep/egrep/fgrep/rgwc/sort/uniq/cut/awk/sedecho/printfmkdirpwd/cdfile/stat/du/dfwhich/whereisgit(terminal_tool.py);
  2. shell 语义:默认启用default_shell_mode=True(体验更像 Claude Code),支持管道等写法(如rg ... | head);但重定向(>/>>/dev/null除外)、子命令替换($()/反引号)、rm/chmodgit reset --hard均被判定为高风险,必须allow_dangerous=true并通过交互确认(confirm_dangerous=True)后才执行(terminal_tool.py);
  3. 路径沙箱cd被限制在工作空间内,rm/chmod/mkdir的路径参数(跳过-选项)逐一resolve()后校验是否位于 workspace 内;
  4. 超时与输出限制:默认超时 30 秒(CodeAgent 实例化时传入 60 秒)、输出上限 10MB,超限截断(terminal_tool.py);
  5. argv-only 执行:非 shell 模式使用shlex.split+subprocess.run(shell=False),避免 shell 注入;git 子命令仅放行只读的status/diff

git的默认策略是"仅允许status/diff",git reset --hard需要显式放行——这与 CLI 层补丁确认策略一致,共同构成"默认只读、危险操作必须人工确认"的安全基调(terminal_tool.py)。

补丁落盘(B 路线):从模型输出到原子写入

补丁格式规范

模型在Finish[...]中输出 Codex 风格补丁,格式必须严格遵守(system.md):

*** Begin Patch *** Add File: path/to/new_file.py 文件内容... 可以多行... *** Update File: path/to/existing_file.py 更新后的完整文件内容... *** Delete File: path/to/old_file.py *** End Patch

关键规则:第一行必须是*** Begin Patch(前面不能有任何文字);*** End Patch独占最后一行;Add/Update后跟完整文件内容、Delete后不需要内容;不要在补丁外包裹 markdown 代码块;路径相对于仓库根目录。

CLI 侧的提取与确认

CLI 使用两个正则从响应中提取补丁:PATCH_FENCE_RE优先匹配 ```patch/diff/text 围栏内的补丁块,PATCH_RE作为宽松兜底(跨行匹配*** Begin Patch ... *** End Patch)(hello_code_cli.py)。_normalize_patch会宽容修复模型常见的格式错误——如缺少前导***Add File: / Update File: / Delete File:行会被自动补齐(hello_code_cli.py)。

_patch_requires_confirmation定义高风险补丁触发二次确认的条件(hello_code_cli.py):

  • 包含*** Delete File:删除操作;
  • 文件操作数 ≥ 6 个;
  • 变更行数 ≥ 400 行。

命中任一条件即进入y/n确认流程;拒绝则取消落盘。应用成功后,CLI 会自动通过 NoteTool 以note_type=actiontags=[project, patch_applied]记录一条"Patch applied"笔记,失败则记录blocker类型的"Patch failed"笔记,便于后续复盘(hello_code_cli.py)。

ApplyPatchExecutor 的安全执行

落盘由code_agent/executors/apply_patch_executor.pyApplyPatchExecutor完成,支持三种操作:Add FileUpdate FileDelete File。其安全特性(MVP)包括:

  • repo_root 路径限制_safe_path拒绝绝对路径(/~开头)、拒绝逃逸 repo_root 的路径(resolve 后前缀校验)、拒绝修改符号链接,防止路径穿越(apply_patch_executor.py);
  • 后缀白名单allowed_write_suffixes默认仅允许.py/.md/.toml/.json/.yml/.yaml/.txt/.html/.htm/.css/.js等文本文件,防止误改二进制或敏感文件(apply_patch_executor.py);
  • 规模限制:单个补丁最多 10 个文件、总变更行数上限 800 行(_estimate_changed_lines对 add 按行数、delete 按 1 行、update 只计+/-行);
  • 原子写入_atomic_write先写临时文件并os.fsync刷盘,再用os.replace原子替换,避免中断导致文件损坏(apply_patch_executor.py);
  • 自动备份:每次应用前在<repo>/.helloagents/backups/<时间戳>/下为被修改文件生成.bak备份(保留仓库相对路径结构);
  • 冲突检测Update File按 hunk(@@或空行分隔)精确匹配上下文子序列,找不到匹配时抛出PatchApplyError并附recheck_targets提示(如rel_path:search:'<上下文行>');匹配失败还会尝试忽略行尾空白的宽松匹配,以及"将 payload 视作新的完整文件"的兜底回退(apply_patch_executor.py)。

记忆与笔记:episodic 情景记忆与结构化笔记

  • NoteTool:在<repo>/.helloagents/notes/下写入结构化 Markdown 笔记,note_type支持action / decision / blocker / task_state等,用于记录决策、阻塞与行动;CLI 还会自动把补丁成功/失败写入笔记。
  • MemoryTool:仅启用episodic类型(SQLite 持久化),默认存储在<repo>/.helloagents/memory/;情景记忆需要显式add,不会自动写入,避免上下文污染;跨会话可通过search回忆"发生过什么"(tools.md)。
  • 会话持久化:每轮对话结束后,最近 50 条历史以 JSON 形式写入<repo>/.helloagents/sessions/<session_id>.json(code_agent.py)。

存储布局默认使用<repo>/.helloagents/(notes/memory/sessions/logs/backups/todos),可通过环境变量覆盖。

配置项与存储布局

core/config.pyConfig类集中管理全部配置,支持环境变量加载(CODE_AGENT_<配置项大写>或传统命名)与手动覆盖(config.py)。code_agent/README.md明确给出的覆盖变量:

  • HELLOAGENTS_DIR=.helloagents:状态存储根目录(也可用CODE_AGENT_STATE_DIR);
  • CODE_AGENT_MAX_STEPS=8:ReAct 最大推理步数(源码默认 20,源码另支持CODE_AGENT_MAX_REACT_STEPS)。

其余可通过环境变量调节的常用项(源码确认):CODE_AGENT_PATCH_MAX_FILES(默认 10)、CODE_AGENT_PATCH_MAX_LINES(默认 800)、CODE_AGENT_TERMINAL_TIMEOUT(默认 60 秒)、LLM_TIMEOUT(默认 60 秒)、TEMPERATURE(默认 0.7)、LOG_LEVEL(默认 INFO)。上下文构建的独立配置ContextConfig见上文表格;补丁确认阈值(6 个文件 / 400 行)对应Config.large_change_threshold_files/large_change_threshold_lines

约束与已知限制

  • 目前"敏感操作确认"优先覆盖:Delete Filegit reset --hardrm/chmod、大规模变更;更细粒度的策略(如按命令/路径/目录的白名单)后续可扩展;
  • TerminalTool仍是"字符串命令"入口,但非 shell 模式执行为 argv-only,并在工具内拦截 shell 语义(重定向/命令替换/危险命令需确认);更严格的参数级白名单可以继续收紧;
  • 补丁应用依赖上下文精确匹配,若文件在生成补丁后被改动,Update File可能失败并给出recheck_targets提示,需要人工复核;
  • 记忆默认只启用 episodic 类型,semantic/perceptual/working 等其他记忆类型(memory/types/下均有实现)未在 Code Agent 中启用。

相关文件索引

  • CLI 入口:code_agent/hello_code_cli.py
  • 主逻辑/上下文工程:code_agent/agentic/code_agent.py
  • 补丁执行器:code_agent/executors/apply_patch_executor.py
  • 提示词模板:code_agent/prompts/(system.md/react.md/plan.md/tools.md/summarize_observation.md
  • 终端安全工具:tools/builtin/terminal_tool.py
  • 上下文构建 GSSC:context/builder.py
  • 统一配置:core/config.py
  • 依赖清单:requirement.txt
  • 上下文工程原理解读:可对照仓库文档 docs/chapter9/第九章 上下文工程.md

如需深入理解 Code Agent 所依赖的组件原理,可继续阅读仓库agents/core/memory/tools/目录下的对应实现。

【免费下载链接】hello-agents📚 《从零开始构建智能体》——从零开始的智能体原理与实践教程项目地址: https://gitcode.com/GitHub_Trending/he/hello-agents

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询