Lazy loaded image
前沿技术
如何将 Claude Code 转换为特定领域的编码代理
字数 4365阅读时长 11 分钟
2025-9-13
2025-9-13
type
status
date
slug
summary
tags
category
icon
password
作者:Aliyan Ishfaq
编码代理擅长编写使用流行库的代码,LLMs 对这些库进行了大量训练。但如果你指向自定义库、库的新版本、内部 API 或小众框架——它们的表现就不那么好了。这对于使用领域特定库或企业代码的团队来说是个问题。
作为库(LangGraph、LangChain)的开发者,我们非常关注如何让这些编码代理在编写 LangGraph 和 LangChain 代码方面表现出色。我们尝试了多种上下文工程技术,有些有效,有些则无效。在这篇博文中,我们将分享我们进行的实验和获得的经验。我们最大的收获是:
高质量、精简的信息与按需获取更多详情的工具相结合,能产生最佳结果
让代理访问原始文档并没有像我们希望的那样提高性能。实际上,上下文窗口填充得更快了。以 Claude.md 形式提供的简洁、结构化指南总是胜过简单地接入文档工具。最佳结果来自于将两者结合,即代理拥有一些基础知识(通过 Claude.md ),但如果需要更多信息,也可以访问文档的特定部分。
notion image
在本文中,我们将分享:
  • 我们测试的不同 Claude Code 配置
  • 我们用于评估生成代码的评估框架(一个可以为您自己的库重复使用的模板)
  • 结果与关键要点

Claude Code 设置

我们测试了四种不同的配置,为保持一致性,均使用 Claude 4 Sonnet 作为模型:
Claude 原版:未经任何修改的 Claude Code 原始版本。
Claude + MCP:连接到我们 MCPDoc 服务器的 Claude Code,用于文档访问。
Claude + Claude.md:带有详细 Claude.md 文件的 Claude Code,包含 LangGraph 特定指导。
Claude + MCP + Claude.md:可访问详细 Claude.md 和 MCPDoc 服务器的 Claude。

用于文档的 MCP 工具

我们构建 MCPDoc 服务器是因为我们希望为编码代理提供访问任何库文档的能力。它是一个开源的 MCP 服务器,提供两个工具: list_doc_sources 和 fetch_docs 。第一个工具分享可用 llms.txt 文件的 URL,后者则读取特定的 llms.txt 文件。在我们的设置中,我们提供了对 LangGraph 和 LangChain 的 Python 和 JavaScript 文档的访问。您可以通过在 MCP 配置中传入您库的 llms.txt 文件的 URL,轻松地将其适配到您的用例中。
notion image

Claude.md

对于 Claude.md ,我们创建了一个 LangGraph 库指南。它包含了常见 LangGraph 项目结构要求的详细说明,例如创建文件前的强制代码库搜索、正确的导出模式以及部署最佳实践。它包含了构建单代理和多代理系统所需原语的示例代码,例如 create_react_agent 、监督者模式以及用于动态交接的群体模式。有一些实现是 LLMs 难以处理的,比如面向用户的代理的流式处理和人机交互。我们为这些添加了广泛的指导原则。
notion image
我们发现包含关于常见陷阱和反模式的全面章节特别有价值。这涵盖了常见错误,如不正确的 interrupt() 使用、错误的状态更新模式、类型假设错误以及过于复杂的实现。这些是我们经常看到 LLMs 犯的错误,原因是使用了过时的库或对其他框架的模式感到困惑。
我们还包含了 LangGraph 特定的编码标准,如结构化输出验证、正确的消息处理以及其他框架集成调试模式。由于 Claude 可以访问网络工具,我们在每个章节末尾添加了特定的文档 URL,以供进一步参考和导航指导。
这个文件与 llms.txt 的不同之处在于,前者是一个包含 URL 的页面全部内容的纯文本文件,而这个文件包含了从零开始时最重要的浓缩信息。正如我们将在结果中看到的,当单独传递 llms.txt 时,它并不是最有效的,因为它有时会让 LLMs 因更多上下文而感到困惑,并且没有关于如何导航和辨别重要内容的说明。
在介绍我们的 Claude Code 配置在不同任务中的表现之前,我们想先分享我们用于评估任务完成度和代码质量的评估框架。

评估

我们的目标是衡量什么对代码质量的贡献最大,而不仅仅是功能性。像 Pass@k 这样的流行指标只能捕捉功能性,而不能捕捉最佳实践,而最佳实践因上下文而异。
我们构建了一个特定任务的评估工具,它既能检查技术要求,也能评估主观方面,如代码质量、设计选择和对首选方法的遵循程度。
我们为评估定义了三个类别:
冒烟测试
这些测试验证基本功能。测试确认代码能够编译、暴露 .invoke() 方法、处理预期的输入状态,并返回预期的输出结构,如具有必需状态属性的 AIMessage 对象。
我们使用加权求和计算分数:
Score = Σᵢ wᵢ × cᵢ
其中 wi 是测试 i 的权重,ci 是测试的二进制结果。
任务需求测试
这些测试验证特定任务的功能。测试包括验证部署配置文件、验证对外部 API(如网络搜索或 LLM 提供商)的 HTTP 请求,以及针对每个编码任务的单元测试。评分通过对每个测试结果进行加权求和来完成,与冒烟测试相同。
代码质量与实现评估
对于这一类别,我们使用 LLM 作为评判者来捕捉二元测试所遗漏的内容。采用更好方法的实现应该比那些仅仅编译和运行的实现得分更高。代码质量、设计选择以及 LangGraph 抽象的使用都需要细致入微的评估。
我们审查了每个任务的专家编写的代码,并构建了特定任务的评分标准。使用温度设置为 0 的 Claude Sonnet 4( claude-sonnet-4-20250514 ),我们根据这些标准评估生成的代码,以专家编写的代码作为参考,并使用人工注释记录编译和运行时错误。
我们的评分标准有两种类型:
客观检查:这些是关于代码的二进制事实(例如特定节点的存在、正确的图结构、模块分离、测试文件的缺失)。LLM 评估器为每项检查返回一个布尔响应,我们使用加权求和(与冒烟测试相同)来获得客观检查的分数。
主观评估:这是使用专家编写的代码作为参考,并通过人工注释记录编译和运行错误日志来对代码进行的定性评估。LLM 评判器识别出问题,并按照严重程度(严重、主要、次要)在两个维度上进行分类:正确性违规和质量问题。
我们为此采用基于惩罚的评分机制:
分数 = 分数ₘₐₓ - Σₛ (nₛ × pₛ)
其中分数ₘₐₓ是可能获得的最高分数,nₛ是严重程度为 s 的违规数量,pₛ是该严重程度的惩罚权重。
综合客观和主观结果的整体评分如下:
分数 = Σᵢ wᵢ × cᵢ + Σₛ (Scoreₘₐₓ,ₛ - Σₛ (nₛ × pₛ))
其中第一项代表客观检查,第二项代表所有主观类别的评估。
我们为每个任务运行了三次 Claude Code 配置以考虑方差。为保持一致性,所有分数均以总可能分数的百分比报告,然后跨任务取平均值。
您可以使用 LangSmith 平台为自己的库复制此方法,以比较编码代理配置。

结果

我们通过平均三个不同 LangGraph 任务的分数来比较 Claude Code 的配置。下图显示了总体分数:
notion image
对我们来说,最有趣的发现是,Claude + Claude.md 的表现优于 Claude + MCP,尽管 Claude.md 只包含了 MCP 服务器所能提供功能的一部分。追踪记录解释了原因:Claude 并不像我们预期的那样频繁调用 MCP 工具。即使一项任务需要浏览两到三个链接页面,它通常只调用一次 MCP,然后就停留在主页面上,而这只能提供表面级别的描述,无法获得所需的详细信息。
相比之下,Claude + Claude.md + MCP 更有效地利用了文档。我们在追踪中观察到它更频繁地调用 MCP 工具,甚至在需要时触发网络搜索工具。这种行为是由 Claude.md 驱动的,它在每个部分的末尾包含了参考 URL,以便查找更多信息。
这并不意味着 MCP 工具本身没有帮助。它们将分数提高了约 10 个百分点,主要是通过让代理掌握基本语法和概念。但对于任务完成和代码质量而言, Claude.md 更为重要。该指南包含了需要避免的陷阱和需要遵循的原则,这帮助 Claude Code 更好地思考并探索库的不同部分,而不是停留在高层次描述上。
这些结果为任何配置编码代理的人指出了几个更广泛的教训。

关键要点

这些结果给我们带来了一些启示。如果你在考虑为自己的代码库定制编码代理,以下几点可能会有用:
上下文过载:从文档中转储大量 llms.txt 文件可能会挤占上下文窗口。这会导致性能下降和成本增加。我们的 MCP 服务器在获取页面内容方面有一个简单的实现,即使只调用一次,也会触发 Claude Code 的上下文窗口即将占满的警告。如果你的文档足够广泛以至于需要工具来检索特定文档,那么值得构建更智能的检索工具,只提取相关的代码片段。
Claude.md 的回报最高:它比 MCP 服务器或特定工具更容易设置,运行成本也更低。在任务#2 中,Claude + Claude.md 比 Claude MCP 和 Claude + Claude.md + MCP 便宜约 2.5 倍。它比 Claude MCP 更便宜,性能也更好。在考虑定制 Claude Code 时,这是一个很好的起点,对于某些用例来说可能已经足够好了。
编写良好的指令。 Claude.md (或 Agents.md )应突出显示库中的核心概念、独特功能和常见原语。手动审查失败的运行以找到反复出现的陷阱,并为此添加指导。对我们来说,这意味着在 LangGraph 中使用 Streamlit 处理异步任务,其中代理经常在 asyncio 集成上失败。我们还添加了启动开发服务器的调试步骤,这修复了导入错误,并让 Claude Code 能够向服务器发送请求以验证输出。流行的代码生成工具通常使用长系统提示(7-10k 令牌)。在指令上投入努力会带来相当好的回报。
Claude + Claude.md + MCP 胜出:虽然 Claude.md 每个令牌提供最大的效用,但最强的结果来自于将其与一个允许它详细阅读文档的 MCP 服务器配对。该指南提供了概念导向,而文档则有助于深入研究。它们一起可以在特定领域库上产生最佳结果。
在附录中,我们包含了每个任务的结果和类别级别的图表,供希望深入了解每个任务性能的读者参考。

附录

任务 #1:文本到 SQL 代理
我们要求每个配置构建一个基于 LangGraph 的文本转 SQL 代理,该代理能够从自然语言生成 SQL 查询,针对数据库执行查询,并返回自然语言响应。此任务需要从远程 URL 获取 Chinook SQLite 数据库并设置内存数据库。您可以在此处阅读我们传递给 Claude Code 实例的提示。
对于此任务,我们的冒烟测试验证了基本的 LangGraph 功能。任务要求检查了数据库设置;简单查询、连接查询、日期范围查询的 SQL 查询处理;以及 LLM 作为评估者对代码设计选择的评估,如远程 URL 获取、SQL 生成、执行和响应的独立节点。LLM 作为评估者的提示可在此处获取。
结果显示了 Claude Code 配置和类别之间的性能差异:
notion image
notion image
糟糕的实现通常难以在线程间连接内存数据库,在 LLM 提示中下载和硬编码模式,而不是使用带有运行时模式读取的远程 URL,并且未能正确解析 LLM 输出以执行 SQL(当 LLM 生成略微不同格式的结果时会中断)。
任务 #2:公司研究员
对于这项任务,我们要求每个 Claude 配置构建一个多节点 LangGraph 代理,该代理通过 Tavily API 使用网络搜索来研究公司。该代理需要处理结构化数据收集,实现并行搜索执行,并添加一个确保收集所有请求信息的反思步骤。您可以在此处阅读提示。
我们的测试验证了基本功能、Tavily API 集成以及结构化对象类中所有请求属性的存在。LLM 作为评判者检查了反思逻辑、最小搜索查询限制和并行网络搜索执行等功能的实现情况。
以下是此任务的结果:
notion image
notion image
大多数实现失败都与在状态和反思步骤中构建对象中的信息有关。糟糕的实现要么没有功能性的反思节点,要么未能触发额外的搜索。
任务 #3:记忆类别
这是一个编辑任务,我们为每个 Claude Code 配置提供了一个现有的记忆代理作为基础代码。我们要求它们扩展记忆存储方法,除了用户 ID 外,还要按类型(个人、专业、其他)对记忆进行分类,实现基于消息类别而非仅基于用户 ID 的选择性记忆检索,并在保存记忆前添加人工确认步骤。我们还故意添加了语法错误。完整提示可在此处查看。
通过测试,我们验证了实现是否正确地在记忆存储前添加了中断功能,实现了按类别存储和检索,使用了三个特定类别(个人、专业、其他),并保持了只有在用户接受时才保存记忆的功能中断逻辑。LLM 作为评估者评估了实现是否使用了基于 LLM 的分类而非脆弱的关键词匹配和不必要的文件。
对于编辑任务,我们看到以下结果:
notion image
notion image
大多数实现在正确实现中断功能方面遇到了困难。错误的实现要么添加简单的 input() 调用来获取终端输入,要么通过创建单独的节点而不是使用几行正确的中断逻辑来使解决方案过于复杂。糟糕的实现还依赖于关键词匹配进行分类,而不是基于 LLM 的分类,而且几乎所有实现都未能捕捉到我们故意包含的语法错误。
 
本文翻译自Langchain官方的《Writing effective tools for agents — with agents》
原文作者:Aliyan Ishfaq
原文链接:https://blog.langchain.com/how-to-turn-claude-code-into-a-domain-specific-coding-agent/
 
上一篇
Apple 应用开发及开发者注册
下一篇
智能体新时代:构建高效工具的关键策略与最佳实践