AX Agent 도구·스킬 정합성 재구성 및 실행 품질 보강

변경 목적:
- AX Agent의 도구 이름, 내부 설정, 스킬 정책, 실행 루프 사이의 불일치를 줄이고 전체 동작 품질을 높인다.
- claw-code 수준의 일관된 동작 품질을 참고하되 AX 구조에 맞는 고유한 카탈로그·정규화 레이어로 재구성한다.

핵심 수정사항:
- 도구 canonical id, legacy alias, 탭 노출, 설정 카테고리, read-only 분류를 중앙 카탈로그로 통합했다.
- ToolRegistry, AgentLoopService, 병렬 실행 분류, 권한 처리, 훅 처리, 스킬 allowed-tools 해석이 같은 이름 체계를 사용하도록 정리했다.
- Agent 설정/일반 설정/도움말의 도구 카드와 훅 편집기, 스킬 설명을 현재 런타임 구조에 맞게 갱신했다.
- 컨텍스트 압축, intent gate, spawn agents, session learning, model prompt adapter, workspace context 관련 변경과 테스트 추가를 함께 반영했다.
- 문서 이력과 비교/로드맵 문서를 최신 상태로 갱신했다.

검증 결과:
- dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\verify_toolcat\ -p:IntermediateOutputPath=obj\verify_toolcat\ : 경고 0 / 오류 0
- dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj -c Release -v minimal --filter AgentToolCatalogTests -p:OutputPath=bin\verify_toolcat_tests\ -p:IntermediateOutputPath=obj\verify_toolcat_tests\ : 통과 8
This commit is contained in:
2026-04-14 17:52:46 +09:00
parent fa33b98f7e
commit 8cb08576d5
200 changed files with 13522 additions and 5764 deletions

View File

@@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using AxCopilot.Models;
using AxCopilot.Services;
using AxCopilot.Services.Agent;
namespace AxCopilot.Views;
@@ -166,6 +167,9 @@ public partial class ChatWindow
sb.AppendLine("\n" + _currentConversation.SystemCommand);
}
// P4: 워크스페이스 컨텍스트 자동 생성 + 주입
sb.Append(LoadWorkspaceContext(workFolder));
// 프로젝트 문맥 파일 (AGENTS.md) 주입
sb.Append(LoadProjectContext(workFolder));
@@ -178,7 +182,7 @@ public partial class ChatWindow
// 피드백 학습 컨텍스트 주입
sb.Append(BuildFeedbackContext());
return sb.ToString();
return ApplyModelPromptAdaptation(sb.ToString());
}
private string BuildCodeSystemPrompt()
@@ -330,6 +334,9 @@ public partial class ChatWindow
sb.AppendLine("\n" + sysCmd);
}
// P4: 워크스페이스 컨텍스트 자동 생성 + 주입
sb.Append(LoadWorkspaceContext(workFolder));
// 프로젝트 문맥 파일 (AGENTS.md) 주입
sb.Append(LoadProjectContext(workFolder));
@@ -342,7 +349,52 @@ public partial class ChatWindow
// 피드백 학습 컨텍스트 주입
sb.Append(BuildFeedbackContext());
return sb.ToString();
return ApplyModelPromptAdaptation(sb.ToString());
}
/// <summary>
/// ModelPromptLevel에 따라 모델 패밀리별 프롬프트 어댑테이션을 적용합니다.
/// "off"이면 원본 그대로 반환, "basic"이면 가벼운 규칙 추가, "detailed"이면 전용 프롬프트 적용.
/// </summary>
private string ApplyModelPromptAdaptation(string basePrompt)
{
var level = _settings.Settings.Llm.ModelPromptLevel ?? "off";
if (string.Equals(level, "off", StringComparison.OrdinalIgnoreCase))
return basePrompt;
var modelFamily = ResolveCurrentModelFamily();
return ModelPromptAdapter.AdaptSystemPrompt(basePrompt, modelFamily, level);
}
/// <summary>
/// 현재 활성 모델의 프롬프트 패밀리를 결정합니다.
/// RegisteredModel.PromptFamily → 자동 감지 → "default" 순서.
/// </summary>
private string ResolveCurrentModelFamily()
{
try
{
var (_, modelName) = _llm.GetCurrentModelInfo();
// RegisteredModel에 명시적 PromptFamily가 설정되어 있으면 우선 사용
var llm = _settings.Settings.Llm;
var registered = llm.RegisteredModels.FirstOrDefault(m =>
{
var decrypted = CryptoService.DecryptIfEnabled(m.EncryptedModelName, llm.EncryptionEnabled);
return string.Equals(decrypted, modelName, StringComparison.OrdinalIgnoreCase)
|| string.Equals(m.Alias, modelName, StringComparison.OrdinalIgnoreCase);
});
if (registered != null && !string.IsNullOrWhiteSpace(registered.PromptFamily))
return registered.PromptFamily.Trim().ToLowerInvariant();
// 자동 감지
return ModelPromptAdapter.DetectModelFamily(modelName);
}
catch
{
return "default";
}
}
private static string BuildSubAgentDelegationSection(bool codeMode)