Add multi-surface optimization: prompt, skills and tool descriptions - #17
Merged
Teq2412 merged 7 commits intoSep 17, 2026
Merged
Conversation
ToolDescriptionFormula holds a full base map of tool descriptions and a
sparse set of overrides. The overrides are the tunable parameter and the
only thing delivered, so unedited tools keep the runtime's own text and
the edited set stays visible. A name outside the base or a description
over 800 characters is dropped with a warning (raises under strict); an
empty string keeps the current text. from_yaml / render_effective_yaml
read and write the `tool_descriptions: {name: text}` shape.
StrandsAdapter now reports `tool_descriptions` in extract_context from the
agent's tool registry and patches the named tools in place on
update_context: `mcp_tool.description` for MCP tools, the `tool_spec` dict
for @tool functions. apply_to_agent checks that seam when a formula tunes
tool descriptions, so a missing registry fails at attach time with a clear
message rather than inside a hook.
Adds pyyaml as a dependency and documents the new formula and context key.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
MultiSurfaceFormula wraps a SystemPromptFormula, a SkillLibraryFormula and a ToolDescriptionFormula as one Formula, so an optimizer that edits several surfaces in one step still fits FormulaOptimizer's single-formula contract. get_tunable_params merges the members' parameters; update_params routes by key (system_prompt, decisions_dir/skill_dir, tool_descriptions) and leaves a member with no key untouched. process runs the members in order and returns only the keys that changed. collect_decisions now reads update/ alongside optimize/. It is the word the multi-surface templates use for a revised skill body under an existing name; aliasing it keeps one set algebra for both vocabularies. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The sandboxed Jinja environment had autoescape on. These templates render prompts for an LLM, not HTML, so a system prompt or skill description passed in as a variable came out with `"` as `"` and `<` as `<`, and the optimizer reasoned about text that was never in the agent. Sandboxing is unrelated to escaping and stays on. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…e pass One reflector agent reads a sample of traces plus a harness-computed census and objective table, is shown the current prompt, the deployed skills in full and the current tool descriptions, and writes only the surfaces it decided to change, plus a findings.json ledger, into a fresh output_folder/step_NNNN/. The harness then applies what is on disk through MultiSurfaceFormula.update_params and materializes the resolved skill set. Step outcome is decided by what is on disk: valid surfaces apply and invalid ones are dropped with a logged reason; all-invalid raises; no artifacts with a findings.json is a legitimate no-op; no artifacts and no ledger raises. Validation is structural only (frontmatter, YAML shape). Objective: TaskSuccessScore = Reward.reward by default. objective_weights names additional terms read from Reward.metadata["scores"]; a missing term raises before the agent runs. Trace files gain an `objective` block and `response.eval_result`, copied from the rollout's evaluator output. The reflector runs with shell and editor, a 120-message window with the task message pinned, and is rebuilt and re-run on transient Bedrock errors with agent-written paths cleared between attempts. The base class gains two hooks for this: _conversation_manager and _trace_extra. Templates ship verbatim under templates/multi_surface/. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Both example runtimes accept a `tool_descriptions` payload key: a sparse
{tool_name: description} of the tools the optimizer edited. The runtime
resets every tool to its docstring and then patches the named ones, so an
override the optimizer later drops does not linger on the long-lived agent.
It echoes `tool_descriptions_applied` next to `skills_applied`, and both
AgentCore rollout engines now keep those echoes in Rollout.metadata, where
the client can tell "the change did not help" from "it never reached the
agent".
Each runtime ships prompts/tool_descriptions.yaml, its tool descriptions as
the agent sees them, generated from the @tool docstrings by
dump_tool_descriptions.py; the optimizer starts from that map.
New clients *_multi_surface_optimization.py drive one MultiSurfaceOptimizer
across iterations, shipping prompt text, the packed skill set and the tool
overrides on every batch. run_example.sh gains --multi.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
python:3.12-slim now tracks Debian 13, which no longer ships openjdk-17-jdk-headless, so the image build fails at apt-get. Pinning the tag to -bookworm keeps JDK 17 and the JAVA_HOME paths the Dockerfiles already set. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Three integration test modules import it at collection time, so the CI test step (`hatch run test -x --strict-markers`) has failed at collection since the package was renamed, on main as well as on every PR. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Teq2412
previously approved these changes
Sep 16, 2026
Contributor
Author
|
@Teq2412 Pushed one commit on top of your review: python-dotenv declared as a dev dependency. CI's test step has been failing at collection since strands-agents 1.55 moved to mcp 2.x, which stopped pulling python-dotenv in transitively; main at 05bb1f9 has the same failure. Could you approve the workflow run and re-approve once it is green? |
Teq2412
self-requested a review
September 17, 2026 01:46
Teq2412
approved these changes
Sep 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
One reflector reads a sample of traces and edits the agent's system prompt, skill
library and tool descriptions together, placing each finding in the surface that
reaches the agent when it matters. Builds on the skill-library work in #15.
ToolDescriptionFormula: full base map plus sparse overrides; only the overridesare delivered, so unedited tools keep the runtime's own text.
StrandsAdapterpatches tool specs in place for in-process agents.
MultiSurfaceFormula: wraps the prompt, skill-library and tool-descriptionformulas as one
Formula.update_paramsroutes by key and is all-or-nothing.MultiSurfaceOptimizer: writes each step into a freshoutput_folder/step_NNNN/;applies whatever is structurally valid on disk, drops the rest with a reason,
raises when nothing usable was written and no
findings.jsonexplains why.Objective is
TaskSuccessScore = Reward.rewardby default;objective_weightsand
objective_definitionsadd terms read fromReward.metadata["scores"].tool_descriptionspayload key, echotool_descriptions_applied, and ship their tool descriptions as YAML. New*_multi_surface_optimization.pyclients;run_example.sh --multi.Two fixes as their own commits: the template environment HTML-escaped variables
(
"became"in every rendered prompt), and the WebShop Dockerfiles no longerbuilt after
python:3.12-slimmoved to Debian 13.Verification
assertions are deterministic.
prompt edit and one skill out, delivered to the live container, three real tasks
echoed
skills_applied=1and scored 1.0.By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.